Live Events
This guide targets the Tiramisu testnet. Check Networks for current testnets and faucets.
The watchEntityEvents method on the public client lets you listen for entity changes in real time. It polls the chain for new events. When an entity is created, patched, deleted, extended, or handed to a new owner, it calls the handlers you pass.
Basic Usage
Section titled “Basic Usage”import { createPublicClient } from "@arkiv-network/sdk"import { tiramisu } from "@arkiv-network/sdk/chains"import { http } from "viem"
const client = createPublicClient({ chain: tiramisu, transport: http(),})
const unwatch = client.watchEntityEvents({ onEntityCreated: (event) => { console.log("Entity created:", event.entityKey) }, onEntityPatched: (event) => { console.log("Entity patched:", event.entityKey) }, onEntityDeleted: (event) => { console.log("Entity deleted:", event.entityKey) }, onExpiryExtended: (event) => { console.log("Expiry extended:", event.entityKey) }, onOwnershipTransferred: (event) => { console.log("Ownership transferred:", event.entityKey) }, onError: (error) => { console.error("Watch error:", error) },})
// Later, stop listening:unwatch()Parameters
Section titled “Parameters”watchEntityEvents takes one object with the event handlers plus a couple of optional settings:
| Parameter | Type | Description |
|---|---|---|
| Event handlers | see below | One callback per event type, all optional |
onEvent | (event: EntityEvent) => void | Every event, whatever its type, runs before the per-event handler |
onError | (error: Error) => void | Transport failures, undecodable logs, or a handler that throws. Defaults to console.error. |
fromBlock | bigint | Replay from this block before following the head. Defaults to the head. |
pollingInterval | number | How often to poll, in milliseconds. Defaults to half a block. |
Event Handlers
Section titled “Event Handlers”| Handler | Event Type | Fires When |
|---|---|---|
onEntityCreated | EntityCreatedEvent | A new entity is created |
onEntityPatched | EntityPatchedEvent | An entity’s attributes or payload change |
onExpiryExtended | ExpiryExtendedEvent | An entity’s expiry moves further out |
onOwnershipTransferred | OwnershipTransferredEvent | An entity changes owner |
onEntityDeleted | EntityDeletedEvent | An entity is deleted by its owner, before its expiry |
Every event carries blockNumber, transactionHash and logIndex, which together give you the order the operations were applied in.
Event Types
Section titled “Event Types”EntityCreatedEvent
Section titled “EntityCreatedEvent”{ type: "EntityCreated" entityKey: Hex owner: Address expiresAt: bigint // block the entity is set to expire at creationFlags: { readonly: boolean; permissionlessExtension: boolean } blockNumber: bigint transactionHash: Hex logIndex: number}EntityPatchedEvent
Section titled “EntityPatchedEvent”{ type: "EntityPatched" entityKey: Hex owner: Address blockNumber: bigint transactionHash: Hex logIndex: number}The event only says an entity’s attributes or payload changed, not what changed. Call getEntity() to read the new state.
ExpiryExtendedEvent
Section titled “ExpiryExtendedEvent”{ type: "ExpiryExtended" entityKey: Hex owner: Address // the entity's owner, not necessarily who extended it expiresAt: bigint // the new expiry block blockNumber: bigint transactionHash: Hex logIndex: number}OwnershipTransferredEvent
Section titled “OwnershipTransferredEvent”{ type: "OwnershipTransferred" entityKey: Hex previousOwner: Address newOwner: Address blockNumber: bigint transactionHash: Hex logIndex: number}EntityDeletedEvent
Section titled “EntityDeletedEvent”{ type: "EntityDeleted" entityKey: Hex owner: Address blockNumber: bigint transactionHash: Hex logIndex: number}Watching from a Specific Block
Section titled “Watching from a Specific Block”Use fromBlock to replay events. The replay starts from a past block:
const unwatch = client.watchEntityEvents({ onEntityCreated: (event) => { console.log("Created:", event.entityKey, "at block", event.blockNumber) }, fromBlock: 100n, pollingInterval: 5000, // poll every 5 seconds})Practical Example
Section titled “Practical Example”Listen for changes to your own entities and log a summary:
import { createPublicClient } from "@arkiv-network/sdk"import { tiramisu } from "@arkiv-network/sdk/chains"import { http } from "viem"
const client = createPublicClient({ chain: tiramisu, transport: http(),})
const MY_ADDRESS = "0xYourAddress..."
const unwatch = client.watchEntityEvents({ onEntityCreated: (event) => { if (event.owner === MY_ADDRESS) { console.log(`New entity ${event.entityKey} expires at block ${event.expiresAt}`) } }, onEntityDeleted: (event) => { if (event.owner === MY_ADDRESS) { console.log(`Entity ${event.entityKey} was deleted`) } }, onError: (error) => { console.error("Event stream error:", error) },})
// Clean up on exitprocess.on("SIGINT", () => { unwatch() process.exit()})