Browse Source

.

activeAddress
Ivan Socolsky 10 years ago
parent
commit
94509eebab
  1. 67
      lib/server.js
  2. 24
      test/integration.js

67
lib/server.js

@ -222,18 +222,57 @@ CopayServer.prototype._getUtxos = function (opts, cb) {
bc.getUnspentUtxos(addresses, function (err, utxos) {
if (err) return cb(err);
// TODO: filter 'locked' utxos
self.getPendingTxs({ walletId: opts.walletId }, function (err, txps) {
if (err) return cb(err);
var inputs = _.chain(txps)
.pluck('input')
.flatten()
.map(function (utxo) { return utxo.txid + '|' + utxo.vout });
var dictionary = _.groupBy(utxos, function (utxo) {
return utxo.txid + '|' + utxo.vout;
});
_.each(inputs, function (input) {
if (dictionary[input]) {
dictionary[input].locked = true;
}
});
return cb(null, utxos);
});
});
});
};
/**
* Creates a new transaction proposal.
* @param {Object} opts
* @param {string} opts.walletId - The wallet id.
* @returns {Object} balance - Total amount & locked amount.
*/
CopayServer.prototype.getBalance = function (opts, cb) {
var self = this;
self._getUtxos({ walletId: opts.walletId }, function (err, utxos) {
if (err) return cb(err);
var balance = {};
balance.totalAmount = _.reduce(utxos, function(sum, utxo) { return sum + utxo.amount; });
balance.lockedAmount = _.reduce(_.without(utxos, { locked: true }), function(sum, utxo) { return sum + utxo.amount; });
return cb(null, balance);
});
};
CopayServer.prototype._createRawTx = function (tx) {
CopayServer.prototype._createRawTx = function (txp, utxos) {
var rawTx = new Bitcore.Transaction()
.from(tx.inputs)
.to(tx.toAddress, tx.amount)
.change(tx.changeAddress);
.from(utxos)
.to(txp.toAddress, txp.amount)
.change(txp.changeAddress);
return rawTx;
};
@ -258,16 +297,19 @@ CopayServer.prototype.createTx = function (opts, cb) {
self._getUtxos({ walletId: wallet.id }, function (err, utxos) {
if (err) return cb(err);
utxos = _.without(utxos, { locked: true });
var txp = new TxProposal({
creatorId: opts.copayerId,
toAddress: opts.toAddress,
amount: opts.amount,
changeAddress: opts.changeAddress,
inputs: utxos,
requiredSignatures: wallet.m,
maxRejections: wallet.n - wallet.m,
});
txp.rawTx = self._createRawTx(txp);
txp.rawTx = self._createRawTx(txp, utxos);
// TODO: assign used inputs
self.storage.storeTx(wallet.id, txp, function (err) {
if (err) return cb(err);
@ -342,29 +384,18 @@ CopayServer.prototype.rejectTx = function (opts, cb) {
txp.reject(opts.copayerId);
self.storage.storeTx(opts.walletId, txp, function (err) {
if (err) return cb(err);
if (txp.status == 'accepted');
self._broadcastTx(txp.rawTx, function (err, txid) {
if (err) return cb(err);
tx.setBroadcasted(txid);
self.storage.storeTx(opts.walletId, txp, function (err) {
if (err) return cb(err);
return cb();
});
});
});
});
};
/**
* Retrieves all pending transaction proposals.
* @param {Object} opts
* @param {string} opts.walletId - The wallet id.
* @param {string} opts.copayerId - The wallet id.
* @returns {TxProposal[]} Transaction proposal.
*/
CopayServer.prototype.getPendingTxs = function (opts, cb) {

24
test/integration.js

@ -48,6 +48,17 @@ helpers.createAndJoinWallet = function (id, m, n, cb) {
});
});
};
helpers.createUtxos = function (amounts) {
amounts = [].concat(amounts);
return _.map(amounts, function (amount) {
return {
txid: 'dummy' + Math.random(),
vout: Math.floor((Math.random() * 10) + 1),
amount: amount,
};
});
};
var db, storage;
var server;
@ -403,7 +414,7 @@ describe('Copay server', function() {
it('should create tx', function (done) {
var bc = sinon.stub();
bc.getUnspentUtxos = sinon.stub().callsArgWith(1, null, ['utxo1', 'utxo2']);
bc.getUnspentUtxos = sinon.stub().callsArgWith(1, null, helpers.createUtxos([100, 200]));
server._getBlockExplorer = sinon.stub().returns(bc);
server._createRawTx = sinon.stub().returns('raw');
@ -426,9 +437,18 @@ describe('Copay server', function() {
server.getPendingTxs({ walletId: '123' }, function (err, txs) {
should.not.exist(err);
txs.length.should.equal(1);
});
done();
});
});
});
it.skip('should fail to create tx when insufficient funds', function (done) {
});
it.skip('should create tx when there is a pending tx and enough UTXOs', function (done) {
});
it.skip('should fail to create tx when there is a pending tx and not enough UTXOs', function (done) {
});
});
});

Loading…
Cancel
Save