Decode historical event logs
Fetch and decode past transaction event logs from the archive using @qubic.org/rpc and @qubic.org/events.
The Qubic archive indexes event logs for every tick. This guide shows how to fetch logs for a specific identity or tick range and decode them into typed structures.
Prerequisites
bun add @qubic.org/rpc @qubic.org/events @qubic.org/crypto @qubic.org/typesnpm install @qubic.org/rpc @qubic.org/events @qubic.org/crypto @qubic.org/typespnpm add @qubic.org/rpc @qubic.org/events @qubic.org/crypto @qubic.org/typesFetch event logs for an identity
getEventLogs returns all logs for a given identity within an optional epoch range:
import { createQueryClient } from "@qubic.org/rpc"
import { toIdentity } from "@qubic.org/types"
const archive = createQueryClient()
const logs = await archive.getEventLogs({
identity: toIdentity("CFBMEMZOIDEXQAUXYYSZIURADQLAPWPMNJXQSNVQZAHYVOPYUKKJBJUCTVJL"),
startTick: 17_000_000,
endTick: 17_001_000,
})
console.log(`Found ${logs.events.length} events`)Each event in logs.events has eventType, eventData (base64), tick, and txId fields.
Decode events
decodeEvent from @qubic.org/events parses the base64 eventData into a typed structure:
import { decodeEvent } from "@qubic.org/events"
import { publicKeyToIdentity } from "@qubic.org/crypto"
for (const raw of logs.events) {
const decoded = decodeEvent(raw, publicKeyToIdentity)
if (!decoded) {
console.log("Unknown event type:", raw.eventType)
continue
}
console.log(`Tick ${raw.tick} — type ${decoded.eventType}:`, decoded.data)
}decodeEvent returns null for unknown event types (not yet in the decoder table). Check for null before using the result.
Filter by event type
Use eventFilter() to pre-filter before decoding:
import { eventFilter } from "@qubic.org/events"
const isQuTransfer = eventFilter().type(14).build()
const transfers = logs.events.filter(isQuTransfer)
for (const raw of transfers) {
const decoded = decodeEvent(raw, publicKeyToIdentity)
if (decoded) {
// decoded.data is typed as QuTransferData
const { sourceIdentity, destIdentity, amount } = decoded.data as { sourceIdentity: string; destIdentity: string; amount: bigint }
console.log(`${sourceIdentity} → ${destIdentity}: ${amount} QU`)
}
}Fetch transactions for an identity
For a higher-level view of an account's transaction history, use getTransactionsForIdentity from the archive client:
const txs = await archive.getTransactionsForIdentity({
identity: toIdentity("CFBMEMZOIDEXQAUXYYSZIURADQLAPWPMNJXQSNVQZAHYVOPYUKKJBJUCTVJL"),
startTick: 17_000_000,
endTick: 17_001_000,
})
for (const tx of txs.transactions) {
console.log(`TX ${tx.txId} in tick ${tx.tickNumber}: ${tx.amount} QU → ${tx.destId}`)
}Fetch a single transaction
If you have a transaction hash (e.g. from a broadcast), look it up directly:
const tx = await archive.getTransaction("your-tx-hash-here")
console.log("Source:", tx.sourceId)
console.log("Destination:", tx.destId)
console.log("Amount:", tx.amount)
console.log("Tick:", tx.tickNumber)
console.log("Status:", tx.transactionStatus)getTransaction throws QubicRpcError if the transaction is not indexed yet or the hash is unknown.
React with archive hooks
In a React app, use the archive hooks from @qubic.org/react:
import { useEventLogs, useTransactionsForIdentity, useTransaction } from "@qubic.org/react"
import { decodeEvent } from "@qubic.org/events"
import { publicKeyToIdentity } from "@qubic.org/crypto"
import { toIdentity } from "@qubic.org/types"
import type { Identity } from "@qubic.org/types"
const identity: Identity = toIdentity("CFBMEMZOIDEXQAUXYYSZIURADQLAPWPMNJXQSNVQZAHYVOPYUKKJBJUCTVJL")
function EventHistory() {
const { data, isPending } = useEventLogs({
identity,
startTick: 17_000_000,
endTick: 17_001_000,
})
if (isPending) return <p>Loading…</p>
return (
<ul>
{data?.events.map((raw) => {
const decoded = decodeEvent(raw, publicKeyToIdentity)
return (
<li key={`${raw.tick}-${raw.eventType}`}>
Tick {raw.tick} — type {raw.eventType}
{decoded && `: ${JSON.stringify(decoded.data)}`}
</li>
)
})}
</ul>
)
}Complete example
import { createQueryClient } from "@qubic.org/rpc"
import { decodeEvent, eventFilter } from "@qubic.org/events"
import { publicKeyToIdentity } from "@qubic.org/crypto"
import { toIdentity } from "@qubic.org/types"
const archive = createQueryClient()
const identity = toIdentity("CFBMEMZOIDEXQAUXYYSZIURADQLAPWPMNJXQSNVQZAHYVOPYUKKJBJUCTVJL")
const isTransfer = eventFilter().type(14).build()
const logs = await archive.getEventLogs({
identity,
startTick: 17_000_000,
endTick: 17_001_000,
})
console.log(`${logs.events.length} total events`)
for (const raw of logs.events.filter(isTransfer)) {
const decoded = decodeEvent(raw, publicKeyToIdentity)
if (decoded) {
console.log(`Tick ${raw.tick} transfer:`, decoded.data)
}
}Run it:
bun decode-history.tsEvent type reference
See the @qubic.org/events reference for a table of all 17 event types and the shape of each event's data field.