|
|
@ -25,7 +25,8 @@ BlockchainMonitor.prototype.start = function(opts, cb) { |
|
|
|
async.parallel([ |
|
|
|
|
|
|
|
function(done) { |
|
|
|
self.explorers = _.indexBy(_.map(['livenet', 'testnet'], function(network) { |
|
|
|
self.explorers = {}; |
|
|
|
_.map(['livenet', 'testnet'], function(network) { |
|
|
|
var explorer; |
|
|
|
if (opts.blockchainExplorers) { |
|
|
|
explorer = opts.blockchainExplorers[network]; |
|
|
@ -42,9 +43,9 @@ BlockchainMonitor.prototype.start = function(opts, cb) { |
|
|
|
}); |
|
|
|
} |
|
|
|
$.checkState(explorer); |
|
|
|
self._initExplorer(explorer); |
|
|
|
return explorer; |
|
|
|
}), 'network'); |
|
|
|
self._initExplorer(network, explorer); |
|
|
|
self.explorers[network] = explorer; |
|
|
|
}); |
|
|
|
done(); |
|
|
|
}, |
|
|
|
function(done) { |
|
|
@ -72,7 +73,7 @@ BlockchainMonitor.prototype.start = function(opts, cb) { |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
BlockchainMonitor.prototype._initExplorer = function(explorer) { |
|
|
|
BlockchainMonitor.prototype._initExplorer = function(network, explorer) { |
|
|
|
var self = this; |
|
|
|
|
|
|
|
var socket = explorer.initSocket(); |
|
|
@ -85,7 +86,7 @@ BlockchainMonitor.prototype._initExplorer = function(explorer) { |
|
|
|
log.error('Error connecting to ' + explorer.getConnectionInfo()); |
|
|
|
}); |
|
|
|
socket.on('tx', _.bind(self._handleIncomingTx, self)); |
|
|
|
socket.on('block', _.bind(self._handleNewBlock, self, explorer.network)); |
|
|
|
socket.on('block', _.bind(self._handleNewBlock, self, network)); |
|
|
|
}; |
|
|
|
|
|
|
|
BlockchainMonitor.prototype._handleThirdPartyBroadcasts = function(data, processIt) { |
|
|
@ -209,7 +210,7 @@ BlockchainMonitor.prototype._handleIncomingTx = function(data) { |
|
|
|
BlockchainMonitor.prototype._notifyNewBlock = function(network, hash) { |
|
|
|
var self = this; |
|
|
|
|
|
|
|
log.info('New ' + network + ' block: ', hash); |
|
|
|
log.info('New ' + network + ' block: ' + hash); |
|
|
|
var notification = Notification.create({ |
|
|
|
type: 'NewBlock', |
|
|
|
walletId: network, // use network name as wallet id for global notifications
|
|
|
@ -229,17 +230,52 @@ BlockchainMonitor.prototype._notifyNewBlock = function(network, hash) { |
|
|
|
BlockchainMonitor.prototype._handleTxConfirmations = function(network, hash) { |
|
|
|
var self = this; |
|
|
|
|
|
|
|
function processTriggeredSubs(subs, cb) { |
|
|
|
async.each(subs, function(sub) { |
|
|
|
log.info('New tx confirmation ' + sub.txid); |
|
|
|
sub.isActive = false; |
|
|
|
self.storage.storeTxConfirmationSub(sub, function(err) { |
|
|
|
if (err) return cb(err); |
|
|
|
|
|
|
|
var notification = Notification.create({ |
|
|
|
type: 'TxConfirmation', |
|
|
|
walletId: sub.walletId, |
|
|
|
creatorId: sub.copayerId, |
|
|
|
data: { |
|
|
|
txid: sub.txid, |
|
|
|
network: network, |
|
|
|
// TODO: amount
|
|
|
|
}, |
|
|
|
}); |
|
|
|
self._storeAndBroadcastNotification(notification, cb); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
var explorer = self.explorers[network]; |
|
|
|
if (!explorer) return; |
|
|
|
|
|
|
|
explorer.getTxidsInBlock(hash, function(err, txids) { |
|
|
|
if (err) { |
|
|
|
log.error('Could not fetch txids from block ' + hash); |
|
|
|
log.error('Could not fetch txids from block ' + hash, err); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// self.storage.fetchTx
|
|
|
|
|
|
|
|
self.storage.fetchActiveTxConfirmationSubs(null, function(err, subs) { |
|
|
|
if (err) return; |
|
|
|
if (_.isEmpty(subs)) return; |
|
|
|
var indexedSubs = _.indexBy(subs, 'txid'); |
|
|
|
var triggered = []; |
|
|
|
_.each(txids, function(txid) { |
|
|
|
if (indexedSubs[txid]) triggered.push(indexedSubs[txid]); |
|
|
|
}); |
|
|
|
processTriggeredSubs(triggered, function(err) { |
|
|
|
if (err) { |
|
|
|
log.error('Could not process tx confirmations', err); |
|
|
|
} |
|
|
|
return; |
|
|
|
}); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|