Building Awesome bcoin Plugins
Introduction
bcoin has an extensible interface for writing plugins of all sizes . For example, did you know that the bcoin wallet is actually a plugin?
// file: https://github.com/bcoin-org/bcoin/blob/master/bin/node #48
const plugin = require('../lib/wallet/plugin');
node.use(plugin);For a plugin to be usable by bcoin, all it needs is an init function which
accepts a node. Plugins can use node to access objects like mempool,
chain or pool.
Hello World
For example, hello.js might look like
'use strict';
const plugin = exports;
class Plugin {
constructor(node) {
console.log('connecting to: %s', node.network);
}
}
plugin.init = function init(node) {
return new Plugin(node);
};Running bcoin --testnet --plugins=${PWD}/hello should start with
connecting to: testnet
Optionally plugins may have a unique id string as an identifier, along with
functions open() and close() which can be used to hook into the startup and
shutdown processes of the node, respectively.
Note: Some identifiers are reserved by bcoin, so you’ll need to use something
other than chain fees mempool miner pool rpc http.
If the plugin needs to maintain any persistent data, it may write to it’s own
database, using open and close to load and unload connections and handles
for example.
...
class Plugin {
constructor(node) {
}
async open() {
await this.db.open();
console.log('db opened');
}
async close() {
await this.db.close();
console.log('db closed');
}
};
...bcoin is thoroughly event driven, which means that most of the time, you just
need to listen to the appropriate event and add a hook for your handler.
Depending on the level of granularity required, you can choose which object to
listen for the events. For example, fullnode emits tx, block events which
may be sufficient level of detail for your plugin, but you can also dig into the
mempool or chain for finer details, if required.
Multiple plugins can be enabled by passing an array of modules to theplugins
configuration option for example:plugins=plugin1,plugin2.
Peers Plugin
Example: peers.js plugin to announce connected peers
...
class Plugin {
constructor(node) {
this.node = node;
this.node.pool.on('peer open', this.peerOpen)
}
async peerOpen(peer) {
console.log('connected to peer %s', peer.hostname())
}
}
plugin.id = 'peers';
...You can find official bcoin plugins under the bcoin-org github:
bindex
To showcase some advanced features of the bcoin plugin system, let’s talk about a new official plugin which is currently being developed.
bindex is a plugin that creates an index database for transactions and addresses, and soon for generating BIP 158 filters to add support for Neutrino light clients. This functionality can be extended even further to support custom indexes, for example for your own colored coins.
In order to persist the indexes, bindex also maintains its own database. This also allows it to add indexing retroactively without needing to resync the whole chain.
Important events that bindex would need to listen to are chain: connect for
new blocks and chain: disconnect for disconnected blocks (due to re-org)
To learn more about the bindex plugin, checkout the repo:
https://github.com/bcoin-org/bindex
So, go ahead and write your first bcoin plugin!
Reach out to us on telegram telegram-app.svg or IRC #bcoin with your feedback!