broadcastTx
This commit is contained in:
parent
bca18b4292
commit
dba306045c
|
@ -64,7 +64,7 @@ TxProposal.prototype._updateStatus = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
TxProposal.prototype._getBitcoreTx = function(n) {
|
TxProposal.prototype._getBitcoreTx = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var t = new Bitcore.Transaction();
|
var t = new Bitcore.Transaction();
|
||||||
|
@ -80,6 +80,13 @@ TxProposal.prototype._getBitcoreTx = function(n) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
TxProposal.prototype.getRawTx = function() {
|
||||||
|
var t = this._getBitcoreTx();
|
||||||
|
|
||||||
|
return t.serialize();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
TxProposal.prototype.addAction = function(copayerId, type, signatures) {
|
TxProposal.prototype.addAction = function(copayerId, type, signatures) {
|
||||||
var action = new TxProposalAction({
|
var action = new TxProposalAction({
|
||||||
copayerId: copayerId,
|
copayerId: copayerId,
|
||||||
|
|
|
@ -96,6 +96,10 @@ Wallet.prototype.getCopayer = function(copayerId) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Wallet.prototype.getNetworkName = function() {
|
||||||
|
return this.isTestnet ? 'testnet' : 'livenet';
|
||||||
|
};
|
||||||
|
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -263,52 +263,62 @@ CopayServer.prototype._getBlockExplorer = function(provider, network) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _getUtxos
|
||||||
|
*
|
||||||
|
* @param opts.walletId
|
||||||
|
*/
|
||||||
CopayServer.prototype._getUtxos = function(opts, cb) {
|
CopayServer.prototype._getUtxos = function(opts, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
// Get addresses for this wallet
|
|
||||||
self.storage.fetchAddresses(opts.walletId, function(err, addresses) {
|
self.storage.fetchWallet(opts.walletId, function(err, wallet) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
if (addresses.length == 0) return cb(new ClientError('The wallet has no addresses'));
|
|
||||||
|
|
||||||
var addressStrs = _.pluck(addresses, 'address');
|
// Get addresses for this wallet
|
||||||
var addressToPath = _.indexBy(addresses, 'address'); // TODO : check performance
|
self.storage.fetchAddresses(opts.walletId, function(err, addresses) {
|
||||||
|
|
||||||
var bc = self._getBlockExplorer('insight', opts.network);
|
|
||||||
bc.getUnspentUtxos(addressStrs, function(err, utxos) {
|
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
if (addresses.length == 0) return cb(new ClientError('The wallet has no addresses'));
|
||||||
|
|
||||||
self.getPendingTxs({
|
var addressStrs = _.pluck(addresses, 'address');
|
||||||
walletId: opts.walletId
|
var addressToPath = _.indexBy(addresses, 'address'); // TODO : check performance
|
||||||
}, function(err, txps) {
|
|
||||||
|
var bc = self._getBlockExplorer('insight', wallet.getNetworkName());
|
||||||
|
bc.getUnspentUtxos(addressStrs, function(err, utxos) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
||||||
var inputs = _.chain(txps)
|
self.getPendingTxs({
|
||||||
.pluck('inputs')
|
walletId: opts.walletId
|
||||||
.flatten()
|
}, function(err, txps) {
|
||||||
.map(function(utxo) {
|
if (err) return cb(err);
|
||||||
return utxo.txid + '|' + utxo.vout
|
|
||||||
})
|
|
||||||
.value();
|
|
||||||
|
|
||||||
var dictionary = _.reduce(utxos, function(memo, utxo) {
|
var inputs = _.chain(txps)
|
||||||
memo[utxo.txid + '|' + utxo.vout] = utxo;
|
.pluck('inputs')
|
||||||
return memo;
|
.flatten()
|
||||||
}, {});
|
.map(function(utxo) {
|
||||||
|
return utxo.txid + '|' + utxo.vout
|
||||||
|
})
|
||||||
|
.value();
|
||||||
|
|
||||||
_.each(inputs, function(input) {
|
var dictionary = _.reduce(utxos, function(memo, utxo) {
|
||||||
if (dictionary[input]) {
|
memo[utxo.txid + '|' + utxo.vout] = utxo;
|
||||||
dictionary[input].locked = true;
|
return memo;
|
||||||
}
|
}, {});
|
||||||
|
|
||||||
|
_.each(inputs, function(input) {
|
||||||
|
if (dictionary[input]) {
|
||||||
|
dictionary[input].locked = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Needed for the clients to sign UTXOs
|
||||||
|
_.each(utxos, function(utxo) {
|
||||||
|
utxo.path = addressToPath[utxo.address].path;
|
||||||
|
utxo.publicKeys = addressToPath[utxo.address].publicKeys;
|
||||||
|
});
|
||||||
|
|
||||||
|
return cb(null, utxos);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Needed for the clients to sign UTXOs
|
|
||||||
_.each(utxos, function(utxo) {
|
|
||||||
utxo.path = addressToPath[utxo.address].path;
|
|
||||||
utxo.publicKeys = addressToPath[utxo.address].publicKeys;
|
|
||||||
});
|
|
||||||
|
|
||||||
return cb(null, utxos);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -452,11 +462,12 @@ CopayServer.prototype.getTx = function(opts, cb) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
CopayServer.prototype._broadcastTx = function(rawTx, cb) {
|
CopayServer.prototype._broadcastTx = function(txp, networkName, cb) {
|
||||||
// TODO: this should attempt to broadcast _all_ accepted and not-yet broadcasted (status=='accepted') txps?
|
var raw = txp.getRawTx();
|
||||||
cb = cb || function() {};
|
var bc = self._getBlockExplorer('insight', networkName);
|
||||||
|
bc.broadcast(raw, function(err, txid) {
|
||||||
throw 'not implemented';
|
return cb(err, txid);
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -486,9 +497,9 @@ CopayServer.prototype.signTx = function(opts, cb) {
|
||||||
var action = _.find(txp.actions, {
|
var action = _.find(txp.actions, {
|
||||||
copayerId: opts.copayerId
|
copayerId: opts.copayerId
|
||||||
});
|
});
|
||||||
if (action)
|
if (action)
|
||||||
return cb(new ClientError('CVOTED', 'Copayer already voted on this transaction proposal'));
|
return cb(new ClientError('CVOTED', 'Copayer already voted on this transaction proposal'));
|
||||||
if (txp.status != 'pending')
|
if (txp.status != 'pending')
|
||||||
return cb(new ClientError('TXNOTPENDING', 'The transaction proposal is not pending'));
|
return cb(new ClientError('TXNOTPENDING', 'The transaction proposal is not pending'));
|
||||||
|
|
||||||
var copayer = wallet.getCopayer(opts.copayerId);
|
var copayer = wallet.getCopayer(opts.copayerId);
|
||||||
|
@ -502,7 +513,7 @@ CopayServer.prototype.signTx = function(opts, cb) {
|
||||||
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, wallet.getNetworkName(), function(err, txid) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
||||||
tx.setBroadcasted(txid);
|
tx.setBroadcasted(txid);
|
||||||
|
|
Loading…
Reference in New Issue