lightning
Version:
Lightning Network client library
98 lines (77 loc) • 2.55 kB
JavaScript
const EventEmitter = require('events');
const {isLnd} = require('./../../lnd_requests');
const {rpcTxAsTransaction} = require('./../../lnd_responses');
const cancelError = 'Cancelled on client';
const {isArray} = Array;
const method = 'subscribeTransactions';
const type = 'default';
/** Subscribe to transactions
Requires `onchain:read` permission
`inputs` are not supported on LND 0.15.0 and below
{
lnd: <Authenticated LND API Object>
}
@throws
<Error>
@returns
<EventEmitter Object>
@event 'chain_transaction'
{
[block_id]: <Block Hash String>
[confirmation_count]: <Confirmation Count Number>
[confirmation_height]: <Confirmation Block Height Number>
created_at: <Created ISO 8601 Date String>
[fee]: <Fees Paid Tokens Number>
id: <Transaction Id String>
inputs: [{
is_local: <Spent Outpoint is Local Bool>
transaction_id: <Transaction Id Hex String>
transaction_vout: <Transaction Output Index Number>
}]
is_confirmed: <Is Confirmed Bool>
is_outgoing: <Transaction Outbound Bool>
output_addresses: [<Address String>]
tokens: <Tokens Including Fee Number>
[transaction]: <Raw Transaction Hex String>
}
*/
module.exports = ({lnd}) => {
if (!isLnd({lnd, method, type})) {
throw new Error('ExpectedAuthenticatedLndToSubscribeToTransactions');
}
const eventEmitter = new EventEmitter();
const subscription = lnd[type][method]({});
// Cancel the subscription when all listeners are removed
eventEmitter.on('removeListener', () => {
// Exit early when there are still listeners
if (!!eventEmitter.listenerCount('chain_transaction')) {
return;
}
subscription.cancel();
return;
});
const emitErr = err => {
if (!!err && err.details === cancelError) {
subscription.removeAllListeners();
}
// Exit early when there are no listeners on error
if (!eventEmitter.listenerCount('error')) {
return;
}
if (isArray(err)) {
return eventEmitter.emit('error', err);
}
return eventEmitter.emit('error', [503, 'UnexpectedChainTxSubErr', {err}]);
};
subscription.on('data', tx => {
try {
return eventEmitter.emit('chain_transaction', rpcTxAsTransaction(tx));
} catch (err) {
return emitErr([503, err.message]);
}
});
subscription.on('end', () => eventEmitter.emit('end'));
subscription.on('error', err => emitErr(err));
subscription.on('status', status => eventEmitter.emit('status', status));
return eventEmitter;
};