Reading
Transaction reader
After broadcasting, confirm what actually landed on chain. The reader fetches a transaction, locates its custom_json operations and decodes them into typed events.
Read a transactionRead by id
TypeScript
const read = await hive.reader.transaction({
transactionId: "b1e2...",
id: "my-application", // optional custom_json id filter
actions: ["claim"], // optional standardized action filter
});
// every operation, in blockchain order
for (const operation of read.operations) {
console.log(operation.operationIndex, operation.kind, operation.operationType);
}
// derived views
read.customJson; // standardized Custom JSON events
read.payments; // native + Layer 2 payments, triggers already associated
read.nfts; // Hive Engine NFT actionsOperations that match the id filter but break the payload protocol are never thrown — they land in invalid with a reason, so one malformed transaction cannot break a batch. Operations the SDK does not interpret are reported as kind: "unknown" instead of being dropped.
Result shape
| Parameter | Type | Required | Description |
|---|---|---|---|
| transactionId | string | No | The transaction that was read. |
| blockNumber | number | No | Block containing the transaction. |
| blockTimestamp | string | No | Block timestamp in ISO form. |
| transactionIndex | number | null | No | Position of the transaction inside its block. |
| operations | TransactionOperationResult<T>[] | No | Every operation in blockchain order, tagged custom_json / payment / nft / unknown. |
| customJson | CustomJsonEvent<T>[] | No | Decoded, protocol-valid Custom JSON events. |
| payments | ParsedPayment<T>[] | No | Payments with triggers associated. Layer 2 stays pending until verified. |
| nfts | NormalizedNftOperation[] | No | Hive Engine NFT issue / transfer / burn actions. |
| invalid | { reason, raw }[] | No | Matching operations that failed validation. |
| raw | unknown | No | Untouched RPC response. |
Run a live stream
Reading by id is a one-shot lookup. To keep watching the chain, use the same reader in streaming mode — one block loop shared by every filter you register.
TypeScript
// multi-filter dispatcher over the single block stream
const stream = hive.reader.stream({ fromBlock: 90_000_000 });
stream.customJson({
id: "my-application",
actions: ["claim"],
handler: (event) => console.log(event.blockNumber, event.action, event.metadata),
});
stream.payment({
account: "my-shop",
handler: (payment) => fulfilOrder(payment.trigger?.metadata),
onFailed: (payment) => console.warn(payment.error),
});
await stream.start(); // starts reading blocks
stream.stop(); // ends the loopPrefer async iteration? The same engine is exposed as iterators: hive.blocks.watch(), hive.customJson.watch() and hive.payments.watch().
TypeScript
const controller = new AbortController();
for await (const event of hive.customJson.watch({
id: "my-application",
actions: ["claim"],
signal: controller.signal,
})) {
console.log(event.blockNumber, event.action, event.metadata);
}