run js-beautifier
This commit is contained in:
parent
f4f7af09d9
commit
c387b51867
|
@ -14,26 +14,26 @@ var MESSAGE_SIGNING_PATH = "m/1/0";
|
||||||
|
|
||||||
function Copayer(opts) {
|
function Copayer(opts) {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
opts.copayerIndex = opts.copayerIndex || 0;
|
opts.copayerIndex = opts.copayerIndex || 0;
|
||||||
Copayer.super_.apply(this, [opts]);
|
Copayer.super_.apply(this, [opts]);
|
||||||
|
|
||||||
this.version = VERSION;
|
this.version = VERSION;
|
||||||
this.createdOn = Math.floor(Date.now() / 1000);
|
this.createdOn = Math.floor(Date.now() / 1000);
|
||||||
this.id = opts.id;
|
this.id = opts.id;
|
||||||
this.name = opts.name;
|
this.name = opts.name;
|
||||||
this.xPubKey = opts.xPubKey;
|
this.xPubKey = opts.xPubKey;
|
||||||
this.xPubKeySignature = opts.xPubKeySignature; // So third parties can check independently
|
this.xPubKeySignature = opts.xPubKeySignature; // So third parties can check independently
|
||||||
this.signingPubKey = opts.signingPubKey || this.getSigningPubKey();
|
this.signingPubKey = opts.signingPubKey || this.getSigningPubKey();
|
||||||
};
|
};
|
||||||
|
|
||||||
util.inherits(Copayer, Addressable);
|
util.inherits(Copayer, Addressable);
|
||||||
|
|
||||||
Copayer.prototype.getSigningPubKey = function () {
|
Copayer.prototype.getSigningPubKey = function() {
|
||||||
if (!this.xPubKey) return null;
|
if (!this.xPubKey) return null;
|
||||||
return HDPublicKey.fromString(this.xPubKey).derive(MESSAGE_SIGNING_PATH).publicKey.toString();
|
return HDPublicKey.fromString(this.xPubKey).derive(MESSAGE_SIGNING_PATH).publicKey.toString();
|
||||||
};
|
};
|
||||||
|
|
||||||
Copayer.fromObj = function (obj) {
|
Copayer.fromObj = function(obj) {
|
||||||
var x = new Copayer();
|
var x = new Copayer();
|
||||||
|
|
||||||
x.createdOn = obj.createdOn;
|
x.createdOn = obj.createdOn;
|
||||||
|
|
|
@ -57,11 +57,11 @@ Wallet.getMaxRequiredCopayers = function(totalCopayers) {
|
||||||
return Wallet.COPAYER_PAIR_LIMITS[totalCopayers];
|
return Wallet.COPAYER_PAIR_LIMITS[totalCopayers];
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.verifyCopayerLimits = function (m, n) {
|
Wallet.verifyCopayerLimits = function(m, n) {
|
||||||
return (n >= 1 && n <= 12) && (m >= 1 && m <= Wallet.COPAYER_PAIR_LIMITS[n]);
|
return (n >= 1 && n <= 12) && (m >= 1 && m <= Wallet.COPAYER_PAIR_LIMITS[n]);
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.fromObj = function (obj) {
|
Wallet.fromObj = function(obj) {
|
||||||
var x = new Wallet();
|
var x = new Wallet();
|
||||||
|
|
||||||
x.createdOn = obj.createdOn;
|
x.createdOn = obj.createdOn;
|
||||||
|
@ -71,7 +71,7 @@ Wallet.fromObj = function (obj) {
|
||||||
x.n = obj.n;
|
x.n = obj.n;
|
||||||
x.status = obj.status;
|
x.status = obj.status;
|
||||||
x.publicKeyRing = obj.publicKeyRing;
|
x.publicKeyRing = obj.publicKeyRing;
|
||||||
x.copayers = _.map(obj.copayers, function (copayer) {
|
x.copayers = _.map(obj.copayers, function(copayer) {
|
||||||
return new Copayer(copayer);
|
return new Copayer(copayer);
|
||||||
});
|
});
|
||||||
x.pubKey = obj.pubKey;
|
x.pubKey = obj.pubKey;
|
||||||
|
@ -81,7 +81,7 @@ Wallet.fromObj = function (obj) {
|
||||||
return x;
|
return x;
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.addCopayer = function (copayer) {
|
Wallet.prototype.addCopayer = function(copayer) {
|
||||||
this.copayers.push(copayer);
|
this.copayers.push(copayer);
|
||||||
|
|
||||||
if (this.copayers.length < this.n) return;
|
if (this.copayers.length < this.n) return;
|
||||||
|
@ -90,17 +90,19 @@ Wallet.prototype.addCopayer = function (copayer) {
|
||||||
this.publicKeyRing = _.pluck(this.copayers, 'xPubKey');
|
this.publicKeyRing = _.pluck(this.copayers, 'xPubKey');
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.getCopayer = function (copayerId) {
|
Wallet.prototype.getCopayer = function(copayerId) {
|
||||||
return _.find(this.copayers, { id: copayerId });
|
return _.find(this.copayers, {
|
||||||
|
id: copayerId
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Wallet.prototype._getBitcoreNetwork = function () {
|
Wallet.prototype._getBitcoreNetwork = function() {
|
||||||
return this.isTestnet ? Bitcore.Networks.testnet : Bitcore.Networks.livenet;
|
return this.isTestnet ? Bitcore.Networks.testnet : Bitcore.Networks.livenet;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Wallet.prototype.createAddress = function (path) {
|
Wallet.prototype.createAddress = function(path) {
|
||||||
|
|
||||||
var publicKeys = _.map(this.copayers, function(copayer) {
|
var publicKeys = _.map(this.copayers, function(copayer) {
|
||||||
var xpub = new Bitcore.HDPublicKey(copayer.xPubKey);
|
var xpub = new Bitcore.HDPublicKey(copayer.xPubKey);
|
||||||
|
|
127
lib/server.js
127
lib/server.js
|
@ -31,12 +31,12 @@ var TxProposal = require('./model/txproposal');
|
||||||
*/
|
*/
|
||||||
function CopayServer(opts) {
|
function CopayServer(opts) {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
this.storage = opts.storage || new Storage();
|
this.storage = opts.storage || new Storage();
|
||||||
};
|
};
|
||||||
|
|
||||||
inherits(CopayServer, events.EventEmitter);
|
inherits(CopayServer, events.EventEmitter);
|
||||||
|
|
||||||
CopayServer._emit = function (event) {
|
CopayServer._emit = function(event) {
|
||||||
var args = Array.prototype.slice.call(arguments);
|
var args = Array.prototype.slice.call(arguments);
|
||||||
log.debug('Emitting: ', args);
|
log.debug('Emitting: ', args);
|
||||||
this.emit.apply(this, arguments);
|
this.emit.apply(this, arguments);
|
||||||
|
@ -52,8 +52,9 @@ CopayServer._emit = function (event) {
|
||||||
* @param {string} opts.pubKey - Public key to verify copayers joining have access to the wallet secret.
|
* @param {string} opts.pubKey - Public key to verify copayers joining have access to the wallet secret.
|
||||||
* @param {string} [opts.network = 'livenet'] - The Bitcoin network for this wallet.
|
* @param {string} [opts.network = 'livenet'] - The Bitcoin network for this wallet.
|
||||||
*/
|
*/
|
||||||
CopayServer.prototype.createWallet = function (opts, cb) {
|
CopayServer.prototype.createWallet = function(opts, cb) {
|
||||||
var self = this, pubKey;
|
var self = this,
|
||||||
|
pubKey;
|
||||||
|
|
||||||
Utils.checkRequired(opts, ['id', 'name', 'm', 'n', 'pubKey']);
|
Utils.checkRequired(opts, ['id', 'name', 'm', 'n', 'pubKey']);
|
||||||
if (!Wallet.verifyCopayerLimits(opts.m, opts.n)) return cb('Incorrect m or n value');
|
if (!Wallet.verifyCopayerLimits(opts.m, opts.n)) return cb('Incorrect m or n value');
|
||||||
|
@ -66,7 +67,7 @@ CopayServer.prototype.createWallet = function (opts, cb) {
|
||||||
return cb(e.toString());
|
return cb(e.toString());
|
||||||
};
|
};
|
||||||
|
|
||||||
self.storage.fetchWallet(opts.id, function (err, wallet) {
|
self.storage.fetchWallet(opts.id, function(err, wallet) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
if (wallet) return cb('Wallet already exists');
|
if (wallet) return cb('Wallet already exists');
|
||||||
|
|
||||||
|
@ -89,10 +90,10 @@ CopayServer.prototype.createWallet = function (opts, cb) {
|
||||||
* @param {string} opts.id - The wallet id.
|
* @param {string} opts.id - The wallet id.
|
||||||
* @returns {Object} wallet
|
* @returns {Object} wallet
|
||||||
*/
|
*/
|
||||||
CopayServer.prototype.getWallet = function (opts, cb) {
|
CopayServer.prototype.getWallet = function(opts, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.storage.fetchWallet(opts.id, function (err, wallet) {
|
self.storage.fetchWallet(opts.id, function(err, wallet) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
if (!wallet) return cb('Wallet not found');
|
if (!wallet) return cb('Wallet not found');
|
||||||
return cb(null, wallet);
|
return cb(null, wallet);
|
||||||
|
@ -119,13 +120,15 @@ CopayServer.prototype._verifySignature = function(text, signature, pubKey) {
|
||||||
* @param {number} opts.xPubKey - Extended Public Key for this copayer.
|
* @param {number} opts.xPubKey - Extended Public Key for this copayer.
|
||||||
* @param {number} opts.xPubKeySignature - Signature of xPubKey using the wallet pubKey.
|
* @param {number} opts.xPubKeySignature - Signature of xPubKey using the wallet pubKey.
|
||||||
*/
|
*/
|
||||||
CopayServer.prototype.joinWallet = function (opts, cb) {
|
CopayServer.prototype.joinWallet = function(opts, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
Utils.checkRequired(opts, ['walletId', 'id', 'name', 'xPubKey', 'xPubKeySignature']);
|
Utils.checkRequired(opts, ['walletId', 'id', 'name', 'xPubKey', 'xPubKeySignature']);
|
||||||
|
|
||||||
Utils.runLocked(opts.walletId, cb, function (cb) {
|
Utils.runLocked(opts.walletId, cb, function(cb) {
|
||||||
self.getWallet({ id: opts.walletId }, function (err, wallet) {
|
self.getWallet({
|
||||||
|
id: opts.walletId
|
||||||
|
}, function(err, wallet) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
||||||
if (!self._verifySignature(opts.xPubKey, opts.xPubKeySignature, wallet.pubKey)) {
|
if (!self._verifySignature(opts.xPubKey, opts.xPubKeySignature, wallet.pubKey)) {
|
||||||
|
@ -147,7 +150,7 @@ CopayServer.prototype._verifySignature = function(text, signature, pubKey) {
|
||||||
|
|
||||||
wallet.addCopayer(copayer);
|
wallet.addCopayer(copayer);
|
||||||
|
|
||||||
self.storage.storeWallet(wallet, function (err) {
|
self.storage.storeWallet(wallet, function(err) {
|
||||||
return cb(err);
|
return cb(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -164,14 +167,16 @@ CopayServer.prototype._verifySignature = function(text, signature, pubKey) {
|
||||||
* @param {truthy} opts.isChange - Indicates whether this is a regular address or a change address.
|
* @param {truthy} opts.isChange - Indicates whether this is a regular address or a change address.
|
||||||
* @returns {Address} address
|
* @returns {Address} address
|
||||||
*/
|
*/
|
||||||
CopayServer.prototype.createAddress = function (opts, cb) {
|
CopayServer.prototype.createAddress = function(opts, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var isChange = opts.isChange || false;
|
var isChange = opts.isChange || false;
|
||||||
|
|
||||||
Utils.checkRequired(opts, ['walletId', 'isChange']);
|
Utils.checkRequired(opts, ['walletId', 'isChange']);
|
||||||
|
|
||||||
Utils.runLocked(opts.walletId, cb, function (cb) {
|
Utils.runLocked(opts.walletId, cb, function(cb) {
|
||||||
self.getWallet({ id: opts.walletId }, function (err, wallet) {
|
self.getWallet({
|
||||||
|
id: opts.walletId
|
||||||
|
}, function(err, wallet) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
||||||
var copayer = wallet.copayers[0]; // TODO: Assign copayer from authentication.
|
var copayer = wallet.copayers[0]; // TODO: Assign copayer from authentication.
|
||||||
|
@ -202,12 +207,14 @@ CopayServer.prototype._verifySignature = function(text, signature, pubKey) {
|
||||||
* @param {string} opts.signature - The signature of message to verify.
|
* @param {string} opts.signature - The signature of message to verify.
|
||||||
* @returns {truthy} The result of the verification.
|
* @returns {truthy} The result of the verification.
|
||||||
*/
|
*/
|
||||||
CopayServer.prototype.verifyMessageSignature = function (opts, cb) {
|
CopayServer.prototype.verifyMessageSignature = function(opts, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
Utils.checkRequired(opts, ['walletId', 'copayerId', 'message', 'signature']);
|
Utils.checkRequired(opts, ['walletId', 'copayerId', 'message', 'signature']);
|
||||||
|
|
||||||
self.getWallet({ id: opts.walletId }, function (err, wallet) {
|
self.getWallet({
|
||||||
|
id: opts.walletId
|
||||||
|
}, function(err, wallet) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
||||||
var copayer = wallet.getCopayer(opts.copayerId);
|
var copayer = wallet.getCopayer(opts.copayerId);
|
||||||
|
@ -219,7 +226,7 @@ CopayServer.prototype.verifyMessageSignature = function (opts, cb) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
CopayServer.prototype._getBlockExplorer = function (provider, network) {
|
CopayServer.prototype._getBlockExplorer = function(provider, network) {
|
||||||
var url;
|
var url;
|
||||||
|
|
||||||
switch (provider) {
|
switch (provider) {
|
||||||
|
@ -239,33 +246,37 @@ CopayServer.prototype._getBlockExplorer = function (provider, network) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
CopayServer.prototype._getUtxos = function (opts, cb) {
|
CopayServer.prototype._getUtxos = function(opts, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
// Get addresses for this wallet
|
// Get addresses for this wallet
|
||||||
self.storage.fetchAddresses(opts.walletId, function (err, addresses) {
|
self.storage.fetchAddresses(opts.walletId, function(err, addresses) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
if (addresses.length == 0) return cb('The wallet has no addresses');
|
if (addresses.length == 0) return cb('The wallet has no addresses');
|
||||||
|
|
||||||
var addresses = _.pluck(addresses, 'address');
|
var addresses = _.pluck(addresses, 'address');
|
||||||
|
|
||||||
var bc = self._getBlockExplorer('insight', opts.network);
|
var bc = self._getBlockExplorer('insight', opts.network);
|
||||||
bc.getUnspentUtxos(addresses, function (err, utxos) {
|
bc.getUnspentUtxos(addresses, function(err, utxos) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
||||||
self.getPendingTxs({ walletId: opts.walletId }, function (err, txps) {
|
self.getPendingTxs({
|
||||||
|
walletId: opts.walletId
|
||||||
|
}, function(err, txps) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
||||||
var inputs = _.chain(txps)
|
var inputs = _.chain(txps)
|
||||||
.pluck('inputs')
|
.pluck('inputs')
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(function (utxo) { return utxo.txid + '|' + utxo.vout });
|
.map(function(utxo) {
|
||||||
|
return utxo.txid + '|' + utxo.vout
|
||||||
|
});
|
||||||
|
|
||||||
var dictionary = _.groupBy(utxos, function (utxo) {
|
var dictionary = _.groupBy(utxos, function(utxo) {
|
||||||
return utxo.txid + '|' + utxo.vout;
|
return utxo.txid + '|' + utxo.vout;
|
||||||
});
|
});
|
||||||
|
|
||||||
_.each(inputs, function (input) {
|
_.each(inputs, function(input) {
|
||||||
if (dictionary[input]) {
|
if (dictionary[input]) {
|
||||||
dictionary[input].locked = true;
|
dictionary[input].locked = true;
|
||||||
}
|
}
|
||||||
|
@ -283,17 +294,25 @@ CopayServer.prototype._getUtxos = function (opts, cb) {
|
||||||
* @param {string} opts.walletId - The wallet id.
|
* @param {string} opts.walletId - The wallet id.
|
||||||
* @returns {Object} balance - Total amount & locked amount.
|
* @returns {Object} balance - Total amount & locked amount.
|
||||||
*/
|
*/
|
||||||
CopayServer.prototype.getBalance = function (opts, cb) {
|
CopayServer.prototype.getBalance = function(opts, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
Utils.checkRequired(opts, 'walletId');
|
Utils.checkRequired(opts, 'walletId');
|
||||||
|
|
||||||
self._getUtxos({ walletId: opts.walletId }, function (err, utxos) {
|
self._getUtxos({
|
||||||
|
walletId: opts.walletId
|
||||||
|
}, function(err, utxos) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
||||||
var balance = {};
|
var balance = {};
|
||||||
balance.totalAmount = _.reduce(utxos, function(sum, utxo) { return sum + utxo.amount; }, 0);
|
balance.totalAmount = _.reduce(utxos, function(sum, utxo) {
|
||||||
balance.lockedAmount = _.reduce(_.without(utxos, { locked: true }), function(sum, utxo) { return sum + utxo.amount; }, 0);
|
return sum + utxo.amount;
|
||||||
|
}, 0);
|
||||||
|
balance.lockedAmount = _.reduce(_.without(utxos, {
|
||||||
|
locked: true
|
||||||
|
}), function(sum, utxo) {
|
||||||
|
return sum + utxo.amount;
|
||||||
|
}, 0);
|
||||||
|
|
||||||
return cb(null, balance);
|
return cb(null, balance);
|
||||||
});
|
});
|
||||||
|
@ -336,18 +355,24 @@ CopayServer.prototype._selectUtxos = function(txp, utxos) {
|
||||||
* @param {string} opts.message - A message to attach to this transaction.
|
* @param {string} opts.message - A message to attach to this transaction.
|
||||||
* @returns {TxProposal} Transaction proposal.
|
* @returns {TxProposal} Transaction proposal.
|
||||||
*/
|
*/
|
||||||
CopayServer.prototype.createTx = function (opts, cb) {
|
CopayServer.prototype.createTx = function(opts, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
Utils.checkRequired(opts, ['walletId', 'copayerId', 'toAddress', 'amount', 'message']);
|
Utils.checkRequired(opts, ['walletId', 'copayerId', 'toAddress', 'amount', 'message']);
|
||||||
|
|
||||||
self.getWallet({ id: opts.walletId }, function (err, wallet) {
|
self.getWallet({
|
||||||
|
id: opts.walletId
|
||||||
|
}, function(err, wallet) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
||||||
self._getUtxos({ walletId: wallet.id }, function (err, utxos) {
|
self._getUtxos({
|
||||||
|
walletId: wallet.id
|
||||||
|
}, function(err, utxos) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
||||||
utxos = _.without(utxos, { locked: true });
|
utxos = _.without(utxos, {
|
||||||
|
locked: true
|
||||||
|
});
|
||||||
|
|
||||||
var txp = new TxProposal({
|
var txp = new TxProposal({
|
||||||
creatorId: opts.copayerId,
|
creatorId: opts.copayerId,
|
||||||
|
@ -361,7 +386,7 @@ CopayServer.prototype.createTx = function (opts, cb) {
|
||||||
|
|
||||||
txp.rawTx = self._createRawTx(txp);
|
txp.rawTx = self._createRawTx(txp);
|
||||||
|
|
||||||
self.storage.storeTx(wallet.id, txp, function (err) {
|
self.storage.storeTx(wallet.id, txp, function(err) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
||||||
return cb(null, txp);
|
return cb(null, txp);
|
||||||
|
@ -370,9 +395,9 @@ CopayServer.prototype.createTx = function (opts, cb) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
CopayServer.prototype._broadcastTx = function (rawTx, cb) {
|
CopayServer.prototype._broadcastTx = function(rawTx, cb) {
|
||||||
// TODO: this should attempt to broadcast _all_ accepted and not-yet broadcasted (status=='accepted') txps?
|
// TODO: this should attempt to broadcast _all_ accepted and not-yet broadcasted (status=='accepted') txps?
|
||||||
cb = cb || function () {};
|
cb = cb || function() {};
|
||||||
|
|
||||||
throw 'not implemented';
|
throw 'not implemented';
|
||||||
};
|
};
|
||||||
|
@ -385,29 +410,31 @@ CopayServer.prototype._broadcastTx = function (rawTx, cb) {
|
||||||
* @param {string} opts.txProposalId - The identifier of the transaction.
|
* @param {string} opts.txProposalId - The identifier of the transaction.
|
||||||
* @param {string} opts.signature - The signature of the tx for this copayer.
|
* @param {string} opts.signature - The signature of the tx for this copayer.
|
||||||
*/
|
*/
|
||||||
CopayServer.prototype.signTx = function (opts, cb) {
|
CopayServer.prototype.signTx = function(opts, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
Utils.checkRequired(opts, ['walletId', 'copayerId', 'txProposalId', 'signature']);
|
Utils.checkRequired(opts, ['walletId', 'copayerId', 'txProposalId', 'signature']);
|
||||||
|
|
||||||
self.fetchTx(opts.walletId, opts.txProposalId, function (err, txp) {
|
self.fetchTx(opts.walletId, opts.txProposalId, function(err, txp) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
if (!txp) return cb('Transaction proposal not found');
|
if (!txp) return cb('Transaction proposal not found');
|
||||||
var action = _.find(txp.actions, { copayerId: opts.copayerId });
|
var action = _.find(txp.actions, {
|
||||||
|
copayerId: opts.copayerId
|
||||||
|
});
|
||||||
if (action) return cb('Copayer already voted on this transaction proposal');
|
if (action) return cb('Copayer already voted on this transaction proposal');
|
||||||
if (txp.status != 'pending') return cb('The transaction proposal is not pending');
|
if (txp.status != 'pending') return cb('The transaction proposal is not pending');
|
||||||
|
|
||||||
txp.sign(opts.copayerId, opts.signature);
|
txp.sign(opts.copayerId, opts.signature);
|
||||||
|
|
||||||
self.storage.storeTx(opts.walletId, txp, function (err) {
|
self.storage.storeTx(opts.walletId, txp, function(err) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
||||||
if (txp.status == 'accepted');
|
if (txp.status == 'accepted');
|
||||||
self._broadcastTx(txp.rawTx, function (err, txid) {
|
self._broadcastTx(txp.rawTx, function(err, txid) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
||||||
tx.setBroadcasted(txid);
|
tx.setBroadcasted(txid);
|
||||||
self.storage.storeTx(opts.walletId, txp, function (err) {
|
self.storage.storeTx(opts.walletId, txp, function(err) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
||||||
return cb();
|
return cb();
|
||||||
|
@ -425,21 +452,23 @@ CopayServer.prototype.signTx = function (opts, cb) {
|
||||||
* @param {string} opts.txProposalId - The identifier of the transaction.
|
* @param {string} opts.txProposalId - The identifier of the transaction.
|
||||||
* @param {string} [opts.reason] - A message to other copayers explaining the rejection.
|
* @param {string} [opts.reason] - A message to other copayers explaining the rejection.
|
||||||
*/
|
*/
|
||||||
CopayServer.prototype.rejectTx = function (opts, cb) {
|
CopayServer.prototype.rejectTx = function(opts, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
Utils.checkRequired(opts, ['walletId', 'copayerId', 'txProposalId']);
|
Utils.checkRequired(opts, ['walletId', 'copayerId', 'txProposalId']);
|
||||||
|
|
||||||
self.fetchTx(opts.walletId, opts.txProposalId, function (err, txp) {
|
self.fetchTx(opts.walletId, opts.txProposalId, function(err, txp) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
if (!txp) return cb('Transaction proposal not found');
|
if (!txp) return cb('Transaction proposal not found');
|
||||||
var action = _.find(txp.actions, { copayerId: opts.copayerId });
|
var action = _.find(txp.actions, {
|
||||||
|
copayerId: opts.copayerId
|
||||||
|
});
|
||||||
if (action) return cb('Copayer already voted on this transaction proposal');
|
if (action) return cb('Copayer already voted on this transaction proposal');
|
||||||
if (txp.status != 'pending') return cb('The transaction proposal is not pending');
|
if (txp.status != 'pending') return cb('The transaction proposal is not pending');
|
||||||
|
|
||||||
txp.reject(opts.copayerId);
|
txp.reject(opts.copayerId);
|
||||||
|
|
||||||
self.storage.storeTx(opts.walletId, txp, function (err) {
|
self.storage.storeTx(opts.walletId, txp, function(err) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
||||||
return cb();
|
return cb();
|
||||||
|
@ -453,15 +482,17 @@ CopayServer.prototype.rejectTx = function (opts, cb) {
|
||||||
* @param {string} opts.walletId - The wallet id.
|
* @param {string} opts.walletId - The wallet id.
|
||||||
* @returns {TxProposal[]} Transaction proposal.
|
* @returns {TxProposal[]} Transaction proposal.
|
||||||
*/
|
*/
|
||||||
CopayServer.prototype.getPendingTxs = function (opts, cb) {
|
CopayServer.prototype.getPendingTxs = function(opts, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
Utils.checkRequired(opts, 'walletId');
|
Utils.checkRequired(opts, 'walletId');
|
||||||
|
|
||||||
self.storage.fetchTxs(opts.walletId, function (err, txps) {
|
self.storage.fetchTxs(opts.walletId, function(err, txps) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
||||||
var pending = _.filter(txps, { status: 'pending' });
|
var pending = _.filter(txps, {
|
||||||
|
status: 'pending'
|
||||||
|
});
|
||||||
return cb(null, pending);
|
return cb(null, pending);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -53,7 +53,7 @@ var someXPubKeysSignatures = [
|
||||||
|
|
||||||
//Copayer signature
|
//Copayer signature
|
||||||
var aText = 'hello world';
|
var aText = 'hello world';
|
||||||
var aTextSignature = '3045022100addd20e5413865d65d561ad2979f2289a40d52594b1f804840babd9a63e4ebbf02204b86285e1fcab02df772e7a1325fc4b511ecad79a8f80a2bd1ad8bfa858ac3d4'; // with someXPrivKey[0].derive('m/1/0')=5c0e043a513032907d181325a8e7990b076c0af15ed13dc5e611cda9bb3ae52a;
|
var aTextSignature = '3045022100addd20e5413865d65d561ad2979f2289a40d52594b1f804840babd9a63e4ebbf02204b86285e1fcab02df772e7a1325fc4b511ecad79a8f80a2bd1ad8bfa858ac3d4'; // with someXPrivKey[0].derive('m/1/0')=5c0e043a513032907d181325a8e7990b076c0af15ed13dc5e611cda9bb3ae52a;
|
||||||
|
|
||||||
|
|
||||||
var helpers = {};
|
var helpers = {};
|
||||||
|
@ -432,7 +432,7 @@ describe('Copay server', function() {
|
||||||
xPubKey: someXPubKeys[0],
|
xPubKey: someXPubKeys[0],
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
server.joinWallet(copayerOpts, function(err) {});
|
server.joinWallet(copayerOpts, function(err) {});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
e.should.contain('xPubKeySignature');
|
e.should.contain('xPubKeySignature');
|
||||||
done();
|
done();
|
||||||
|
@ -487,7 +487,7 @@ describe('Copay server', function() {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
wallet.status.should.equal('complete');
|
wallet.status.should.equal('complete');
|
||||||
wallet.publicKeyRing.length.should.equal(3);
|
wallet.publicKeyRing.length.should.equal(3);
|
||||||
_.each([0,1,2], function(i) {
|
_.each([0, 1, 2], function(i) {
|
||||||
var copayer = wallet.copayers[i];
|
var copayer = wallet.copayers[i];
|
||||||
copayer.receiveAddressIndex.should.equal(0);
|
copayer.receiveAddressIndex.should.equal(0);
|
||||||
copayer.changeAddressIndex.should.equal(0);
|
copayer.changeAddressIndex.should.equal(0);
|
||||||
|
@ -584,20 +584,17 @@ describe('Copay server', function() {
|
||||||
server = new CopayServer({
|
server = new CopayServer({
|
||||||
storage: storage,
|
storage: storage,
|
||||||
});
|
});
|
||||||
server._doCreateAddress = sinon.stub().returns(new Address({
|
|
||||||
address: 'addr1',
|
|
||||||
path: 'path1'
|
|
||||||
}));
|
|
||||||
helpers.createAndJoinWallet('123', 2, 2, function(err, wallet) {
|
helpers.createAndJoinWallet('123', 2, 2, function(err, wallet) {
|
||||||
server.createAddress({
|
server.createAddress({
|
||||||
walletId: '123'
|
walletId: '123',
|
||||||
|
isChange: false,
|
||||||
}, function(err, address) {
|
}, function(err, address) {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip('should create tx', function(done) {
|
it.only('should create tx', function(done) {
|
||||||
var bc = sinon.stub();
|
var bc = sinon.stub();
|
||||||
bc.getUnspentUtxos = sinon.stub().callsArgWith(1, null, helpers.createUtxos([100, 200]));
|
bc.getUnspentUtxos = sinon.stub().callsArgWith(1, null, helpers.createUtxos([100, 200]));
|
||||||
server._getBlockExplorer = sinon.stub().returns(bc);
|
server._getBlockExplorer = sinon.stub().returns(bc);
|
||||||
|
|
Loading…
Reference in New Issue