Streaming Client for Hyperion History API (v3+)
npm install @eosrio/hyperion-stream-client --save
ESM (Node and Browser):
import {HyperionStreamClient} from "@eosrio/hyperion-stream-client";
CommonJs (Node):
const {HyperionStreamClient} = require('@eosrio/hyperion-stream-client');
Without installing via npm, you can also load the webpack bundle directly:
<script src="https://<ENDPOINT>/stream-client.js"></script>
Where <ENDPOINT>
is the Hyperion API (e.g. https://eos.hyperion.eosrio.io
)
For other usages, the bundle is also available at dist/hyperion-stream-client.js
Set up the endpoint that you want to fetch data from:
const client = new HyperionStreamClient({
endpoint: 'https://example.com',
debug: true,
libStream: false
});
https://example.com
is the host, from where https://example.com/v2/history/...
is served.
libStream
to true
if you want to enable a stream of only irreversible data.
Don't forget to attach the handler using the method: setAsyncLibDataHandler(handler: AsyncHandlerFunction)
debug
to true
to print debugging messagesto ensure the client is connected, requests should be made only after calling the client.connect()
method, refer to examples
below;
client.streamActions(request: StreamActionsRequest): void
contract
- contract accountaction
- action nameaccount
- notified account namestart_from
- start reading on block or on a specific date. 0=disabled means it will read starting from HEAD block.read_until
- stop reading on block (0=disable) or on a specific date (0=disabled)filters
- actions filter (more details below)Notes
import {HyperionStreamClient, StreamClientEvents} from "@eosrio/hyperion-stream-client";
const client = new HyperionStreamClient({
endpoint: "http://localhost:1234",
debug: true,
libStream: false
});
client.on(StreamClientEvents.LIBUPDATE, (data: EventData) => {
console.log(data);
});
client.on('connect', () => {
console.log('connected!');
});
client.setAsyncDataHandler(async (data) => {
console.log(data);
// process incoming data, replace with your code
// await processSomethingHere();
})
await client.connect();
client.streamActions({
contract: 'eosio',
action: 'voteproducer',
account: '',
start_from: '2020-03-15T00:00:00.000Z',
read_until: 0,
filters: [],
});
You can set up filters to refine your stream. Filters should use fields following the Hyperion Action Data Structure, such as:
act.data.producers
(on eosio::voteproducer)@transfer.to
(here the @ prefix is required since transfers have special mappings)Please refer to the mapping definitions to know which data fields are available
For example, to filter the stream for
every transfer made to the eosio.ramfee
account:
client.streamActions({
contract: 'eosio.token',
action: 'transfer',
account: 'eosio',
start_from: 0,
read_until: 0,
filters: [
{field: '@transfer.to', value: 'eosio.ramfee'}
],
});
To refine even more your stream, you could add more filters. Remember that adding more filters will result in AND operations. For OR operations setup another request.
client.streamDeltas(request: StreamDeltasRequest): void
code
- contract accounttable
- table namescope
- table scopepayer
- ram payerstart_from
- start reading on block or on a specific date. 0=disabled means it will read starting from HEAD block.read_until
- stop reading on block (0=disable) or on a specific date (0=disabled)Example:
Referring to the same pattern as the action stream example above, one could also include a delta stream request
client.streamDeltas({
code: 'eosio.token',
table: '*',
scope: '',
payer: '',
start_from: 0,
read_until: 0,
});
Note: Delta filters are planned to be implemented soon.
Incoming data handler is defined via the client.setAsyncDataHandler(async (data)=> void)
method
if you set libStream
to true
another stream of only irreversible data will be available.
Don't forget to attach the handler using the method: setAsyncLibDataHandler(handler: AsyncHandlerFunction)
data object is structured as follows:
type
- action | deltamode
- live | historycontent
- Hyperion Data Structure (
see action index
and delta index
templates)client.setAsyncDataHandler(async (data) => {
console.log(data);
// process incoming data, replace with your code
// await processSomethingHere();
})
// irreversible data stream only for when libStream: true on client connection setup
client.setAsyncLibDataHandler(async (data) => {
console.log(data);
// process incoming data, replace with your code
// await processSomethingHere();
})
Useful information about load-balancing multiple Socket.IO servers: https://socket.io/docs/v4/using-multiple-nodes/#NginX-configuration