Steem-lib Guide [Part3]

in #steem-lib7 years ago (edited)

Previous: Steem-lib Guide [Part2]


Listening to all transactions.

The easiest way is use remote.stream() and listen for 'transaction' event, as describe in Guide[Part1]:

remote.on('transaction', function (tx) {
  //process transactions here.
})
remote.stream();

this will stream all transactions on blockchain as they get into an irreversible-block.
The emitted txns are formatted as follow:

{
    ref_block_num: 10718,
    ref_block_prefix: 316154747,
    expiration: '2017-02-26T15:49:30',
    operations: [
        ['vote', { /*omitted....*/ }]
    ],
    extensionts: [],
    signatures:[ '20249....omited.....'],
    timestamp: '2017-02-26T15:49:21'
    block_num: 9710283,
    block_id: '108103dc5b6eee9ab60cc90f56cc00cd6feef4be',
    transaction_num: 0
}

Listening to a particular Account.

Add an account to the client, and listen to its 'transaction' event.

var acc = remote.addAccount('ripplerm');
acc.on('transaction', function (tx){
    // process transaction.
})
remote.stream();

Txns format same as above. Basically it just filter out un-related txns from the stream;


Alternative way for Account Subscription

listening to 'tx' event of an Account, use either Remote.stream() or Account.subscribe() to start the stream.

var acc = remote.addAccount('ripplerm');
acc.on('tx', function (tx){
    // process tx here
})
acc.subscribe();
// remote.stream();

Transactions emmited through 'tx' event has a different format.
Here, we have one single 'op' property instead of an Array of operations.

{
    trx_id: '108103dc5b6eee9ab60cc90f56cc00cd6feef4be',
    block: 9711077,
    trx_in_block: 2,
    op_in_trx: 0,
    virtual_op: 0,
    timestamp: '2017-02-26T15:49:21'
    op: ['vote', {/*....vote data omitted...*/}]
}

for 'tx' stream, the response will be received on per-operation basis, i.e. if there're more than one operations in a single transaction thats affecting this account, it will emit 'tx' for each operation.

In addition to 'tx' event, the Account object will also emit an event that's match the name of operation type.
Examples:

acc.on('transfer', function(tx) {
  //process payment....
});
acc.on('comment', function(tx) {
  //handle comment...
});

Account.subscribe() method can take a Boolean argument. Pass in 'true' if we like to heard 'tx' immediately without waiting the irreversible-block confirmation.

acc.subscribe(true);  // not recommended for important transaction e.g. payment.

What's under the hood.

Currently, there's no Steem API that's allow us to make a websocket subscription for blocks or transactions directly. (AFAIK the only working subscription is 'set_block_applied_callback' api which can only stream us the headers of new head-blocks).

For Remote.stream() to work, what we are doing is having our client check the blockchain-status periodically (via 'get_dynamic_global_properties', every 3-seconds), and request the blocks whenever we saw new ones. 'transaction' event is emitted when we parsing the transactions on these blocks.

Account.subscribe() uses different approach, where we periodically query account-history for the latest transactions. That's why the object emitted by 'tx' event has a format similar to the responses from 'get_account_history' API.

As a conclusion, if we like to monitor only few accounts, then the Account.subscribe() method can save us some bandwidth (we don't need to fetch all blocks)... if network bandwidth is not a concern or we are monitoring a bunches of accounts, then blocks-streaming might be a better choice.


github: https://github.com/ripplerm/steem-lib
npm: https://www.npmjs.com/package/steem-lib

Sort:  

I'm trying to kickstart the use of the #steemdev tag. Your post would fit well in that category.