commit
83de3b5248
|
@ -1,10 +0,0 @@
|
||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
var program = require('commander');
|
|
||||||
var cli = require('../lib/clilib.js');
|
|
||||||
|
|
||||||
program
|
|
||||||
.version('0.0.1')
|
|
||||||
.parse(process.argv);
|
|
||||||
|
|
||||||
|
|
|
@ -72,8 +72,6 @@ CliLib.prototype._loadAndCheck = function() {
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
|
||||||
delete data['verified'];
|
|
||||||
if (data.verified == 'corrupt') {
|
if (data.verified == 'corrupt') {
|
||||||
log.error('The wallet is tagged as corrupt. Some of the copayers cannot be verified to have known the wallet secret.');
|
log.error('The wallet is tagged as corrupt. Some of the copayers cannot be verified to have known the wallet secret.');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
|
@ -143,10 +141,10 @@ CliLib.prototype._joinWallet = function(data, secret, copayerName, cb) {
|
||||||
|
|
||||||
var secretSplit = secret.split(':');
|
var secretSplit = secret.split(':');
|
||||||
var walletId = secretSplit[0];
|
var walletId = secretSplit[0];
|
||||||
var privKey = Bitcore.PrivateKey.fromString(secretSplit[1]);
|
var walletPrivKey = Bitcore.PrivateKey.fromString(secretSplit[1]);
|
||||||
|
|
||||||
var xPubKey = new Bitcore.HDPublicKey(data.xPrivKey);
|
var xPubKey = new Bitcore.HDPublicKey(data.xPrivKey);
|
||||||
var xPubKeySignature = SignUtils.sign(xPubKey.toString(), privKey);
|
var xPubKeySignature = SignUtils.sign(xPubKey.toString(), walletPrivKey);
|
||||||
|
|
||||||
var signingPrivKey = (new Bitcore.HDPrivateKey(data.xPrivKey)).derive('m/1/0').privateKey;
|
var signingPrivKey = (new Bitcore.HDPrivateKey(data.xPrivKey)).derive('m/1/0').privateKey;
|
||||||
|
|
||||||
|
@ -171,6 +169,7 @@ CliLib.prototype._joinWallet = function(data, secret, copayerName, cb) {
|
||||||
|
|
||||||
var wallet = body.wallet;
|
var wallet = body.wallet;
|
||||||
data.copayerId = body.copayerId;
|
data.copayerId = body.copayerId;
|
||||||
|
data.walletPrivKey = walletPrivKey;
|
||||||
data.signingPrivKey = signingPrivKey.toString();
|
data.signingPrivKey = signingPrivKey.toString();
|
||||||
data.m = wallet.m;
|
data.m = wallet.m;
|
||||||
data.n = wallet.n;
|
data.n = wallet.n;
|
||||||
|
|
|
@ -332,7 +332,6 @@ CopayServer.prototype._getUtxos = function(cb) {
|
||||||
|
|
||||||
// Get addresses for this wallet
|
// Get addresses for this wallet
|
||||||
self.storage.fetchAddresses(self.walletId, function(err, addresses) {
|
self.storage.fetchAddresses(self.walletId, function(err, addresses) {
|
||||||
console.log('[server.js.334:addresses:]',addresses); //TODO
|
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
if (addresses.length == 0)
|
if (addresses.length == 0)
|
||||||
return cb(null, []);
|
return cb(null, []);
|
||||||
|
@ -389,7 +388,6 @@ CopayServer.prototype.getBalance = function(opts, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self._getUtxos(function(err, utxos) {
|
self._getUtxos(function(err, utxos) {
|
||||||
console.log('[server.js.390:utxos:]',utxos); //TODO
|
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
||||||
var balance = {};
|
var balance = {};
|
||||||
|
@ -445,15 +443,13 @@ CopayServer.prototype._selectUtxos = function(txp, utxos) {
|
||||||
CopayServer.prototype.createTx = function(opts, cb) {
|
CopayServer.prototype.createTx = function(opts, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (!Utils.checkRequired(opts, ['toAddress', 'amount']))
|
if (!Utils.checkRequired(opts, ['toAddress', 'amount', 'proposalSignature']))
|
||||||
return cb(new ClientError('Required argument missing'));
|
return cb(new ClientError('Required argument missing'));
|
||||||
|
|
||||||
Utils.runLocked(self.walletId, cb, function(cb) {
|
Utils.runLocked(self.walletId, cb, function(cb) {
|
||||||
self.getWallet({}, function(err, wallet) {
|
self.getWallet({}, function(err, wallet) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
if (!wallet.isComplete()) return cb(new ClientError('Wallet is not complete'));
|
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 copayer = wallet.getCopayer(self.copayerId);
|
||||||
var msg = opts.toAddress + '|' + opts.amount + '|' + opts.message;
|
var msg = opts.toAddress + '|' + opts.amount + '|' + opts.message;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
var Bitcore = require('bitcore');
|
var Bitcore = require('bitcore');
|
||||||
var PrivateKey = Bitcore.PrivateKey;
|
var PrivateKey = Bitcore.PrivateKey;
|
||||||
|
@ -10,8 +9,7 @@ var BufferReader = Bitcore.encoding.BufferReader;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var SignUtils = function () {
|
var SignUtils = function() {};
|
||||||
};
|
|
||||||
|
|
||||||
/* TODO: It would be nice to be compatible with bitcoind signmessage. How
|
/* TODO: It would be nice to be compatible with bitcoind signmessage. How
|
||||||
* the hash is calculated there? */
|
* the hash is calculated there? */
|
||||||
|
|
|
@ -167,9 +167,13 @@ helpers.createProposalOpts = function(toAddress, amount, message, signingKey) {
|
||||||
toAddress: toAddress,
|
toAddress: toAddress,
|
||||||
amount: helpers.toSatoshi(amount),
|
amount: helpers.toSatoshi(amount),
|
||||||
message: message,
|
message: message,
|
||||||
|
proposalSignature: null,
|
||||||
};
|
};
|
||||||
var msg = opts.toAddress + '|' + opts.amount + '|' + opts.message;
|
var msg = opts.toAddress + '|' + opts.amount + '|' + opts.message;
|
||||||
|
try {
|
||||||
opts.proposalSignature = SignUtils.sign(msg, signingKey);
|
opts.proposalSignature = SignUtils.sign(msg, signingKey);
|
||||||
|
} catch (ex) {}
|
||||||
|
|
||||||
return opts;
|
return opts;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -667,6 +671,34 @@ describe('Copay server', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should fail to create tx with invalid proposal signature', function(done) {
|
||||||
|
helpers.createUtxos(server, wallet, [100, 200], function(utxos) {
|
||||||
|
helpers.stubBlockExplorer(server, utxos);
|
||||||
|
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 80, null, 'dummy');
|
||||||
|
|
||||||
|
server.createTx(txOpts, function(err, tx) {
|
||||||
|
should.not.exist(tx);
|
||||||
|
err.should.exist;
|
||||||
|
err.message.should.equal('Invalid proposal signature');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fail to create tx with proposal signed by another copayer', function(done) {
|
||||||
|
helpers.createUtxos(server, wallet, [100, 200], function(utxos) {
|
||||||
|
helpers.stubBlockExplorer(server, utxos);
|
||||||
|
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 80, null, TestData.copayers[1].privKey);
|
||||||
|
|
||||||
|
server.createTx(txOpts, function(err, tx) {
|
||||||
|
should.not.exist(tx);
|
||||||
|
err.should.exist;
|
||||||
|
err.message.should.equal('Invalid proposal signature');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should fail to create tx for address invalid address', function(done) {
|
it('should fail to create tx for address invalid address', function(done) {
|
||||||
helpers.createUtxos(server, wallet, [100, 200], function(utxos) {
|
helpers.createUtxos(server, wallet, [100, 200], function(utxos) {
|
||||||
helpers.stubBlockExplorer(server, utxos);
|
helpers.stubBlockExplorer(server, utxos);
|
||||||
|
|
Loading…
Reference in New Issue