From 43f294876b5d1cd854735a6e091a9098b3c51faa Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Mon, 9 Mar 2015 18:11:25 -0300 Subject: [PATCH 1/5] use external requestPubKey & fix tests --- lib/model/copayer.js | 19 +--- lib/model/wallet.js | 6 -- lib/server.js | 8 +- test/integration/server.js | 179 ++++++++++++++++++++++--------------- test/testdata.js | 144 ++++++++++++++++++++--------- 5 files changed, 218 insertions(+), 138 deletions(-) diff --git a/lib/model/copayer.js b/lib/model/copayer.js index 2ab2287..505bf1a 100644 --- a/lib/model/copayer.js +++ b/lib/model/copayer.js @@ -16,7 +16,9 @@ function Copayer() { }; Copayer.create = function(opts) { - $.checkArgument(opts && opts.xPubKey, 'need to provide an xPubKey'); + opts = opts || {}; + $.checkArgument(opts.xPubKey, 'Missing extended public key'); + $.checkArgument(opts.requestPubKey, 'Missing request public key'); opts.copayerIndex = opts.copayerIndex || 0; @@ -28,7 +30,7 @@ Copayer.create = function(opts) { x.id = WalletUtils.xPubToCopayerId(x.xPubKey); x.name = opts.name; x.xPubKeySignature = opts.xPubKeySignature; // So third parties can check independently - x.requestPubKey = x.getRequestPubKey(); + x.requestPubKey = opts.requestPubKey; x.addressManager = AddressManager.create({ copayerIndex: opts.copayerIndex }); @@ -50,18 +52,5 @@ Copayer.fromObj = function(obj) { return x; }; -Copayer.prototype.getPublicKey = function(path) { - return HDPublicKey - .fromString(this.xPubKey) - .derive(path) - .publicKey - .toString(); -}; - -Copayer.prototype.getRequestPubKey = function() { - return this.getPublicKey('m/1/1'); -}; - - module.exports = Copayer; diff --git a/lib/model/wallet.js b/lib/model/wallet.js index eed1d9e..3453278 100644 --- a/lib/model/wallet.js +++ b/lib/model/wallet.js @@ -108,12 +108,6 @@ Wallet.prototype.getNetworkName = function() { return this.network; }; - -Wallet.prototype.getPublicKey = function(copayerId, path) { - var copayer = this.getCopayer(copayerId); - return copayer.getPublicKey(path); -}; - Wallet.prototype.isComplete = function() { return this.status == 'complete'; }; diff --git a/lib/server.js b/lib/server.js index f31c648..d34f7d9 100644 --- a/lib/server.js +++ b/lib/server.js @@ -191,13 +191,14 @@ WalletService.prototype._notify = function(type, data) { * @param {Object} opts * @param {string} opts.walletId - The wallet id. * @param {string} opts.name - The copayer name. - * @param {number} opts.xPubKey - Extended Public Key for this copayer. - * @param {number} opts.xPubKeySignature - Signature of xPubKey using the wallet pubKey. + * @param {string} opts.xPubKey - Extended Public Key for this copayer. + * @param {string} opts.xPubKeySignature - Signature of xPubKey using the wallet pubKey. + * @param {string} opts.requestPubKey - Public Key used to check requests from this copayer. */ WalletService.prototype.joinWallet = function(opts, cb) { var self = this; - if (!Utils.checkRequired(opts, ['walletId', 'name', 'xPubKey', 'xPubKeySignature'])) + if (!Utils.checkRequired(opts, ['walletId', 'name', 'xPubKey', 'xPubKeySignature', 'requestPubKey'])) return cb(new ClientError('Required argument missing')); if (_.isEmpty(opts.name)) @@ -224,6 +225,7 @@ WalletService.prototype.joinWallet = function(opts, cb) { xPubKey: opts.xPubKey, xPubKeySignature: opts.xPubKeySignature, copayerIndex: wallet.copayers.length, + requestPubKey: opts.requestPubKey, }); self.storage.fetchCopayerLookup(copayer.id, function(err, res) { diff --git a/test/integration/server.js b/test/integration/server.js index 011df7b..03f00b4 100644 --- a/test/integration/server.js +++ b/test/integration/server.js @@ -38,6 +38,36 @@ helpers.getAuthServer = function(copayerId, cb) { }); }; +helpers._generateCopayersTestData = function(n) { + console.log('var copayers = ['); + _.each(_.range(n), function(c) { + var xpriv = new Bitcore.HDPrivateKey(); + var xpub = Bitcore.HDPublicKey(xpriv); + + var xpriv_45H = xpriv.derive(45, true); + var xpub_45H = Bitcore.HDPublicKey(xpriv_45H); + var xpub_45H_sig = WalletUtils.signMessage(xpub_45H.toString(), TestData.keyPair.priv); + var id = WalletUtils.xPubToCopayerId(xpub_45H.toString()); + + var xpriv_1H = xpriv.derive(1, true); + var xpub_1H = Bitcore.HDPublicKey(xpriv_1H); + var priv = xpriv_1H.derive(0).privateKey; + var pub = xpub_1H.derive(0).publicKey; + + console.log('{id: ', "'" + id + "',"); + console.log('xPrivKey: ', "'" + xpriv.toString() + "',"); + console.log('xPubKey: ', "'" + xpub.toString() + "',"); + console.log('xPrivKey_45H: ', "'" + xpriv_45H.toString() + "',"); + console.log('xPubKey_45H: ', "'" + xpub_45H.toString() + "',"); + console.log('xPubKey_45H_Signature: ', "'" + xpub_45H_sig + "',"); + console.log('xPrivKey_1H: ', "'" + xpriv_1H.toString() + "',"); + console.log('xPubKey_1H: ', "'" + xpub_1H.toString() + "',"); + console.log('privKey_1H_0: ', "'" + priv.toString() + "',"); + console.log('pubKey_1H_0: ', "'" + pub.toString() + "'},"); + }); + console.log('];'); +}; + helpers.createAndJoinWallet = function(m, n, cb) { var server = new WalletService(); var copayerIds = []; @@ -56,8 +86,9 @@ helpers.createAndJoinWallet = function(m, n, cb) { var copayerOpts = { walletId: walletId, name: 'copayer ' + (i + 1), - xPubKey: TestData.copayers[i + offset].xPubKey, - xPubKeySignature: TestData.copayers[i + offset].xPubKeySignature, + xPubKey: TestData.copayers[i + offset].xPubKey_45H, + xPubKeySignature: TestData.copayers[i + offset].xPubKey_45H_Signature, + requestPubKey: TestData.copayers[i + offset].pubKey_1H_0, }; server.joinWallet(copayerOpts, function(err, result) { @@ -222,11 +253,7 @@ describe('Copay server', function() { helpers.createAndJoinWallet(1, 2, function(s, wallet) { var xpriv = TestData.copayers[0].xPrivKey; - var priv = Bitcore.HDPrivateKey - .fromString(xpriv) - .derive('m/1/1') - .privateKey - .toString(); + var priv = TestData.copayers[0].privKey_1H_0; var sig = WalletUtils.signMessage('hello world', priv); @@ -383,8 +410,9 @@ describe('Copay server', function() { var copayerOpts = { walletId: walletId, name: 'me', - xPubKey: TestData.copayers[0].xPubKey, - xPubKeySignature: TestData.copayers[0].xPubKeySignature, + xPubKey: TestData.copayers[0].xPubKey_45H, + xPubKeySignature: TestData.copayers[0].xPubKey_45H_Signature, + requestPubKey: TestData.copayers[0].pubKey_1H_0, }; server.joinWallet(copayerOpts, function(err, result) { should.not.exist(err); @@ -406,8 +434,9 @@ describe('Copay server', function() { var copayerOpts = { walletId: walletId, name: '', - xPubKey: TestData.copayers[0].xPubKey, - xPubKeySignature: TestData.copayers[0].xPubKeySignature, + xPubKey: TestData.copayers[0].xPubKey_45H, + xPubKeySignature: TestData.copayers[0].xPubKey_45H_Signature, + requestPubKey: TestData.copayers[0].pubKey_1H_0, }; server.joinWallet(copayerOpts, function(err, result) { should.not.exist(result); @@ -435,8 +464,9 @@ describe('Copay server', function() { var copayerOpts = { walletId: wallet.id, name: 'me', - xPubKey: TestData.copayers[1].xPubKey, - xPubKeySignature: TestData.copayers[1].xPubKeySignature, + xPubKey: TestData.copayers[1].xPubKey_45H, + xPubKeySignature: TestData.copayers[1].xPubKey_45H_Signature, + requestPubKey: TestData.copayers[1].pubKey_1H_0, }; server.joinWallet(copayerOpts, function(err) { should.exist(err); @@ -451,8 +481,9 @@ describe('Copay server', function() { var copayerOpts = { walletId: walletId, name: 'me', - xPubKey: TestData.copayers[0].xPubKey, - xPubKeySignature: TestData.copayers[0].xPubKeySignature, + xPubKey: TestData.copayers[0].xPubKey_45H, + xPubKeySignature: TestData.copayers[0].xPubKey_45H_Signature, + requestPubKey: TestData.copayers[0].pubKey_1H_0, }; server.joinWallet(copayerOpts, function(err) { should.not.exist(err); @@ -469,8 +500,9 @@ describe('Copay server', function() { var copayerOpts = { walletId: walletId, name: 'me', - xPubKey: TestData.copayers[0].xPubKey, - xPubKeySignature: TestData.copayers[0].xPubKeySignature, + xPubKey: TestData.copayers[0].xPubKey_45H, + xPubKeySignature: TestData.copayers[0].xPubKey_45H_Signature, + requestPubKey: TestData.copayers[0].pubKey_1H_0, }; server.joinWallet(copayerOpts, function(err) { should.not.exist(err); @@ -486,8 +518,9 @@ describe('Copay server', function() { copayerOpts = { walletId: walletId, name: 'me', - xPubKey: TestData.copayers[0].xPubKey, - xPubKeySignature: TestData.copayers[0].xPubKeySignature, + xPubKey: TestData.copayers[0].xPubKey_45H, + xPubKeySignature: TestData.copayers[0].xPubKey_45H_Signature, + requestPubKey: TestData.copayers[0].pubKey_1H_0, }; server.joinWallet(copayerOpts, function(err) { should.exist(err); @@ -503,8 +536,9 @@ describe('Copay server', function() { var copayerOpts = { walletId: walletId, name: 'me', - xPubKey: TestData.copayers[0].xPubKey, + xPubKey: TestData.copayers[0].xPubKey_45H, xPubKeySignature: 'bad sign', + requestPubKey: TestData.copayers[0].pubKey_1H_0, }; server.joinWallet(copayerOpts, function(err) { err.message.should.equal('Bad request'); @@ -516,7 +550,7 @@ describe('Copay server', function() { var copayerOpts = { walletId: walletId, name: 'me', - xPubKey: TestData.copayers[0].xPubKey[0], + xPubKey: TestData.copayers[0].xPubKey_45H, }; server.joinWallet(copayerOpts, function(err) { should.exist(err); @@ -529,8 +563,9 @@ describe('Copay server', function() { var copayerOpts = { walletId: walletId, name: 'me', - xPubKey: TestData.copayers[0].xPubKey, - xPubKeySignature: TestData.copayers[1].xPubKeySignature, + xPubKey: TestData.copayers[0].xPubKey_45H, + xPubKeySignature: TestData.copayers[1].xPubKey_45H_Signature, + requestPubKey: TestData.copayers[0].pubKey_1H_0, }; server.joinWallet(copayerOpts, function(err) { err.message.should.equal('Bad request'); @@ -601,7 +636,7 @@ describe('Copay server', function() { server.createAddress({}, function(err, address) { should.not.exist(err); address.should.exist; - address.address.should.equal('38Jf1QE7ddXscW76ACgJrNkMWBwDAgMm6M'); + address.address.should.equal('3KxttbKQQPWmpsnXZ3rB4mgJTuLnVR7frg'); address.isChange.should.be.false; address.path.should.equal('m/2147483647/0/0'); done(); @@ -636,7 +671,7 @@ describe('Copay server', function() { server.createAddress({}, function(err, address) { should.not.exist(err); address.should.exist; - address.address.should.equal('38Jf1QE7ddXscW76ACgJrNkMWBwDAgMm6M'); + address.address.should.equal('3KxttbKQQPWmpsnXZ3rB4mgJTuLnVR7frg'); address.path.should.equal('m/2147483647/0/0'); done(); }); @@ -731,8 +766,9 @@ describe('Copay server', function() { var copayerOpts = { walletId: walletId, name: 'me', - xPubKey: TestData.copayers[0].xPubKey, - xPubKeySignature: TestData.copayers[0].xPubKeySignature, + xPubKey: TestData.copayers[0].xPubKey_45H, + xPubKeySignature: TestData.copayers[0].xPubKey_45H_Signature, + requestPubKey: TestData.copayers[0].pubKey_1H_0, }; server.joinWallet(copayerOpts, function(err, result) { should.not.exist(err); @@ -761,8 +797,9 @@ describe('Copay server', function() { var copayerOpts = { walletId: walletId, name: 'me', - xPubKey: TestData.copayers[0].xPubKey, - xPubKeySignature: TestData.copayers[0].xPubKeySignature, + xPubKey: TestData.copayers[0].xPubKey_45H, + xPubKeySignature: TestData.copayers[0].xPubKey_45H_Signature, + requestPubKey: TestData.copayers[0].pubKey_1H_0, }; server.joinWallet(copayerOpts, function(err, result) { should.not.exist(err); @@ -792,7 +829,7 @@ describe('Copay server', function() { it('should create a tx', function(done) { helpers.stubUtxos(server, wallet, [100, 200], function() { - var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 80, 'some message', TestData.copayers[0].privKey); + var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 80, 'some message', TestData.copayers[0].privKey_1H_0); server.createTx(txOpts, function(err, tx) { should.not.exist(err); should.exist(tx); @@ -836,7 +873,7 @@ describe('Copay server', function() { it('should fail to create tx with proposal signed by another copayer', function(done) { helpers.stubUtxos(server, wallet, [100, 200], function() { - var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 80, null, TestData.copayers[1].privKey); + var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 80, null, TestData.copayers[1].privKey_1H_0); server.createTx(txOpts, function(err, tx) { should.not.exist(tx); @@ -849,7 +886,7 @@ describe('Copay server', function() { it('should fail to create tx for invalid address', function(done) { helpers.stubUtxos(server, wallet, [100, 200], function() { - var txOpts = helpers.createProposalOpts('invalid address', 80, null, TestData.copayers[0].privKey); + var txOpts = helpers.createProposalOpts('invalid address', 80, null, TestData.copayers[0].privKey_1H_0); server.createTx(txOpts, function(err, tx) { should.not.exist(tx); @@ -863,7 +900,7 @@ describe('Copay server', function() { it('should fail to create tx for address of different network', function(done) { helpers.stubUtxos(server, wallet, [100, 200], function() { - var txOpts = helpers.createProposalOpts('myE38JHdxmQcTJGP1ZiX4BiGhDxMJDvLJD', 80, null, TestData.copayers[0].privKey); + var txOpts = helpers.createProposalOpts('myE38JHdxmQcTJGP1ZiX4BiGhDxMJDvLJD', 80, null, TestData.copayers[0].privKey_1H_0); server.createTx(txOpts, function(err, tx) { should.not.exist(tx); @@ -876,7 +913,7 @@ describe('Copay server', function() { }); it('should fail to create tx for invalid amount', function(done) { - var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 0, null, TestData.copayers[0].privKey); + var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 0, null, TestData.copayers[0].privKey_1H_0); server.createTx(txOpts, function(err, tx) { should.not.exist(tx); should.exist(err); @@ -887,7 +924,7 @@ describe('Copay server', function() { it('should fail to create tx when insufficient funds', function(done) { helpers.stubUtxos(server, wallet, [100], function() { - var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 120, null, TestData.copayers[0].privKey); + var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 120, null, TestData.copayers[0].privKey_1H_0); server.createTx(txOpts, function(err, tx) { should.exist(err); err.code.should.equal('INSUFFICIENTFUNDS'); @@ -908,7 +945,7 @@ describe('Copay server', function() { it('should fail to create tx when insufficient funds for fee', function(done) { helpers.stubUtxos(server, wallet, [100], function() { - var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 100, null, TestData.copayers[0].privKey); + var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 100, null, TestData.copayers[0].privKey_1H_0); server.createTx(txOpts, function(err, tx) { should.exist(err); err.code.should.equal('INSUFFICIENTFUNDS'); @@ -920,7 +957,7 @@ describe('Copay server', function() { it('should fail to create tx for dust amount', function(done) { helpers.stubUtxos(server, wallet, [1], function() { - var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 0.00000001, null, TestData.copayers[0].privKey); + var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 0.00000001, null, TestData.copayers[0].privKey_1H_0); server.createTx(txOpts, function(err, tx) { should.exist(err); err.code.should.equal('DUSTAMOUNT'); @@ -937,7 +974,7 @@ describe('Copay server', function() { name: 'dummy', message: 'dummy exception' }); - var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 2, null, TestData.copayers[0].privKey); + var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 2, null, TestData.copayers[0].privKey_1H_0); server.createTx(txOpts, function(err, tx) { should.exist(err); err.message.should.equal('dummy exception'); @@ -949,11 +986,11 @@ describe('Copay server', function() { it('should create tx when there is a pending tx and enough UTXOs', function(done) { helpers.stubUtxos(server, wallet, [10.1, 10.2, 10.3], function() { - var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 12, null, TestData.copayers[0].privKey); + var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 12, null, TestData.copayers[0].privKey_1H_0); server.createTx(txOpts, function(err, tx) { should.not.exist(err); should.exist(tx); - var txOpts2 = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 8, null, TestData.copayers[0].privKey); + var txOpts2 = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 8, null, TestData.copayers[0].privKey_1H_0); server.createTx(txOpts2, function(err, tx) { should.not.exist(err); should.exist(tx); @@ -974,11 +1011,11 @@ describe('Copay server', function() { it('should fail to create tx when there is a pending tx and not enough UTXOs', function(done) { helpers.stubUtxos(server, wallet, [10.1, 10.2, 10.3], function() { - var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 12, null, TestData.copayers[0].privKey); + var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 12, null, TestData.copayers[0].privKey_1H_0); server.createTx(txOpts, function(err, tx) { should.not.exist(err); should.exist(tx); - var txOpts2 = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 24, null, TestData.copayers[0].privKey); + var txOpts2 = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 24, null, TestData.copayers[0].privKey_1H_0); server.createTx(txOpts2, function(err, tx) { err.code.should.equal('INSUFFICIENTFUNDS'); err.message.should.equal('Insufficient funds'); @@ -1005,7 +1042,7 @@ describe('Copay server', function() { should.not.exist(err); balance.totalAmount.should.equal(helpers.toSatoshi(N * 100)); balance.lockedAmount.should.equal(helpers.toSatoshi(0)); - var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 80, null, TestData.copayers[0].privKey); + var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 80, null, TestData.copayers[0].privKey_1H_0); async.map(_.range(N), function(i, cb) { server.createTx(txOpts, function(err, tx) { cb(err, tx); @@ -1036,7 +1073,7 @@ describe('Copay server', function() { server = s; wallet = w; helpers.stubUtxos(server, wallet, _.range(1, 9), function() { - var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 10, null, TestData.copayers[0].privKey); + var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 10, null, TestData.copayers[0].privKey_1H_0); server.createTx(txOpts, function(err, tx) { should.not.exist(err); should.exist(tx); @@ -1126,7 +1163,7 @@ describe('Copay server', function() { server = s; wallet = w; helpers.stubUtxos(server, wallet, _.range(1, 9), function() { - var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 10, null, TestData.copayers[0].privKey); + var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 10, null, TestData.copayers[0].privKey_1H_0); server.createTx(txOpts, function(err, tx) { should.not.exist(err); should.exist(tx); @@ -1142,7 +1179,7 @@ describe('Copay server', function() { var tx = txs[0]; tx.id.should.equal(txid); - var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey); + var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey_45H); server.signTx({ txProposalId: txid, signatures: signatures, @@ -1169,7 +1206,7 @@ describe('Copay server', function() { server.getPendingTxs({}, function(err, txs) { var tx = txs[0]; tx.id.should.equal(txid); - var signatures = helpers.clientSign(tx, TestData.copayers[1].xPrivKey); + var signatures = helpers.clientSign(tx, TestData.copayers[1].xPrivKey_45H); server.signTx({ txProposalId: txid, signatures: signatures, @@ -1185,7 +1222,7 @@ describe('Copay server', function() { var tx = txs[0]; tx.id.should.equal(txid); - var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey); + var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey_45H); signatures[0] = 1; server.signTx({ @@ -1220,7 +1257,7 @@ describe('Copay server', function() { var tx = txs[0]; tx.id.should.equal(txid); - var signatures = _.take(helpers.clientSign(tx, TestData.copayers[0].xPrivKey), 2); + var signatures = _.take(helpers.clientSign(tx, TestData.copayers[0].xPrivKey_45H), 2); server.signTx({ txProposalId: txid, signatures: signatures, @@ -1237,7 +1274,7 @@ describe('Copay server', function() { var tx = txs[0]; tx.id.should.equal(txid); - var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey); + var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey_45H); server.signTx({ txProposalId: txid, signatures: signatures, @@ -1260,7 +1297,7 @@ describe('Copay server', function() { server.rejectTx({ txProposalId: txid, }, function(err) { - var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey); + var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey_45H); server.signTx({ txProposalId: txid, signatures: signatures, @@ -1308,7 +1345,7 @@ describe('Copay server', function() { txProposalId: txid }, function(err, tx) { should.not.exist(err); - var signatures = helpers.clientSign(tx, TestData.copayers[2].xPrivKey); + var signatures = helpers.clientSign(tx, TestData.copayers[2].xPrivKey_45H); server.signTx({ txProposalId: txid, signatures: signatures, @@ -1331,11 +1368,11 @@ describe('Copay server', function() { server = s; wallet = w; helpers.stubUtxos(server, wallet, [10, 10], function() { - var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 9, 'some message', TestData.copayers[0].privKey); + var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 9, 'some message', TestData.copayers[0].privKey_1H_0); server.createTx(txOpts, function(err, txp) { should.not.exist(err); should.exist(txp); - var signatures = helpers.clientSign(txp, TestData.copayers[0].xPrivKey); + var signatures = helpers.clientSign(txp, TestData.copayers[0].xPrivKey_45H); server.signTx({ txProposalId: txp.id, signatures: signatures, @@ -1390,7 +1427,7 @@ describe('Copay server', function() { it('should fail to brodcast a not yet accepted tx', function(done) { helpers.stubBroadcast('999'); - var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 9, 'some other message', TestData.copayers[0].privKey); + var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 9, 'some other message', TestData.copayers[0].privKey_1H_0); server.createTx(txOpts, function(err, txp) { should.not.exist(err); should.exist(txp); @@ -1438,7 +1475,7 @@ describe('Copay server', function() { }); it('other copayers should see pending proposal created by one copayer', function(done) { - var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 10, 'some message', TestData.copayers[0].privKey); + var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 10, 'some message', TestData.copayers[0].privKey_1H_0); server.createTx(txOpts, function(err, txp) { should.not.exist(err); should.exist(txp); @@ -1459,7 +1496,7 @@ describe('Copay server', function() { async.waterfall([ function(next) { - var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 10, 'some message', TestData.copayers[0].privKey); + var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 10, 'some message', TestData.copayers[0].privKey_1H_0); server.createTx(txOpts, function(err, txp) { txpId = txp.id; should.not.exist(err); @@ -1477,7 +1514,7 @@ describe('Copay server', function() { }); }, function(txp, next) { - var signatures = helpers.clientSign(txp, TestData.copayers[0].xPrivKey); + var signatures = helpers.clientSign(txp, TestData.copayers[0].xPrivKey_45H); server.signTx({ txProposalId: txpId, signatures: signatures, @@ -1508,7 +1545,7 @@ describe('Copay server', function() { }, function(txp, next) { helpers.getAuthServer(wallet.copayers[1].id, function(server, wallet) { - var signatures = helpers.clientSign(txp, TestData.copayers[1].xPrivKey); + var signatures = helpers.clientSign(txp, TestData.copayers[1].xPrivKey_45H); server.signTx({ txProposalId: txpId, signatures: signatures, @@ -1545,7 +1582,7 @@ describe('Copay server', function() { async.waterfall([ function(next) { - var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 10, 'some message', TestData.copayers[0].privKey); + var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 10, 'some message', TestData.copayers[0].privKey_1H_0); server.createTx(txOpts, function(err, txp) { txpId = txp.id; should.not.exist(err); @@ -1627,7 +1664,7 @@ describe('Copay server', function() { server = s; wallet = w; helpers.stubUtxos(server, wallet, 10, function() { - var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 9, 'some message', TestData.copayers[0].privKey); + var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 9, 'some message', TestData.copayers[0].privKey_1H_0); server.createTx(txOpts, function(err, txp) { should.not.exist(err); should.exist(txp); @@ -1675,7 +1712,7 @@ describe('Copay server', function() { server = s; wallet = w; helpers.stubUtxos(server, wallet, _.range(10), function() { - var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 0.1, null, TestData.copayers[0].privKey); + var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 0.1, null, TestData.copayers[0].privKey_1H_0); async.eachSeries(_.range(10), function(i, next) { clock.tick(10000); server.createTx(txOpts, function(err, tx) { @@ -1757,7 +1794,7 @@ describe('Copay server', function() { server = s; wallet = w; helpers.stubUtxos(server, wallet, helpers.toSatoshi(_.range(4)), function() { - var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 0.01, null, TestData.copayers[0].privKey); + var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 0.01, null, TestData.copayers[0].privKey_1H_0); async.eachSeries(_.range(3), function(i, next) { server.createTx(txOpts, function(err, tx) { should.not.exist(err); @@ -1812,7 +1849,7 @@ describe('Copay server', function() { server.getPendingTxs({}, function(err, txs) { helpers.stubBroadcastFail(); var tx = txs[0]; - var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey); + var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey_45H); server.signTx({ txProposalId: tx.id, signatures: signatures, @@ -1854,7 +1891,7 @@ describe('Copay server', function() { it('should notify sign, acceptance, and broadcast, and emit', function(done) { server.getPendingTxs({}, function(err, txs) { var tx = txs[2]; - var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey); + var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey_45H); sinon.spy(server, 'emit'); server.signTx({ txProposalId: tx.id, @@ -1973,7 +2010,7 @@ describe('Copay server', function() { server = s; wallet = w; helpers.stubUtxos(server, wallet, [100, 200], function() { - var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 80, 'some message', TestData.copayers[0].privKey); + var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 80, 'some message', TestData.copayers[0].privKey_1H_0); server.createTx(txOpts, function(err, tx) { server.getPendingTxs({}, function(err, txs) { txp = txs[0]; @@ -1997,7 +2034,7 @@ describe('Copay server', function() { }); it('should allow creator to remove an signed TX by himself', function(done) { - var signatures = helpers.clientSign(txp, TestData.copayers[0].xPrivKey); + var signatures = helpers.clientSign(txp, TestData.copayers[0].xPrivKey_45H); server.signTx({ txProposalId: txp.id, signatures: signatures, @@ -2019,7 +2056,7 @@ describe('Copay server', function() { async.waterfall([ function(next) { - var signatures = helpers.clientSign(txp, TestData.copayers[0].xPrivKey); + var signatures = helpers.clientSign(txp, TestData.copayers[0].xPrivKey_45H); server.signTx({ txProposalId: txp.id, signatures: signatures, @@ -2083,7 +2120,7 @@ describe('Copay server', function() { it('should not allow creator copayer to remove an TX signed by other copayer', function(done) { helpers.getAuthServer(wallet.copayers[1].id, function(server2) { - var signatures = helpers.clientSign(txp, TestData.copayers[1].xPrivKey); + var signatures = helpers.clientSign(txp, TestData.copayers[1].xPrivKey_45H); server2.signTx({ txProposalId: txp.id, signatures: signatures, @@ -2215,12 +2252,12 @@ describe('Copay server', function() { server._normalizeTxHistory = sinon.stub().returnsArg(0); helpers.stubUtxos(server, wallet, [100, 200], function(utxos) { - var txOpts = helpers.createProposalOpts(mainAddresses[0].address, 80, 'some message', TestData.copayers[0].privKey); + var txOpts = helpers.createProposalOpts(mainAddresses[0].address, 80, 'some message', TestData.copayers[0].privKey_1H_0); server.createTx(txOpts, function(err, tx) { should.not.exist(err); should.exist(tx); - var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey); + var signatures = helpers.clientSign(tx, TestData.copayers[0].xPrivKey_45H); server.signTx({ txProposalId: tx.id, signatures: signatures, diff --git a/test/testdata.js b/test/testdata.js index 76e4ecc..62f7312 100644 --- a/test/testdata.js +++ b/test/testdata.js @@ -5,63 +5,121 @@ var keyPair = { var message = { text: 'hello world', - signature: '304402204c5c754f35ac3f4766f246a71f956dee8233964a51991c261f2611c79e906641022070cb6ed2b1c3afae8110f110f332bebf30b3154ff8cf56fb1fe8db5cc09ce07d', // with e57d978f1d4a43df38a451ca2adf70c0416c202a89badf068e0d6de2023879cc (m/1/1 of copayer's xpriv) + signature: '30440220091598edbe4b45d41b551c941f24401fd3d72a8ccd18721dbfc58be9bdc234d802203870d36cf1fee89bb78cf161334849774c5684d287a74a9bd6681ee5e012150d', // Signed with copayer[0].privKey_1H_0 }; var copayers = [{ - id: '03bc5f0504c8dd480926dbe90449ccc7b2fc4c96e79f1cb8ffcd31731e2ee8db9b', - xPrivKey: 'xprv9s21ZrQH143K2rMHbXTJmWTuFx6ssqn1vyRoZqPkCXYchBSkp5ey8kMJe84sxfXq5uChWH4gk94rWbXZt2opN9kg4ufKGvUM7HQSLjnoh7e', - xPubKey: 'xpub661MyMwAqRbcFLRkhYzK8eQdoywNHJVsJCMQNDoMks5bZymuMcyDgYfnVQYq2Q9npnVmdTAthYGc3N3uxm5sEdnTpSqBc4YYTAhNnoSxCm9', - xPubKeySignature: '30440220192ae7345d980f45f908bd63ccad60ce04270d07b91f1a9d92424a07a38af85202201591f0f71dd4e79d9206d2306862e6b8375e13a62c193953d768e884b6fb5a46', // signed using keyPair.priv - privKey: 'e57d978f1d4a43df38a451ca2adf70c0416c202a89badf068e0d6de2023879cc', // derived with 'm/1/1' + id: 'ec2dd28c76367b6cfbf4a8d7cc17c9473fd78c995092a83e1776e1be43a30dc6', + xPrivKey: 'xprv9s21ZrQH143K2TjAA6HcG4p2eikKc4qQMVekTPqwNcesQ89nFZHzHKmekbwMKeiK6cPSzmqAavdemUS6VUzhGc5Uf4TCtjBa9qwDfbnWQcJ', + xPubKey: 'xpub661MyMwAqRbcEwodG7pcdCkmCkap1XZFiiaMFnFYvxBrGvUvo6cEq868bukLYM938wPm1CMzFuvbDQbA2tJvsWKgTz4xDKTyEfbQvBbo1AR', + xPrivKey_45H: 'xprv9uZiJ2ZYFNQ3RDBvjtz1HcivbfWbncMAb6EvKKose8rUbRo9dwX5hnThGodivCDuV8s48xZk7DZSuNpYb9ZwCpsatsnibRyirQbqqroftMP', + xPubKey_45H: 'xpub68Z4hY6S5jxLdhGPqvX1ekff9hM6C551xKAX7iDVCUPTUE8JBUqLFanB8697EoXbwN5rjDLHgPWkbofr8otNeb8Kr8SSh8pCiNMp7sWkBj4', + xPubKey_45H_Signature: '3045022100bd2c10387236c29b4171d7584f72427c858de8bc24c03ee71e933a616d2a2053022034cd1bf5efb53bd9c860e12398d3aab75a02a8ef3e057c2bda1098e6a98b9e52', + xPrivKey_1H: 'xprv9uZiJ2ZYFNQ1WeKrKfTxrbUnXfNnCtpbdHVuUMSVGB57nhbmjqWbJBQbgGNa2jSbrgQX9NFHXtAoQ3y1hsEgwjKHxUU52ZYTC6m5kjXoNpJ', + xPubKey_1H: 'xpub68Z4hY6S5jxJj8QKRgzyDjRX5hDGcMYSzWRWGjr6pWc6fVvvHNpqqyj5XXbMcfW737beYZcd7EQau5HS74Ws6Ctx9XwFn2wHQjSUKLbfdFk', + privKey_1H_0: 'e334a0ce3d573bd99fc4cd7e2065e39dc7851cb61da7f381431c253c3e230828', + pubKey_1H_0: '02db35c363e2c904bba3cd0eadb6b8d68fc1d8e6160d632b8fb91a471b80e40c86' }, { - id: '0235223413f8219260aa892c518969701af7c339284afecc7044f98dd47d48754b', - xPrivKey: 'xprv9s21ZrQH143K2JgXh8Va3Taq22D2gXw2nYULffV5dc9acQvAmB3KhomPKGwV9AbVsBcAXMW2QxCnvmHU1rVtHRfZwTxdEEAN5ZojRYdryQ1', - xPubKey: 'xpub661MyMwAqRbcEnkzoA2aQbXZa43X5zet9mPwU3thBwgZVDFKJiMaFc5sAYS97qVtMxpvceittobtoH2JKmpweSN1CLSe91hiE1Wrf5YJhsQ', - xPubKeySignature: '3045022100b9079d0d9b70da828b0e9c776fe01c5c13fc254a314c0b09a638c8695ec9360c022079922950779080569163c692ed8ee882f9ef37e7b2dff03de9c6756e7599960e', + id: 'cf652642ebf997460d642231f9929c39257bcd4c42e9ecb312c226961e21c882', + xPrivKey: 'xprv9s21ZrQH143K2XtR13LpXVAPaGTFsPY5dJfNvNTShfhdVW16vdDaYGjLwHmyKLCtv3F6h9NpKsAGusmKCZNQvKcYqYf9MjCLwJwsoEyAuge', + xPubKey: 'xpub661MyMwAqRbcF1xt74sptd788JHkGrFvzXayiks4G1EcNJLFUAXq653pncPaLt6vcEARqSHopD8PHT5PWkDryuZNBYpxX5wUdeV7DtgjKoL', + xPrivKey_45H: 'xprv9v8AzYcRrUwmJQGbDDKXvydEG2NZZDqXn9J3B6au2S8yhLfJyQidhZgMfTpFxBqAkUxgtTDc9JWFt4JaTmwKNLGxr6oSKjpaheQ5EG8jHz6', + xPubKey_45H: 'xpub697XQ49KgrW4WtM4KErYJ7Zxp4D3xgZP9NDdyUzWamfxa8zTWx2tFMzqWktiJG1yDo6mYpp8NAySfzRS8JoJyz2Br26vARWY9d9QAJdYFYh', + xPubKey_45H_Signature: '304402200b307113a4a3108a986db5247a04651b908a7fc2dadc940e3b71f9ecd862d980022056a2a5b6f5d7d2c4c4dd88a990c774b65990ad39ee4f0bb7c0c86a4a23b41be6', + xPrivKey_1H: 'xprv9v8AzYcRrUwjNBGAL5pzBaLvDBwepj9YVDM5UHjZXYYdoAxi9uaJjALUKPRcMxZZWq265CZuEfhTbwE6BD1tndRGESV4Jbr4c3pLanhnZHm', + xPubKey_1H: 'xpub697XQ49KgrW2afLdS7MzYiHemDn9EBsPrSGgGg9B5t5cfyHrhStZGxexAdekvK84XDZGunARoEzzHWmPjPwaRkKJwV2KWiRcHxVPfwwWKtg', + privKey_1H_0: '64274141d3ed98d3ee159409939627bd32229eac8b29cddc4c744c4e7f20235f', + pubKey_1H_0: '02787e683b17a4729e4e9405f80b74fb19b369133dd1c98b801230ae6603cc28aa' }, { - id: '023f31628856799ce6a12d02d362fbf6acc2c112207eeeb7bd34a048ec2127645d', - xPrivKey: 'xprv9s21ZrQH143K2DoxHNrecLmp121HU4nZRB57jj2cGmSkp9Wrgz2AevFT98AcYocYXEyyWDwC1JUn13beDjQU87FwfCaHiWhgoSx9G31tmDa', - xPubKey: 'xpub661MyMwAqRbcEhtRPQPeyUiYZ3qmsXWQnPziY7SDq6yjgwr1EXLRCiZvzQsfnQehH8hBzCxNPYCJXx51QKcbervpkBK931H1A9F39z5E1XD', - xPubKeySignature: '3045022100ed04aca131acf6f030018a7e3dd564788bbad5528e9edb7880f032ae6917bf10022022879ca8a60700c9c3bf9d603ae2555d4be1914084c912579b4bc09a432e9c32', + id: 'ff98c0b625e7824219f6a8054470a332ce1bdc9bb5a46a57eb424ed0848c0183', + xPrivKey: 'xprv9s21ZrQH143K3F4gznfMiq1rFLNAJbWnC9HJdkdrL7xpt4YxeLWRJTPXFvMn5Ky8rqaunWNTxwrLF6Nhptjyq8mAJvmc13R3fRJLDWWmgon', + xPubKey: 'xpub661MyMwAqRbcFj9A6pCN5xxaoNCei4EdZNCuS93TtTVokrt7BspfrFi17DdM2Z4HYYseVoZ2nmeu5mCvsn8gYGyW94m7EfXQDbXymLw2Yi1', + xPrivKey_45H: 'xprv9vUaCxyzkmLHHUpZZFUvh9oqzm9R6UMCTsJn8F7mDN3AR7rwLobojATJYgSx3pJjrv3EWCaSYeBjhouiM1m9Y9kAHAku3ZiAxZyWRxQZyHf', + xPubKey_45H: 'xpub69TvcUWtb8taVxu2fH1w4HkaYnyuVw53q6ENvdXNmha9HvC5tLv4GxmnPxemekKx8jVx7kmbtATgH5KXEMibhpZh7x2NN8AXcwF7FvJmvXo', + xPubKey_45H_Signature: '3045022100e2cfe2d828d987a9c8185f9dfcf2c3d61b20159f14dc65aa6b3443c2d14bce3b02201f91f1a1df81ef5caa32ab78c384217847b3dffd12a35446cfc9c1f4b3ecdb35', + xPrivKey_1H: 'xprv9vUaCxyzkmLFMyQhaN3knpLSWHeqTbNbxVa9cHgJ88m287K6iLazaT5CYBgCaW6PEJy7bKeDZ2Wi8UsWnzND9QtzSy9CFWdgMxZAJ3mP5hW', + xPubKey_1H: 'xpub69TvcUWtb8tYaTVAgPam9xHB4KVKs46TKiVkQg5ugUHzzueFFsuF8FPgPTLeRcZmq3EwbrnYGX6gHmShDNL1YgNqjo5ctqw5Z7WXe9LSErX', + privKey_1H_0: '25ac29ca9bffe835bdafed55feebe606c7250e2b399cd3d95347a746dd6d3388', + pubKey_1H_0: '031a69ea8a3d487743c7d6acdcecc151c685fd25f8f41b327f4c25d8b21f6c80ba' }, { - id: '024062aae3d6575b03a8532e618feeb70d6926c069e24cca0cb1a24db4dec6562e', - xPrivKey: 'xprv9s21ZrQH143K3dHn6j7zuLSnnMpBAceHfQFDm6R3wbkD26pTSUuZ7JY4549T8mMhwwUeq6SW6guDwy6cUhqs6PwoF2svKKkLjJdeKi1BzUn', - xPubKey: 'xpub661MyMwAqRbcG7NFCkf1GUPXLPefa5N92dApZUpfVwHBtu9bz2Dof6rXvKjioVpLXRBHKeyX2AxLdtaCbUtz2zx3dE9F4mPkDsARrPaGsSL', - xPubKeySignature: '3045022100a17dee46810e379aa37104ec1a4e20276aa41eac67b7e555475b15db6f6ee8ca0220472d114368f6d78bd8dba5c5fed77b22437341621d7879331bc48f7ee7701853', + id: 'ab0bc4e4c251376d733d9ba63242fb0ca258b0dff4def1f67e2a5e0441b86a8f', + xPrivKey: 'xprv9s21ZrQH143K24Vs7f7xhvrMgojXW5444PtT7Qkw3opZ2Dwpxwz5tERpSMtEa4YTgrfDhRqzw8X9b4TnCKrhcoZiPRgJDQaH9Lz8LEvLSpF', + xPubKey: 'xpub661MyMwAqRbcEYaLDgey54o6Eqa1uXmuRcp3uoAYc9MXu2GyWVJLS2kJHeTLPTohioPuLNadiYZDBRXzzeZLFTvZTgEvrSHDTExFuutcPX3', + xPrivKey_45H: 'xprv9tzvDbfzt6dy5aiWx2qovpw2sxLUHm5zM3ZBX3AH1oTEa7PjZoHWhfSZp5LnmMayDCHJEM4ATCDWECkQUjgxYjnEczMjyvujwzUAWXNMy8L', + xPubKey_45H: 'xpub67zGd7CtiUCGJ4nz44NpHxsmRzAxhDoqiGUnKRZta8zDSuit7LbmFTm3fMTBmgk4aiZyGMswwdEiTr3DPwhc6Gu7EEgaDyRk9G6VTTmMNTw', + xPubKey_45H_Signature: '30440220383cd70b450bb179722c165822d592bdd3c7a175f2f20c1817e5d49c4a5f495d0220746d680aea75e5f4874fcc9f0b5f2a340b22cfaf87e13f4ce6a9f929b9bf9409', + xPrivKey_1H: 'xprv9tzvDbfzt6dw8EKieKg6hLykKuvTB4nKocQNp977xoQr6TCxDqqdDf5oK21i3FFjPG2jCtSxuGnJpBYnpmtHEZyRuxuG1RmLC3NVvVKzYEe', + xPubKey_1H: 'xpub67zGd7CtiUCELiQBkMD74UvUswkwaXWBAqKycXWjX8wpyFY6mP9smTQHAFFY8vUDcEnoUfbgUJsktwQ96igzGNfT22ujQFiSKBFAqzkwpcW', + privKey_1H_0: '5ff5b3cab4ae8f1487b75ee3b688d0cb54d11db3d21044ae6eaabd04a2a379c9', + pubKey_1H_0: '030da118db806d1758983ab078c8b5e5651270cba8a587e34337eb0b9b5e555b21' }, { - id: '031114b2afe5d1e87d834ac71798028724f8f89e2d3324b5e6abb513fdcde2e69d', - xPrivKey: 'xprv9s21ZrQH143K3Wac3NKJ8nZsBsn4HboPtCD2LDB8zkXcmo9q97efAi9i6KkcyBoJ4vjD59corGsdJebmNXud4nH3bCBSo64uWfwauo3Kdco', - xPubKey: 'xpub661MyMwAqRbcFzf59PrJVvWbjucYh4XFFR8d8bakZ64bebUygexuiWUBwa7EnFosoFstoocLQTrLPeAQThonSrYTDQ18gkS219dLJuwUHDb', - xPubKeySignature: '30440220023c1902434aaca0c2ed3c92262d56ee4296cd5c7598b009b8556deab2df89e70220714117970debf5cc1232441aa2d1ce335b5b99958acb2d000c4241e2a2fc567f', + id: '65fa0d2c2bd1d09da631e12c746562687d43364104e65bc7e0009c9cd6efb9f8', + xPrivKey: 'xprv9s21ZrQH143K44coj9AbkrT5B43PjRY91RnobCw8WGQVY7VvUDDA6VauoYs2PsKrW8MWQb9qUi2KgoWatAKf2qGZLBAT5wo98zxDsm4wog8', + xPubKey: 'xpub661MyMwAqRbcGYhGqAhc7zPoj5st8tFzNeiQPbLk4bwUQuq51kXQeHuPeqb4wxi8zkrzVThRKkBEGoT5H3M4kfFrdER1BfNCr3AV7rxSHB2', + xPrivKey_45H: 'xprv9uAoUcLPWHxJS36XQi8Mt3rywiVXK5MsY4bn6hLgyPVb8WDoqW81vvXrN7kwR9r52GTDEs6CZBXdAoEbqEbEsLxPVfCRRFZSzAnXFpaxnoy', + xPubKey_45H: 'xpub68A9t7sHLfWbeXAzWjfNFBoiVkL1iY5iuHXNu5kJXj2a1JYxP3SGUirLDPueKxxHmee12FBnjcQzspG2f8KkCqoV8vaUiVt75L4Bhsqffep', + xPubKey_45H_Signature: '3045022100d6386afa0af0f96bb204e077059868c3b9dcefa6b3e736c92d47aead05bf674502200df35eea1d95a253def3e945750f71c869c7ce002650629175ca011eb2317213', + xPrivKey_1H: 'xprv9uAoUcLPWHxGY9eCE8gXxRSTUkVpjfVWg6LQaopBQHvv8LbPCzzQHcu7mi6hWsV6EGnNqPX8xxJSwroeBiRj3TVfsGH2etA6ZNtDZqskL2h', + xPubKey_1H: 'xpub68A9t7sHLfWZkdifLADYKZPC2nLK98DN3KG1PCDnxdTu18vXkYJeqRDbd1MTj2mBjYPCix49qz2wsBWAKuPZ5crUMLemYPK7mZd5GpF4s8D', + privKey_1H_0: '259dddf1b0bcc4ab005002de457ce118771cb0ebfa8711f2b65bafec09ccfa22', + pubKey_1H_0: '02e3a4d6d1d2043e4643c1505a7dfd30c27d2b34863e7dbaacd50f896dfb16dd86' }, { - id: '03d5352705f1f587dad9814cbdae1ec627a9252f18ca677cd9d5243d41d44a7fea', - xPrivKey: 'xprv9s21ZrQH143K2Hxh1Xj59WjAimbDuubNBFknLYPr563BBziVuLhMvw7F3CkYMYj1y6QSbDnKQVHrMGekXi7awjLwKR1XWcMoR3eKEcH65Pa', - xPubKey: 'xpub661MyMwAqRbcEn3A7ZG5WefuGoRiKNKDYUgP8voTdRaA4o3eSt1cUjRitVc75a2gsifRDufbicYXeQCchDvkRKSSTWi1uy7PPaNHnerGvTa', - xPubKeySignature: '3044022042f063cd154a359f1d49202d79efc0737c47077ee50e36ed3d796327b9b29a9602206a4baf2902b49d1cb265eb31b9ab12d470fd023a11d9d425679a1630ba0b0e29', + id: '551984256819ededc0ee851f99546fc1856d20f883960c868917626091128d30', + xPrivKey: 'xprv9s21ZrQH143K27WsnsbtSync63dMn5ADYT7yf8ARMGtG5CyhAxhcNfjrx9yYUYTApZUfkLqvgYzeLwB5K56pfWkLxvy8wSK4Bog5o8XUKJ6', + xPubKey: 'xpub661MyMwAqRbcEbbLtu8tp7jLe5TrBXt4ug3aTWa2ucREx1JqiW1rvU4LoSwm4B1DoXhkGSTRSKpSUYQVENP9AYX3EHAP4oyeGtGBeKJ7hwd', + xPrivKey_45H: 'xprv9vdUpVGJA9iQf5GDq7eR34N75DjytYj5adyggnqdA9fCCfgofiQEELA7o4UiNQ2zf3xjHyeNDhQhib7RQjTeYnapWxu1eSQdCrExzb9J8v7', + xPubKey_45H: 'xpub69cqDzoBzXGhsZLgw9BRQCJqdFaUJ1SvwruHVBFEiVCB5U1xDFiUn8UbeKmXemb5ENTgJhoxYKe4yQazwsXFScehhMrc5vAXUVK1mQfyVST', + xPubKey_45H_Signature: '304402204c92ed4d6145be4ea0200367464b8ac6ee3ecf36357c1107eff1766ff791825602206a0608092dcdcf0b84c7a4e3a8f3d7b0aa5b8d5687264a2cab9330c3f21db109', + xPrivKey_1H: 'xprv9vdUpVGJA9iNgurZGgm6HhVHF7GQbcpWbezkQcCnwCdz5Tigip2AyEtg2Jz98e7Mthm6yEK72CzNagyMyCGQNuYhErB1Er1ykTpBKeTjsan', + xPubKey_1H: 'xpub69cqDzoBzXGfuPw2NiJ6eqS1o96u15YMxsvMCzcQVYAxxG3qGMLRX3D9sZxY3V2CLNX5rZZYB4QUg5zLb961c7CPD46fM9M4rVatc65qeF6', + privKey_1H_0: 'c8e4cd009e0ed12564eb96b2ffc68181716748ec9a7f6b218b08587337438bba', + pubKey_1H_0: '032137a03bc2cbba134fc3a1529358b56ca0764f699f6e3cc74118044f9bfad33b' }, { - id: '036fa483c6f226afecb2782a69ab11d1cf43c26f277280cb2ec69f88681d8a4418', - xPrivKey: 'xprv9s21ZrQH143K2L2wxVQ5nJ8FrTjz2KHB4wy83Xu6y6jdxmzrKNWvh6g7apPJqwj5NjhrmyJ6TYe9Hk4fbYx4tRg7Zk4Y7dAdgej4RVeUBTn', - xPubKey: 'xpub661MyMwAqRbcEp7R4Ww69S4zQVaURn12SAtiqvJiXSGcqaKzruqBEtzbS97V145KiYxsW4g9M3pqsibfc5mtbMn4R52v7bnnrHGAoiHb1pz', - xPubKeySignature: '304402207b082a63fc39b90a0f18edeb20d191430f11a9e5378681f15a68aac052aa858202201fd127b374e4a301a45f0c73d2a747d156a60075e643308e489a672bd0a7b4fb', + id: '364783ba3fa7f82a188ad665ddee376a0abe930194b1dfc148199b54205b992b', + xPrivKey: 'xprv9s21ZrQH143K2scQXETcb8fMvaao2ApiBWsuYiLz1GLr3T5UWi8bmEvpVWvTGEYjcMEnHEET4RrouGhYo3qBX4yuLXJ9q6viSFykJcGmNXn', + xPubKey: 'xpub661MyMwAqRbcFMgsdFzcxGc6UcRHRdYZYjoWM6kbZbspvFQd4FSrK3FJLpwdhqsEL3PYLarn1Av24qDwxfizXkgaKmvLAdJ16MPao2o4MNq', + xPrivKey_45H: 'xprv9u2Yq2Sc1xugbPWe4LBefYGiRKbytz9vpbZgWdqk1fZKoLSeTFC5Qb6ospfKzbmNai2TCEX1uRtgfaXgnnwUFyGxEUtjwVq8s39kQcv8SxU', + xPubKey_45H: 'xpub681uEXyVrLTyosb7AMif2gDSyMSUJSsnBpVHK2FMa16Jg8mnznWKxPRHj5kWjpHXiJUutUZqAmy6EpomMGRP5im9U95jq85aMwyS7YcJVim', + xPubKey_45H_Signature: '3045022100a51e182d5ff18c069445822e59b0c8316af09dd0a2324513716bef03b87207710220491ef764fae8e3511372554298805f5338a38df905eb784d42e7f50be56795d9', + xPrivKey_1H: 'xprv9u2Yq2Sc1xueeYe6GSDWWr7LUJTyjzcf1EjWPLEmT6T12je2PPk8D47h65RFC5i2Xqfj5og2FAJFRSHNaa2dwBtJi4AoBDSqL1NLhyXLyGf', + xPubKey_1H: 'xpub681uEXyVrLTws2iZNTkWsz452LJU9TLWNTf7BieP1RyyuXyAvw4NkrSAwMmgHcYNTYYwtdMQPLQKXL8JeEzHAfAhYVbA2xqjjkfCnoAd4tC', + privKey_1H_0: '97456bcde0704e054a63a96c11853ba412ab7c33e2ef9fa8661a66db2ce6a94d', + pubKey_1H_0: '022edcbe1542c789bb0c39e6fef3cd15823d396e355b05139659a059d08da62e50' }, { - id: '03bc5f0504c8dd480926dbe90449ccc7b2fc4c96e79f1cb8ffcd31731e2ee8db9b', - xPrivKey: 'xprv9s21ZrQH143K3Pqe7LhTkE84VM6GysvSvggfhS3KbHvgBLaaQeR9YNePRo3vpLMVBv5SNhNVAaEDyj6Q8vMRVYM4X9bWYCiPgsJXkH8WzX1', - xPubKey: 'xpub661MyMwAqRbcFLRkhYzK8eQdoywNHJVsJCMQNDoMks5bZymuMcyDgYfnVQYq2Q9npnVmdTAthYGc3N3uxm5sEdnTpSqBc4YYTAhNnoSxCm9', - xPubKeySignature: '30440220192ae7345d980f45f908bd63ccad60ce04270d07b91f1a9d92424a07a38af85202201591f0f71dd4e79d9206d2306862e6b8375e13a62c193953d768e884b6fb5a46', + id: '23892f5b034019d81397f97570a1ea5b9f2977654269623f42abbdb33fe7c4e0', + xPrivKey: 'xprv9s21ZrQH143K4bhBXV3MvydmC9WKrJ4pY4w9zTyihwunrPsSim2vb5VDsX7zVzLPLXVTN6y2Gc5y7qpYr8Vdow3v3a14zgccPobib5Q5jik', + xPubKey: 'xpub661MyMwAqRbcH5medWaNJ7aVkBLpFknfuHrknrPLGHSmjCCbGJMB8sohipo1DSXpR7xcnZfsUooP6k8RVoQQ7Ewtmj7jnLbCQDGcBi9Sr3L', + xPrivKey_45H: 'xprv9twC9XfPNCFMmqBU3UyVLByyFH9QgmUuwy1gpteoAiLN4rSdG3hcLHjqXSqf36JXwavTFNhawGPYYtZUch6qJNoXfZ2XAeyeeWwrnnGdpD7', + xPubKey_45H: 'xpub67vYZ3CHCZoezKFw9WWVhKvhoJyu6ECmKBwHdH4Qj3sLwemmob1rt64KNkQVNrFhy85WAcokstPsA3JPz6qTHqumg98Lzo6ccL7wKCL3sDt', + xPubKey_45H_Signature: '304402207da854acd0132f390425ba77a0af52e4bbbd9756e9846aa3fbaf1c1490bfbe5402200ed615fe0367e433539964d63eae9e3185816e68bc533f13f4415e89cf668882', + xPrivKey_1H: 'xprv9twC9XfPNCFKozsRsSNChbiQJpRBkjVZoL4McXGyWQRD3dkkazNW7LhFP85DeM5DKw6AgfJPX7F2VggCznFqbsbUXUdwd7QEpTRYb8Agas3', + xPubKey_1H: 'xpub67vYZ3CHCZod2UwtyTuD4jf8rrFgACDRAYyxQugb4jxBvS5u8Xgkf91jESCqi5jydqLYeATXbk58bM6vfa3kviLHuyFKMVM1KSWB1uWRBdB', + privKey_1H_0: '5f0011757ae447218cc11b0845b87b7ac9742c8dc37de8d10d590fb096005430', + pubKey_1H_0: '027e8c73e3c176c7fe992de80fa891a5b73f82151f11b1f9e97ce7b902b20f81b6' }, { - id: '02ec9ec4fd013c67312e0365128d470a89e13e53d9b44f026c5eca0b6e2ab9ae29', - xPrivKey: 'xprv9s21ZrQH143K2QSAHGxQhUsJYFDcZ6h2oiTjKFPmbnzeNzXgRW73NwX7ifBgbJ35eHGR7toyj9CCXB6Wzf5iCjj3YDuJuvBoJFJsiQAdTUH', - xPubKey: 'xpub661MyMwAqRbcEtWdPJVR4cp36H46xZQtAwPL7doPA8XdFnrpy3RHvjqbZxERYNMd4E2tt84xy4F2PqtKkHFDzZbSAaUabp36oZDwwPEqFjK', - xPubKeySignature: '304502210081a88684d4e27cab752d0df6a746aeb4bbcac57e73edd3847ffb43f1cf6740b20220312598f47dc5e775ea2ba97048764675afa4796173115049b4dacc8882b5c7b7', + id: '5f69e118def0b38ee88c8d47c7254136d081221bfd2c6c3d9d4e7890bc60c22b', + xPrivKey: 'xprv9s21ZrQH143K3bFvCtYiQZr9seRAjj5sBH3NsvF2mut5NtuSL6CVWhYiKjsdDCXLgxwYB3GUsXqpSfmkjSEoghASHxvS4fNPwbkwk3cn1DM', + xPubKey: 'xpub661MyMwAqRbcG5LPJv5imhntRgFf9BoiYVxygJeeLFR4FhEasdWk4VsCB3EEw6meT2hGYTE2dN6x1597ekpFJp5wtqoNo25QFe8LBGZatsN', + xPrivKey_45H: 'xprv9ugBxZE4n42UY137XuYcWPEf1WrtN7Gyj7LEpDyQXwhPQ6iHtXe9LuBXyMyPgFABe9sagz3KKfTXGsJJnDycv3bZv2vZLibnLZyCX5ug5PT', + xPubKey_45H: 'xpub68fYN4kxcRamkV7adw5csXBPZYhNmZzq6LFqccP26HENGu3SS4xPthW1pdKoSrb4KVonrxpE1pPvi3CjzmB1X19xpmE2dSJwdBLw98Au1EA', + xPubKey_45H_Signature: '304502210098ef1cce342fdad94982bca42c5eeacc5cf83d1712807aa4cd707d262eee43d602202dcabc17a32974a63b48bf2537d47df64418208fea5e553a0fbea11ffa22cda4', + xPrivKey_1H: 'xprv9ugBxZE4n42Sb78sFa42f8K3mSCm5buKAXTz4Yo7oJvfRFtuy5AtedbsdGMtFULvesJ7KjJtuq8iUv3gxksYFohBHf8jEBihrx4ZkFqLivb', + xPubKey_1H: 'xpub68fYN4kxcRajobDLMbb32GFnKU3FV4dAXkParwCjMeTeJ4E4WcV9CRvMUX3t7dUu381jjAir4hB588mN4mFkWCVtoDSH8RhEPCzXJtvzHZG', + privKey_1H_0: '084f923954681d1bfc6622ff69fe225c89561f3f8976832acb436c6b0dc6dd01', + pubKey_1H_0: '029f7003e5e0a3c53db12439b4b7862c471d4e2fd56879497022cc420ce7a13fee' }, { - id: '02ec5f9178f77b306bc92362f3c1ef8f10b8cce44dc255ba20435f24d6459981db', - xPrivKey: 'xprv9s21ZrQH143K2bj7Azs1rCkumDJmbNveDA96wDJThzsDEJjBngkFXEr646AbvrTAfRd2scqq7hN48fGXesobx4sKRkddCrLaCpoWUkMJErj', - xPubKey: 'xpub661MyMwAqRbcF5oaH2Q2DLheKF9FzqeVaP4hjbi5GLQC774LLE4W53AZuMztQ6e6SMmEMj8K8zsP3iMMnJgK2PawWZCh7QcdgAg7eJWSJFr', - xPubKeySignature: '304402207781231f8bd9a679938057373702afdeec43e84b5b239e2e4dc8e35c63e4ee7102207f7ed929c81dfb59ebd14f56609dcd8255de6337c967704340a2089080fd896f', + id: 'ebd86096bf0f7902e293f9d399361204ba5a4bf484c4a7bf3e29f8891f96dca2', + xPrivKey: 'xprv9s21ZrQH143K2JQLtqcR7QgEXwhwhLWS63pAsEgmRqPu4x9d1oPcv14qTSbV19LWzFTfMbJ2nieS7oCrBxgSKF5hmqFeBCYwFh2kSV8pFRy', + xPubKey: 'xpub661MyMwAqRbcEnUozs9RUYcy5yYS6oEHTGjmfd6NzAvswkUmZLhsToPKJj4moN2BSSonQDTL9qFYtGsqoRAEwHcxrkwqBfkPBncm23QqrAg', + xPrivKey_45H: 'xprv9uj2TGqrHjzvdEQrYby5oGHPT96YBzSNUPHe82g9j6xqcJhx19KhWoPu6RxE4EisvuUTjBAwmsTnxYyT9EuSQJvyrWntQkiQ3QSjLx3XSRZ', + xPubKey_45H: 'xpub68iNrnNk87ZDqiVKedW6AQE81Aw2bTADqcDEvR5mHSVpV736Ygdx4biNwiSFYNFzTY6UziVFffDc92iL6WmANV16SexCX8WfGcDcRvaPJfh', + xPubKey_45H_Signature: '3045022100849be80222463f50db39aeb7b7a06826f66d5019ad56f140fce50229247f333002205f279a500b8556fbec0f8ca0ad1cff576af8ddb1e9eee52ebd166817507689c6', + xPrivKey_1H: 'xprv9uj2TGqrHjztgbraNVLwq38Smz8Mi1MQE6yN3MXQSj4DaqkyfF1Td8cxpiH4Pd88X6K8qcveM7zpGxFwmi5hB8sQGn3Xnjesojznikr6n9e', + xPubKey_1H: 'xpub68iNrnNk87ZBu5w3UWsxCB5BL1xr7U5FbKtxqjw214bCTe68CnKiAvwSfzRQkT4hp27XRHRAewgYiV6uVKGgyoiFnKQaVpDWgiexFf5f4zD', + privKey_1H_0: '8c0552de8b785bf395794e88fbe6e0b87e74dbb49282e00acd98f44064913c41', + pubKey_1H_0: '034433ac6358faebed43ae5e48061b6796a7ec4523fad547e13d16433140557831' }, ]; - var history = [{ txid: "0279ef7b21630f859deb723e28beac9e7011660bd1346c2da40321d2f7e34f04", vin: [{ From 4fd84cd2ce5cbff1c2da67152fb2194f6b336d28 Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Tue, 10 Mar 2015 11:23:23 -0300 Subject: [PATCH 2/5] add copayer signature on joining --- lib/server.js | 9 +++--- test/integration/server.js | 65 ++++++++++++++++++-------------------- test/testdata.js | 10 ------ 3 files changed, 36 insertions(+), 48 deletions(-) diff --git a/lib/server.js b/lib/server.js index d34f7d9..31be2c8 100644 --- a/lib/server.js +++ b/lib/server.js @@ -192,13 +192,13 @@ WalletService.prototype._notify = function(type, data) { * @param {string} opts.walletId - The wallet id. * @param {string} opts.name - The copayer name. * @param {string} opts.xPubKey - Extended Public Key for this copayer. - * @param {string} opts.xPubKeySignature - Signature of xPubKey using the wallet pubKey. * @param {string} opts.requestPubKey - Public Key used to check requests from this copayer. + * @param {string} opts.copayerSignature - opts.proposalSignature - S(name|xPubKey|requestPubKey). Used by other copayers to verify the that the copayer joining knows the wallet secret. */ WalletService.prototype.joinWallet = function(opts, cb) { var self = this; - if (!Utils.checkRequired(opts, ['walletId', 'name', 'xPubKey', 'xPubKeySignature', 'requestPubKey'])) + if (!Utils.checkRequired(opts, ['walletId', 'name', 'xPubKey', 'requestPubKey', 'copayerSignature'])) return cb(new ClientError('Required argument missing')); if (_.isEmpty(opts.name)) @@ -209,7 +209,8 @@ WalletService.prototype.joinWallet = function(opts, cb) { if (err) return cb(err); if (!wallet) return cb(new ClientError('Wallet not found')); - if (!self._verifySignature(opts.xPubKey, opts.xPubKeySignature, wallet.pubKey)) { + var hash = WalletUtils.getCopayerHash(opts.name, opts.xPubKey, opts.requestPubKey); + if (!self._verifySignature(hash, opts.copayerSignature, wallet.pubKey)) { return cb(new ClientError()); } @@ -499,7 +500,7 @@ WalletService.prototype._selectUtxos = function(txp, utxos) { * @param {string} opts.toAddress - Destination address. * @param {number} opts.amount - Amount to transfer in satoshi. * @param {string} opts.message - A message to attach to this transaction. - * @param {string} opts.proposalSignature - S(toAddress + '|' + amount + '|' + message). Used by other copayers to verify the proposal. Optional in 1-of-1 wallets. + * @param {string} opts.proposalSignature - S(toAddress|amount|message). Used by other copayers to verify the proposal. * @returns {TxProposal} Transaction proposal. */ WalletService.prototype.createTx = function(opts, cb) { diff --git a/test/integration/server.js b/test/integration/server.js index 03f00b4..c34b1a2 100644 --- a/test/integration/server.js +++ b/test/integration/server.js @@ -46,7 +46,6 @@ helpers._generateCopayersTestData = function(n) { var xpriv_45H = xpriv.derive(45, true); var xpub_45H = Bitcore.HDPublicKey(xpriv_45H); - var xpub_45H_sig = WalletUtils.signMessage(xpub_45H.toString(), TestData.keyPair.priv); var id = WalletUtils.xPubToCopayerId(xpub_45H.toString()); var xpriv_1H = xpriv.derive(1, true); @@ -59,7 +58,6 @@ helpers._generateCopayersTestData = function(n) { console.log('xPubKey: ', "'" + xpub.toString() + "',"); console.log('xPrivKey_45H: ', "'" + xpriv_45H.toString() + "',"); console.log('xPubKey_45H: ', "'" + xpub_45H.toString() + "',"); - console.log('xPubKey_45H_Signature: ', "'" + xpub_45H_sig + "',"); console.log('xPrivKey_1H: ', "'" + xpriv_1H.toString() + "',"); console.log('xPubKey_1H: ', "'" + xpub_1H.toString() + "',"); console.log('privKey_1H_0: ', "'" + priv.toString() + "',"); @@ -68,6 +66,12 @@ helpers._generateCopayersTestData = function(n) { console.log('];'); }; +helpers.getSignedCopayerOpts = function(opts) { + var hash = WalletUtils.getCopayerHash(opts.name, opts.xPubKey, opts.requestPubKey); + opts.copayerSignature = WalletUtils.signMessage(hash, TestData.keyPair.priv); + return opts; +}; + helpers.createAndJoinWallet = function(m, n, cb) { var server = new WalletService(); var copayerIds = []; @@ -83,13 +87,12 @@ helpers.createAndJoinWallet = function(m, n, cb) { if (err) return cb(err); async.each(_.range(n), function(i, cb) { - var copayerOpts = { + var copayerOpts = helpers.getSignedCopayerOpts({ walletId: walletId, name: 'copayer ' + (i + 1), xPubKey: TestData.copayers[i + offset].xPubKey_45H, - xPubKeySignature: TestData.copayers[i + offset].xPubKey_45H_Signature, requestPubKey: TestData.copayers[i + offset].pubKey_1H_0, - }; + }); server.joinWallet(copayerOpts, function(err, result) { should.not.exist(err); @@ -407,13 +410,12 @@ describe('Copay server', function() { }); it('should join existing wallet', function(done) { - var copayerOpts = { + var copayerOpts = helpers.getSignedCopayerOpts({ walletId: walletId, name: 'me', xPubKey: TestData.copayers[0].xPubKey_45H, - xPubKeySignature: TestData.copayers[0].xPubKey_45H_Signature, requestPubKey: TestData.copayers[0].pubKey_1H_0, - }; + }); server.joinWallet(copayerOpts, function(err, result) { should.not.exist(err); var copayerId = result.copayerId; @@ -431,13 +433,12 @@ describe('Copay server', function() { }); it('should fail to join with no name', function(done) { - var copayerOpts = { + var copayerOpts = helpers.getSignedCopayerOpts({ walletId: walletId, name: '', xPubKey: TestData.copayers[0].xPubKey_45H, - xPubKeySignature: TestData.copayers[0].xPubKey_45H_Signature, requestPubKey: TestData.copayers[0].pubKey_1H_0, - }; + }); server.joinWallet(copayerOpts, function(err, result) { should.not.exist(result); should.exist(err); @@ -451,7 +452,8 @@ describe('Copay server', function() { walletId: '123', name: 'me', xPubKey: 'dummy', - xPubKeySignature: 'dummy', + requestPubKey: 'dummy', + copayerSignature: 'dummy', }; server.joinWallet(copayerOpts, function(err) { should.exist(err); @@ -461,13 +463,12 @@ describe('Copay server', function() { it('should fail to join full wallet', function(done) { helpers.createAndJoinWallet(1, 1, function(s, wallet) { - var copayerOpts = { + var copayerOpts = helpers.getSignedCopayerOpts({ walletId: wallet.id, name: 'me', xPubKey: TestData.copayers[1].xPubKey_45H, - xPubKeySignature: TestData.copayers[1].xPubKey_45H_Signature, requestPubKey: TestData.copayers[1].pubKey_1H_0, - }; + }); server.joinWallet(copayerOpts, function(err) { should.exist(err); err.code.should.equal('WFULL'); @@ -478,13 +479,12 @@ describe('Copay server', function() { }); it('should fail to re-join wallet', function(done) { - var copayerOpts = { + var copayerOpts = helpers.getSignedCopayerOpts({ walletId: walletId, name: 'me', xPubKey: TestData.copayers[0].xPubKey_45H, - xPubKeySignature: TestData.copayers[0].xPubKey_45H_Signature, requestPubKey: TestData.copayers[0].pubKey_1H_0, - }; + }); server.joinWallet(copayerOpts, function(err) { should.not.exist(err); server.joinWallet(copayerOpts, function(err) { @@ -497,13 +497,12 @@ describe('Copay server', function() { }); it('should fail two wallets with same xPubKey', function(done) { - var copayerOpts = { + var copayerOpts = helpers.getSignedCopayerOpts({ walletId: walletId, name: 'me', xPubKey: TestData.copayers[0].xPubKey_45H, - xPubKeySignature: TestData.copayers[0].xPubKey_45H_Signature, requestPubKey: TestData.copayers[0].pubKey_1H_0, - }; + }); server.joinWallet(copayerOpts, function(err) { should.not.exist(err); @@ -515,13 +514,12 @@ describe('Copay server', function() { }; server.createWallet(walletOpts, function(err, walletId) { should.not.exist(err); - copayerOpts = { + copayerOpts = helpers.getSignedCopayerOpts({ walletId: walletId, name: 'me', xPubKey: TestData.copayers[0].xPubKey_45H, - xPubKeySignature: TestData.copayers[0].xPubKey_45H_Signature, requestPubKey: TestData.copayers[0].pubKey_1H_0, - }; + }); server.joinWallet(copayerOpts, function(err) { should.exist(err); err.code.should.equal('CREGISTERED'); @@ -537,8 +535,8 @@ describe('Copay server', function() { walletId: walletId, name: 'me', xPubKey: TestData.copayers[0].xPubKey_45H, - xPubKeySignature: 'bad sign', requestPubKey: TestData.copayers[0].pubKey_1H_0, + copayerSignature: 'bad sign', }; server.joinWallet(copayerOpts, function(err) { err.message.should.equal('Bad request'); @@ -551,6 +549,7 @@ describe('Copay server', function() { walletId: walletId, name: 'me', xPubKey: TestData.copayers[0].xPubKey_45H, + requestPubKey: TestData.copayers[0].pubKey_1H_0, }; server.joinWallet(copayerOpts, function(err) { should.exist(err); @@ -560,13 +559,13 @@ describe('Copay server', function() { }); it('should fail to join with wrong signature', function(done) { - var copayerOpts = { + var copayerOpts = helpers.getSignedCopayerOpts({ walletId: walletId, name: 'me', xPubKey: TestData.copayers[0].xPubKey_45H, - xPubKeySignature: TestData.copayers[1].xPubKey_45H_Signature, requestPubKey: TestData.copayers[0].pubKey_1H_0, - }; + }); + copayerOpts.name = 'me2'; server.joinWallet(copayerOpts, function(err) { err.message.should.equal('Bad request'); done(); @@ -763,13 +762,12 @@ describe('Copay server', function() { }; server.createWallet(walletOpts, function(err, walletId) { should.not.exist(err); - var copayerOpts = { + var copayerOpts = helpers.getSignedCopayerOpts({ walletId: walletId, name: 'me', xPubKey: TestData.copayers[0].xPubKey_45H, - xPubKeySignature: TestData.copayers[0].xPubKey_45H_Signature, requestPubKey: TestData.copayers[0].pubKey_1H_0, - }; + }); server.joinWallet(copayerOpts, function(err, result) { should.not.exist(err); helpers.getAuthServer(result.copayerId, function(server) { @@ -794,13 +792,12 @@ describe('Copay server', function() { }; server.createWallet(walletOpts, function(err, walletId) { should.not.exist(err); - var copayerOpts = { + var copayerOpts = helpers.getSignedCopayerOpts({ walletId: walletId, name: 'me', xPubKey: TestData.copayers[0].xPubKey_45H, - xPubKeySignature: TestData.copayers[0].xPubKey_45H_Signature, requestPubKey: TestData.copayers[0].pubKey_1H_0, - }; + }); server.joinWallet(copayerOpts, function(err, result) { should.not.exist(err); helpers.getAuthServer(result.copayerId, function(server, wallet) { diff --git a/test/testdata.js b/test/testdata.js index 62f7312..ca9a279 100644 --- a/test/testdata.js +++ b/test/testdata.js @@ -14,7 +14,6 @@ var copayers = [{ xPubKey: 'xpub661MyMwAqRbcEwodG7pcdCkmCkap1XZFiiaMFnFYvxBrGvUvo6cEq868bukLYM938wPm1CMzFuvbDQbA2tJvsWKgTz4xDKTyEfbQvBbo1AR', xPrivKey_45H: 'xprv9uZiJ2ZYFNQ3RDBvjtz1HcivbfWbncMAb6EvKKose8rUbRo9dwX5hnThGodivCDuV8s48xZk7DZSuNpYb9ZwCpsatsnibRyirQbqqroftMP', xPubKey_45H: 'xpub68Z4hY6S5jxLdhGPqvX1ekff9hM6C551xKAX7iDVCUPTUE8JBUqLFanB8697EoXbwN5rjDLHgPWkbofr8otNeb8Kr8SSh8pCiNMp7sWkBj4', - xPubKey_45H_Signature: '3045022100bd2c10387236c29b4171d7584f72427c858de8bc24c03ee71e933a616d2a2053022034cd1bf5efb53bd9c860e12398d3aab75a02a8ef3e057c2bda1098e6a98b9e52', xPrivKey_1H: 'xprv9uZiJ2ZYFNQ1WeKrKfTxrbUnXfNnCtpbdHVuUMSVGB57nhbmjqWbJBQbgGNa2jSbrgQX9NFHXtAoQ3y1hsEgwjKHxUU52ZYTC6m5kjXoNpJ', xPubKey_1H: 'xpub68Z4hY6S5jxJj8QKRgzyDjRX5hDGcMYSzWRWGjr6pWc6fVvvHNpqqyj5XXbMcfW737beYZcd7EQau5HS74Ws6Ctx9XwFn2wHQjSUKLbfdFk', privKey_1H_0: 'e334a0ce3d573bd99fc4cd7e2065e39dc7851cb61da7f381431c253c3e230828', @@ -25,7 +24,6 @@ var copayers = [{ xPubKey: 'xpub661MyMwAqRbcF1xt74sptd788JHkGrFvzXayiks4G1EcNJLFUAXq653pncPaLt6vcEARqSHopD8PHT5PWkDryuZNBYpxX5wUdeV7DtgjKoL', xPrivKey_45H: 'xprv9v8AzYcRrUwmJQGbDDKXvydEG2NZZDqXn9J3B6au2S8yhLfJyQidhZgMfTpFxBqAkUxgtTDc9JWFt4JaTmwKNLGxr6oSKjpaheQ5EG8jHz6', xPubKey_45H: 'xpub697XQ49KgrW4WtM4KErYJ7Zxp4D3xgZP9NDdyUzWamfxa8zTWx2tFMzqWktiJG1yDo6mYpp8NAySfzRS8JoJyz2Br26vARWY9d9QAJdYFYh', - xPubKey_45H_Signature: '304402200b307113a4a3108a986db5247a04651b908a7fc2dadc940e3b71f9ecd862d980022056a2a5b6f5d7d2c4c4dd88a990c774b65990ad39ee4f0bb7c0c86a4a23b41be6', xPrivKey_1H: 'xprv9v8AzYcRrUwjNBGAL5pzBaLvDBwepj9YVDM5UHjZXYYdoAxi9uaJjALUKPRcMxZZWq265CZuEfhTbwE6BD1tndRGESV4Jbr4c3pLanhnZHm', xPubKey_1H: 'xpub697XQ49KgrW2afLdS7MzYiHemDn9EBsPrSGgGg9B5t5cfyHrhStZGxexAdekvK84XDZGunARoEzzHWmPjPwaRkKJwV2KWiRcHxVPfwwWKtg', privKey_1H_0: '64274141d3ed98d3ee159409939627bd32229eac8b29cddc4c744c4e7f20235f', @@ -36,7 +34,6 @@ var copayers = [{ xPubKey: 'xpub661MyMwAqRbcFj9A6pCN5xxaoNCei4EdZNCuS93TtTVokrt7BspfrFi17DdM2Z4HYYseVoZ2nmeu5mCvsn8gYGyW94m7EfXQDbXymLw2Yi1', xPrivKey_45H: 'xprv9vUaCxyzkmLHHUpZZFUvh9oqzm9R6UMCTsJn8F7mDN3AR7rwLobojATJYgSx3pJjrv3EWCaSYeBjhouiM1m9Y9kAHAku3ZiAxZyWRxQZyHf', xPubKey_45H: 'xpub69TvcUWtb8taVxu2fH1w4HkaYnyuVw53q6ENvdXNmha9HvC5tLv4GxmnPxemekKx8jVx7kmbtATgH5KXEMibhpZh7x2NN8AXcwF7FvJmvXo', - xPubKey_45H_Signature: '3045022100e2cfe2d828d987a9c8185f9dfcf2c3d61b20159f14dc65aa6b3443c2d14bce3b02201f91f1a1df81ef5caa32ab78c384217847b3dffd12a35446cfc9c1f4b3ecdb35', xPrivKey_1H: 'xprv9vUaCxyzkmLFMyQhaN3knpLSWHeqTbNbxVa9cHgJ88m287K6iLazaT5CYBgCaW6PEJy7bKeDZ2Wi8UsWnzND9QtzSy9CFWdgMxZAJ3mP5hW', xPubKey_1H: 'xpub69TvcUWtb8tYaTVAgPam9xHB4KVKs46TKiVkQg5ugUHzzueFFsuF8FPgPTLeRcZmq3EwbrnYGX6gHmShDNL1YgNqjo5ctqw5Z7WXe9LSErX', privKey_1H_0: '25ac29ca9bffe835bdafed55feebe606c7250e2b399cd3d95347a746dd6d3388', @@ -47,7 +44,6 @@ var copayers = [{ xPubKey: 'xpub661MyMwAqRbcEYaLDgey54o6Eqa1uXmuRcp3uoAYc9MXu2GyWVJLS2kJHeTLPTohioPuLNadiYZDBRXzzeZLFTvZTgEvrSHDTExFuutcPX3', xPrivKey_45H: 'xprv9tzvDbfzt6dy5aiWx2qovpw2sxLUHm5zM3ZBX3AH1oTEa7PjZoHWhfSZp5LnmMayDCHJEM4ATCDWECkQUjgxYjnEczMjyvujwzUAWXNMy8L', xPubKey_45H: 'xpub67zGd7CtiUCGJ4nz44NpHxsmRzAxhDoqiGUnKRZta8zDSuit7LbmFTm3fMTBmgk4aiZyGMswwdEiTr3DPwhc6Gu7EEgaDyRk9G6VTTmMNTw', - xPubKey_45H_Signature: '30440220383cd70b450bb179722c165822d592bdd3c7a175f2f20c1817e5d49c4a5f495d0220746d680aea75e5f4874fcc9f0b5f2a340b22cfaf87e13f4ce6a9f929b9bf9409', xPrivKey_1H: 'xprv9tzvDbfzt6dw8EKieKg6hLykKuvTB4nKocQNp977xoQr6TCxDqqdDf5oK21i3FFjPG2jCtSxuGnJpBYnpmtHEZyRuxuG1RmLC3NVvVKzYEe', xPubKey_1H: 'xpub67zGd7CtiUCELiQBkMD74UvUswkwaXWBAqKycXWjX8wpyFY6mP9smTQHAFFY8vUDcEnoUfbgUJsktwQ96igzGNfT22ujQFiSKBFAqzkwpcW', privKey_1H_0: '5ff5b3cab4ae8f1487b75ee3b688d0cb54d11db3d21044ae6eaabd04a2a379c9', @@ -58,7 +54,6 @@ var copayers = [{ xPubKey: 'xpub661MyMwAqRbcGYhGqAhc7zPoj5st8tFzNeiQPbLk4bwUQuq51kXQeHuPeqb4wxi8zkrzVThRKkBEGoT5H3M4kfFrdER1BfNCr3AV7rxSHB2', xPrivKey_45H: 'xprv9uAoUcLPWHxJS36XQi8Mt3rywiVXK5MsY4bn6hLgyPVb8WDoqW81vvXrN7kwR9r52GTDEs6CZBXdAoEbqEbEsLxPVfCRRFZSzAnXFpaxnoy', xPubKey_45H: 'xpub68A9t7sHLfWbeXAzWjfNFBoiVkL1iY5iuHXNu5kJXj2a1JYxP3SGUirLDPueKxxHmee12FBnjcQzspG2f8KkCqoV8vaUiVt75L4Bhsqffep', - xPubKey_45H_Signature: '3045022100d6386afa0af0f96bb204e077059868c3b9dcefa6b3e736c92d47aead05bf674502200df35eea1d95a253def3e945750f71c869c7ce002650629175ca011eb2317213', xPrivKey_1H: 'xprv9uAoUcLPWHxGY9eCE8gXxRSTUkVpjfVWg6LQaopBQHvv8LbPCzzQHcu7mi6hWsV6EGnNqPX8xxJSwroeBiRj3TVfsGH2etA6ZNtDZqskL2h', xPubKey_1H: 'xpub68A9t7sHLfWZkdifLADYKZPC2nLK98DN3KG1PCDnxdTu18vXkYJeqRDbd1MTj2mBjYPCix49qz2wsBWAKuPZ5crUMLemYPK7mZd5GpF4s8D', privKey_1H_0: '259dddf1b0bcc4ab005002de457ce118771cb0ebfa8711f2b65bafec09ccfa22', @@ -69,7 +64,6 @@ var copayers = [{ xPubKey: 'xpub661MyMwAqRbcEbbLtu8tp7jLe5TrBXt4ug3aTWa2ucREx1JqiW1rvU4LoSwm4B1DoXhkGSTRSKpSUYQVENP9AYX3EHAP4oyeGtGBeKJ7hwd', xPrivKey_45H: 'xprv9vdUpVGJA9iQf5GDq7eR34N75DjytYj5adyggnqdA9fCCfgofiQEELA7o4UiNQ2zf3xjHyeNDhQhib7RQjTeYnapWxu1eSQdCrExzb9J8v7', xPubKey_45H: 'xpub69cqDzoBzXGhsZLgw9BRQCJqdFaUJ1SvwruHVBFEiVCB5U1xDFiUn8UbeKmXemb5ENTgJhoxYKe4yQazwsXFScehhMrc5vAXUVK1mQfyVST', - xPubKey_45H_Signature: '304402204c92ed4d6145be4ea0200367464b8ac6ee3ecf36357c1107eff1766ff791825602206a0608092dcdcf0b84c7a4e3a8f3d7b0aa5b8d5687264a2cab9330c3f21db109', xPrivKey_1H: 'xprv9vdUpVGJA9iNgurZGgm6HhVHF7GQbcpWbezkQcCnwCdz5Tigip2AyEtg2Jz98e7Mthm6yEK72CzNagyMyCGQNuYhErB1Er1ykTpBKeTjsan', xPubKey_1H: 'xpub69cqDzoBzXGfuPw2NiJ6eqS1o96u15YMxsvMCzcQVYAxxG3qGMLRX3D9sZxY3V2CLNX5rZZYB4QUg5zLb961c7CPD46fM9M4rVatc65qeF6', privKey_1H_0: 'c8e4cd009e0ed12564eb96b2ffc68181716748ec9a7f6b218b08587337438bba', @@ -80,7 +74,6 @@ var copayers = [{ xPubKey: 'xpub661MyMwAqRbcFMgsdFzcxGc6UcRHRdYZYjoWM6kbZbspvFQd4FSrK3FJLpwdhqsEL3PYLarn1Av24qDwxfizXkgaKmvLAdJ16MPao2o4MNq', xPrivKey_45H: 'xprv9u2Yq2Sc1xugbPWe4LBefYGiRKbytz9vpbZgWdqk1fZKoLSeTFC5Qb6ospfKzbmNai2TCEX1uRtgfaXgnnwUFyGxEUtjwVq8s39kQcv8SxU', xPubKey_45H: 'xpub681uEXyVrLTyosb7AMif2gDSyMSUJSsnBpVHK2FMa16Jg8mnznWKxPRHj5kWjpHXiJUutUZqAmy6EpomMGRP5im9U95jq85aMwyS7YcJVim', - xPubKey_45H_Signature: '3045022100a51e182d5ff18c069445822e59b0c8316af09dd0a2324513716bef03b87207710220491ef764fae8e3511372554298805f5338a38df905eb784d42e7f50be56795d9', xPrivKey_1H: 'xprv9u2Yq2Sc1xueeYe6GSDWWr7LUJTyjzcf1EjWPLEmT6T12je2PPk8D47h65RFC5i2Xqfj5og2FAJFRSHNaa2dwBtJi4AoBDSqL1NLhyXLyGf', xPubKey_1H: 'xpub681uEXyVrLTws2iZNTkWsz452LJU9TLWNTf7BieP1RyyuXyAvw4NkrSAwMmgHcYNTYYwtdMQPLQKXL8JeEzHAfAhYVbA2xqjjkfCnoAd4tC', privKey_1H_0: '97456bcde0704e054a63a96c11853ba412ab7c33e2ef9fa8661a66db2ce6a94d', @@ -91,7 +84,6 @@ var copayers = [{ xPubKey: 'xpub661MyMwAqRbcH5medWaNJ7aVkBLpFknfuHrknrPLGHSmjCCbGJMB8sohipo1DSXpR7xcnZfsUooP6k8RVoQQ7Ewtmj7jnLbCQDGcBi9Sr3L', xPrivKey_45H: 'xprv9twC9XfPNCFMmqBU3UyVLByyFH9QgmUuwy1gpteoAiLN4rSdG3hcLHjqXSqf36JXwavTFNhawGPYYtZUch6qJNoXfZ2XAeyeeWwrnnGdpD7', xPubKey_45H: 'xpub67vYZ3CHCZoezKFw9WWVhKvhoJyu6ECmKBwHdH4Qj3sLwemmob1rt64KNkQVNrFhy85WAcokstPsA3JPz6qTHqumg98Lzo6ccL7wKCL3sDt', - xPubKey_45H_Signature: '304402207da854acd0132f390425ba77a0af52e4bbbd9756e9846aa3fbaf1c1490bfbe5402200ed615fe0367e433539964d63eae9e3185816e68bc533f13f4415e89cf668882', xPrivKey_1H: 'xprv9twC9XfPNCFKozsRsSNChbiQJpRBkjVZoL4McXGyWQRD3dkkazNW7LhFP85DeM5DKw6AgfJPX7F2VggCznFqbsbUXUdwd7QEpTRYb8Agas3', xPubKey_1H: 'xpub67vYZ3CHCZod2UwtyTuD4jf8rrFgACDRAYyxQugb4jxBvS5u8Xgkf91jESCqi5jydqLYeATXbk58bM6vfa3kviLHuyFKMVM1KSWB1uWRBdB', privKey_1H_0: '5f0011757ae447218cc11b0845b87b7ac9742c8dc37de8d10d590fb096005430', @@ -102,7 +94,6 @@ var copayers = [{ xPubKey: 'xpub661MyMwAqRbcG5LPJv5imhntRgFf9BoiYVxygJeeLFR4FhEasdWk4VsCB3EEw6meT2hGYTE2dN6x1597ekpFJp5wtqoNo25QFe8LBGZatsN', xPrivKey_45H: 'xprv9ugBxZE4n42UY137XuYcWPEf1WrtN7Gyj7LEpDyQXwhPQ6iHtXe9LuBXyMyPgFABe9sagz3KKfTXGsJJnDycv3bZv2vZLibnLZyCX5ug5PT', xPubKey_45H: 'xpub68fYN4kxcRamkV7adw5csXBPZYhNmZzq6LFqccP26HENGu3SS4xPthW1pdKoSrb4KVonrxpE1pPvi3CjzmB1X19xpmE2dSJwdBLw98Au1EA', - xPubKey_45H_Signature: '304502210098ef1cce342fdad94982bca42c5eeacc5cf83d1712807aa4cd707d262eee43d602202dcabc17a32974a63b48bf2537d47df64418208fea5e553a0fbea11ffa22cda4', xPrivKey_1H: 'xprv9ugBxZE4n42Sb78sFa42f8K3mSCm5buKAXTz4Yo7oJvfRFtuy5AtedbsdGMtFULvesJ7KjJtuq8iUv3gxksYFohBHf8jEBihrx4ZkFqLivb', xPubKey_1H: 'xpub68fYN4kxcRajobDLMbb32GFnKU3FV4dAXkParwCjMeTeJ4E4WcV9CRvMUX3t7dUu381jjAir4hB588mN4mFkWCVtoDSH8RhEPCzXJtvzHZG', privKey_1H_0: '084f923954681d1bfc6622ff69fe225c89561f3f8976832acb436c6b0dc6dd01', @@ -113,7 +104,6 @@ var copayers = [{ xPubKey: 'xpub661MyMwAqRbcEnUozs9RUYcy5yYS6oEHTGjmfd6NzAvswkUmZLhsToPKJj4moN2BSSonQDTL9qFYtGsqoRAEwHcxrkwqBfkPBncm23QqrAg', xPrivKey_45H: 'xprv9uj2TGqrHjzvdEQrYby5oGHPT96YBzSNUPHe82g9j6xqcJhx19KhWoPu6RxE4EisvuUTjBAwmsTnxYyT9EuSQJvyrWntQkiQ3QSjLx3XSRZ', xPubKey_45H: 'xpub68iNrnNk87ZDqiVKedW6AQE81Aw2bTADqcDEvR5mHSVpV736Ygdx4biNwiSFYNFzTY6UziVFffDc92iL6WmANV16SexCX8WfGcDcRvaPJfh', - xPubKey_45H_Signature: '3045022100849be80222463f50db39aeb7b7a06826f66d5019ad56f140fce50229247f333002205f279a500b8556fbec0f8ca0ad1cff576af8ddb1e9eee52ebd166817507689c6', xPrivKey_1H: 'xprv9uj2TGqrHjztgbraNVLwq38Smz8Mi1MQE6yN3MXQSj4DaqkyfF1Td8cxpiH4Pd88X6K8qcveM7zpGxFwmi5hB8sQGn3Xnjesojznikr6n9e', xPubKey_1H: 'xpub68iNrnNk87ZBu5w3UWsxCB5BL1xr7U5FbKtxqjw214bCTe68CnKiAvwSfzRQkT4hp27XRHRAewgYiV6uVKGgyoiFnKQaVpDWgiexFf5f4zD', privKey_1H_0: '8c0552de8b785bf395794e88fbe6e0b87e74dbb49282e00acd98f44064913c41', From 7e43e70e6c7beeb221d85917d306988996e6d5d0 Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Tue, 10 Mar 2015 13:48:46 -0300 Subject: [PATCH 3/5] refactor PKR to hold other pub keys --- lib/model/copayer.js | 4 ++-- lib/model/wallet.js | 4 +++- lib/server.js | 4 ++-- test/models/wallet.js | 26 ++++++++++++++++---------- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/lib/model/copayer.js b/lib/model/copayer.js index 505bf1a..1cfffd4 100644 --- a/lib/model/copayer.js +++ b/lib/model/copayer.js @@ -29,7 +29,7 @@ Copayer.create = function(opts) { x.id = WalletUtils.xPubToCopayerId(x.xPubKey); x.name = opts.name; - x.xPubKeySignature = opts.xPubKeySignature; // So third parties can check independently + x.signature = opts.signature; // So third parties can check independently x.requestPubKey = opts.requestPubKey; x.addressManager = AddressManager.create({ copayerIndex: opts.copayerIndex @@ -45,8 +45,8 @@ Copayer.fromObj = function(obj) { x.id = obj.id; x.name = obj.name; x.xPubKey = obj.xPubKey; - x.xPubKeySignature = obj.xPubKeySignature; x.requestPubKey = obj.requestPubKey; + x.signature = obj.signature; x.addressManager = AddressManager.fromObj(obj.addressManager); return x; diff --git a/lib/model/wallet.js b/lib/model/wallet.js index 3453278..711b1d3 100644 --- a/lib/model/wallet.js +++ b/lib/model/wallet.js @@ -95,7 +95,9 @@ Wallet.prototype.addCopayer = function(copayer) { if (this.copayers.length < this.n) return; this.status = 'complete'; - this.publicKeyRing = _.pluck(this.copayers, 'xPubKey'); + this.publicKeyRing = _.map(this.copayers, function(copayer) { + return _.pick(copayer, ['xPubKey', 'requestPubKey']); + }); }; Wallet.prototype.getCopayer = function(copayerId) { diff --git a/lib/server.js b/lib/server.js index 31be2c8..827e5b6 100644 --- a/lib/server.js +++ b/lib/server.js @@ -223,10 +223,10 @@ WalletService.prototype.joinWallet = function(opts, cb) { var copayer = Copayer.create({ name: opts.name, - xPubKey: opts.xPubKey, - xPubKeySignature: opts.xPubKeySignature, copayerIndex: wallet.copayers.length, + xPubKey: opts.xPubKey, requestPubKey: opts.requestPubKey, + signature: opts.copayerSignature, }); self.storage.fetchCopayerLookup(copayer.id, function(err, res) { diff --git a/test/models/wallet.js b/test/models/wallet.js index 54d0959..0f2f7d0 100644 --- a/test/models/wallet.js +++ b/test/models/wallet.js @@ -39,10 +39,16 @@ var testWallet = { m: 2, n: 3, status: 'complete', - publicKeyRing: ['xpub661MyMwAqRbcFLRkhYzK8eQdoywNHJVsJCMQNDoMks5bZymuMcyDgYfnVQYq2Q9npnVmdTAthYGc3N3uxm5sEdnTpSqBc4YYTAhNnoSxCm9', - 'xpub661MyMwAqRbcEzHgVwwxoXksq21rRNsJsn7AFy4VD4PzsEmjjWwsyEiTjsdQviXbqZ5yHVWJR8zFUDgUKkq4R97su3UyNo36Z8hSaCPrv6o', - 'xpub661MyMwAqRbcFXUfkjfSaRwxJbAPpzNUvTiNFjgZwDJ8sZuhyodkP24L4LvsrgThYAAwKkVVSSmL7Ts7o9EHEHPB3EE89roAra7njoSeiMd' - ], + publicKeyRing: [{ + xPubKey: 'xpub661MyMwAqRbcFLRkhYzK8eQdoywNHJVsJCMQNDoMks5bZymuMcyDgYfnVQYq2Q9npnVmdTAthYGc3N3uxm5sEdnTpSqBc4YYTAhNnoSxCm9', + requestPubKey: '03814ac7decf64321a3c6967bfb746112fdb5b583531cd512cc3787eaf578947dc' + }, { + xPubKey: 'xpub661MyMwAqRbcEzHgVwwxoXksq21rRNsJsn7AFy4VD4PzsEmjjWwsyEiTjsdQviXbqZ5yHVWJR8zFUDgUKkq4R97su3UyNo36Z8hSaCPrv6o', + requestPubKey: '03fc086d2bd8b6507b1909b24c198c946e68775d745492ea4ca70adfce7be92a60' + }, { + xPubKey: 'xpub661MyMwAqRbcFXUfkjfSaRwxJbAPpzNUvTiNFjgZwDJ8sZuhyodkP24L4LvsrgThYAAwKkVVSSmL7Ts7o9EHEHPB3EE89roAra7njoSeiMd', + requestPubKey: '0246c30040eda1e36e02629ae8cd2a845fcfa947239c4c703f7ea7550d39cfb43a' + }, ], copayers: [{ addressManager: { receiveAddressIndex: 0, @@ -53,9 +59,9 @@ var testWallet = { id: '1', name: 'copayer 1', xPubKey: 'xpub661MyMwAqRbcFLRkhYzK8eQdoywNHJVsJCMQNDoMks5bZymuMcyDgYfnVQYq2Q9npnVmdTAthYGc3N3uxm5sEdnTpSqBc4YYTAhNnoSxCm9', - xPubKeySignature: '30440220192ae7345d980f45f908bd63ccad60ce04270d07b91f1a9d92424a07a38af85202201591f0f71dd4e79d9206d2306862e6b8375e13a62c193953d768e884b6fb5a46', + requestPubKey: '03814ac7decf64321a3c6967bfb746112fdb5b583531cd512cc3787eaf578947dc', + signature: '30440220192ae7345d980f45f908bd63ccad60ce04270d07b91f1a9d92424a07a38af85202201591f0f71dd4e79d9206d2306862e6b8375e13a62c193953d768e884b6fb5a46', version: '1.0.0', - signingPubKey: '03814ac7decf64321a3c6967bfb746112fdb5b583531cd512cc3787eaf578947dc' }, { addressManager: { receiveAddressIndex: 0, @@ -66,9 +72,9 @@ var testWallet = { id: '2', name: 'copayer 2', xPubKey: 'xpub661MyMwAqRbcEzHgVwwxoXksq21rRNsJsn7AFy4VD4PzsEmjjWwsyEiTjsdQviXbqZ5yHVWJR8zFUDgUKkq4R97su3UyNo36Z8hSaCPrv6o', - xPubKeySignature: '30440220134d13139323ba16ff26471c415035679ee18b2281bf85550ccdf6a370899153022066ef56ff97091b9be7dede8e40f50a3a8aad8205f2e3d8e194f39c20f3d15c62', + requestPubKey: '03fc086d2bd8b6507b1909b24c198c946e68775d745492ea4ca70adfce7be92a60', + signature: '30440220134d13139323ba16ff26471c415035679ee18b2281bf85550ccdf6a370899153022066ef56ff97091b9be7dede8e40f50a3a8aad8205f2e3d8e194f39c20f3d15c62', version: '1.0.0', - signingPubKey: '03fc086d2bd8b6507b1909b24c198c946e68775d745492ea4ca70adfce7be92a60' }, { addressManager: { receiveAddressIndex: 0, @@ -79,9 +85,9 @@ var testWallet = { id: '3', name: 'copayer 3', xPubKey: 'xpub661MyMwAqRbcFXUfkjfSaRwxJbAPpzNUvTiNFjgZwDJ8sZuhyodkP24L4LvsrgThYAAwKkVVSSmL7Ts7o9EHEHPB3EE89roAra7njoSeiMd', - xPubKeySignature: '304402207a4e7067d823a98fa634f9c9d991b8c42cd0f82da24f686992acf96cdeb5e387022021ceba729bf763fc8e4277f6851fc2b856a82a22b35f20d2eeb23d99c5f5a41c', + requestPubKey: '0246c30040eda1e36e02629ae8cd2a845fcfa947239c4c703f7ea7550d39cfb43a', + signature: '304402207a4e7067d823a98fa634f9c9d991b8c42cd0f82da24f686992acf96cdeb5e387022021ceba729bf763fc8e4277f6851fc2b856a82a22b35f20d2eeb23d99c5f5a41c', version: '1.0.0', - signingPubKey: '0246c30040eda1e36e02629ae8cd2a845fcfa947239c4c703f7ea7550d39cfb43a' }], version: '1.0.0', pubKey: '{"x":"6092daeed8ecb2212869395770e956ffc9bf453f803e700f64ffa70c97a00d80","y":"ba5e7082351115af6f8a9eb218979c7ed1f8aa94214f627ae624ab00048b8650","compressed":true}', From b9aae4eacb0a75372187245b30bd121bf211c897 Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Tue, 10 Mar 2015 13:55:07 -0300 Subject: [PATCH 4/5] update readme --- README.md | 5 +++-- lib/server.js | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d25a060..a73c312 100644 --- a/README.md +++ b/README.md @@ -91,8 +91,9 @@ Returns: Required Arguments: * walletId: Id of the wallet to join * name: Copayer Name - * xPubKey: Peer's extended public key - * xPubKeySignature: xPubKey signature with Wallet Creation private key + * xPubKey - Extended Public Key for this copayer. + * requestPubKey - Public Key used to check requests from this copayer. + * copayerSignature - Signature sed by other copayers to verify the that the copayer joining knows the wallet secret. Returns: * copayerId: Assigned ID of the copayer (to be used on x-identity header) diff --git a/lib/server.js b/lib/server.js index 827e5b6..b2d2520 100644 --- a/lib/server.js +++ b/lib/server.js @@ -193,7 +193,7 @@ WalletService.prototype._notify = function(type, data) { * @param {string} opts.name - The copayer name. * @param {string} opts.xPubKey - Extended Public Key for this copayer. * @param {string} opts.requestPubKey - Public Key used to check requests from this copayer. - * @param {string} opts.copayerSignature - opts.proposalSignature - S(name|xPubKey|requestPubKey). Used by other copayers to verify the that the copayer joining knows the wallet secret. + * @param {string} opts.copayerSignature - S(name|xPubKey|requestPubKey). Used by other copayers to verify the that the copayer joining knows the wallet secret. */ WalletService.prototype.joinWallet = function(opts, cb) { var self = this; From e109a43e4c3e7764e0a7dcb465ff2d33f77e38c6 Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Tue, 10 Mar 2015 15:07:36 -0300 Subject: [PATCH 5/5] v0.0.4 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 8641d96..71b08c0 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "bitcore-wallet-service", "description": "A service for Mutisig HD Bitcoin Wallets", "author": "BitPay Inc", - "version": "0.0.3", + "version": "0.0.4", "keywords": [ "bitcoin", "copay", @@ -20,7 +20,7 @@ "dependencies": { "async": "^0.9.0", "bitcore": "^0.11.2", - "bitcore-wallet-utils": "0.0.1", + "bitcore-wallet-utils": "0.0.2", "bitcore-explorers": "^0.9.1", "body-parser": "^1.11.0", "coveralls": "^2.11.2",