rm networking on nonShared wallets
This commit is contained in:
parent
3310bb6677
commit
a7de2ababd
6 changed files with 179 additions and 153 deletions
|
|
@ -24,6 +24,7 @@ angular.module('copayApp.controllers').controller('SendController',
|
|||
|
||||
$scope.isRateAvailable = false;
|
||||
$scope.rateService = rateService;
|
||||
$scope.showScanner = false;
|
||||
|
||||
|
||||
rateService.whenAvailable(function() {
|
||||
|
|
@ -105,33 +106,19 @@ angular.module('copayApp.controllers').controller('SendController',
|
|||
|
||||
var msg = err.toString();
|
||||
if (msg.match('BIG'))
|
||||
msg = 'The transaction have too many inputs. Try creating many transactions for smaller amounts.'
|
||||
msg = 'The transaction have too many inputs. Try creating many transactions for smaller amounts'
|
||||
|
||||
if (msg.match('totalNeededAmount'))
|
||||
msg = 'Not enough funds.'
|
||||
msg = 'Not enough funds'
|
||||
|
||||
var message = 'The transaction' + (w.isShared() ? ' proposal' : '') +
|
||||
' could not be created: ' + msg;
|
||||
|
||||
var message = 'The transaction' + (w.isShared() ? ' proposal' : '') + ' could not be created: ' + msg;
|
||||
$scope.error = message;
|
||||
$scope.loading = false;
|
||||
$scope.loadTxs();
|
||||
};
|
||||
|
||||
$scope._afterSend = function(err, ntxid, merchantData) {
|
||||
$scope.loading = false;
|
||||
|
||||
if (err)
|
||||
return $scope._showError(err);
|
||||
|
||||
|
||||
if (w.requiresMultipleSignatures()) {
|
||||
notification.success('Success', 'The transaction proposal created');
|
||||
$scope.loadTxs();
|
||||
} else {
|
||||
$scope.send(ntxid);
|
||||
}
|
||||
$rootScope.pendingPayment = null;
|
||||
};
|
||||
|
||||
$scope.submitForm = function(form) {
|
||||
if (form.$invalid) {
|
||||
$scope.error = 'Unable to send transaction proposal';
|
||||
|
|
@ -160,16 +147,21 @@ angular.module('copayApp.controllers').controller('SendController',
|
|||
merchant: $rootScope.merchant.request_url
|
||||
};
|
||||
}
|
||||
// reset fields
|
||||
$scope.address = $scope.amount = $scope.commentText = null;
|
||||
form.address.$pristine = form.amount.$pristine = true;
|
||||
|
||||
w.createTx({
|
||||
toAddress: address,
|
||||
amountSat: amount,
|
||||
comment: commentText,
|
||||
w.spend({
|
||||
toAddress: address,
|
||||
amountSat: amount,
|
||||
comment: commentText,
|
||||
url: (payInfo && payInfo.merchant) ? payInfo.merchant : null,
|
||||
}, $scope._afterSend);
|
||||
}, function(err, txid, status) {
|
||||
// reset fields
|
||||
$scope.address = $scope.amount = $scope.commentText = null;
|
||||
form.address.$pristine = form.amount.$pristine = true;
|
||||
$rootScope.pendingPayment = null;
|
||||
if (err) return $scope._showError(err);
|
||||
|
||||
$scope.notifyStatus(status);
|
||||
$scope.loadTxs();
|
||||
});
|
||||
};
|
||||
|
||||
// QR code Scanner
|
||||
|
|
@ -267,6 +259,7 @@ angular.module('copayApp.controllers').controller('SendController',
|
|||
$scope.openScanner = function() {
|
||||
if (window.cordova) return $scope.scannerIntent();
|
||||
|
||||
console.log('[send.js.260] OPENN'); //TODO
|
||||
$scope.showScanner = true;
|
||||
|
||||
// Wait a moment until the canvas shows
|
||||
|
|
@ -371,22 +364,24 @@ angular.module('copayApp.controllers').controller('SendController',
|
|||
$scope.amount = $rootScope.topAmount;
|
||||
};
|
||||
|
||||
$scope.notifyStatus = function(status) {
|
||||
if (status == copay.Wallet.TX_BROADCASTED)
|
||||
notification.success('Success', 'Transaction broadcasted!');
|
||||
else if (status == copay.Wallet.TX_PROPOSAL_SENT)
|
||||
notification.success('Success', 'Transaction proposal created');
|
||||
else if (status == copay.Wallet.TX_SIGNED)
|
||||
notification.success('Success', 'Transaction proposal was signed');
|
||||
else
|
||||
notification.error('Error', 'Unknown error occured');
|
||||
};
|
||||
|
||||
|
||||
$scope.send = function(ntxid, cb) {
|
||||
$scope.error = $scope.success = null;
|
||||
$scope.loading = true;
|
||||
$rootScope.txAlertCount = 0;
|
||||
w.sendTx(ntxid, function(txid, merchantData) {
|
||||
if (!txid) {
|
||||
notification.error('Error', 'There was an error sending the transaction');
|
||||
} else {
|
||||
if (!merchantData) {
|
||||
notification.success('Success', 'Transaction broadcasted!');
|
||||
} else {
|
||||
notification.success('Success', 'Payment sent. ' + merchantData.ack.memo);
|
||||
}
|
||||
}
|
||||
|
||||
w.broadcastTx(ntxid, function(err, txid, status) {
|
||||
$scope.notifyStatus(status);
|
||||
if (cb) return cb();
|
||||
else $scope.loadTxs();
|
||||
});
|
||||
|
|
@ -396,20 +391,10 @@ angular.module('copayApp.controllers').controller('SendController',
|
|||
$scope.loading = true;
|
||||
$scope.error = $scope.success = null;
|
||||
|
||||
try {
|
||||
w.sign(ntxid);
|
||||
} catch (e) {
|
||||
notification.error('Error', 'There was an error signing the transaction');
|
||||
w.signAndSend(ntxid, function(err, id, status) {
|
||||
$scope.notifyStatus(status);
|
||||
$scope.loadTxs();
|
||||
return;
|
||||
}
|
||||
|
||||
var p = w.txProposals.getTxProposal(ntxid);
|
||||
if (p.builder.isFullySigned()) {
|
||||
$scope.send(ntxid);
|
||||
} else {
|
||||
$scope.loadTxs();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.reject = function(ntxid) {
|
||||
|
|
@ -417,7 +402,6 @@ angular.module('copayApp.controllers').controller('SendController',
|
|||
$rootScope.txAlertCount = 0;
|
||||
w.reject(ntxid);
|
||||
notification.warning('Transaction rejected', 'You rejected the transaction successfully');
|
||||
$scope.loading = false;
|
||||
$scope.loadTxs();
|
||||
};
|
||||
|
||||
|
|
@ -510,7 +494,9 @@ angular.module('copayApp.controllers').controller('SendController',
|
|||
}, 10 * 1000);
|
||||
|
||||
// Payment Protocol URI (BIP-72)
|
||||
$scope.wallet.fetchPaymentRequest({url: uri.merchant}, function(err, merchantData) {
|
||||
$scope.wallet.fetchPaymentRequest({
|
||||
url: uri.merchant
|
||||
}, function(err, merchantData) {
|
||||
if (!timeout) return;
|
||||
clearTimeout(timeout);
|
||||
|
||||
|
|
|
|||
|
|
@ -207,7 +207,9 @@ Network.prototype._onMessage = function(enc) {
|
|||
log.debug('Ignoring trailing message. Ts:', enc.ts);
|
||||
return;
|
||||
}
|
||||
log.debug('Async: receiving ' + JSON.stringify(payload));
|
||||
|
||||
log.info('Network message: ', payload.type);
|
||||
log.debug('Message payload:', payload);
|
||||
|
||||
var self = this;
|
||||
switch (payload.type) {
|
||||
|
|
@ -239,6 +241,7 @@ Network.prototype._onMessage = function(enc) {
|
|||
|
||||
Network.prototype._setupConnectionHandlers = function(opts, cb) {
|
||||
preconditions.checkState(this.socket);
|
||||
log.debug('setting up connection', opts);
|
||||
var self = this;
|
||||
|
||||
self.socket.on('connect_error', function(m) {
|
||||
|
|
@ -260,7 +263,7 @@ Network.prototype._setupConnectionHandlers = function(opts, cb) {
|
|||
if (fromTs) {
|
||||
self.ignoreMessageFromTs = fromTs;
|
||||
}
|
||||
log.info('Async: synchronizing from: ',fromTs);
|
||||
log.info('Async: syncing from: ', fromTs);
|
||||
self.socket.emit('sync', fromTs);
|
||||
self.started = true;
|
||||
});
|
||||
|
|
@ -398,8 +401,6 @@ Network.prototype.send = function(dest, payload, cb) {
|
|||
if (to == this.copayerId)
|
||||
continue;
|
||||
|
||||
log.debug('SEND to: ' + to, this.copayerId, JSON.stringify(payload));
|
||||
|
||||
var message = this.encode(to, payload);
|
||||
this.socket.emit('message', message);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -224,9 +224,7 @@ Insight.prototype.subscribe = function(addresses) {
|
|||
|
||||
s.emit('subscribe', address);
|
||||
s.on(address, handler);
|
||||
} else {
|
||||
log.debug('Already subcribed to: ', address);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,24 @@ TxProposal.prototype._checkPayPro = function() {
|
|||
|
||||
};
|
||||
|
||||
|
||||
TxProposal.prototype.isFullySigned = function() {
|
||||
return txp.builder && txp.builder.isFullySigned();
|
||||
};
|
||||
|
||||
TxProposal.prototype.sign = function(keys, signerId) {
|
||||
var before = txp.countSignatures();
|
||||
txp.builder.sign(keys);
|
||||
|
||||
var signaturesAdded = txp.countSignatures() > before;
|
||||
if (signaturesAdded){
|
||||
txp.signedBy[signerId] = Date.now();
|
||||
}
|
||||
return signturesAdded;
|
||||
};
|
||||
|
||||
|
||||
|
||||
TxProposal.prototype._check = function() {
|
||||
|
||||
if (this.builder.signhash && this.builder.signhash !== Transaction.SIGHASH_ALL) {
|
||||
|
|
|
|||
|
|
@ -205,4 +205,22 @@ TxProposals.prototype.getUsedUnspent = function(maxRejectCount) {
|
|||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* purge
|
||||
*
|
||||
* @param deleteAll
|
||||
* @return {undefined}
|
||||
*/
|
||||
TxProposals.prototype.purge = function(deleteAll, maxRejectCount) {
|
||||
var m = _.size(this.txps);
|
||||
|
||||
if (deleteAll) {
|
||||
this.deleteAll();
|
||||
} else {
|
||||
this.deletePending(maxRejectCount);
|
||||
}
|
||||
var n = _.size(this.txps);
|
||||
return m - n;
|
||||
};
|
||||
|
||||
module.exports = TxProposals;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ var copayConfig = require('../../config');
|
|||
|
||||
var TX_MAX_SIZE_KB = 50;
|
||||
var TX_MAX_INS = 70;
|
||||
|
||||
|
||||
/**
|
||||
* @desc
|
||||
* Wallet manages a private key for Copay, network, storage of the wallet for
|
||||
|
|
@ -119,6 +121,11 @@ function Wallet(opts) {
|
|||
|
||||
inherits(Wallet, events.EventEmitter);
|
||||
|
||||
|
||||
Wallet.TX_BROADCASTED = 'txBroadcasted';
|
||||
Wallet.TX_PROPOSAL_SENT = 'txProposalSent';
|
||||
Wallet.TX_SIGNED = 'txSigned';
|
||||
|
||||
Wallet.prototype.emitAndKeepAlive = function(args) {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
log.debug('Wallet Emitting:', args);
|
||||
|
|
@ -260,13 +267,10 @@ Wallet.prototype._newAddresses = function(dontUpdateUx) {
|
|||
* Processes the data using {@link HDParams#fromList} and merges it with the
|
||||
* {@link Wallet#publicKeyRing}.
|
||||
*
|
||||
* Triggers a {@link Wallet#store} if the internal state has changed.
|
||||
*
|
||||
* @param {string} senderId - the sender id
|
||||
* @param {Object} data - the data recived, {@see HDParams#fromList}
|
||||
*/
|
||||
Wallet.prototype._onIndexes = function(senderId, data) {
|
||||
log.debug('Wallet:' + this.id + ' RECV INDEXES:', data);
|
||||
var inIndexes = HDParams.fromList(data.indexes);
|
||||
var hasChanged = this.publicKeyRing.mergeIndexes(inIndexes);
|
||||
if (hasChanged) {
|
||||
|
|
@ -448,7 +452,8 @@ Wallet.prototype._processTxProposalSeen = function(ntxid) {
|
|||
};
|
||||
|
||||
|
||||
Wallet.prototype._processTxProposalSent = function(ntxid, cb) {
|
||||
|
||||
Wallet.prototype._checkIfTxProposalIsSent = function(ntxid, cb) {
|
||||
var self = this;
|
||||
var txp = this.txProposals.get(ntxid);
|
||||
|
||||
|
|
@ -459,7 +464,7 @@ Wallet.prototype._processTxProposalSent = function(ntxid, cb) {
|
|||
}
|
||||
}
|
||||
self.emitAndKeepAlive('txProposalsUpdated');
|
||||
if (cb) return cb(null, txid);
|
||||
if (cb) return cb(null, txid, txid ? Wallet.TX_BROADCASTED : null);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -501,9 +506,8 @@ Wallet.prototype._processIncomingTxProposal = function(mergeInfo, cb) {
|
|||
|
||||
var tx = mergeInfo.txp.builder.build();
|
||||
if (tx.isComplete())
|
||||
self._processTxProposalSent(mergeInfo.ntxid);
|
||||
else if (mergeInfo.hasChanged) {
|
||||
self.sendTxProposal(mergeInfo.ntxid);
|
||||
self._checkIfTxProposalIsSent(mergeInfo.ntxid);
|
||||
else {
|
||||
self.emitAndKeepAlive('txProposalsUpdated');
|
||||
}
|
||||
return cb();
|
||||
|
|
@ -521,9 +525,9 @@ Wallet.prototype._processIncomingTxProposal = function(mergeInfo, cb) {
|
|||
*/
|
||||
Wallet.prototype._onTxProposal = function(senderId, data) {
|
||||
var self = this;
|
||||
log.debug('Wallet:' + this.id + ' RECV TXPROPOSAL: ', data);
|
||||
var m;
|
||||
|
||||
console.log('[Wallet.js.533]a', this.txProposals.txps); //TODO
|
||||
try {
|
||||
m = this.txProposals.merge(data.txProposal, Wallet.builderOpts);
|
||||
var keyMap = this._getKeyMap(m.txp);
|
||||
|
|
@ -534,8 +538,9 @@ Wallet.prototype._onTxProposal = function(senderId, data) {
|
|||
this.txProposals.deleteOne(m.ntxid);
|
||||
m = null;
|
||||
}
|
||||
console.log('[Wallet.js.533]a', this.txProposals.txps); //TODO
|
||||
|
||||
self._processIncomingTxProposal(m, function(err) {
|
||||
this._processIncomingTxProposal(m, function(err) {
|
||||
if (err) {
|
||||
log.error('Corrupt TX proposal received from:', senderId, err.toString());
|
||||
if (m && m.ntxid)
|
||||
|
|
@ -588,8 +593,6 @@ Wallet.prototype._onReject = function(senderId, data) {
|
|||
*/
|
||||
Wallet.prototype._onSeen = function(senderId, data) {
|
||||
preconditions.checkState(data.ntxid);
|
||||
log.debug('Wallet:' + this.id + ' RECV SEEN:', data);
|
||||
|
||||
var txp = this.txProposals.get(data.ntxid);
|
||||
txp.setSeen(senderId);
|
||||
this.emitAndKeepAlive('txProposalEvent', {
|
||||
|
|
@ -611,14 +614,12 @@ Wallet.prototype._onSeen = function(senderId, data) {
|
|||
* @emits txProposalEvent
|
||||
*/
|
||||
Wallet.prototype._onAddressBook = function(senderId, data) {
|
||||
preconditions.checkState(data.addressBook);
|
||||
log.debug('Wallet:' + this.id + ' RECV ADDRESSBOOK:', data);
|
||||
if (!data.addressBook || !_.isArray(data.addressBook))
|
||||
return;
|
||||
|
||||
var rcv = data.addressBook;
|
||||
console.log('[Wallet.js.618:rcv:]', rcv); //TODO
|
||||
var self = this, hasChange;
|
||||
|
||||
var hasChange, self = this;
|
||||
_.each(rcv, function(value, key) {
|
||||
_.each(data.addressBook, function(value, key) {
|
||||
if (!self.addressBook[key] && Address.validate(key)) {
|
||||
|
||||
self.addressBook[key] = _.pick(value, ['createdTs', 'label']);
|
||||
|
|
@ -660,8 +661,6 @@ Wallet.prototype.updateSyncedTimestamp = function(ts) {
|
|||
* Triggers a call to {@link Wallet#sendWalletReady}
|
||||
*/
|
||||
Wallet.prototype._onNoMessages = function() {
|
||||
if (!this.isShared()) return;
|
||||
|
||||
log.debug('Wallet:' + this.id + ' No messages at the server. Requesting peer sync from: ' + (this.syncedTimestamp + 1));
|
||||
this.sendWalletReady(null, parseInt((this.syncedTimestamp + 1) / 1000000));
|
||||
};
|
||||
|
|
@ -676,13 +675,14 @@ Wallet.prototype._onNoMessages = function() {
|
|||
* @emits corrupt
|
||||
*/
|
||||
Wallet.prototype._onData = function(senderId, data, ts) {
|
||||
console.log('[Wallet.js.533]0', this.txProposals.txps); //TODO
|
||||
preconditions.checkArgument(senderId);
|
||||
preconditions.checkArgument(data);
|
||||
preconditions.checkArgument(data.type);
|
||||
preconditions.checkArgument(ts);
|
||||
preconditions.checkArgument(_.isNumber(ts));
|
||||
log.debug('Wallet:' + this.id + ' RECV', senderId, data);
|
||||
|
||||
log.debug('Wallet:' + this.getName() + ' RECV:', data.type, data, senderId);
|
||||
|
||||
this.updateSyncedTimestamp(ts);
|
||||
|
||||
|
|
@ -917,8 +917,13 @@ Wallet.prototype._setBlockchainListeners = function() {
|
|||
*/
|
||||
Wallet.prototype.netStart = function() {
|
||||
var self = this;
|
||||
var net = this.network;
|
||||
|
||||
if (!this.isShared()) {
|
||||
self.emitAndKeepAlive('ready');
|
||||
return;
|
||||
}
|
||||
|
||||
var net = this.network;
|
||||
net.removeAllListeners();
|
||||
net.on('connect', self._onConnect.bind(self));
|
||||
net.on('data', self._onData.bind(self));
|
||||
|
|
@ -953,7 +958,7 @@ Wallet.prototype.netStart = function() {
|
|||
};
|
||||
|
||||
|
||||
log.debug('Wallet:' + self.id + ' Starting networking: ' + startOpts.copayerId);
|
||||
log.debug('Wallet:' + self.id + ' Starting network.');
|
||||
net.start(startOpts, function() {
|
||||
self._setBlockchainListeners();
|
||||
self.emitAndKeepAlive('ready', net.getPeer());
|
||||
|
|
@ -1154,11 +1159,16 @@ Wallet.fromObj = function(o, readOpts) {
|
|||
|
||||
|
||||
/**
|
||||
* @desc Send a message to other peers
|
||||
* @desc sendToPeers a message to other peers
|
||||
* @param {string[]} recipients - the pubkey of the recipients of the message
|
||||
* @param {Object} obj - the data to be sent to them
|
||||
*/
|
||||
Wallet.prototype.send = function(recipients, obj) {
|
||||
Wallet.prototype._sendToPeers = function(recipients, obj) {
|
||||
if (!this.isShared()) return;
|
||||
|
||||
log.info('Wallet:' + this.getName() + ' ### SENDING ' + obj.type);
|
||||
log.debug('Sending obj', obj);
|
||||
|
||||
this.network.send(recipients, obj);
|
||||
};
|
||||
|
||||
|
|
@ -1181,8 +1191,7 @@ Wallet.prototype.sendAllTxProposals = function(recipients, sinceTs) {
|
|||
*/
|
||||
Wallet.prototype.sendTxProposal = function(ntxid, recipients) {
|
||||
preconditions.checkArgument(ntxid);
|
||||
log.debug('Wallet:' + this.id + ' ### SENDING txProposal ' + ntxid + ' TO:', recipients || 'All', this.txProposals);
|
||||
this.send(recipients, {
|
||||
this._sendToPeers(recipients, {
|
||||
type: 'txProposal',
|
||||
txProposal: this.txProposals.get(ntxid).toObjTrim(),
|
||||
walletId: this.id,
|
||||
|
|
@ -1195,8 +1204,7 @@ Wallet.prototype.sendTxProposal = function(ntxid, recipients) {
|
|||
*/
|
||||
Wallet.prototype.sendSeen = function(ntxid) {
|
||||
preconditions.checkArgument(ntxid);
|
||||
log.debug('Wallet:' + this.id + ' ### SENDING seen: ' + ntxid + ' TO: All');
|
||||
this.send(null, {
|
||||
this._sendToPeers(null, {
|
||||
type: 'seen',
|
||||
ntxid: ntxid,
|
||||
walletId: this.id,
|
||||
|
|
@ -1209,8 +1217,8 @@ Wallet.prototype.sendSeen = function(ntxid) {
|
|||
*/
|
||||
Wallet.prototype.sendReject = function(ntxid) {
|
||||
preconditions.checkArgument(ntxid);
|
||||
log.debug('Wallet:' + this.id + ' ### SENDING reject: ' + ntxid + ' TO: All');
|
||||
this.send(null, {
|
||||
|
||||
this._sendToPeers(null, {
|
||||
type: 'reject',
|
||||
ntxid: ntxid,
|
||||
walletId: this.id,
|
||||
|
|
@ -1222,9 +1230,7 @@ Wallet.prototype.sendReject = function(ntxid) {
|
|||
* @param {string[]} [recipients] - the pubkeys of the recipients
|
||||
*/
|
||||
Wallet.prototype.sendWalletReady = function(recipients, sinceTs) {
|
||||
log.debug('Wallet:' + this.id + ' ### SENDING WalletReady TO:', recipients || 'All');
|
||||
|
||||
this.send(recipients, {
|
||||
this._sendToPeers(recipients, {
|
||||
type: 'walletReady',
|
||||
walletId: this.id,
|
||||
sinceTs: sinceTs,
|
||||
|
|
@ -1239,7 +1245,7 @@ Wallet.prototype.sendWalletReady = function(recipients, sinceTs) {
|
|||
Wallet.prototype.sendWalletId = function(recipients) {
|
||||
log.debug('Wallet:' + this.id + ' ### SENDING walletId TO:', recipients || 'All', this.id);
|
||||
|
||||
this.send(recipients, {
|
||||
this._sendToPeers(recipients, {
|
||||
type: 'walletId',
|
||||
walletId: this.id,
|
||||
opts: this._optsToObj(),
|
||||
|
|
@ -1252,12 +1258,11 @@ Wallet.prototype.sendWalletId = function(recipients) {
|
|||
* @param {string[]} [recipients] - the pubkeys of the recipients
|
||||
*/
|
||||
Wallet.prototype.sendPublicKeyRing = function(recipients) {
|
||||
log.debug('Wallet:' + this.id + ' ### SENDING publicKeyRing TO:', recipients || 'All', this.publicKeyRing.toObj());
|
||||
var publicKeyRing = this.publicKeyRing.toObj();
|
||||
var publicKeyRingObj = this.publicKeyRing.toObj();
|
||||
|
||||
this.send(recipients, {
|
||||
this._sendToPeers(recipients, {
|
||||
type: 'publicKeyRing',
|
||||
publicKeyRing: publicKeyRing,
|
||||
publicKeyRing: publicKeyRingObj,
|
||||
walletId: this.id,
|
||||
});
|
||||
};
|
||||
|
|
@ -1268,9 +1273,7 @@ Wallet.prototype.sendPublicKeyRing = function(recipients) {
|
|||
*/
|
||||
Wallet.prototype.sendIndexes = function(recipients) {
|
||||
var indexes = HDParams.serialize(this.publicKeyRing.indexes);
|
||||
log.debug('Wallet:' + this.id + ' ### INDEXES TO:', recipients || 'All', indexes);
|
||||
|
||||
this.send(recipients, {
|
||||
this._sendToPeers(recipients, {
|
||||
type: 'indexes',
|
||||
indexes: indexes,
|
||||
walletId: this.id,
|
||||
|
|
@ -1289,18 +1292,17 @@ Wallet.prototype.sendAddressBook = function(recipients, onlyKey) {
|
|||
var toSend = [],
|
||||
myId = this.getMyCopayerId();
|
||||
|
||||
if (onlyKey) {
|
||||
toSend = [this.addressBook[onlyKey]];
|
||||
if (onlyKey && this.addressBook[onlyKey]) {
|
||||
toSend = {};
|
||||
toSend[onlyKey] = this.addressBook[onlyKey];
|
||||
} else {
|
||||
toSend = _.find(this.addressBook, function(key, value) {
|
||||
return value.copayerId = myId;
|
||||
toSend = _.filter(this.addressBook, function(entry) {
|
||||
return entry.copayerId === myId;
|
||||
});
|
||||
}
|
||||
if (_.isEmpty(toSend)) return;
|
||||
|
||||
log.debug('Wallet:' + this.id + ' ### SENDING addressBook TO:', recipients || 'All', toSend);
|
||||
|
||||
this.send(recipients, {
|
||||
this._sendToPeers(recipients, {
|
||||
type: 'addressbook',
|
||||
addressBook: toSend,
|
||||
walletId: this.id,
|
||||
|
|
@ -1432,17 +1434,11 @@ Wallet.prototype.getPendingTxProposals = function() {
|
|||
* @return {number} the number of deleted proposals
|
||||
*/
|
||||
Wallet.prototype.purgeTxProposals = function(deleteAll) {
|
||||
var m = this.txProposals.length();
|
||||
|
||||
if (deleteAll) {
|
||||
this.txProposals.deleteAll();
|
||||
} else {
|
||||
this.txProposals.deletePending(this.maxRejectCount());
|
||||
var deleted = this.txProposals.purge(deleteAll, this.maxRejectCount());
|
||||
if (deleted) {
|
||||
this.emitAndKeepAlive('txProposalsUpdated');
|
||||
}
|
||||
this.emitAndKeepAlive('txProposalsUpdated');
|
||||
|
||||
var n = this.txProposals.length();
|
||||
return m - n;
|
||||
return deleted;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1467,34 +1463,40 @@ Wallet.prototype.reject = function(ntxid) {
|
|||
Wallet.prototype.sign = function(ntxid) {
|
||||
preconditions.checkState(!_.isUndefined(this.getMyCopayerId()));
|
||||
|
||||
var myId = this.getMyCopayerId();
|
||||
var txp = this.txProposals.get(ntxid);
|
||||
|
||||
var before = txp.countSignatures();
|
||||
var keys = this.privateKey.getForPaths(txp.inputChainPaths);
|
||||
txp.builder.sign(keys);
|
||||
|
||||
if (txp.countSignatures() <= before) {
|
||||
var signaturesAdded = txp.sign(keys, this.getMyCopayerId());
|
||||
if (!signturesAdded)
|
||||
return false;
|
||||
}
|
||||
|
||||
txp.signedBy[myId] = Date.now();
|
||||
this.sendTxProposal(ntxid);
|
||||
this.emitAndKeepAlive('txProposalsUpdated');
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @callback broadcastCallback
|
||||
* @param {string} txid - the transaction id on the blockchain
|
||||
*/
|
||||
|
||||
Wallet.prototype.signAndSend = function(ntxid, cb) {
|
||||
if (this.sign(ntxid)) {
|
||||
var txp = w.txProposals.get(ntxid);
|
||||
if (txp.isFullySigned()) {
|
||||
return this.broadcastTx(ntxid, cb);
|
||||
} else {
|
||||
this.sendTxProposal(ntxid);
|
||||
return cb(null, ntxid, Wallet.TX_SIGNED );
|
||||
}
|
||||
} else {
|
||||
return cb(new Error('Could not sign the proposal'));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @desc Broadcasts a transaction to the blockchain
|
||||
* @param {string} ntxid - the transaction proposal id
|
||||
* @param {broadcastCallback} cb
|
||||
* @callback broadcastCallback
|
||||
* @param {string} txid - the transaction id on the blockchain
|
||||
*/
|
||||
Wallet.prototype.sendTx = function(ntxid, cb) {
|
||||
Wallet.prototype.broadcastTx = function(ntxid, cb) {
|
||||
var self = this;
|
||||
|
||||
var txp = this.txProposals.get(ntxid);
|
||||
|
|
@ -1506,7 +1508,6 @@ Wallet.prototype.sendTx = function(ntxid, cb) {
|
|||
|
||||
var serializedTx = tx.serialize();
|
||||
|
||||
|
||||
if (txp.merchant) {
|
||||
this.sendPaymentTx(ntxid, serializedTx);
|
||||
}
|
||||
|
|
@ -1519,17 +1520,15 @@ Wallet.prototype.sendTx = function(ntxid, cb) {
|
|||
log.error('Error sending TX:', err);
|
||||
|
||||
if (txid) {
|
||||
log.debug('Wallet:' + self.getName() + ' Broadcasted TX. BITCOIND txid:', txid);
|
||||
log.debug('Wallet:' + self.getName() + ' broadcasted a TX. BITCOIND txid:', txid);
|
||||
var txp = self.txProposals.get(ntxid);
|
||||
txp.setSent(txid);
|
||||
self.sendTxProposal(ntxid);
|
||||
self.emitAndKeepAlive('txProposalsUpdated');
|
||||
return cb(txid);
|
||||
return cb(null, txid, Wallet.TX_BROADCASTED);
|
||||
} else {
|
||||
log.info('Wallet:' + self.getName() + '. Sent failed. Checking if the TX was sent already');
|
||||
self._processTxProposalSent(ntxid, function(err, txid) {
|
||||
return cb(txid);
|
||||
});
|
||||
self._checkIfTxProposalIsSent(ntxid, cb);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
@ -2062,9 +2061,11 @@ Wallet.prototype.removeTxWithSpentInputs = function(cb) {
|
|||
};
|
||||
|
||||
/**
|
||||
* @desc Create a transaction proposal, and run many sanity checks
|
||||
* @desc Spends coins from the wallet
|
||||
* Create a Transaction Proposal and broadcast it or send it
|
||||
* to copayers
|
||||
*/
|
||||
Wallet.prototype.createTx = function(opts, cb) {
|
||||
Wallet.prototype.spend = function(opts, cb) {
|
||||
preconditions.checkArgument(_.isObject(opts));
|
||||
log.debug('create Options', opts);
|
||||
|
||||
|
|
@ -2098,7 +2099,8 @@ Wallet.prototype.createTx = function(opts, cb) {
|
|||
|
||||
var ntxid, txp;
|
||||
try {
|
||||
txp = self.createTxProposal(toAddress, amountSat, comment, safeUnspent, opts.builderOpts);
|
||||
txp = self._createTxProposal(toAddress,
|
||||
amountSat, comment, safeUnspent, opts.builderOpts);
|
||||
} catch (e) {
|
||||
log.error(e);
|
||||
return cb(e);
|
||||
|
|
@ -2109,17 +2111,21 @@ Wallet.prototype.createTx = function(opts, cb) {
|
|||
}
|
||||
|
||||
var ntxid = self.txProposals.add(txp);
|
||||
log.debug('TXP Added: ', ntxid);
|
||||
|
||||
|
||||
if (!ntxid) {
|
||||
return cb(new Error('Error creating the transaction'));
|
||||
}
|
||||
|
||||
log.debug('TXP Added: ', ntxid);
|
||||
|
||||
self.sendIndexes();
|
||||
self.sendTxProposal(ntxid);
|
||||
self.emitAndKeepAlive('txProposalsUpdated');
|
||||
return cb(null, ntxid);
|
||||
// Needs only one signature? Broadcast it!
|
||||
if (!self.requiresMultipleSignatures()) {
|
||||
self.broadcastTx(ntxid, cb);
|
||||
} else {
|
||||
self.sendTxProposal(ntxid);
|
||||
self.emitAndKeepAlive('txProposalsUpdated');
|
||||
return cb(null, ntxid, Wallet.TX_PROPOSAL_SENT);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -2159,7 +2165,7 @@ Wallet.prototype._getBuilder = function(opts) {
|
|||
|
||||
|
||||
/*
|
||||
* createTxProposal
|
||||
* _createTxProposal
|
||||
* Creates a transaction proposal and run many sanity checks
|
||||
*
|
||||
* @param toAddress
|
||||
|
|
@ -2171,7 +2177,7 @@ Wallet.prototype._getBuilder = function(opts) {
|
|||
* Throws errors on unexpected inputs.
|
||||
*/
|
||||
|
||||
Wallet.prototype.createTxProposal = function(toAddress, amountSat, comment, utxos, builderOpts) {
|
||||
Wallet.prototype._createTxProposal = function(toAddress, amountSat, comment, utxos, builderOpts) {
|
||||
preconditions.checkArgument(toAddress);
|
||||
preconditions.checkArgument(amountSat);
|
||||
preconditions.checkArgument(_.isArray(utxos));
|
||||
|
|
@ -2234,7 +2240,6 @@ Wallet.prototype.createTxProposal = function(toAddress, amountSat, comment, utxo
|
|||
* @desc Updates all the indexes for the current publicKeyRing. This scans
|
||||
* the blockchain looking for transactions on derived addresses.
|
||||
*
|
||||
* Triggers a wallet {@link Wallet#store} call
|
||||
* @param {Function} callback - called when all indexes have been updated. Receives an error, if any, as first argument
|
||||
*/
|
||||
Wallet.prototype.updateIndexes = function(callback) {
|
||||
|
|
@ -2380,7 +2385,7 @@ Wallet.prototype.getNetwork = function() {
|
|||
*/
|
||||
Wallet.prototype._checkAddressBook = function(key) {
|
||||
if (this.addressBook[key] && this.addressBook[key].copayerId != -1) {
|
||||
throw new Error('This address already exists in your Address Book: ' + address);
|
||||
throw new Error('This address already exists in your Address Book');
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue