<!-- GENERATED by scripts/gen-reference-docs.ts from chainc/node-schema.ts — do not edit by hand; edit the source and rerun. -->

# 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](./vocabulary.md)**.

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-<name>; 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` |  | seconds |
| `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.
