add export to text and qr
This commit is contained in:
parent
42f1abf19b
commit
705773aa37
|
@ -15,6 +15,7 @@ program
|
|||
.command('reject <txpId> [reason]', 'reject a transaction proposal')
|
||||
.command('broadcast <txpId>', 'broadcast a transaction proposal to the Bitcoin network')
|
||||
.command('rm <txpId>', 'remove a transaction proposal')
|
||||
.command('export', 'export wallet critical data')
|
||||
.parse(process.argv);
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
var program = require('commander');
|
||||
var qr = require('qr-image');
|
||||
|
||||
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')
|
||||
.option('-q, --qr')
|
||||
.parse(process.argv);
|
||||
|
||||
var args = program.args;
|
||||
var client = utils.getClient(program);
|
||||
|
||||
client.export(function(err, x) {
|
||||
utils.die(err);
|
||||
if (program.qr) {
|
||||
var filename = program.config + '.svg';
|
||||
var qr_svg = qr.image(x, { type: 'svg' });
|
||||
qr_svg.pipe(require('fs').createWriteStream(filename));
|
||||
} else {
|
||||
console.log('Wallet Critical Data:\n', x);
|
||||
}
|
||||
});
|
|
@ -309,66 +309,73 @@ API.prototype.getBalance = function(cb) {
|
|||
});
|
||||
};
|
||||
|
||||
API.prototype.export = function(cb) {
|
||||
var self = this;
|
||||
|
||||
this._loadAndCheck( function(err, data) {
|
||||
if (err) return cb(err);
|
||||
var x = _.pick(data,['publicKeyRing','xPrivKey', 'copayerId', 'signingPrivKey'])
|
||||
return cb(null, JSON.stringify(x));
|
||||
});
|
||||
}
|
||||
|
||||
API.prototype.getTxProposals = function(opts, cb) {
|
||||
var self = this;
|
||||
|
||||
this._loadAndCheck(
|
||||
function(err, data) {
|
||||
if (err) return cb(err);
|
||||
var url = '/v1/txproposals/';
|
||||
self._doGetRequest(url, data, cb);
|
||||
});
|
||||
this._loadAndCheck(function(err, data) {
|
||||
if (err) return cb(err);
|
||||
var url = '/v1/txproposals/';
|
||||
self._doGetRequest(url, data, cb);
|
||||
});
|
||||
};
|
||||
|
||||
API.prototype.signTxProposal = function(txp, cb) {
|
||||
var self = this;
|
||||
|
||||
this._loadAndCheck(
|
||||
function(err, data) {
|
||||
if (err) return cb(err);
|
||||
this._loadAndCheck(function(err, data) {
|
||||
if (err) return cb(err);
|
||||
|
||||
if (!Verifier.checkTxProposal(data, txp)) {
|
||||
return cb(new ServerCompromisedError('Server sent fake transaction proposal'));
|
||||
}
|
||||
|
||||
|
||||
//Derive proper key to sign, for each input
|
||||
var privs = [],
|
||||
derived = {};
|
||||
//Derive proper key to sign, for each input
|
||||
var privs = [],
|
||||
derived = {};
|
||||
|
||||
var network = new Bitcore.Address(txp.toAddress).network.name;
|
||||
var xpriv = new Bitcore.HDPrivateKey(data.xPrivKey, network);
|
||||
var network = new Bitcore.Address(txp.toAddress).network.name;
|
||||
var xpriv = new Bitcore.HDPrivateKey(data.xPrivKey, network);
|
||||
|
||||
_.each(txp.inputs, function(i) {
|
||||
if (!derived[i.path]) {
|
||||
derived[i.path] = xpriv.derive(i.path).privateKey;
|
||||
}
|
||||
privs.push(derived[i.path]);
|
||||
});
|
||||
|
||||
var t = new Bitcore.Transaction();
|
||||
_.each(txp.inputs, function(i) {
|
||||
t.from(i, i.publicKeys, txp.requiredSignatures);
|
||||
});
|
||||
|
||||
t.to(txp.toAddress, txp.amount)
|
||||
.change(txp.changeAddress)
|
||||
.sign(privs);
|
||||
|
||||
var signatures = [];
|
||||
_.each(privs, function(p) {
|
||||
var s = t.getSignatures(p)[0].signature.toDER().toString('hex');
|
||||
signatures.push(s);
|
||||
});
|
||||
|
||||
var url = '/v1/txproposals/' + txp.id + '/signatures/';
|
||||
var args = {
|
||||
signatures: signatures
|
||||
};
|
||||
|
||||
self._doPostRequest(url, args, data, cb);
|
||||
_.each(txp.inputs, function(i) {
|
||||
if (!derived[i.path]) {
|
||||
derived[i.path] = xpriv.derive(i.path).privateKey;
|
||||
}
|
||||
privs.push(derived[i.path]);
|
||||
});
|
||||
|
||||
var t = new Bitcore.Transaction();
|
||||
_.each(txp.inputs, function(i) {
|
||||
t.from(i, i.publicKeys, txp.requiredSignatures);
|
||||
});
|
||||
|
||||
t.to(txp.toAddress, txp.amount)
|
||||
.change(txp.changeAddress)
|
||||
.sign(privs);
|
||||
|
||||
var signatures = [];
|
||||
_.each(privs, function(p) {
|
||||
var s = t.getSignatures(p)[0].signature.toDER().toString('hex');
|
||||
signatures.push(s);
|
||||
});
|
||||
|
||||
var url = '/v1/txproposals/' + txp.id + '/signatures/';
|
||||
var args = {
|
||||
signatures: signatures
|
||||
};
|
||||
|
||||
self._doPostRequest(url, args, data, cb);
|
||||
});
|
||||
};
|
||||
|
||||
API.prototype.rejectTxProposal = function(txp, reason, cb) {
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
"npmlog": "^0.1.1",
|
||||
"preconditions": "^1.0.7",
|
||||
"request": "^2.53.0",
|
||||
"qr-image": "*",
|
||||
"uuid": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
Loading…
Reference in New Issue