⚠️ Alpha · testnets only. ChainRender is in active alpha and deployed on testnets only — Ethereum Sepolia, the Robinhood Chain Testnet, and the Circle Arc Testnet — not on any mainnet. Contracts, addresses, and APIs may change. Do not use with real funds or production assets.
Reference

Reference: Node Fields (what compile() reads)

Every field the compiler encodes, per node type. It is generated from chainc/node-schema.ts — the same table behind nodeJsonSchema(), checkNode(), vocabulary().nodeTypes and the MCP chainrender_check_node tool. That table is drift-locked to compile() in both directions: the TypeScript build fails if the compiler's node type gains a field the table doesn't list, and test/node-schema.ts changes every listed field and checks the compiled bytes change.

Why check a tree before compiling. compile() is lenient on purpose: it silently drops anything it doesn't read — an unknown field, a misspelled enum value (direction: "vertical", role: "note"), a11y fields on an image, args on a batch member. The tree still compiles, and the component ships without what was written. checkNode(tree) reports each of those with its path. See The Vocabulary.

Value kinds: address = 0x + 20 bytes · bytes32 = 0x + 32 bytes · hex = 0x + whole bytes · arg = hex bytes when resolver is set, otherwise free text for a client hook · integer = whole number ≥ 1 · number|string = a positive number or the same as a decimal string · record = a string-keyed map.

text

Field Value Required Note
content string
children node[]

Also takes the accessibility fields and the behaviour fields (below).

box

Field Value Required Note
direction one of row, column
children node[]

Also takes the accessibility fields and the behaviour fields (below).

button

Field Value Required Note
variant one of primary, secondary, ghost, danger
content string
children node[]
action object declared submit — gated by the enforcer (R3-R6); the label is never a guarantee on its own
action.to address
action.sig string yes function signature, e.g. "mint(uint256)"
action.value string wei, decimal string
action.args string template the client fills, e.g. "$amount,0xSpender"
batch object[] atomic multi-action under one signature; requires BATCH_EXECUTE, each member gated individually; '|' and ';' are stripped from member fields
batch[].to address yes
batch[].sig string yes
batch[].value string wei, decimal string; defaults to 0
batch[].label string consent-list label; defaults to sig
sign object EIP-712 typed-data signature; requires SIGN_MESSAGE; decoded before signing, never a blind hex sign
sign.domain object yes
sign.domain.name string
sign.domain.version string
sign.domain.chainId integer
sign.domain.verifyingContract address
sign.primaryType string yes
sign.types record yes
sign.message record yes

Also takes the accessibility fields and the behaviour fields (below).

input

Field Value Required Note
inputType one of text, number, password, search
placeholder string
content string

Also takes the accessibility fields and the behaviour fields (below).

icon

Field Value Required Note
name string

Also takes the accessibility fields and the behaviour fields (below).

link

Field Value Required Note
href string
content string
children node[]

Also takes the accessibility fields and the behaviour fields (below).

slot

Field Value Required Note
bind string yes the resolver kind (e.g. "ensText") or a client hook name
resolver address on-chain resolver; resolved during render
arg arg 0x-hex resolver args when resolver is set (encode per the kind's descriptor); otherwise a display string a client hook reads
content string fallback text

Also takes the accessibility fields and the behaviour fields (below).

image

Field Value Required Note
bind string
resolver address
arg arg 0x-hex resolver args when resolver is set (encode per the kind's descriptor); otherwise a display string a client hook reads
alt string the image's accessible text (images take no role/label)
provenance one of inline-vector, computed, onchain-blob, hash-pointer, external, onchain-vector-nft, computed-gpu

Also takes the behaviour fields (below).

Images take no role/label/ARIA fields — alt is the image's accessible text. Those fields are dropped by compile() and reported by checkNode().

ref

Field Value Required Note
hash bytes32 yes ComponentRegistry content hash

A ref takes only type and hash.

Accessibility fields

On every element type except image and ref.

Field Value Required Note
role one of button, textbox, link, img, group, heading, tablist, tab, tabpanel, switch, dialog, listbox, option, radiogroup, radio, menu, menuitem, checkbox, region, alert, status, separator, tooltip ARIA role; tablist..separator opt the component into format V3, tooltip into V4
label string aria-label
state object one ARIA state, emitted as aria-; opts into V3
state.name one of selected, checked, expanded, modal, current, disabled, pressed yes
state.value bool yes
id string element id for relationships; opts into V3
controls string aria-controls target id; opts into V3
describedby string aria-describedby target id; opts into V4
labelledby string aria-labelledby target id; opts into V4
activedescendant string aria-activedescendant target id; opts into V4
haspopup string aria-haspopup token ("menu" | "dialog" | ...); opts into V4

Behaviour fields

On every element type except ref (images included).

Field Value Required Note
cond object render only when one resolver read matches; fail-closed
cond.resolver address yes
cond.bind string yes
cond.arg hex
cond.equals string omit for a truthy test
cond.not bool
step object a button's 1-based position in a state-driven flow (labels progress only)
step.index integer yes
step.total integer yes
anim object bounded declarative animation (no script)
anim.kind one of fade, pulse, spin, slide, blink, breathe yes
anim.duration `number string`
anim.repeat one of once, infinite defaults to infinite
live bool viewer re-reads this element on new blocks (real chain state, never a stream)

Fields compile() ignores

Allowed by the TypeScript type but never encoded; checkNode() reports them as ignored-field:

  • image: role, label, state, id, controls, describedby, labelledby, activedescendant, haspopup
  • button.batch[]: args

Builder authoring fields

Read by the visual builder and grade(), never by compile(). checkNode(tree) reports them as authoring-field; checkNode(tree, { authoring: true }) and nodeJsonSchema({ authoring: true }) accept them.

  • argValues on slot and image (an object): the resolver args typed in the builder, by name; the builder encodes them into arg at export.
  • image.scene (an object): the client-side sketch that runs above the on-chain floor.
  • pinnedDep on the root node (an object): the pinned-dependency declaration grade() reads (Grade B).
  • Any key starting with _ (for example _multiview, _view, _mvId): design-time metadata such as multi-view tabs.

Limits

  • At most 1024 nodes and depth 64 (the interpreter's bounds).
  • At most 255 children and 255 attributes on one node.
  • Each literal value at most 65535 UTF-8 bytes.