Event Query and Subscription
IOTA full nodes support publish/subscribe using JSON-RPC notifications via the WebSocket API. You can use this service with IOTA client to filter and subscribe to a real-time event stream generated from Move or from the IOTA network.
The client provides an event filter to limit the scope of events. IOTA returns a notification with the event data and subscription ID for each event that matches the filter.
Event types
An IOTA node emits the following types of events:
- Move event
- Publish event
- Transfer object event
- Delete object event
- New object event
- Epoch change event
Move event
Move calls emit Move events. You can define custom events in Move contracts.
Attributes
Move event attributes:
packageId
transactionModule
sender
type
fields
bcs
Example Move event
{
"moveEvent": {
"packageId": "<PACKAGE-ID>",
"transactionModule": "nft",
"sender": "0x008e9c621f4fdb210b873aab59a1e5bf32ddb1d33ee85eb069b348c234465106",
"type": "<PACKAGE-ID>::nft::MintNFTEvent",
"fields": {
"creator": "0x008e9c621f4fdb210b873aab59a1e5bf32ddb1d33ee85eb069b348c234465106",
"name": "NFT",
"object_id": "0x727b37454ab13d5c1dbb22e8741bff72b145d1e660f71b275c01f24e7860e5e5"
},
"bcs": "SXkTpH3AAoqF8kxw2CWZG3HGAAFwYT9PF64TY/en5yUdqrXFsG9owQtFeGFtcGxlIE5GVA=="
}
}
Publish event
Publish events occur when you publish a package to the network.
Attributes
Publish event attributes:
sender
packageId
Example publish event
{
"publish": {
"sender": "0x008e9c621f4fdb210b873aab59a1e5bf32ddb1d33ee85eb069b348c234465106",
"packageId": "0x5f01a29887a1d95e5b548b616da63b0ce07d816e89ef7b9a382177b4422bbaa2"
}
}
Transfer object event
Transfer object events occur when you transfer an object from one address to another.
Attributes
Transfer event attributes:
packageId
transactionModule
sender
recipient
objectId
version
type
Example transfer object event
{
"transferObject": {
"packageId": "0x0000000000000000000000000000000000000000000000000000000000000002",
"transactionModule": "native",
"sender": "0x008e9c621f4fdb210b873aab59a1e5bf32ddb1d33ee85eb069b348c234465106",
"recipient": {
"AddressOwner": "0xa3c00467938b392a12355397bdd3d319cea5c9b8f4fc9c51b46b8e15a807f030"
},
"objectId": "0x727b37454ab13d5c1dbb22e8741bff72b145d1e660f71b275c01f24e7860e5e5",
"version": 1,
"type": "Coin"
}
}
Delete object event
Delete object events occur when you delete an object.
Attributes
packageId
transactionModule
sender
objectId
Example delete object event
{
"deleteObject": {
"packageId": "0x5f01a29887a1d95e5b548b616da63b0ce07d816e89ef7b9a382177b4422bbaa2",
"transactionModule": "discount_coupon",
"sender": "0x008e9c621f4fdb210b873aab59a1e5bf32ddb1d33ee85eb069b348c234465106",
"objectId": "0x727b37454ab13d5c1dbb22e8741bff72b145d1e660f71b275c01f24e7860e5e5"
}
}
New object event
New object events occur when you create an object on the network.
Attributes
New object event attributes:
packageId
transactionModule
sender
recipient
objectId
Example new object event
{
"newObject": {
"packageId": "<PACKAGE-ID>",
"transactionModule": "nft",
"sender": "0x008e9c621f4fdb210b873aab59a1e5bf32ddb1d33ee85eb069b348c234465106",
"recipient": {
"AddressOwner": "0xa3c00467938b392a12355397bdd3d319cea5c9b8f4fc9c51b46b8e15a807f030"
},
"objectId": "0x727b37454ab13d5c1dbb22e8741bff72b145d1e660f71b275c01f24e7860e5e5"
}
}
Epoch change event
Epoch change events occur when an epoch ends and a new epoch starts.
Attributes
None, Epoch change events do not have any attributes. The event includes an Epoch ID associated with the epochChange
.
Example epoch change event
{
"epochChange": 20
}
Checkpoint event
A checkpoint event occurs for each checkpoint.
Attributes
None, Checkpoint events do not have any attributes. The event includes the Checkpoint sequence number associated with the checkpoint.
Example checkpoint event
{
"checkpoint": 10
}
IOTA event query criteria
You can use the EventQuery
criteria object to query an IOTA node and retrieve events that match query criteria.
Query | Description | JSON-RPC Parameter Example |
---|---|---|
All | All events | {"All"} |
Transaction | Events emitted from the specified transaction. | {"Transaction":"DGUe2TXiJdN3FI6MH1FwghYbiHw+NKu8Nh579zdFtUk="} |
MoveModule | Events emitted from the specified Move module | {"MoveModule":{"package":"<PACKAGE-ID>", "module":"nft"}} |
MoveEvent | Move struct name of the event | {"MoveEvent":"<PACKAGE-ID>::nft::MintNFTEvent"} |
EventType | Type of event described in Events section | {"EventType": "NewObject"} |
Sender | Query by sender address | {"Sender":"0x008e9c621f4fdb210b873aab59a1e5bf32ddb1d33ee85eb069b348c234465106"} |
Recipient | Query by recipient | {"Recipient":{"AddressOwner":"0xa3c00467938b392a12355397bdd3d319cea5c9b8f4fc9c51b46b8e15a807f030"}} |
Object | Return events associated with the given object | {"Object":"0x727b37454ab13d5c1dbb22e8741bff72b145d1e660f71b275c01f24e7860e5e5"} |
TimeRange | Return events emitted in [start_time, end_time] interval | {"TimeRange":{"startTime":1669039504014, "endTime":1669039604014}} |
Pagination
The Event Query API provides cursor-based pagination to make it easier to work with large result sets. You can provide a cursor
parameter in paginated query to indicate the starting position of the query. The query returns the number of results specified by limit
, and returns the next_cursor
value when there are additional results. The maximum limit
is 1000 per query.
The following examples demonstrate how to create queries that use pagination for the results.
1. Get all events an nft module emits, in descending time order
Request
curl --location --request POST '127.0.0.1:9000' \
--header 'Content-Type: application/json' \
--data-raw '{
"jsonrpc": "2.0",
"id": 1,
"method": "iota_getEvents",
"params": [
{"MoveModule":{"package":"<PACKAGE-ID>", "module":"nft"}},
null,
null,
true
]
}'
Response
{
"jsonrpc": "2.0",
"result": {
"data": [
{
"timestamp": 1666699837426,
"txDigest": "cZXsToU6r0Uia6HIAwvr1eMlGsrg6b9+2oYZAskJ0wc=",
"id": {
"txSeq": 1001,
"eventSeq": 1
},
"event": {
"moveEvent": {
"packageId": "<PACKAGE-ID>",
"transactionModule": "nft",
"sender": "0x008e9c621f4fdb210b873aab59a1e5bf32ddb1d33ee85eb069b348c234465106",
"type": "<PACKAGE-ID>::nft::MintNFTEvent",
"fields": {
"creator": "0x008e9c621f4fdb210b873aab59a1e5bf32ddb1d33ee85eb069b348c234465106",
"name": "NFT",
"object_id": "0x727b37454ab13d5c1dbb22e8741bff72b145d1e660f71b275c01f24e7860e5e5"
},
"bcs": "LugLSi0gM2XfvWipCorZoNyhkVX+1JBtcbilg//9jpVnYCe2u4HXzwtFeGFtcGxlIE5GVA=="
}
}
},
{
"timestamp": 1666699837426,
"txDigest": "cZXsToU6r0Uia6HIAwvr1eMlGsrg6b9+2oYZAskJ0wc=",
"id": {
"txSeq": 1001,
"eventSeq": 0
},
"event": {
"newObject": {
"packageId": "<PACKAGE-ID>",
"transactionModule": "nft",
"sender": "0x008e9c621f4fdb210b873aab59a1e5bf32ddb1d33ee85eb069b348c234465106",
"recipient": {
"AddressOwner": "0xa3c00467938b392a12355397bdd3d319cea5c9b8f4fc9c51b46b8e15a807f030"
},
"objectId": "0x727b37454ab13d5c1dbb22e8741bff72b145d1e660f71b275c01f24e7860e5e5"
}
}
},
{
"timestamp": 1666698739180,
"txDigest": "WF2V6FM6y/kpAgRqzsQmR/osy4pmTgVVbE6qvSJxWh4=",
"id": {
"txSeq": 998,
"eventSeq": 1
},
"event": {
"moveEvent": {
"packageId": "<PACKAGE-ID>",
"transactionModule": "nft",
"sender": "0x008e9c621f4fdb210b873aab59a1e5bf32ddb1d33ee85eb069b348c234465106",
"type": "<PACKAGE-ID>::nft::MintNFTEvent",
"fields": {
"creator": "0x008e9c621f4fdb210b873aab59a1e5bf32ddb1d33ee85eb069b348c234465106",
"name": "NFT",
"object_id": "0x727b37454ab13d5c1dbb22e8741bff72b145d1e660f71b275c01f24e7860e5e5"
},
"bcs": "1WV89qyrqVjFsB7AUW9PDax3x9L+1JBtcbilg//9jpVnYCe2u4HXzwtFeGFtcGxlIE5GVA=="
}
}
},
{
"timestamp": 1666698739180,
"txDigest": "WF2V6FM6y/kpAgRqzsQmR/osy4pmTgVVbE6qvSJxWh4=",
"id": {
"txSeq": 998,
"eventSeq": 0
},
"event": {
"newObject": {
"packageId": "<PACKAGE-ID>",
"transactionModule": "nft",
"sender": "0x008e9c621f4fdb210b873aab59a1e5bf32ddb1d33ee85eb069b348c234465106",
"recipient": {
"AddressOwner": "0xa3c00467938b392a12355397bdd3d319cea5c9b8f4fc9c51b46b8e15a807f030"
},
"objectId": "0x727b37454ab13d5c1dbb22e8741bff72b145d1e660f71b275c01f24e7860e5e5"
}
}
}
],
"nextCursor": null
},
"id": 1
}
2. Get all MintNFTEvent events
Request
curl --location --request POST '127.0.0.1:9000' \
--header 'Content-Type: application/json' \
--data-raw '{
"jsonrpc": "2.0",
"id": 1,
"method": "iota_getEvents",
"params": [
{"MoveEvent":"<PACKAGE-ID>::nft::MintNFTEvent"},
null,
null,
"Ascending"
]
}'
Response
{
"jsonrpc": "2.0",
"result": {
"data": [
{
"timestamp": 1666699837426,
"txDigest": "cZXsToU6r0Uia6HIAwvr1eMlGsrg6b9+2oYZAskJ0wc=",
"id": {
"txSeq": 1001,
"eventSeq": 1
},
"event": {
"moveEvent": {
"packageId": "<PACKAGE-ID>",
"transactionModule": "nft",
"sender": "0x008e9c621f4fdb210b873aab59a1e5bf32ddb1d33ee85eb069b348c234465106",
"type": "<PACKAGE-ID>::nft::MintNFTEvent",
"fields": {
"creator": "0x008e9c621f4fdb210b873aab59a1e5bf32ddb1d33ee85eb069b348c234465106",
"name": "NFT",
"object_id": "0x727b37454ab13d5c1dbb22e8741bff72b145d1e660f71b275c01f24e7860e5e5"
},
"bcs": "LugLSi0gM2XfvWipCorZoNyhkVX+1JBtcbilg//9jpVnYCe2u4HXzwtFeGFtcGxlIE5GVA=="
}
}
},
{
"timestamp": 1666698739180,
"txDigest": "WF2V6FM6y/kpAgRqzsQmR/osy4pmTgVVbE6qvSJxWh4=",
"id": {
"txSeq": 998,
"eventSeq": 1
},
"event": {
"moveEvent": {
"packageId": "<PACKAGE-ID>",
"transactionModule": "nft",
"sender": "0x008e9c621f4fdb210b873aab59a1e5bf32ddb1d33ee85eb069b348c234465106",
"type": "<PACKAGE-ID>::nft::MintNFTEvent",
"fields": {
"creator": "0x008e9c621f4fdb210b873aab59a1e5bf32ddb1d33ee85eb069b348c234465106",
"name": "NFT",
"object_id": "0x727b37454ab13d5c1dbb22e8741bff72b145d1e660f71b275c01f24e7860e5e5"
},
"bcs": "1WV89qyrqVjFsB7AUW9PDax3x9L+1JBtcbilg//9jpVnYCe2u4HXzwtFeGFtcGxlIE5GVA=="
}
}
}
],
"nextCursor": null
},
"id": 1
}
3. Get all events and return 2 items per page in descending time order
Request
curl --location --request POST '127.0.0.1:9000' \
--header 'Content-Type: application/json' \
--data-raw '{
"jsonrpc": "2.0",
"id": 1,
"method": "iota_getEvents",
"params": [
"All",
null,
2,
"Ascending"
]
}'
Response
{
"jsonrpc": "2.0",
"result": {
"data": [
{
"timestamp": 1666698739180,
"txDigest": "WF2V6FM6y/kpAgRqzsQmR/osy4pmTgVVbE6qvSJxWh4=",
"id": {
"txSeq": 998,
"eventSeq": 0
},
"event": {
"newObject": {
"packageId": "<PACKAGE-ID>",
"transactionModule": "nft",
"sender": "0x008e9c621f4fdb210b873aab59a1e5bf32ddb1d33ee85eb069b348c234465106",
"recipient": {
"AddressOwner": "0xa3c00467938b392a12355397bdd3d319cea5c9b8f4fc9c51b46b8e15a807f030"
},
"objectId": "0x727b37454ab13d5c1dbb22e8741bff72b145d1e660f71b275c01f24e7860e5e5"
}
}
},
{
"timestamp": 1666698739180,
"txDigest": "WF2V6FM6y/kpAgRqzsQmR/osy4pmTgVVbE6qvSJxWh4=",
"id": {
"txSeq": 998,
"eventSeq": 1
},
"event": {
"moveEvent": {
"packageId": "<PACKAGE-ID>",
"transactionModule": "nft",
"sender": "0x008e9c621f4fdb210b873aab59a1e5bf32ddb1d33ee85eb069b348c234465106",
"type": "<PACKAGE-ID>::nft::MintNFTEvent",
"fields": {
"creator": "0x008e9c621f4fdb210b873aab59a1e5bf32ddb1d33ee85eb069b348c234465106",
"name": "NFT",
"object_id": "0x727b37454ab13d5c1dbb22e8741bff72b145d1e660f71b275c01f24e7860e5e5"
},
"bcs": "1WV89qyrqVjFsB7AUW9PDax3x9L+1JBtcbilg//9jpVnYCe2u4HXzwtFeGFtcGxlIE5GVA=="
}
}
}
],
"nextCursor": 3
},
"id": 1
}
Subscribe to IOTA events
When you subscribe to the events described in the preceding sections, you can apply event filters to match the events you want to filter.
Event filters
You can use EventFilter
to filter the events included in your subscription to the event stream. EventFilter
supports filtering on one attribute or a combination of attributes.
List of attributes that support filters
Filter | Description | Applicable to Event Type | JSON-RPC Parameter Example |
---|---|---|---|
Package | Move package ID | MoveEvent Publish TransferObject DeleteObject NewObject | {"Package":"<PACKAGE-ID>"} |
Module | Move module name | MoveEvent TransferObject DeleteObject NewObject | {"Module":"nft"} |
MoveEventType | Move event type defined in the move code | MoveEvent | {"MoveEventType":"<PACKAGE-ID>::nft::MintNFTEvent"} |
MoveEventField | Filter using the data fields in the move event object | MoveEvent | {"MoveEventField":{ "path":"/name", "value":"NFT"}} |
SenderAddress | Address that started the transaction | MoveEvent Publish TransferObject DeleteObject NewObject | {"SenderAddress": "0x008e9c621f4fdb210b873aab59a1e5bf32ddb1d33ee85eb069b348c234465106"} |
EventType | Type of event described in the Events section | MoveEvent Publish TransferObject DeleteObject NewObject EpochChange Checkpoint | {"EventType":"Publish"} |
ObjectId | Object ID | TransferObject DeleteObject NewObject | {"ObjectId":"0x727b37454ab13d5c1dbb22e8741bff72b145d1e660f71b275c01f24e7860e5e5"} |
Combining filters
IOTA provides a few operators for combining filters:
Operator | Description | JSON-RPC Parameter Example |
---|---|---|
And | Combine two filters; behaves the same as boolean And operator | {"And":[{"Package":"<PACKAGE-ID>"}, {"Module":"nft"}]} |
Or | Combine two filters; behaves the same as boolean Or operator | {"Or":[{"Package":"<PACKAGE-ID>"}, {"Package":"0x1"}]} |
All | Combine a list of filters; returns true if all filters match the event | {"All":[{"EventType":"MoveEvent"}, {"Package":"<PACKAGE-ID>"}, {"Module":"nft"}]} |
Any | Combine a list of filters; returns true if any filter matches the event | {"Any":[{"EventType":"MoveEvent"}, {"EventType":"TransferObject"}, {"EventType":"DeleteObject"}]} |
Example using a combined filter
The following example demonstrates how to subscribe to Move events (MoveEvent
) that a <PACKAGE-ID>::nft
package emits:
>> {"jsonrpc":"2.0", "id": 1, "method": "iota_subscribeEvent", "params": [{"All":[{"EventType":"MoveEvent"}, {"Package":"<PACKAGE-MODULE-ID>"}, {"Module":"nft"}]}]}
<< {"jsonrpc":"2.0","result":3121662727959200,"id":1}
To unsubscribe from this stream, use:
>> {"jsonrpc":"2.0", "id": 1, "method": "iota_unsubscribeEvent", "params": [3121662727959200]}
<< {"jsonrpc":"2.0","result":true,"id":1}
The subscribeEvent
and subscribeTransaction
methods are deprecated. Please use queryEvents
and queryTransactionBlocks
instead.