From 18da32df64e8c6b75e34c68f28347bdc17959ba4 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Sun, 15 Feb 2015 18:26:05 -0300 Subject: [PATCH 1/4] better wallet creation for 1-1 --- bit-wallet/bit-create | 13 +++++++------ bit-wallet/cli-utils.js | 20 ++++++++++---------- lib/client/API.js | 7 +++++-- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/bit-wallet/bit-create b/bit-wallet/bit-create index c3053bb..dae6ad6 100755 --- a/bit-wallet/bit-create +++ b/bit-wallet/bit-create @@ -1,13 +1,14 @@ #!/usr/bin/env node +var _ = require('lodash'); var program = require('commander'); var ClientLib = require('../lib/client'); -var utils = require('./cli-utils'); +var utils = require('./cli-utils'); program .version('0.0.1') .option('-c, --config [file]', 'Wallet config filename') - .option('-n, --network [networkname]', 'livenet|testnet', String, 'livenet') + .option('-t, --testnet', 'Create a Testnet Wallet', String) .usage('[options] [copayerName]') .parse(process.argv); @@ -17,14 +18,14 @@ if (!args[0]) var walletName = args[0]; var copayerName = args[2] || process.env.USER; -var network = program.network; +var network = program.testnet ? 'testnet' : 'livenet'; var mn = utils.parseMN(args[1]); var client = utils.getClient(program); client.createWallet(walletName, copayerName, mn[0], mn[1], network, function(err, secret) { utils.die(err); - console.log(' * Wallet Created.'); - console.log(' - Secret to share:\n\t' + secret); + console.log(' * ' + _.capitalize(network) + ' Wallet Created.'); + if (secret) + console.log(' - Secret to share:\n\t' + secret); }); - diff --git a/bit-wallet/cli-utils.js b/bit-wallet/cli-utils.js index fbef376..1f47be4 100644 --- a/bit-wallet/cli-utils.js +++ b/bit-wallet/cli-utils.js @@ -2,16 +2,16 @@ var _ = require('lodash'); var Client = require('../lib/client'); -var lib = function() {}; +var Utils = function() {}; -var die = lib.die = function(err) { +var die = Utils.die = function(err) { if (err) { console.error(err); process.exit(1); } }; -lib.parseMN = function(MN) { +Utils.parseMN = function(MN) { if (!MN) die('No m-n parameter'); var mn = MN.split('-'); @@ -27,11 +27,11 @@ lib.parseMN = function(MN) { }; -lib.shortID = function(id) { +Utils.shortID = function(id) { return id.substr(id.length - 4); }; -lib.getClient = function(args) { +Utils.getClient = function(args) { var storage = new Client.FileStorage({ filename: args.config }); @@ -41,16 +41,16 @@ lib.getClient = function(args) { }); } -lib.findOneTxProposal = function(txps, id) { +Utils.findOneTxProposal = function(txps, id) { var matches = _.filter(txps, function(tx) { - return _.endsWith(lib.shortID(tx.id), id); + return _.endsWith(Utils.shortID(tx.id), id); }); if (!matches.length) - lib.die('Could not find TX Proposal:' + id); + Utils.die('Could not find TX Proposal:' + id); if (matches.length > 1) - lib.die('More than one TX Proposals match:' + id + ' : ' + _.map(matches, function(tx) { + Utils.die('More than one TX Proposals match:' + id + ' : ' + _.map(matches, function(tx) { return tx.id; }).join(' '));; @@ -59,4 +59,4 @@ lib.findOneTxProposal = function(txps, id) { -module.exports = lib; +module.exports = Utils; diff --git a/lib/client/API.js b/lib/client/API.js index c3cad57..a51af67 100644 --- a/lib/client/API.js +++ b/lib/client/API.js @@ -148,13 +148,16 @@ API.prototype.createWallet = function(walletName, copayerName, m, n, network, cb var walletId = body.walletId; var secret = walletId + ':' + privKey.toString() + ':' + (network == 'testnet' ? 'T' : 'L'); - data.secret = secret; + var ret; + + if (n > 1) + ret = data.secret = secret; self.storage.save(data); self._joinWallet(data, secret, copayerName, function(err) { if (err) return cb(err); - return cb(null, data.secret); + return cb(null, ret); }); }); }; From 1a8eaf0c7fc6fae27f8843b832113e1f754868af Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Sun, 15 Feb 2015 18:52:48 -0300 Subject: [PATCH 2/4] add broadcastTx --- app.js | 11 ++++++++++ bit-wallet/bit | 1 + bit-wallet/bit-broadcast | 30 +++++++++++++++++++++++++++ lib/client/API.js | 10 +++++++++ lib/server.js | 45 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 97 insertions(+) create mode 100644 bit-wallet/bit-broadcast diff --git a/app.js b/app.js index 99eba80..eb7aab5 100644 --- a/app.js +++ b/app.js @@ -204,6 +204,17 @@ router.post('/v1/txproposals/:id/signatures/', function(req, res) { }); }); +// TODO Check HTTP verb and URL name +router.post('/v1/txproposals/:id/broadcast/', function(req, res) { + getServerWithAuth(req, res, function(server) { + req.body.txProposalId = req.params['id']; + server.broadcastTx(req.body, function(err, txp) { + if (err) return returnError(err, res, req); + res.end(); + }); + }); +}); + router.post('/v1/txproposals/:id/rejections', function(req, res) { getServerWithAuth(req, res, function(server) { req.body.txProposalId = req.params['id']; diff --git a/bit-wallet/bit b/bit-wallet/bit index cffe423..b5b3026 100755 --- a/bit-wallet/bit +++ b/bit-wallet/bit @@ -13,6 +13,7 @@ program .command('send
', 'send bitcoins') .command('sign ', 'sign a transaction proposal') .command('reject [reason]', 'reject a transaction proposal') + .command('broadcast ', 'broadcast a transaction proposal to the Bitcoin network') .command('rm ', 'remove a transaction proposal') .parse(process.argv); diff --git a/bit-wallet/bit-broadcast b/bit-wallet/bit-broadcast new file mode 100644 index 0000000..24597fa --- /dev/null +++ b/bit-wallet/bit-broadcast @@ -0,0 +1,30 @@ +#!/usr/bin/env node + +var _ = require('lodash'); +var program = require('commander'); +var Client = require('../lib/client'); +var utils = require('./cli-utils'); + +program +.version('0.0.1') +.option('-c,--config [file]', 'Wallet config filename') +.option('-v,--verbose', 'be verbose') +.usage('[options] ') +.parse(process.argv); + +var args = program.args; +if (!args[0]) + program.help(); + + var txpid = args[0]; + var client = utils.getClient(program); + + client.getTxProposals({}, function(err, txps) { + utils.die(err); + + var txp = utils.findOneTxProposal(txps, txpid); + client.broadcastTxProposal(txp, function(err, txid) { + utils.die(err); + console.log('TX Broadcasted: ',txid); + }); + }); diff --git a/lib/client/API.js b/lib/client/API.js index a51af67..f582925 100644 --- a/lib/client/API.js +++ b/lib/client/API.js @@ -360,6 +360,16 @@ API.prototype.rejectTxProposal = function(txp, reason, cb) { this._doPostRequest(url, args, data, cb); }; +API.prototype.broadcastTxProposal = function(txp, cb) { + var self = this; + var data = this._loadAndCheck(); + + var url = '/v1/txproposals/' + txp.id + '/broadcast/'; + this._doPostRequest(url, {}, data, cb); +}; + + + API.prototype.removeTxProposal = function(txp, cb) { var self = this; var data = this._loadAndCheck(); diff --git a/lib/server.js b/lib/server.js index 579129a..7923351 100644 --- a/lib/server.js +++ b/lib/server.js @@ -660,6 +660,51 @@ CopayServer.prototype.signTx = function(opts, cb) { }); }; + +/** + * Broadcast a transaction proposal. + * @param {Object} opts + * @param {string} opts.txProposalId - The identifier of the transaction. + */ +CopayServer.prototype.broadcastTx = function(opts, cb) { + var self = this; + + if (!Utils.checkRequired(opts, ['txProposalId'])) + return cb(new ClientError('Required argument missing')); + + self.getWallet({}, function(err, wallet) { + if (err) return cb(err); + + self.getTx({ + id: opts.txProposalId + }, function(err, txp) { + if (err) return cb(err); + + if (txp.status == 'broadcasted') + return cb(new ClientError('TXALREADYBROADCASTED', 'The transaction proposal is already broadcasted')); + + if (txp.status != 'accepted') + return cb(new ClientError('TXNOTACCEPTED', 'The transaction proposal is not accepted')); + + self._broadcastTx(txp, function(err, txid) { + if (err) return cb(err); + + txp.setBroadcasted(txid); + self.storage.storeTx(self.walletId, txp, function(err) { + if (err) return cb(err); + + self._notify('NewOutgoingTx', { + txProposalId: opts.txProposalId, + txid: txid + }); + + return cb(null, txp); + }); + }); + }); + }); +}; + /** * Reject a transaction proposal. * @param {Object} opts From 7c1860117e0c0575575b07823a2c2509d0a24b86 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Sun, 15 Feb 2015 19:06:11 -0300 Subject: [PATCH 3/4] sign/reject with args (if only one txp) --- bit-wallet/bit-broadcast | 32 ++++++++++++++++---------------- bit-wallet/bit-reject | 4 +--- bit-wallet/bit-sign | 5 +---- lib/model/txproposal.js | 2 +- lib/server.js | 3 ++- 5 files changed, 21 insertions(+), 25 deletions(-) mode change 100644 => 100755 bit-wallet/bit-broadcast diff --git a/bit-wallet/bit-broadcast b/bit-wallet/bit-broadcast old mode 100644 new mode 100755 index 24597fa..82fa266 --- a/bit-wallet/bit-broadcast +++ b/bit-wallet/bit-broadcast @@ -3,28 +3,28 @@ var _ = require('lodash'); var program = require('commander'); var Client = require('../lib/client'); -var utils = require('./cli-utils'); +var utils = require('./cli-utils'); program -.version('0.0.1') -.option('-c,--config [file]', 'Wallet config filename') -.option('-v,--verbose', 'be verbose') -.usage('[options] ') -.parse(process.argv); + .version('0.0.1') + .option('-c,--config [file]', 'Wallet config filename') + .option('-v,--verbose', 'be verbose') + .usage('[options] ') + .parse(process.argv); var args = program.args; if (!args[0]) program.help(); - var txpid = args[0]; - var client = utils.getClient(program); +var txpid = args[0]; +var client = utils.getClient(program); - client.getTxProposals({}, function(err, txps) { - utils.die(err); +client.getTxProposals({}, function(err, txps) { + utils.die(err); - var txp = utils.findOneTxProposal(txps, txpid); - client.broadcastTxProposal(txp, function(err, txid) { - utils.die(err); - console.log('TX Broadcasted: ',txid); - }); - }); + var txp = utils.findOneTxProposal(txps, txpid); + client.broadcastTxProposal(txp, function(err, txid) { + utils.die(err); + console.log('TX Broadcasted: ', txid); + }); +}); diff --git a/bit-wallet/bit-reject b/bit-wallet/bit-reject index 3389a6b..fcaf663 100644 --- a/bit-wallet/bit-reject +++ b/bit-wallet/bit-reject @@ -13,9 +13,7 @@ program .parse(process.argv); var args = program.args; -if (!args[0]) - program.help(); -var txpid = args[0]; +var txpid = args[0] || ''; var reason = args[1] || ''; var client = utils.getClient(program); diff --git a/bit-wallet/bit-sign b/bit-wallet/bit-sign index 845c671..4c41f48 100755 --- a/bit-wallet/bit-sign +++ b/bit-wallet/bit-sign @@ -12,10 +12,7 @@ program .parse(process.argv); var args = program.args; -if (!args[0]) - program.help(); - -var txpid = args[0]; +var txpid = args[0] || ''; var client = utils.getClient(program); client.getTxProposals({}, function(err, txps) { diff --git a/lib/model/txproposal.js b/lib/model/txproposal.js index 7fc7347..6035cd0 100644 --- a/lib/model/txproposal.js +++ b/lib/model/txproposal.js @@ -105,7 +105,7 @@ TxProposal.prototype._getBitcoreTx = function() { }; TxProposal.prototype.getNetworkName = function() { - return Bitcore.Address(this.toAddress).toObject().networkName; + return Bitcore.Address(this.toAddress).toObject().network; }; TxProposal.prototype.getRawTx = function() { diff --git a/lib/server.js b/lib/server.js index 7923351..f5a0362 100644 --- a/lib/server.js +++ b/lib/server.js @@ -317,6 +317,7 @@ CopayServer.prototype._getBlockExplorer = function(provider, network) { url = 'https://test-insight.bitpay.com:443' break; } +console.log('[server.js.320:url:]',url); //TODO return new Explorers.Insight(url, network); break; } @@ -698,7 +699,7 @@ CopayServer.prototype.broadcastTx = function(opts, cb) { txid: txid }); - return cb(null, txp); + return cb(null, txid); }); }); }); From 3b0d95b6908eadcb4b08d76e39afb00d427c4b69 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Sun, 15 Feb 2015 19:12:45 -0300 Subject: [PATCH 4/4] fix broadcasting --- app.js | 3 +++ bit-wallet/bit-broadcast | 3 ++- bit-wallet/bit-reject | 5 ++++- bit-wallet/bit-sign | 5 ++++- lib/server.js | 1 + 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/app.js b/app.js index eb7aab5..9519be1 100644 --- a/app.js +++ b/app.js @@ -199,6 +199,7 @@ router.post('/v1/txproposals/:id/signatures/', function(req, res) { req.body.txProposalId = req.params['id']; server.signTx(req.body, function(err, txp) { if (err) return returnError(err, res, req); + res.json(txp); res.end(); }); }); @@ -210,6 +211,7 @@ router.post('/v1/txproposals/:id/broadcast/', function(req, res) { req.body.txProposalId = req.params['id']; server.broadcastTx(req.body, function(err, txp) { if (err) return returnError(err, res, req); + res.json(txp); res.end(); }); }); @@ -220,6 +222,7 @@ router.post('/v1/txproposals/:id/rejections', function(req, res) { req.body.txProposalId = req.params['id']; server.rejectTx(req.body, function(err, txp) { if (err) return returnError(err, res, req); + res.json(txp); res.end(); }); }); diff --git a/bit-wallet/bit-broadcast b/bit-wallet/bit-broadcast index 82fa266..e97c6e2 100755 --- a/bit-wallet/bit-broadcast +++ b/bit-wallet/bit-broadcast @@ -25,6 +25,7 @@ client.getTxProposals({}, function(err, txps) { var txp = utils.findOneTxProposal(txps, txpid); client.broadcastTxProposal(txp, function(err, txid) { utils.die(err); - console.log('TX Broadcasted: ', txid); + console.log('Transaction Broadcasted: TXID: ' + x.txid); + }); }); diff --git a/bit-wallet/bit-reject b/bit-wallet/bit-reject index fcaf663..3a7ac6a 100644 --- a/bit-wallet/bit-reject +++ b/bit-wallet/bit-reject @@ -23,6 +23,9 @@ client.getTxProposals({}, function(err, txps) { var txp = utils.findOneTxProposal(txps, txpid); client.rejectTxProposal(txp, reason, function(err, tx) { utils.die(err); - console.log('Transaction rejected.'); + if (x.status == 'rejected') + console.log('Transaction finally rejected.'); + else + console.log('Transaction rejected by you.'); }); }); diff --git a/bit-wallet/bit-sign b/bit-wallet/bit-sign index 4c41f48..7c54dd9 100755 --- a/bit-wallet/bit-sign +++ b/bit-wallet/bit-sign @@ -21,6 +21,9 @@ client.getTxProposals({}, function(err, txps) { var txp = utils.findOneTxProposal(txps, txpid); client.signTxProposal(txp, function(err, x) { utils.die(err); - console.log('Transaction signed.'); + if (x.status == 'broadcasted') + console.log('Transaction Broadcasted: TXID: ' + x.txid); + else + console.log('Transaction signed by you.'); }); }); diff --git a/lib/server.js b/lib/server.js index f5a0362..e6d0114 100644 --- a/lib/server.js +++ b/lib/server.js @@ -650,6 +650,7 @@ CopayServer.prototype.signTx = function(opts, cb) { txid: txid }); +console.log('[server.js.653:txp:]',txp); //TODO return cb(null, txp); }); });