/*!
* nodeclient.js - node client for bcoin
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
* https://github.com/bcoin-org/bcoin
*/
'use strict';
var util = require('../utils/util');
var co = require('../utils/co');
var AsyncObject = require('../utils/asyncobject');
/**
* NodeClient
* Sort of a fake local client for separation of concerns.
* @alias module:node.NodeClient
* @constructor
*/
function NodeClient(node) {
if (!(this instanceof NodeClient))
return new NodeClient(node);
AsyncObject.call(this);
this.node = node;
this.network = node.network;
this.filter = null;
this.listen = false;
this._init();
}
util.inherits(NodeClient, AsyncObject);
/**
* Initialize the client.
* @returns {Promise}
*/
NodeClient.prototype._init = function init() {
var self = this;
this.node.on('connect', function(entry, block) {
if (!self.listen)
return;
self.emit('block connect', entry, block.txs);
});
this.node.on('disconnect', function(entry, block) {
if (!self.listen)
return;
self.emit('block disconnect', entry);
});
this.node.on('tx', function(tx) {
if (!self.listen)
return;
self.emit('tx', tx);
});
this.node.on('reset', function(tip) {
if (!self.listen)
return;
self.emit('chain reset', tip);
});
};
/**
* Open the client.
* @returns {Promise}
*/
NodeClient.prototype._open = function open(options) {
this.listen = true;
return Promise.resolve();
};
/**
* Close the client.
* @returns {Promise}
*/
NodeClient.prototype._close = function close() {
this.listen = false;
return Promise.resolve();
};
/**
* Get chain tip.
* @returns {Promise}
*/
NodeClient.prototype.getTip = function getTip() {
return Promise.resolve(this.node.chain.tip);
};
/**
* Get chain entry.
* @param {Hash} hash
* @returns {Promise}
*/
NodeClient.prototype.getEntry = co(function* getEntry(hash) {
var entry = yield this.node.chain.db.getEntry(hash);
if (!entry)
return;
if (!(yield entry.isMainChain()))
return;
return entry;
});
/**
* Send a transaction. Do not wait for promise.
* @param {TX} tx
* @returns {Promise}
*/
NodeClient.prototype.send = function send(tx) {
this.node.relay(tx);
return Promise.resolve();
};
/**
* Set bloom filter.
* @param {Bloom} filter
* @returns {Promise}
*/
NodeClient.prototype.setFilter = function setFilter(filter) {
this.filter = filter;
this.node.pool.setFilter(filter);
return Promise.resolve();
};
/**
* Add data to filter.
* @param {Buffer} data
* @returns {Promise}
*/
NodeClient.prototype.addFilter = function addFilter(data) {
this.node.pool.queueFilterLoad();
return Promise.resolve();
};
/**
* Reset filter.
* @returns {Promise}
*/
NodeClient.prototype.resetFilter = function resetFilter() {
this.node.pool.queueFilterLoad();
return Promise.resolve();
};
/**
* Esimate smart fee.
* @param {Number?} blocks
* @returns {Promise}
*/
NodeClient.prototype.estimateFee = function estimateFee(blocks) {
if (!this.node.fees)
return Promise.resolve(this.network.feeRate);
return Promise.resolve(this.node.fees.estimateFee(blocks));
};
/**
* Rescan for any missed transactions.
* @param {Number|Hash} start - Start block.
* @param {Bloom} filter
* @param {Function} iter - Iterator.
* @returns {Promise}
*/
NodeClient.prototype.rescan = function rescan(start) {
var self = this;
return this.node.chain.scan(start, this.filter, function(entry, txs) {
return new Promise(function(resolve, reject) {
var cb = co.wrap(resolve, reject);
self.emit('block rescan', entry, txs, cb);
});
});
};
/*
* Expose
*/
module.exports = NodeClient;