From 5c9bb4982d15fedc8808d888a444d76b0eace628 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Mon, 15 Sep 2014 18:51:12 -0700 Subject: [PATCH 1/6] paypro: fix signature error. fix merchant_data. see #1409. --- app.js | 3 +++ js/models/core/Wallet.js | 24 ++++++++++++++++-------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/app.js b/app.js index d531b0274..ea1e50f42 100644 --- a/app.js +++ b/app.js @@ -20,6 +20,9 @@ app.start = function(port, callback) { pserver.removeListener('request', pserver.app); + // pserver.options['no-tx'] = true; + // pserver.options['discovery'] = true; + pserver.on('request', function(req, res) { if (req.url.indexOf('/-/') === 0) { return pserver.app(req, res); diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 4246c3a0e..2a9faadc0 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -841,7 +841,7 @@ Wallet.prototype.store = function(cb) { this.keepAlive(); this.storage.setFromObj(this.id, this.toObj(), function(err) { log.debug('Wallet stored'); - if (cb) + if (cb) cb(err); }); }; @@ -1416,9 +1416,9 @@ Wallet.prototype.receivePaymentRequest = function(options, pr, cb) { expires: expires, memo: memo || 'This server would like some BTC from you.', payment_url: payment_url, - merchant_data: merchant_data ? merchant_data.toString('hex') - // : new Buffer('none', 'utf8').toString('hex') - : '00' + merchant_data: merchant_data + ? merchant_data.toString('hex') + : null }, signature: sig.toString('hex'), ca: trust.caName, @@ -1540,8 +1540,10 @@ Wallet.prototype.sendPaymentTx = function(ntxid, options, cb) { var pay = new PayPro(); pay = pay.makePayment(); var merchant_data = txp.merchant.pr.pd.merchant_data; - merchant_data = new Buffer(merchant_data, 'hex'); - pay.set('merchant_data', merchant_data); + if (merchant_data) { + merchant_data = new Buffer(merchant_data, 'hex'); + pay.set('merchant_data', merchant_data); + } pay.set('transactions', [tx.serialize()]); pay.set('refund_to', refund_outputs); @@ -1582,7 +1584,13 @@ Wallet.prototype.sendPaymentTx = function(ntxid, options, cb) { return self.receivePaymentRequestACK(ntxid, tx, txp, ack, cb); }) .error(function(data, status, headers, config) { - return cb(new Error('Status: ' + status)); + log.debug('Sending to server was not met with a returned tx.'); + log.debug('XHR status: ' + status); + return self._checkSentTx(ntxid, function(txid) { + log.debug('[Wallet.js.1581:txid:%s]', txid); + if (txid) self.store(); + return cb(txid, txp.merchant); + }); }); }; @@ -1611,7 +1619,7 @@ Wallet.prototype.receivePaymentRequestACK = function(ntxid, tx, txp, ack, cb) { if (!tx) { log.debug('Sending to server was not met with a returned tx.'); return this._checkSentTx(ntxid, function(txid) { - self.log('[Wallet.js.1048:txid:%s]', txid); + log.debug('[Wallet.js.1613:txid:%s]', txid); if (txid) self.store(); return cb(txid, txp.merchant); }); From efdf8c902a255696ac734421a1c80e44d4cf760f Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Mon, 15 Sep 2014 19:02:38 -0700 Subject: [PATCH 2/6] paypro: fix invalid signature error. --- js/models/core/Wallet.js | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 2a9faadc0..107ad366a 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -1636,12 +1636,23 @@ Wallet.prototype.receivePaymentRequestACK = function(ntxid, tx, txp, ack, cb) { var txid = tx.getHash().toString('hex'); var txHex = tx.serialize().toString('hex'); log.debug('Raw transaction: ', txHex); - log.debug('BITCOIND txid:', txid); - this.txProposals.get(ntxid).setSent(txid); - this.sendTxProposal(ntxid); - this.store(); + this.blockchain.broadcast(txHex, function(err, txid) { + log.debug('BITCOIND txid:', txid); + if (txid) { + self.txProposals.get(ntxid).setSent(txid); + self.sendTxProposal(ntxid); + self.store(); + return cb(txid, txp.merchant); + } else { + log.debug('Sent failed. Checking if the TX was sent already'); + self._checkSentTx(ntxid, function(txid) { + if (txid) + self.store(); - return cb(txid, txp.merchant); + return cb(txid, txp.merchant); + }); + } + }); }; /** From f3ed336278284c81c64c28dad11a74e725265349 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Tue, 16 Sep 2014 09:57:21 -0700 Subject: [PATCH 3/6] paypro: minor fix to createPaymentTx callback. --- js/models/core/Wallet.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 107ad366a..a57acabac 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -1303,7 +1303,14 @@ Wallet.prototype.createPaymentTx = function(options, cb) { return self.receivePaymentRequest(options, pr, cb); }) .error(function(data, status, headers, config) { - return cb(new Error('Status: ' + status)); + log.debug('Server was did not return PaymentRequest.'); + log.debug('XHR status: ' + status); + if (options.fetch) { + return cb(new Error('Status: ' + status)); + } else { + // Should never happen: + return cb(null, null, null); + } }); }; From 10b946bd862aa7d84fb678b1d025b28b1f13c77c Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Mon, 22 Sep 2014 15:14:04 -0700 Subject: [PATCH 4/6] paypro: fix error passing to abide by new flow. see #1410. --- js/models/core/Wallet.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index a57acabac..70b638467 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -1469,7 +1469,7 @@ Wallet.prototype.receivePaymentRequest = function(options, pr, cb) { log.debug('You are currently on this BTC network:', network); log.debug('The server sent you a message:', memo); - return cb(ntxid, merchantData); + return cb(null, ntxid, merchantData); }); }; From 66b845f7fde4ae67f16f0d84e51126160387c534 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Mon, 22 Sep 2014 16:15:46 -0700 Subject: [PATCH 5/6] test: update tests for paypro fix. --- test/test.PayPro.js | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/test/test.PayPro.js b/test/test.PayPro.js index e1d3d88ea..c6fa55d9b 100644 --- a/test/test.PayPro.js +++ b/test/test.PayPro.js @@ -684,7 +684,8 @@ describe('PayPro (in Wallet) model', function() { var req = w.paymentRequests[options.uri]; should.exist(req); delete w.paymentRequests[options.uri]; - w.receivePaymentRequest(options, req.pr, function(ntxid, merchantData) { + w.receivePaymentRequest(options, req.pr, function(err, ntxid, merchantData) { + should.equal(err, null); should.exist(ntxid); should.exist(merchantData); w._ntxid = ntxid; @@ -713,7 +714,8 @@ describe('PayPro (in Wallet) model', function() { w.createPaymentTx({ uri: uri, memo: memo - }, function(ntxid, merchantData) { + }, function(err, ntxid, merchantData) { + should.equal(err, null); should.exist(ntxid); should.exist(merchantData); if (w.isShared()) { @@ -744,7 +746,8 @@ describe('PayPro (in Wallet) model', function() { uri = address.split(/\s+/)[1]; } - w.createPaymentTx({ uri: uri, memo: commentText }, function(ntxid, merchantData) { + w.createPaymentTx({ uri: uri, memo: commentText }, function(err, ntxid, merchantData) { + should.equal(err, null); if (w.isShared()) { should.exist(ntxid); should.exist(merchantData); @@ -765,7 +768,8 @@ describe('PayPro (in Wallet) model', function() { should.exist(w); var address = 'bitcoin:2NBzZdFBoQymDgfzH2Pmnthser1E71MmU47?amount=0.00003&r=' + server.uri + '/request'; var commentText = 'Hello, server. I\'d like to make a payment.'; - w.createPaymentTx({ uri: address, memo: commentText }, function(ntxid, merchantData) { + w.createPaymentTx({ uri: address, memo: commentText }, function(err, ntxid, merchantData) { + should.equal(err, null); if (w.isShared()) { should.exist(ntxid); should.exist(merchantData); @@ -785,7 +789,8 @@ describe('PayPro (in Wallet) model', function() { should.exist(w); var address = 'bitcoin:2NBzZdFBoQymDgfzH2Pmnthser1E71MmU47?amount=0.00003&r=' + server.uri + '/request'; var commentText = 'Hello, server. I\'d like to make a payment.'; - w.createPaymentTx({ uri: address, memo: commentText }, function(ntxid, merchantData) { + w.createPaymentTx({ uri: address, memo: commentText }, function(err, ntxid, merchantData) { + should.equal(err, null); should.exist(ntxid); should.exist(merchantData); @@ -821,7 +826,8 @@ describe('PayPro (in Wallet) model', function() { should.exist(w); var address = 'bitcoin:2NBzZdFBoQymDgfzH2Pmnthser1E71MmU47?amount=0.00003&r=' + server.uri + '/request'; var commentText = 'Hello, server. I\'d like to make a payment.'; - w.createPaymentTx({ uri: address, memo: commentText }, function(ntxid, merchantData) { + w.createPaymentTx({ uri: address, memo: commentText }, function(err, ntxid, merchantData) { + should.equal(err, null); should.exist(ntxid); should.exist(merchantData); @@ -848,7 +854,8 @@ describe('PayPro (in Wallet) model', function() { should.exist(w); var address = 'bitcoin:2NBzZdFBoQymDgfzH2Pmnthser1E71MmU47?amount=0.00003&r=' + server.uri + '/request'; var commentText = 'Hello, server. I\'d like to make a payment.'; - w.createPaymentTx({ uri: address, memo: commentText }, function(ntxid, merchantData) { + w.createPaymentTx({ uri: address, memo: commentText }, function(err, ntxid, merchantData) { + should.equal(err, null); should.exist(ntxid); should.exist(merchantData); @@ -874,7 +881,8 @@ describe('PayPro (in Wallet) model', function() { should.exist(w); var address = 'bitcoin:2NBzZdFBoQymDgfzH2Pmnthser1E71MmU47?amount=0.00003&r=' + server.uri + '/request'; var commentText = 'Hello, server. I\'d like to make a payment.'; - w.createPaymentTx({ uri: address, memo: commentText }, function(ntxid, merchantData) { + w.createPaymentTx({ uri: address, memo: commentText }, function(err, ntxid, merchantData) { + should.equal(err, null); should.exist(ntxid); should.exist(merchantData); From 4ee99603f3c9416514c0dbf2a5e831c3854b1646 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Tue, 23 Sep 2014 09:22:07 -0700 Subject: [PATCH 6/6] paypro: compensate for improperly implemented payment protocol servers. --- js/models/core/Wallet.js | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 70b638467..1d57edd76 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -1621,28 +1621,34 @@ Wallet.prototype.receivePaymentRequestACK = function(ntxid, tx, txp, ack, cb) { memo: memo }; - var tx = payment.message.transactions[0]; - - if (!tx) { - log.debug('Sending to server was not met with a returned tx.'); - return this._checkSentTx(ntxid, function(txid) { - log.debug('[Wallet.js.1613:txid:%s]', txid); - if (txid) self.store(); - return cb(txid, txp.merchant); - }); - } - - if (tx.buffer) { - tx.buffer = new Buffer(new Uint8Array(tx.buffer)); - tx.buffer = tx.buffer.slice(tx.offset, tx.limit); - var ptx = new bitcore.Transaction(); - ptx.parse(tx.buffer); - tx = ptx; + if (payment.message.transactions && payment.message.transactions.length) { + tx = payment.message.transactions[0]; + if (!tx) { + log.debug('Sending to server was not met with a returned tx.'); + return this._checkSentTx(ntxid, function(txid) { + log.debug('[Wallet.js.1613:txid:%s]', txid); + if (txid) self.store(); + return cb(txid, txp.merchant); + }); + } + if (tx.buffer) { + tx.buffer = new Buffer(new Uint8Array(tx.buffer)); + tx.buffer = tx.buffer.slice(tx.offset, tx.limit); + var ptx = new bitcore.Transaction(); + ptx.parse(tx.buffer); + tx = ptx; + } + } else { + log.debug('WARNING: This server does not comply by standards.'); + log.debug('It is not returning a copy of the transaction.'); } var txid = tx.getHash().toString('hex'); var txHex = tx.serialize().toString('hex'); log.debug('Raw transaction: ', txHex); + + // XXX This fixes the invalid signature error: + // we might as well broadcast it ourselves anyway. this.blockchain.broadcast(txHex, function(err, txid) { log.debug('BITCOIND txid:', txid); if (txid) {