Subscription API
Vite nodes provide two types of subscription RPC APIs: Polling API and WebSocket API.
- Polling API returns a subscription filter. The client must periodically call
subscribe_getChangesByFilterId
with the filter ID to fetch new events. If no new events have occurred since the last request, the server returnsnull
.
Note: Filters expire if unused for more than 5 minutes. If the client does not send a request within this time, the subscription will close, and the client must re-subscribe.
Polling APIs include:
- subscribe_newSnapshotBlockFilter
- subscribe_newAccountBlockFilter
- subscribe_newAccountBlockByAddressFilter
- subscribe_newUnreceivedBlockByAddressFilter
- subscribe_newVmLogFilter
- subscribe_uninstallFilter
- subscribe_getChangesByFilterId
- WebSocket API subscribes to new events via a WebSocket connection. When a new event occurs, it is automatically pushed to the client through callbacks. The subscription ends if the connection is broken.
Note
WebSocket APIs require "ws" or "wss" RPC endpoints and cannot be used with HTTP.
The WebSocket API subscribe_subscribe
supports the following events:
- newSnapshotBlock
- newAccountBlock
- newAccountBlockByAddress
- newUnreceivedBlockByAddress
- newVmLog
Note: Events may be reverted. If an event is reverted, the removed
field of the event is set to true
.
Tip
Add the "subscribe" namespace to "PublicModules" and set "SubscribeEnabled": true
in node_config.json
to enable subscription APIs
Topics
Topics are 32-byte event signatures or indexed parameters of a smart contract. For a non-anonymous Solidity++ event, the first topic is the event signature, and the rest (if any) are encoded indexed fields.
Topics are often used to search for specific event logs.
Topic Matching Rules
[]
matches all event logs[[A]]
matches event logs with "A" as the first topic[[], [B]]
matches event logs with "B" as the second topic[[A], [B]]
matches event logs with "A" as the first topic and "B" as the second topic[[A, B], [C, D]]
matches event logs with "A" or "B" as the first topic, and "C" or "D" as the second topic[[A, B], [C, D], [E]]
matches event logs with "A" or "B" as the first topic, "C" or "D" as the second topic, and "E" as the third topic[[T11, T12, ... , T1M], [T21, T22, ... , T2M], ... , [TN1, TN2, ... , TNM]]
matches event logs with T11, T12 ... or T1M as the first topic, T21, T22 ... or T2M as the second topic, ... and TN1, TN2 ... or TNM as the N topic (N <= 4)
Note
Solidity++ allows a maximum of 4 topics, including one event signature and three indexed parameters
Tip
Use an SDK like Vite.js to generate topic filters
Example
Assume address "vite_f48f811a1800d9bde268e3d2eacdc4b4f8b9110e017bd7a76f" is a smart contract and we want to obtain its event logs.
Using WebSocket API
Create a newVmLog
subscription on the contract address by calling subscribe_subscribe
with event type newVmLog
.
{
"jsonrpc": "2.0",
"id": 1,
"method": "subscribe_subscribe",
"params": [
"newVmLog",
{
"addressHeightRange": {
"vite_f48f811a1800d9bde268e3d2eacdc4b4f8b9110e017bd7a76f": {
"fromHeight": "0",
"toHeight": "0"
}
}
}
]
}
subscribe_subscription
{
"jsonrpc": "2.0",
"method": "subscribe_subscription",
"params": {
"subscription": "0x4b97e0674a5ebef942dbb07709c4a608",
"result": [
{
"vmlog": {
"topics": [
"aa65281f5df4b4bd3c71f2ba25905b907205fce0809a816ef8e04b4d496a85bb",
"000000000000000000000000bb6ad02107a4422d6a324fd2e3707ad53cfed935"
],
"data": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo="
},
"accountBlockHash": "23ea04b0dea4b9d0aa4d1f84b246b298a30faba753fa48303ad2deb29cd27f40",
"accountBlockHeight": "10",
"address": "vite_f48f811a1800d9bde268e3d2eacdc4b4f8b9110e017bd7a76f",
"removed": false
}
]
}
}
Tip
A broken network connection may cause the WebSocket subscription to close accidentally. In this situation, you should resume the subscription first. To get the missing blocks or events, call the corresponding Ledger API ledger_getSnapshotBlocks
, ledger_getAccountBlocks
, ledger_getUnreceivedBlocksByAddress
, or ledger_getVmLogsByFilter
to fetch the missing blocks during the downtime.
Using Polling API
First, create a filter for the contract address
{
"jsonrpc": "2.0",
"id": 1,
"method": "subscribe_newVmLogFilter",
"params": [
{
"addressHeightRange": {
"vite_f48f811a1800d9bde268e3d2eacdc4b4f8b9110e017bd7a76f": {
"fromHeight": "0",
"toHeight": "0"
}
}
}
]
}
subscribe_getChangesByFilterId
to poll for new events with the filter id
{
"jsonrpc": "2.0",
"id": 2,
"method": "subscribe_getChangesByFilterId",
"params": [
"0x61d780619649fb0872e1f94a40cec713"
]
}
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"result": [
{
"vmlog": {
"topics": [
"96a65b1cd08da045d0318cafda7b8c8436092851d5a4b7e75054c005a296e3fb",
"0000000000000000000000ab24ef68b84e642c0ddca06beec81c9acb1977bb00"
],
"data": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN4Lazp2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAF"
},
"accountBlockHash": "802b82821ec52bdadb8b79a53363bf2f90645caef95a83c34af20c640a6c320b",
"accountBlockHeight": "10",
"address": "vite_f48f811a1800d9bde268e3d2eacdc4b4f8b9110e017bd7a76f",
"removed": false
}
],
"subscription": "0x61d780619649fb0872e1f94a40cec713"
}
}
subscribe_getChangesByFilterId
is not called for more than 5 minutes, the filter will expire. Always remember to call the API within every 5 minutes to keep it alive.
Additionally, we can call subscribe_uninstallFilter
to stop a filter if necessary.
{
"jsonrpc": "2.0",
"id": 1,
"method": "subscribe_uninstallFilter",
"params": [
"0x61d780619649fb0872e1f94a40cec713"
]
}
subscribe_newSnapshotBlockFilter
Create a filter for new snapshot blocks.
-
Parameters: none
-
Returns:
string
Filter Id
Example
subscribe_newAccountBlockFilter
Create a filter for new transactions (account blocks) for all accounts
-
Parameters: none
-
Returns:
string
Filter Id
Example
subscribe_newAccountBlockByAddressFilter
Create a filter for new account blocks by address
-
Parameters:
address
:address
Address of account
-
Returns:
string
Filter Id
Example
subscribe_newUnreceivedBlockByAddressFilter
Create a filter for new unreceived blocks by address
-
Parameters:
address
:address
Address of account
-
Returns:
string
Filter Id
Example
subscribe_newVmLogFilter
Create a filter for new event logs
-
Parameters:
VmLogFilterParam
addressHeightRange
:map<address, Range>
Map of address and account block height range. At least one address should be specified.fromHeight
:uint64 string
Start height.0
means starting from the latest account blocktoHeight
:uint64 string
End height.0
means no ending account block height
topics
:Array<Array<hash>>
Event topics to match. See here for details.
-
Returns:
string
Filter Id
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "subscribe_newVmLogFilter",
"params": [
{
"addressHeightRange": {
"vite_79ac3daebdfed6947c0aaeacd418eadf38a94dddefbd4acec1": {
"fromHeight": "1",
"toHeight": "0"
}
},
"topics": [
[
"360bba44e4490fae37d6444482aa67cf5ec7418850531522450c3805b8e5425c",
"1d8e14596183a6d73bc8760a43cdaf6992e6cb318cecec67f4b6bcb31fe039d5"
],
[
"91ac0b2bf8c6dc8d37d0bc48a0eacaf6a7ed5bec9be59086116c6f23eca8aaf0",
"3adaf70d6a60eba6aaa6a1884c382ae32b223557ccaa2f3fcab6aec6c2fca21f"
]
]
}
]
}
subscribe_uninstallFilter
Uninstall the filter and stop subscription
-
Parameters:
string
Filter id
-
Returns:
bool
true
means the subscription is stopped
Example
subscribe_getChangesByFilterId
Poll for new snapshot blocks, account blocks, unreceived blocks, or event logs by filter id. Returns an empty array if no update.
-
Parameters:
string
Filter id
-
Returns for case
subscribe_newSnapshotBlockFilter
:subscription
:string
Filter idresult
:Array<SnapshotBlockMessage>
hash
:hash
Hash of snapshot blockheight
:uint64 string
Height of snapshot blockremoved
:bool
true
means the snapshot block was reverted. For new snapshot blocks, the field isfalse
-
Returns for case
subscribe_newAccountBlockFilter
:subscription
:string
Filter idresult
:Array<AccountBlockMessage>
hash
:hash
Hash of account blockremoved
:bool
true
means the account block was reverted. For new account block, the field isfalse
-
Returns for case
subscribe_newAccountBlockByAddressFilter
:subscription
:string
Filter idresult
:Array<AccountBlockWithHeightMessage>
hash
:hash
Hash of account blockheight
:uint64 string
Height of account blockremoved
:bool
true
means the account block was reverted. For new account block, the field isfalse
-
Returns for case
subscribe_newUnreceivedBlockByAddressFilter
:subscription
:string
Filter idresult
:Array<UnreceivedBlockMessage>
hash
:hash
Hash of unreceived blockreceived
:bool
true
means the block has been receivedremoved
:bool
true
means the unreceived block was reverted. For new unreceived blocks, bothremoved
andreceived
isfalse
.
-
Returns for case
subscribe_newVmLogFilter
:subscription
:string
Filter idresult
:Array<VmlogMessage>
accountBlockHash
:hash
Hash of account blockaccountBlockHeight
:uint64 string
Height of account blockaddress
:address
Address of accountvmlog
:VmLog
Event logstopics
:Array<hash>
Event signature and indexed fieldsdata
:base64
Encoded non-indexed parameters in base64 format
removed
:bool
true
means the event log was reverted
Example
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"result": [
{
"hash": "5d47f2e0a532923f7ee53e7b465381f197a669e86155d541b3b7f3d63f07a0e2",
"height": "124",
"removed": false
},
{
"hash": "78b19cb84ac293d4af3f36e741938929f6d3311362e1265e87bbaa74e5fcef09",
"height": "125",
"removed": false
},
{
"hash": "94437996b3e70afd5d8593e2020ae56f63dbbc538df1ead1633340393bd52c1a",
"height": "126",
"removed": false
}
],
"subscription": "0xf90906914486a9c22d620e50022b38d5"
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"result": [
{
"hash": "9cc9ba996a4192e35ddbfe3ba448611fc06f6342463e21d3300e58e9772b348f",
"removed": false
},
{
"hash": "8b9f8067ef09aa09c8f9d652f0d9ac5e99d083722089a6d91323cffd8b2dcf08",
"removed": false
}
],
"subscription": "0xf90906914486a9c22d620e50022b38d5"
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"result": [
{
"hash": "72ec861cb2f6c32a48632407f3aa1b05d5ad450ef75fa7660dd39d7be6d3ab68",
"received": false,
"removed": false
},
{
"hash": "72ec861cb2f6c32a48632407f3aa1b05d5ad450ef75fa7660dd39d7be6d3ab68",
"received": true,
"removed": false
},
{
"hash": "72ec861cb2f6c32a48632407f3aa1b05d5ad450ef75fa7660dd39d7be6d3ab68",
"received": false,
"removed": true
}
],
"subscription": "0xf90906914486a9c22d620e50022b38d5"
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"result": [
{
"vmlog": {
"topics": [
"aa65281f5df4b4bd3c71f2ba25905b907205fce0809a816ef8e04b4d496a85bb",
"000000000000000000000000bb6ad02107a4422d6a324fd2e3707ad53cfed935"
],
"data": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo="
},
"accountBlockHash": "de8cd1dc188fd4bf44c0cb90958ffbcccab5766840d56f7b35443a1a1c5c9d3e",
"accountBlockHeight": "10",
"address": "vite_78926f48bccef67a3b9cc64fdfe864f2a708ebce1d0bbe9aef",
"removed": false
}
],
"subscription": "0xf90906914486a9c22d620e50022b38d5"
}
}
subscribe_subscribe
This WebSocket API should be used with the following event types. A single callback returns up to 128 blocks or logs.
newSnapshotBlock
Subscribe to new snapshot blocks. New snapshot blocks will be returned in callback
-
Parameters: none
-
Returns:
string
Subscription id
-
Callback:
subscription
:string
Subscription idresult
:Array<SnapshotBlockMessage>
hash
:hash
Hash of snapshot blockheight
:uint64 string
Height of snapshot blockremoved
:bool
true
means the snapshot block was reverted. For new snapshot block, the field isfalse
Example
newAccountBlock
Subscribe to new account blocks. New account blocks will be returned in callback
-
Parameters: none
-
Returns:
string
Subscription id
-
Callback:
subscription
:string
Subscription idresult
:Array<AccountBlockMessage>
hash
:hash
Hash of account blockremoved
:bool
true
means the account block was reverted. For new account block, the field isfalse
Example
newAccountBlockByAddress
Subscribe to new account blocks by address. New account blocks will be returned in callback
- Parameters:
-
address
Address of account -
Returns:
string
Subscription id
-
Callback:
subscription
:string
Subscription idresult
:Array<AccountBlockWithHeightMessage>
hash
:hash
Hash of account blockheight
:uint64 string
Height of account blockremoved
:bool
true
means the account block was reverted. For new account block, the field isfalse
Example
newUnreceivedBlockByAddress
Subscribe to unreceived blocks by address. New unreceived blocks will be returned in callback
- Parameters:
-
address
Address of account -
Returns:
string
Subscription id
-
Callback:
subscription
:string
Subscription idresult
:Array<UnreceivedBlockMessage>
hash
:string hash
Hash of unreceived blockreceived
:bool
true
means the block was receivedremoved
:bool
true
means the unreceived block was reverted. For new unreceived blocks, bothremoved
andreceived
isfalse
.
Example
newVmLog
Subscribe to smart contract event logs. New event logs will be returned in callback
-
Parameters:
VmLogFilterParam
addressHeightRange
:map<address, Range>
Map of address and account block height range. At least one address should be specified.fromHeight
:uint64 string
Start height.0
means starting from the latest account blocktoHeight
:uint64 string
End height.0
means no ending account block height
topics
:Array<Array<hash>>
Event topics to match. See here for details.
-
Returns:
string
Subscription id
-
Callback:
subscription
:string
Subscription idresult
:Array<VmlogMessage>
accountBlockHash
:hash
Hash of account blockaccountBlockHeight
:uint64 string
Height of account blockaddress
:address
Address of accountvmlog
:VmLog
Event logstopics
:Array<hash>
Event signature and indexed fieldsdata
:base64
Encoded non-indexed parameters in base64 string
removed
:bool
true
means the event log was reverted
Example
{
"jsonrpc": "2.0",
"method": "subscribe_subscription",
"params": {
"subscription": "0x4b97e0674a5ebef942dbb07709c4a608",
"result": [
{
"vmlog": {
"topics": [
"aa65281f5df4b4bd3c71f2ba25905b907205fce0809a816ef8e04b4d496a85bb",
"000000000000000000000000bb6ad02107a4422d6a324fd2e3707ad53cfed935"
],
"data": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo="
},
"accountBlockHash": "23ea04b0dea4b9d0aa4d1f84b246b298a30faba753fa48303ad2deb29cd27f40",
"accountBlockHeight": "10",
"address": "vite_f48f811a1800d9bde268e3d2eacdc4b4f8b9110e017bd7a76f",
"removed": false
}
]
}
}