bitcore-wallet-service/lib/blockchainmonitor.js

141 lines
3.7 KiB
JavaScript
Raw Normal View History

2015-03-30 15:44:16 -07:00
'use strict';
var $ = require('preconditions').singleton();
var _ = require('lodash');
var async = require('async');
var log = require('npmlog');
log.debug = log.verbose;
2015-05-06 08:48:43 -07:00
2015-03-31 08:04:02 -07:00
var BlockchainExplorer = require('./blockchainexplorer');
2015-05-06 08:48:43 -07:00
var Storage = require('./storage');
var MessageBroker = require('./messagebroker');
2015-05-11 11:35:25 -07:00
var Lock = require('./lock');
2015-03-30 15:44:16 -07:00
var Notification = require('./model/notification');
2015-05-06 08:48:43 -07:00
function BlockchainMonitor() {};
2015-05-06 12:03:58 -07:00
BlockchainMonitor.prototype.start = function(opts, cb) {
2015-04-05 09:56:56 -07:00
opts = opts || {};
2015-05-06 08:48:43 -07:00
2015-05-06 12:03:58 -07:00
var self = this;
2015-05-06 08:48:43 -07:00
async.parallel([
2015-03-30 15:44:16 -07:00
2015-05-06 08:48:43 -07:00
function(done) {
2015-05-06 12:03:58 -07:00
self.explorers = _.map(['livenet', 'testnet'], function(network) {
2015-06-10 07:49:52 -07:00
var explorer;
if (opts.blockchainExplorers) {
explorer = opts.blockchainExplorers[network];
} else {
2015-07-03 11:08:32 -07:00
var config = {}
if (opts.blockchainExplorerOpts && opts.blockchainExplorerOpts[network]) {
config = opts.blockchainExplorerOpts[network];
}
2015-06-10 07:49:52 -07:00
var explorer = new BlockchainExplorer({
provider: config.provider,
network: network,
url: config.url,
});
}
$.checkState(explorer);
self._initExplorer(explorer);
return explorer;
2015-05-06 08:48:43 -07:00
});
done();
},
function(done) {
2015-06-10 07:49:52 -07:00
if (opts.storage) {
self.storage = opts.storage;
done();
} else {
self.storage = new Storage();
self.storage.connect(opts.storageOpts, done);
}
2015-05-06 08:48:43 -07:00
},
function(done) {
2015-06-10 07:49:52 -07:00
self.messageBroker = opts.messageBroker || new MessageBroker(opts.messageBrokerOpts);
2015-06-16 12:16:43 -07:00
self.messageBroker.onMessage(_.bind(self._handleIncommingTx, self));
2015-05-06 08:48:43 -07:00
done();
},
2015-05-11 11:03:17 -07:00
function(done) {
2015-06-10 07:49:52 -07:00
self.lock = opts.lock || new Lock(opts.lockOpts);
2015-05-19 11:30:27 -07:00
done();
2015-05-11 11:03:17 -07:00
},
], function(err) {
2015-05-19 11:30:27 -07:00
if (err) {
log.error(err);
}
2015-05-29 06:30:59 -07:00
return cb(err);
2015-05-11 11:03:17 -07:00
});
2015-05-06 08:48:43 -07:00
};
2015-03-30 15:44:16 -07:00
2015-06-10 07:49:52 -07:00
BlockchainMonitor.prototype._initExplorer = function(explorer) {
2015-05-06 12:03:58 -07:00
var self = this;
2015-03-31 08:29:28 -07:00
var socket = explorer.initSocket();
2015-05-07 10:16:24 -07:00
socket.on('connect', function() {
2015-06-10 07:49:52 -07:00
log.info('Connected to ' + explorer.getConnectionInfo());
2015-05-07 11:04:32 -07:00
socket.emit('subscribe', 'inv');
2015-05-07 10:16:24 -07:00
});
socket.on('connect_error', function() {
2015-06-10 07:49:52 -07:00
log.error('Error connecting to ' + explorer.getConnectionInfo());
2015-05-07 10:16:24 -07:00
});
2015-05-06 12:03:58 -07:00
socket.on('tx', _.bind(self._handleIncommingTx, self));
2015-03-30 15:44:16 -07:00
};
2015-05-06 12:03:58 -07:00
BlockchainMonitor.prototype._handleIncommingTx = function(data) {
var self = this;
2015-05-06 08:48:43 -07:00
if (!data || !data.vout) return;
var outs = _.compact(_.map(data.vout, function(v) {
var addr = _.keys(v)[0];
2015-05-07 10:16:24 -07:00
var startingChar = addr.charAt(0);
if (startingChar != '2' && startingChar != '3') return;
2015-03-30 15:44:16 -07:00
2015-05-06 08:48:43 -07:00
return {
address: addr,
amount: +v[addr]
};
}));
if (_.isEmpty(outs)) return;
2015-03-30 15:44:16 -07:00
2015-05-06 08:48:43 -07:00
async.each(outs, function(out, next) {
2015-05-06 12:03:58 -07:00
self.storage.fetchAddress(out.address, function(err, address) {
2015-05-07 10:16:24 -07:00
if (err) {
log.error('Could not fetch addresses from the db');
return next(err);
}
if (!address || address.isChange) return next();
2015-03-30 15:44:16 -07:00
2015-05-06 10:32:01 -07:00
var walletId = address.walletId;
2015-05-06 12:03:58 -07:00
log.info('Incoming tx for wallet ' + walletId + ' [' + out.amount + 'sat -> ' + out.address + ']');
self._createNotification(walletId, data.txid, out.address, out.amount, next);
2015-03-30 15:44:16 -07:00
});
2015-05-06 08:48:43 -07:00
}, function(err) {
return;
2015-03-30 15:44:16 -07:00
});
};
2015-05-06 12:03:58 -07:00
BlockchainMonitor.prototype._createNotification = function(walletId, txid, address, amount, cb) {
var self = this;
2015-05-11 11:03:17 -07:00
var notification = Notification.create({
2015-05-06 08:48:43 -07:00
type: 'NewIncomingTx',
data: {
txid: txid,
address: address,
amount: amount,
},
walletId: walletId,
});
2015-05-11 11:03:17 -07:00
self.storage.storeNotification(walletId, notification, function() {
self.messageBroker.send(notification)
2015-05-29 06:30:59 -07:00
return cb();
2015-03-30 15:44:16 -07:00
});
};
module.exports = BlockchainMonitor;