diff --git a/lib/client/airgapped.js b/lib/client/airgapped.js index 3e067c5..283ec6c 100644 --- a/lib/client/airgapped.js +++ b/lib/client/airgapped.js @@ -37,10 +37,14 @@ AirGapped.prototype.getSeed = function() { }; }; -AirGapped.prototype.signTxProposal = function(txp) { +AirGapped.prototype.signTxProposal = function(txp, pkr, m, n) { var self = this; // TODO: complete credentials + self.credentials.m = m; + self.credentials.n = n; + self.credentials.addPublicKeyRing(pkr); + if (!Verifier.checkTxProposal(self.credentials, txp)) { throw new Error('Fake transaction proposal'); } diff --git a/lib/client/credentials.js b/lib/client/credentials.js index d59f18e..5af6a76 100644 --- a/lib/client/credentials.js +++ b/lib/client/credentials.js @@ -9,7 +9,6 @@ var FIELDS = [ 'network', 'xPrivKey', 'xPubKey', - // 'roPrivKey', 'requestPrivKey', 'copayerId', 'publicKeyRing', @@ -58,7 +57,6 @@ Credentials.prototype._expand = function() { if (this.xPrivKey) { var xPrivKey = new Bitcore.HDPrivateKey.fromString(this.xPrivKey); this.xPubKey = (new Bitcore.HDPublicKey(xPrivKey)).toString(); - // this.roPrivKey = xPrivKey.derive('m/1/0').privateKey.toString(); this.requestPrivKey = xPrivKey.derive('m/1/1').privateKey.toString(); } this.copayerId = WalletUtils.xPubToCopayerId(this.xPubKey); @@ -100,7 +98,7 @@ Credentials.prototype.canSign = function() { }; Credentials.prototype.isComplete = function() { - if (!this.walletId) return false; + if (!this.m || !this.n) return false; if (!this.publicKeyRing || this.publicKeyRing.length != this.n) return false; return true; }; diff --git a/lib/model/copayer.js b/lib/model/copayer.js index 6869500..04a84cb 100644 --- a/lib/model/copayer.js +++ b/lib/model/copayer.js @@ -11,8 +11,6 @@ var AddressManager = require('./addressmanager'); var Utils = require('../walletutils'); -var RW_SIGNING_PATH = "m/1/1"; - function Copayer() { this.version = '1.0.0'; }; @@ -30,7 +28,7 @@ Copayer.create = function(opts) { x.id = Utils.xPubToCopayerId(x.xPubKey); x.name = opts.name; x.xPubKeySignature = opts.xPubKeySignature; // So third parties can check independently - x.rwPubKey = x.getRWPubKey(); + x.requestPubKey = x.getRequestPubKey(); x.addressManager = AddressManager.create({ copayerIndex: opts.copayerIndex }); @@ -46,8 +44,7 @@ Copayer.fromObj = function(obj) { x.name = obj.name; x.xPubKey = obj.xPubKey; x.xPubKeySignature = obj.xPubKeySignature; - x.roPubKey = obj.roPubKey; - x.rwPubKey = obj.rwPubKey; + x.requestPubKey = obj.requestPubKey; x.addressManager = AddressManager.fromObj(obj.addressManager); return x; @@ -61,8 +58,8 @@ Copayer.prototype.getPublicKey = function(path) { .toString(); }; -Copayer.prototype.getRWPubKey = function() { - return this.getPublicKey(RW_SIGNING_PATH); +Copayer.prototype.getRequestPubKey = function() { + return this.getPublicKey('m/1/1'); }; diff --git a/lib/server.js b/lib/server.js index ace2272..8b19e00 100644 --- a/lib/server.js +++ b/lib/server.js @@ -66,7 +66,7 @@ WalletService.getInstance = function() { * @param {Object} opts * @param {string} opts.copayerId - The copayer id making the request. * @param {string} opts.message - The contents of the request to be signed. - * @param {string} opts.signature - Signature of message to be verified using the copayer's rwPubKey + * @param {string} opts.signature - Signature of message to be verified using the copayer's requestPubKey */ WalletService.getInstanceWithAuth = function(opts, cb) { @@ -78,7 +78,7 @@ WalletService.getInstanceWithAuth = function(opts, cb) { if (err) return cb(err); if (!copayer) return cb(new ClientError('NOTAUTHORIZED', 'Copayer not found')); - var isValid = server._verifySignature(opts.message, opts.signature, copayer.rwPubKey); + var isValid = server._verifySignature(opts.message, opts.signature, copayer.requestPubKey); if (!isValid) return cb(new ClientError('NOTAUTHORIZED', 'Invalid signature')); @@ -312,7 +312,7 @@ WalletService.prototype.verifyMessageSignature = function(opts, cb) { var copayer = wallet.getCopayer(self.copayerId); - var isValid = self._verifySignature(opts.message, opts.signature, copayer.rwPubKey); + var isValid = self._verifySignature(opts.message, opts.signature, copayer.requestPubKey); return cb(null, isValid); }); }; @@ -497,7 +497,7 @@ WalletService.prototype.createTx = function(opts, cb) { var copayer = wallet.getCopayer(self.copayerId); var hash = WalletUtils.getProposalHash(opts.toAddress, opts.amount, opts.message); - if (!self._verifySignature(hash, opts.proposalSignature, copayer.rwPubKey)) + if (!self._verifySignature(hash, opts.proposalSignature, copayer.requestPubKey)) return cb(new ClientError('Invalid proposal signature')); var toAddress; diff --git a/lib/storage.js b/lib/storage.js index 4e333f5..badd80b 100644 --- a/lib/storage.js +++ b/lib/storage.js @@ -81,8 +81,7 @@ Storage.prototype.storeWalletAndUpdateCopayersLookup = function(wallet, cb) { _.each(wallet.copayers, function(copayer) { var value = { walletId: wallet.id, - roPubKey: copayer.roPubKey, - rwPubKey: copayer.rwPubKey, + requestPubKey: copayer.requestPubKey, }; ops.push({ type: 'put', diff --git a/test/integration/client.js b/test/integration/client.js index 8df6f1b..21ba42b 100644 --- a/test/integration/client.js +++ b/test/integration/client.js @@ -949,7 +949,7 @@ describe('client API ', function() { }); }); - it.skip('should be able to sign from airgapped client and broadcast from proxy', function(done) { + it('should be able to sign from airgapped client and broadcast from proxy', function(done) { var airgapped = new AirGapped({ network: 'testnet' }); @@ -993,7 +993,12 @@ describe('client API ', function() { }, next); }, function(txps, rawTxps, next) { - var signatures = airgapped.signTxProposal(rawTxps[0]); + // TODO: these params should be grouped, signed, encrypted, etc + var pkr = proxy.credentials.publicKeyRing; + var m = proxy.credentials.m; + var n = proxy.credentials.n; + + var signatures = airgapped.signTxProposal(rawTxps[0], pkr, m, n); next(null, signatures); }, function(signatures, next) {