From 0bccc864fb912f44542893125d48d8137c54e757 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 2 Feb 2015 16:16:14 -0300 Subject: [PATCH] create address + test in wallet --- lib/model/addressable.js | 2 +- lib/model/copayer.js | 13 +++++++------ lib/model/wallet.js | 28 ++++++++++++++++++++++++++++ lib/server.js | 9 +++++++-- test/integration.js | 2 +- 5 files changed, 44 insertions(+), 10 deletions(-) diff --git a/lib/model/addressable.js b/lib/model/addressable.js index b62c1a4..b67d470 100644 --- a/lib/model/addressable.js +++ b/lib/model/addressable.js @@ -23,7 +23,7 @@ Addressable.prototype.addAddress = function (isChange) { }; Addressable.prototype.getCurrentAddressPath = function (isChange) { - return HDPath.Branch(isChange ? this.changeAddressIndex : this.receiveAddressIndex, isChange, this.copayerIndex); + return HDPath.FullBranch(isChange ? this.changeAddressIndex : this.receiveAddressIndex, isChange, this.copayerIndex); }; Addressable.prototype.getNewAddressPath = function (isChange) { diff --git a/lib/model/copayer.js b/lib/model/copayer.js index c642dcb..2ba89f2 100644 --- a/lib/model/copayer.js +++ b/lib/model/copayer.js @@ -13,15 +13,16 @@ var VERSION = '1.0.0'; var MESSAGE_SIGNING_PATH = "m/1/0"; function Copayer(opts) { - Copayer.super_.apply(this, arguments); opts = opts || {}; + opts.copayerIndex = opts.copayerIndex || 0; + Copayer.super_.apply(this, [opts]); this.version = VERSION; - this.createdOn = Math.floor(Date.now() / 1000); - this.id = opts.id; - this.name = opts.name; - this.xPubKey = opts.xPubKey; - this.xPubKeySignature = opts.xPubKeySignature; // So third parties can check independently + this.createdOn = Math.floor(Date.now() / 1000); + this.id = opts.id; + this.name = opts.name; + this.xPubKey = opts.xPubKey; + this.xPubKeySignature = opts.xPubKeySignature; // So third parties can check independently this.signingPubKey = opts.signingPubKey || this.getSigningPubKey(); }; diff --git a/lib/model/wallet.js b/lib/model/wallet.js index 358419a..40193f0 100644 --- a/lib/model/wallet.js +++ b/lib/model/wallet.js @@ -3,6 +3,10 @@ var _ = require('lodash'); var util = require('util'); +var Bitcore = require('bitcore'); +var BitcoreAddress = Bitcore.Address; + +var Address = require('./address'); var Copayer = require('./copayer'); var Addressable = require('./Addressable'); @@ -23,6 +27,7 @@ function Wallet(opts) { this.addressIndex = 0; this.copayers = []; this.pubKey = opts.pubKey; + this.isTestnet = false; }; /* For compressed keys, m*73 + n*34 <= 496 */ @@ -70,6 +75,7 @@ Wallet.fromObj = function (obj) { return new Copayer(copayer); }); x.pubKey = obj.pubKey; + x.isTestnet = obj.isTestnet; Wallet.super_.prototype.fromObj.apply(this, [obj]); return x; @@ -88,4 +94,26 @@ Wallet.prototype.getCopayer = function (copayerId) { return _.find(this.copayers, { id: copayerId }); }; + +Wallet.prototype._getBitcoreNetwork = function () { + return this.isTestnet ? Bitcore.Networks.testnet : Bitcore.Networks.livenet; +}; + + +Wallet.prototype.createAddress = function (path) { + + var publicKeys = _.map(this.copayers, function(copayer) { + var xpub = new Bitcore.HDPublicKey(copayer.xPubKey); + return xpub.derive(path).publicKey; + }); + + var bitcoreAddress = BitcoreAddress.createMultisig(publicKeys, this.m, this._getBitcoreNetwork()); + + return new Address({ + address: bitcoreAddress.toString(), + path: path, + }); +}; + + module.exports = Wallet; diff --git a/lib/server.js b/lib/server.js index 1e2c3e0..3fb6ad7 100644 --- a/lib/server.js +++ b/lib/server.js @@ -166,17 +166,22 @@ CopayServer.prototype._verifySignature = function(text, signature, pubKey) { */ CopayServer.prototype.createAddress = function (opts, cb) { var self = this; + var isChange = opts.isChange; Utils.checkRequired(opts, ['walletId', 'isChange']); Utils.runLocked(opts.walletId, cb, function (cb) { self.getWallet({ id: opts.walletId }, function (err, wallet) { if (err) return cb(err); - var index = wallet.addressIndex++; + + var copayer = wallet.copayers[0]; // TODO: Assign copayer from authentication. + + var path = copayer.getNewAddressPath(isChange); self.storage.storeWallet(wallet, function(err) { if (err) return cb(err); - var address = self._doCreateAddress(wallet.publicKeyRing, index, opts.isChange); + var address = wallet.createAddress(path); + self.storage.storeAddress(opts.walletId, address, function(err) { if (err) return cb(err); diff --git a/test/integration.js b/test/integration.js index 131a50f..de32579 100644 --- a/test/integration.js +++ b/test/integration.js @@ -479,7 +479,7 @@ describe('Copay server', function() { }); - it('should set pkr and status = complete on last copayer joining', function(done) { + it('should set pkr and status = complete on last copayer joining (2-3)', function(done) { helpers.createAndJoinWallet('123', 2, 3, function(err, wallet) { server.getWallet({ id: '123'