@qubic.org/registry
Versioned ABI registry and binary payload codec for Qubic smart contracts.
Introduction
What is an ABI?
A Qubic smart contract exposes procedures (write functions, called via transactions) and functions (read functions, called via queries). Each has a list of typed binary fields — the ABI. The ABI describes how to pack inputs into bytes and unpack output bytes into named values.
@qubic.org/registry stores a snapshot of each contract's ABI for every epoch where it changed, so you can encode/decode correctly even for historical transactions.
Epoch versioning
An ABI version is valid from effectiveFromEpoch until effectiveToEpoch (or indefinitely if effectiveToEpoch is null). getAbi(registry, contractIndex, epoch) finds the version whose range covers the requested epoch.
Static import vs HTTP client
Two ways to load the registry:
- Static import — bundle the JSON with your app. No network, works offline, always consistent. Best for production apps.
- Registry client (
createRegistryClient()) — fetch ABIs on demand from a remote API. Smaller bundle, always up-to-date, works well in browsers where bundle size matters.
For most use cases, use @qubic.org/contracts
@qubic.org/contracts wraps this package with generated TypeScript for every contract. You only need @qubic.org/registry directly when working with historical epochs not covered by the generated wrappers, or when building tooling.
Installation
bun add @qubic.org/registrynpm install @qubic.org/registrypnpm add @qubic.org/registryIndexed contracts
| Index | Name | Procedures | Functions | |
|---|---|---|---|---|
| 1 | Qx | 7 | 5 | |
| 2 | Quottery | 17 | 8 | |
| 3 | Random | 1 | 0 | |
| 4 | QUtil | 13 | 9 | |
| 5 | MyLastMatch | 0 | 0 | |
| 6 | GeneralQuorumProposal | 2 | 5 | |
| 7 | SupplyWatcher | 0 | 0 | |
| 8 | ComputorControlledFund | 2 | 7 | |
| 9 | Qearn | 2 | 8 | |
| 10 | QVAULT | 12 | 20 | |
| 11 | MsVault | 9 | 16 | |
| 12 | Qbay | 17 | 9 | |
| 13 | Qswap | 11 | 8 | |
| 14 | Nostromo | 9 | 10 | |
| 15 | Qdraw | 1 | 2 | |
| 16 | RandomLottery | 3 | 10 | |
| 17 | QBond | 8 | 8 | |
| 18 | QIP | 3 | 1 | |
| 19 | QRaffle | 8 | 9 | |
| 20 | qRWA | 6 | 14 | |
| 21 | QReservePool | 4 | 2 | |
| 22 | QThirtyFour | 8 | 11 | |
| 23 | QDuel | 7 | 6 | |
| 24 | Pulse | 13 | 14 | |
| 25 | VottunBridge | 8 | 7 | |
| 26 | Qusino | 8 | 5 | |
| 27 | Escrow | 5 | 2 | |
| 27 contracts active · registry last updated May 16, 2026 | ||||
API reference
| Page | What's covered |
|---|---|
| Functions | getAbi, getCurrentAbi, getAbiHistory, getProcedure, getFunction, findContractByIndex, findContractByName |
| Codec | buildPayload, decodePayload — binary encoding and decoding |
| Client | createRegistryClient — HTTP client with session/persistent caching |
Key exports
import {
// ABI lookup
getAbi,
getCurrentAbi,
getAbiHistory,
getProcedure,
getFunction,
findContractByIndex,
findContractByName,
validateRegistry,
// Codec
buildPayload,
decodePayload,
// HTTP client
createRegistryClient,
} from "@qubic.org/registry"Examples
Look up a contract ABI and encode a payload
import { getAbi, getProcedure, buildPayload } from "@qubic.org/registry"
import { identityToPublicKey } from "@qubic.org/crypto"
import registry from "@qubic.org/registry/registry.json"
import type { ContractRegistry } from "@qubic.org/registry"
const reg = registry as ContractRegistry
// Qearn (index 9) at epoch 212
const { version, isCurrent } = getAbi(reg, 9, 212)
const proc = getProcedure(version, 6) // lock_input (inputType 6)
const payload = buildPayload(
proc.inputFields,
version.structs ?? {},
{ amount: 10_000_000n },
identityToPublicKey,
)
console.log("Encoded payload:", payload.length, "bytes")Decode a response
import { getAbi, getFunction, decodePayload } from "@qubic.org/registry"
import { publicKeyToIdentity } from "@qubic.org/crypto"
import registry from "@qubic.org/registry/registry.json"
import type { ContractRegistry } from "@qubic.org/registry"
const reg = registry as ContractRegistry
const { version } = getAbi(reg, 9, 212)
const fn = getFunction(version, 1) // getStateOfRound
const result = decodePayload(
responseBytes,
fn.outputFields,
version.structs ?? {},
publicKeyToIdentity,
)
console.log("State:", result)Browse ABI history for a contract
import { getAbiHistory, findContractByName } from "@qubic.org/registry"
import registry from "@qubic.org/registry/registry.json"
import type { ContractRegistry } from "@qubic.org/registry"
const reg = registry as ContractRegistry
const index = findContractByName(reg, "Qearn")
for (const version of getAbiHistory(reg, index)) {
console.log(
`Epoch ${version.effectiveFromEpoch} – ${version.effectiveToEpoch ?? "current"}:`,
version.procedures?.length ?? 0, "procedures,",
version.functions?.length ?? 0, "functions",
)
}Use the HTTP client in a browser app
import { createRegistryClient, getProcedure, buildPayload } from "@qubic.org/registry"
import { identityToPublicKey } from "@qubic.org/crypto"
const client = createRegistryClient({ cache: "session" })
const { version } = await client.getCurrentAbi(9) // Qearn
const proc = getProcedure(version, 6)
const payload = buildPayload(proc.inputFields, version.structs ?? {}, { amount: 5_000_000n }, identityToPublicKey)