Browse Source

add proposalSignature to txp

activeAddress
Ivan Socolsky 10 years ago
parent
commit
cde30c6b9d
  1. 2
      lib/model/txproposal.js
  2. 4
      lib/model/wallet.js
  3. 6
      lib/server.js
  4. 23
      test/integration.js
  5. 2
      test/txproposal.js

2
lib/model/txproposal.js

@ -19,6 +19,7 @@ function TxProposal(opts) {
this.toAddress = opts.toAddress;
this.amount = opts.amount;
this.message = opts.message;
this.proposalSignature = opts.proposalSignature;
this.changeAddress = opts.changeAddress;
this.inputs = opts.inputs;
this.inputPaths = opts.inputPaths;
@ -38,6 +39,7 @@ TxProposal.fromObj = function(obj) {
x.toAddress = obj.toAddress;
x.amount = obj.amount;
x.message = obj.message;
x.proposalSignature = obj.proposalSignature;
x.changeAddress = obj.changeAddress;
x.inputs = obj.inputs;
x.requiredSignatures = obj.requiredSignatures;

4
lib/model/wallet.js

@ -82,6 +82,10 @@ Wallet.fromObj = function(obj) {
return x;
};
Wallet.prototype.isShared = function() {
return this.n > 1;
};
Wallet.prototype.addCopayer = function(copayer) {
this.copayers.push(copayer);

6
lib/server.js

@ -384,6 +384,7 @@ CopayServer.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.
* @returns {TxProposal} Transaction proposal.
*/
CopayServer.prototype.createTx = function(opts, cb) {
@ -395,6 +396,11 @@ CopayServer.prototype.createTx = function(opts, cb) {
self.getWallet({}, function(err, wallet) {
if (err) return cb(err);
if (!wallet.isComplete()) return cb(new ClientError('Wallet is not complete'));
if (wallet.isShared() && !Utils.checkRequired(opts, 'proposalSignature')) return cb(new ClientError('Proposal signature is required for shared wallets'));
var copayer = wallet.getCopayer(self.copayerId);
var msg = opts.toAddress + '|' + opts.amount + '|' + opts.message;
if (!self._verifySignature(msg, opts.proposalSignature, copayer.signingPubKey)) return cb(new ClientError('Invalid proposal signature'));
var toAddress;
try {

23
test/integration.js

@ -201,6 +201,12 @@ helpers.clientSign = function(tx, xpriv, n) {
return signatures;
};
helpers.addProposalSignature = function(server, wallet, txOpts) {
var msg = txOpts.toAddress + '|' + txOpts.amount + '|' + txOpts.message;
var copayer = wallet.getCopayer(server.copayerId);
txOpts.proposalSignature = SignUtils.sign(msg, copayer.signingPubKey);
};
var db, storage;
@ -596,7 +602,7 @@ describe('Copay server', function() {
});
});
it('should create a tx', function(done) {
it.only('should create a tx', function(done) {
helpers.createUtxos(server, wallet, helpers.toSatoshi([100, 200]), function(utxos) {
helpers.stubBlockExplorer(server, utxos);
var txOpts = {
@ -604,8 +610,10 @@ describe('Copay server', function() {
amount: helpers.toSatoshi(80),
message: 'some message',
};
helpers.addProposalSignature(txOpts, );
console.log(txOpts);
server.createTx(txOpts, function(err, tx) {
console.log(err);
should.not.exist(err);
tx.should.exist;
tx.message.should.equal('some message');
@ -647,6 +655,7 @@ describe('Copay server', function() {
var txOpts = {
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
amount: helpers.toSatoshi(80),
proposalSignature: 'dummy',
};
server.createTx(txOpts, function(err, tx) {
should.not.exist(tx);
@ -665,6 +674,7 @@ describe('Copay server', function() {
var txOpts = {
toAddress: 'invalid address',
amount: helpers.toSatoshi(80),
proposalSignature: 'dummy',
};
server.createTx(txOpts, function(err, tx) {
@ -683,6 +693,7 @@ describe('Copay server', function() {
var txOpts = {
toAddress: 'myE38JHdxmQcTJGP1ZiX4BiGhDxMJDvLJD', // testnet
amount: helpers.toSatoshi(80),
proposalSignature: 'dummy',
};
server.createTx(txOpts, function(err, tx) {
@ -701,6 +712,7 @@ describe('Copay server', function() {
var txOpts = {
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
amount: helpers.toSatoshi(120),
proposalSignature: 'dummy',
};
server.createTx(txOpts, function(err, tx) {
@ -730,6 +742,7 @@ describe('Copay server', function() {
var txOpts = {
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
amount: helpers.toSatoshi(12),
proposalSignature: 'dummy',
};
server.createTx(txOpts, function(err, tx) {
should.not.exist(err);
@ -738,6 +751,7 @@ describe('Copay server', function() {
var txOpts2 = {
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
amount: 8,
proposalSignature: 'dummy',
};
server.createTx(txOpts2, function(err, tx) {
should.not.exist(err);
@ -763,6 +777,7 @@ describe('Copay server', function() {
var txOpts = {
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
amount: helpers.toSatoshi(12),
proposalSignature: 'dummy',
};
server.createTx(txOpts, function(err, tx) {
should.not.exist(err);
@ -771,6 +786,7 @@ describe('Copay server', function() {
var txOpts2 = {
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
amount: helpers.toSatoshi(24),
proposalSignature: 'dummy',
};
server.createTx(txOpts2, function(err, tx) {
err.code.should.equal('INSUFFICIENTFUNDS');
@ -805,6 +821,7 @@ describe('Copay server', function() {
var txOpts = {
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
amount: helpers.toSatoshi(80),
proposalSignature: 'dummy',
};
async.map(_.range(N), function(i, cb) {
server.createTx(txOpts, function(err, tx) {
@ -841,6 +858,7 @@ describe('Copay server', function() {
var txOpts = {
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
amount: helpers.toSatoshi(10),
proposalSignature: 'dummy',
};
server.createTx(txOpts, function(err, tx) {
should.not.exist(err);
@ -1004,6 +1022,7 @@ describe('Copay server', function() {
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
amount: helpers.toSatoshi(10),
message: 'some message',
proposalSignature: 'dummy',
};
server.createTx(txOpts, function(err, txp) {
should.not.exist(err);

2
test/txproposal.js

@ -89,6 +89,8 @@ var aTXP = function() {
"creatorId": "1",
"toAddress": "18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7",
"amount": 50000000,
"message": 'some message',
"proposalSignature": '7035022100896aeb8db75fec22fddb5facf791927a996eb3aee23ee6deaa15471ea46047de02204c0c33f42a9d3ff93d62738712a8c8a5ecd21b45393fdd144e7b01b5a186f1f9',
"changeAddress": "3CauZ5JUFfmSAx2yANvCRoNXccZ3YSUjXH",
"inputs": [{
"txid": "6ee699846d2d6605f96d20c7cc8230382e5da43342adb11b499bbe73709f06ab",

Loading…
Cancel
Save