⚠️ 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: SDK API (every export)

Generated for @chainrender/client 0.21.0 — these are its exports, exactly. Using another version? Check yours with npm ls @chainrender/client.

Every export of @chainrender/client, generated from the SDK source: the signature as written and the doc comment next to it. If a name is not on this page, the package does not export it — do not import it. Import paths are exact: an export listed under @chainrender/client is not available from @chainrender/client/runtime, and a name listed inside a namespace (for example events.eventTopic0) is reached through that namespace (import { events } from "@chainrender/client/runtime").

For what each part is for and how to combine them, start with @chainrender/client, Runtime API and React API. viem is a required peer dependency.

Coverage: 180 value exports across 4 entry points; 171 carry a doc comment in the source. Without one (signature only): compile, decompile, DecompileError, HINTS, HINTS_REGISTRY_VERSION, hintSpec, hintRegistry, presentationFindings, isCrArg.

@chainrender/client

Authoring core: compile, check, grade, describe, validate, the vocabulary, manifests, themes, naming.

import { compileComponent } from "@chainrender/client";

Compile

compileComponent

function compileComponent(root: Node, opts: CompileOptions = {}): Compiled

Compiles a JSON AST component and returns its bytes, hex, content hash, and size.

Source: chainc/index.ts

compileJsx

function compileJsx(src: string): Compiled

Compiles a JSX-like string via the thin front-end, then the shared JSON-AST core.

Source: chainc/index.ts

compile

function compile(root: Node, opts: CompileOptions = {}): Uint8Array

No doc comment in the source.

Source: chainc/compile.ts

parseJsx

function parseJsx(src: string): Node

Parses a JSX-like string into the chainc JSON AST.

Source: chainc/jsx.ts

toHex

function toHex(bytes: Uint8Array): `0x${string}`

Hex-encodes CRO2 bytes as an 0x-prefixed string (for passing to viem/ethers).

Source: chainc/compile.ts

Decompile (0.21.0): CRO2 bytes back to the tree, exact or it throws — the builder's Fork (doc 119 §3.6)

decompile

function decompile(input: Uint8Array | string): Decompiled

No doc comment in the source.

Source: chainc/decompile.ts

DecompileError

class DecompileError extends Error

No doc comment in the source.

Source: chainc/decompile.ts

Vocabulary constants + IR builders (the closed vocabularies)

format (namespace)

chainc — CRO2 format constants.

Source: chainc/format.ts

Member Signature Summary
format.VERSION_1 const VERSION_1 = 0x01
format.VERSION_2 const VERSION_2 = 0x02
format.VERSION_3 const VERSION_3 = 0x03
format.VERSION_4 const VERSION_4 = 0x04
format.VERSION_5 const VERSION_5 = 0x05 docs/202: V4 + style tokens, hints, lang/dir, aria-level and the full WAI-ARIA 1.2 role table (opt-in; strict superset of V4).
format.HEADER_LEN const HEADER_LEN = 4
format.ROOT_FLAGS_RESERVED const ROOT_FLAGS_RESERVED = 0x00
format.TAG const TAG = { … } as const
format.TAG_MAX_KNOWN const TAG_MAX_KNOWN = 0x07
format.ATTR const ATTR = { … } as const
format.ATTR_KEY_MASK const ATTR_KEY_MASK = 0x7f
format.ATTR_DICT_FLAG const ATTR_DICT_FLAG = 0x80
format.ROLE const ROLE = { … } as const
format.ROLE_V5_FROM const ROLE_V5_FROM = 0x17 The first role index that needs VERSION_5.
format.ARIA_STATE const ARIA_STATE = { … } as const ARIA state indices (order matches OpcodeFormat.sol ARIA_* + chainc/a11y.ts A11Y_STATES; drift-guarded).
format.VARIANT const VARIANT = { … } as const
format.DIRECTION const DIRECTION = { … } as const
format.DIR const DIR = { … } as const VERSION_5 (docs/202): text direction, emitted as dir="…".
format.LANG_RE const LANG_RE = /^[A-Za-z]{2,3}(-[A-Za-z0-9]{1,8}){0,3}$/ VERSION_5 (docs/202 §4.1): the shape of a BCP-47 language tag the interpreter accepts for lang="…".
format.ARIA_LEVELS const ARIA_LEVELS = [ … ] as const VERSION_5 (docs/202): heading levels, emitted as aria-level (dict index = level).
format.INPUTTYPE const INPUTTYPE = { … } as const
format.PROVENANCE const PROVENANCE = { … } as const Media provenance — how "on-chain" a media node is.
format.ANIM const ANIM = { … } as const Bounded declarative animation kinds.
format.ANIM_REPEAT const ANIM_REPEAT = { … } as const
format.MAX_NODES const MAX_NODES = 1024
format.MAX_DEPTH const MAX_DEPTH = 64

compose (namespace)

@chainrender/client — compose.*: ergonomic, typed AST builders (doc 73 §4). Thin constructors over the Node union plus re-exported IR builder modules, so a builder / AI / MCP constructs valid trees without hand-writing object literals. Everything here returns plain Nodes in the closed vocabulary — nothing here can express outside it (constrained by construction).

Source: client/compose.ts

Member Signature Summary
compose.text const text = (content: string, extra: Partial<Node> = {}): Node => …
compose.box const box = (children: Kids, extra: Partial<Node> = {}): Node => …
compose.heading const heading = (content: string): Node => …
compose.button const button = (content: string, opts: { variant?: string; action?: { to?: string; sig: string; value?: string; args?: string } } = {},): Node => …
compose.input const input = (opts: { inputType?: string; placeholder?: string; name?: string } = {}): Node => …
compose.link const link = (href: string, content: string): Node => …
compose.icon const icon = (name: string): Node => …
compose.slot const slot = (bind: string, opts: { arg?: string; resolver?: string; content?: string } = {}): Node => …
compose.image const image = (opts: { alt?: string; bind?: string; arg?: string; resolver?: string; provenance?: string } = {}): Node => …
compose.ref const ref = (hash: string): Node => …
compose.composition namespace The higher IR vocabularies (composition / layout / multi-view / data-binding / controls / table / chart), re-exported so compose.layout.*, compose.chart.*, etc.
compose.composition.ANCHOR const ANCHOR = { … } as const Closed placement vocabulary: a 2D anchor over the scene canvas.
compose.composition.ANCHOR_NAME const ANCHOR_NAME: Record<number, string> = { … }
compose.composition.PLACE_MODE const PLACE_MODE = { … } as const Placement mode — composition-v2 adds SPATIAL_3D alongside the original 2D overlay.
compose.composition.PLACE_MODE_NAME const PLACE_MODE_NAME: Record<number, string> = { … }
compose.composition.SCENE_KIND const SCENE_KIND = { … } as const The scene the components are composed over.
compose.composition.aggregateCapabilities function aggregateCapabilities(scene: SceneRef, components: PlacedComponentInput[]): number The honest aggregate: READ_CHAIN baseline + the union of every placed component's capabilities + the scene's GPU capability if it renders on the GPU.
compose.composition.buildComposition function buildComposition(input: CompositionInput): BuiltComposition Build the canonical composition bytes + hash.
compose.layout namespace
compose.layout.LAYOUT_KIND const LAYOUT_KIND = { … } as const Composition-level responsive layout — mirror of contracts/scene/LayoutFormat.sol.
compose.layout.LAYOUT_DIR const LAYOUT_DIR = { … } as const
compose.layout.LAYOUT_ALIGN const LAYOUT_ALIGN = { … } as const
compose.layout.LAYOUT_JUSTIFY const LAYOUT_JUSTIFY = { … } as const
compose.layout.toLayoutTuple function toLayoutTuple(L: LayoutInput)
compose.layout.LAYOUT_ABI const LAYOUT_ABI = { … } as const
compose.layout.encodeLayout function encodeLayout(L: LayoutInput): '0x${string}' Canonical encoded bytes for a layout (for content-addressed storage / an app manifest).
compose.multiview namespace
compose.multiview.TGT_VIEW const TGT_VIEW = 0x40 In-app routing/navigation vocabulary — mirror of contracts/scene/MultiViewFormat.sol.
compose.multiview.NAV const NAV = { … } as const
compose.multiview.VIEW_FLAG const VIEW_FLAG = { … } as const
compose.multiview.FROM_ANY const FROM_ANY = 0xff
compose.multiview.SEL_MODE const SEL_MODE = { … } as const
compose.multiview.buildMultiView function buildMultiView(input: MultiViewInput): BuiltMultiView Build the canonical multi-view bytes + hash (content-addressed, ownerless).
compose.multiview.reachable function reachable(input: MultiViewInput): boolean Client-side mirror of MultiViewFormat._reachable — the reachability invariant (no stranding).
compose.multiview.buildTabs function buildTabs(views: '0x${string}'[], opts: { shell?: '0x${string}'; defaultView?: number; name?: string; version?: string } = {}): TemplateResult TABS — peer views, a persistent shell tab bar reaches every view from every view.
compose.multiview.buildWizard function buildWizard(steps: '0x${string}'[], opts: { shell?: '0x${string}'; name?: string; version?: string } = {}): TemplateResult WIZARD — ordered steps with Next (i→i+1) and Back (i→i-1).
compose.multiview.buildMasterDetail function buildMasterDetail(listView: '0x${string}', detailViews: '0x${string}'[], opts: { shell?: '0x${string}'; name?: string; version?: string } = {}): TemplateResult MASTER-DETAIL — a list (default) plus detail view(s).
compose.multiview.buildModal function buildModal(baseView: '0x${string}', modalViews: '0x${string}'[], opts: { shell?: '0x${string}'; name?: string; version?: string } = {}): TemplateResult MODAL — a base view (default) plus overlay view(s) rendered on top under a scrim.
compose.databind namespace
compose.databind.BIND_ANCHOR const BIND_ANCHOR = { … } as const App-level data-binding — mirror of contracts/DataBinder.sol.
compose.databind.bindKind function bindKind(kind: string): '0x${string}' A binding kind ("balance", "ensName", …) right-padded into bytes32, matching the resolver-hook ABI.
compose.databind.toBindingTuples function toBindingTuples(bindings: DataBindingInput[]) The tuple array form for a direct renderBindings / resolveValue / capabilities call.
compose.databind.encodeDataBindings function encodeDataBindings(bindings: DataBindingInput[]): '0x${string}' Canonical encoded bytes for a data-binding set (for content-addressed storage / an app manifest).
compose.controls namespace Parameter-interaction vocabulary — mirror of contracts/scene/ControlFormat.sol.
compose.controls.CONTROL_KIND const CONTROL_KIND = { … } as const Parameter-interaction vocabulary — mirror of contracts/scene/ControlFormat.sol.
compose.controls.toControlTuple function toControlTuple(c: ControlInput) Tuple form for a direct renderControl / renderControls call.
compose.controls.toControlTuples function toControlTuples(cs: ControlInput[])
compose.table namespace
compose.table.COL_ALIGN const COL_ALIGN = { … } as const Table presentation vocabulary — mirror of contracts/TableRenderer.sol.
compose.table.toColumnTuples function toColumnTuples(cols: ColumnInput[])
compose.table.tableKind function tableKind(kind: string): '0x${string}' A table-source kind ("ledger", …) right-padded into bytes32, matching the source ABI.
compose.chart namespace Chart vocabulary — mirror of contracts/scene/ChartFormat.sol.
compose.chart.CHART_KIND const CHART_KIND = { … } as const
compose.chart.toChartTuple function toChartTuple(c: ChartInput)
compose.chart.niceStep function niceStep(range: bigint, target: bigint): bigint JS mirror of ChartFormat._niceStep — the fixed-point port of D3's nice-tick step (power of ten × {1,2,5}, geometric-nearest via integer squares).
compose.chart.CHART_ABI const CHART_ABI = { … } as const The ChartSlotAdapter arg ABI (mirror of ChartSlotAdapter.resolve decode + seed-explorer's CHART_ABI): abi.encode(ChartFormat.Chart config, address source, bytes32 dataKind, bytes fetchArgs).
compose.chart.PALETTE_ABI const PALETTE_ABI = { … } as const ThemeTokens.Palette ABI tuple — field order MUST match contracts/ThemeTokens.sol Palette exactly.
compose.chart.DEFAULT_CHART_PALETTE const DEFAULT_CHART_PALETTE = { … } as const The default palette (mirror of ThemeTokens.defaults() -> paletteOf).
compose.chart.chartKindOf function chartKindOf(name: string | number | undefined): number A chart type by name: line, area, bar, scatter, pie, donut.
compose.chart.encodeChartSlotArgs function encodeChartSlotArgs(i: ChartSlotInput): Hex The arg of an image bound to ChartSlotAdapter: abi.encode(Chart, source, dataKind, fetchArgs, Palette).
compose.chart.chainlinkHistoryChartArgs function chainlinkHistoryChartArgs(i: ChainlinkHistoryChartInput): Hex The arg for a live price-history chart of a Chainlink-shaped feed: ChainlinkChartSource reads the last N rounds on every render (fails closed to an axes-only frame when the feed is unreadable).
compose.chart.CHART_AUTHORING const CHART_AUTHORING = { … } as const The builder's authoring descriptor for bind: "chart" (an image bound to ChartSlotAdapter).

Introspect

requiredCapabilities

function requiredCapabilities(node: Node): number

Derive the capability bits the behaviour REQUIRES from what the AST actually contains. This is the honest capability set: declaring more is over-claiming, declaring less is under-declaring.

Source: chainc/describe.ts

describeBehavior

function describeBehavior(node: Node, declaredCaps: number): BehaviorDescriptor

What a component can do, in plain language, derived from its AST without running it: the capabilities it requires vs the ones declared (and whether that declaration is honest), its actions, batches, signature requests, chain reads, media, GPU use and off-chain fetches, plus a human-readable summary. Pass requiredCapabilities(node) as declaredCaps to describe the honest set.

Source: chainc/describe.ts

describeComposition

function describeComposition(manifest: { scene: { kind: number; gpu?: boolean }; components: { hash: string; anchor: number; capabilities: number }[]; aggregated?: number; capabilities?: number; }, componentFloors: Map<string, BehaviorDescriptor>, anchorName: (a: number) => string,): CompositionFloor

The composed floor of a mini-app: the scene, every placed component with what each can do, and the aggregated capability set with whether it is escalation-free (the aggregate equals the union of the components' caps).

Source: chainc/describe.ts

Validate

collectBehavior

function collectBehavior(node: Node): Collected

One walk of the AST collecting everything with consequences: actions, resolvers, refs, media, batches and signature requests. The same walk validateApp() and describeBehavior() use, so the description and the checks cannot disagree.

Source: chainc/validate.ts

validateApp

function validateApp(manifest: AppManifestInput, rootAst: Node, knownComponents: Set<string>, knownApps?: Set<string>,): ValidationReport

Validates an assembled app.

Source: chainc/validate.ts

validateComposition

function validateComposition(manifest: { scene: { kind: number; ref: string; gpu?: boolean }; components: { hash: string; anchor: number; capabilities: number }[]; capabilities?: number; aggregated?: number; parent?: string; }, knownComponentCaps: Map<string, number>, knownCompositions?: Set<string>,): ValidationReport

Validate a composition (mini-app): a scene + placed components + aggregated capabilities. The heart is capability aggregation with NO privilege escalation — the mini-app's capability set must be EXACTLY the union of its components' own declared capabilities (plus the scene's GPU), and no placed component may claim a capability it doesn't actually have. Placement aggregates and surfaces power; it never grants it.

Source: chainc/validate.ts

Enforce (the drift-guarded mirrors of the on-chain enforcer)

analyze

function analyze(parts: Part[]): Analysis

The grade computation without the refusal rails: the capability envelope (union of every part's caps), the worst-link grade across the presentation, data and dependency axes, and one deviation per axis below A. Mirrors contracts/enforcer/TrustGrade.sol; most callers want check() or grade().

Source: chainc/trustgrade.ts

check

function check(parts: Part[], declaredEnvelope?: number): Result

The enforcer gate: rails first (R1 escape-hatch, I5 malformed, R2 capability-dishonesty), then grade.

Source: chainc/trustgrade.ts

gateAction

function gateAction(a: Action, envelope: number, allowed: Target[]): number

The action gate (doc 67 §4b): permit an action only if it fits the effective envelope + declared call set.

Source: chainc/trustgrade.ts

gateBinding

function gateBinding(bindCap: number, envelope: number): number

Rule R6: a data binding may not need a capability outside the envelope. Returns GATE.OK or GATE.OFF_ENVELOPE_BIND.

Source: chainc/trustgrade.ts

firstBlocked

function firstBlocked(actions: Action[], envelope: number, allowed: Target[]):

Runs gateAction() over a list and returns the first action it refuses (index and GATE reason), or blocked: false.

Source: chainc/trustgrade.ts

gradeLetter

function gradeLetter(g: number): string

presentation-layer helpers (the label)

Source: chainc/trustgrade.ts

gradeWord

function gradeWord(g: number): string

The word for a grade number: A "Trustless", B "Pinned", C "Live", X "Refused".

Source: chainc/trustgrade.ts

gradeLocks

function gradeLocks(g: number): string

The padlock meter for a grade number: A 🔒🔒🔒, B 🔒🔒◻, C 🔒◻◻, X ⛔.

Source: chainc/trustgrade.ts

CAP

const CAP = { … } as const

capability bits — MUST match chainc/manifest.ts CAP and TrustGrade.sol

Source: chainc/trustgrade.ts

GRADE

const GRADE = { … } as const

Grade numbers: A = 3 (Trustless), B = 2 (Pinned), C = 1 (Live), X = 0 (Refused). Higher is more trustless.

Source: chainc/trustgrade.ts

GATE

const GATE = { … } as const

Action-gate results: OK, or why an action is refused — a capability outside the envelope (R3), value without TRANSFER_VALUE (R4), a target not in the declared call set (R5), a binding outside the envelope (R6).

Source: chainc/trustgrade.ts

PRES

const PRES = { … } as const

Presentation axis: COMPUTED (rendered from on-chain interpreter output) grades A, PINNED B, LIVE C.

Source: chainc/trustgrade.ts

DEP

const DEP = { … } as const

Dependency axis: NONE / IMMUTABLE grade A, ATTESTED (content-addressed, pinned on-chain) B, UNPROVEN / MUTABLE C.

Source: chainc/trustgrade.ts

construct

function construct(a: WriteAction, userArgs: string[], envelope: number, allowed: Target[]): Constructed

Gate-check then construct the tx for signing. Returns ok=false + reason if the gate blocks it (no tx).

Source: chainc/actionvocab.ts

word

function word(n: bigint): string

Encode a bigint as a left-padded 32-byte word (for uint256 / bool user args).

Source: chainc/actionvocab.ts

addrWord

function addrWord(addr: string): string

Encode an address as a left-padded 32-byte word.

Source: chainc/actionvocab.ts

userArgCount

function userArgCount(a: WriteAction): number

How many of an action's argument slots the user fills in (source ARG.USER), as opposed to fixed by the component.

Source: chainc/actionvocab.ts

ARG

const ARG = { … } as const

Where an action argument comes from: FIXED in the component, or USER-supplied at the wallet.

Source: chainc/actionvocab.ts

ATYPE

const ATYPE = { … } as const

The argument types the closed action vocabulary can encode.

Source: chainc/actionvocab.ts

Manifest / addressing

buildManifest

function buildManifest(input: AppManifestInput): BuiltManifest

Builds the canonical manifest bytes and app hash.

Source: chainc/manifest.ts

capabilityNames

function capabilityNames(bitmap: number): string[]

Human-readable capability names for a declared envelope, for consent/display surfaces.

Source: chainc/manifest.ts

NET-NEW core primitives (doc 73 §8)

grade

function grade(node: Node, opts: GradeOptions = {}): GradeResult

Live, no-deploy trust grade of a component AST. Derives caps via requiredCapabilities, then grades as the chain does. Grade (presentation/data/dependency) and envelope (what it can touch) are orthogonal — both are returned; a WRITE component is still Grade A if it renders from computed, immutable, on-chain material.

Source: client/grade.ts

gradeCaps

function gradeCaps(caps: number, opts: GradeOptions = {}): GradeResult

Grade a capability set directly — the single source of truth grade() and gradeComposition() both call. Mirrors the seed's per-item derivation exactly, so it is drift-locked to the on-chain enforcer.

Source: client/grade.ts

gradeComposition

function gradeComposition(aggregatedCaps: number, opts: GradeOptions = {}): GradeResult

Grade a composition / app from its aggregated capability union (the honest aggregate the validator enforces — pass the composition's aggregated caps here).

Source: client/grade.ts

aboveFloorText

function aboveFloorText(kinds: readonly string[]): string

What runs above the floor, in words: "a client-side p5 sketch", "client-side reads of the viewer's own wallet and a client-side transfer history read from logs" (docs/201). The review and the builder say it the same way.

Source: client/grade.ts

isVerifiablePinnedDep

function isVerifiablePinnedDep(pd?: PinnedDep | null): boolean

Pinned-IPFS dependency → Grade B (Pinned): the drift-guarded predicate + type an app/builder/AI uses to declare an honest off-chain-but-content-addressed dependency (docs/B-GRADE-pinned-ipfs-dependency.md).

Source: chainc/pinneddep.ts

pinnedDependencyLevel

function pinnedDependencyLevel(pd?: PinnedDep | null): number | null

The dependency level a pinned dep contributes: DEP.ATTESTED (→ B) when honest, else null (leave the caller's default, i.e. IMMUTABLE → A). Fail-closed: an invalid CID never yields a silent B.

Source: chainc/pinneddep.ts

pinnedCid

function pinnedCid(pd?: PinnedDep | null): string

Pinned-IPFS dependency → Grade B (Pinned): the drift-guarded predicate + type an app/builder/AI uses to declare an honest off-chain-but-content-addressed dependency (docs/B-GRADE-pinned-ipfs-dependency.md).

Source: chainc/pinneddep.ts

RAW_CIDV1

const RAW_CIDV1 = /^bafkrei[a-z2-7]{52}$/

The ONLY re-verifiable shape: a raw CIDv1 (bafkrei…). dag-pb (Qm… / bafybe…) can't be verified in-browser.

Source: chainc/pinneddep.ts

vocabulary

function vocabulary(opts: { mode?: VocabMode } = {}): VocabularySchema

The machine-readable vocabulary. Constrains AI generation to valid IR and generates MCP tool surfaces. { mode: "enhanced" } (docs/202 §16.4) adds the VERSION_5 presentation fields; the default "classic" is exactly the pre-V5 vocabulary, so an AI or tool in classic mode can never emit a tree a chain without V5 refuses.

Source: client/vocabulary.ts

v0.10.0: the strict schema of compile()'s input (chainc/node-schema.ts)

checkNode

function checkNode(root: unknown, opts: { authoring?: boolean; mode?: "classic" | "enhanced" } = {}): NodeCheck

Check a tree against the strict schema plus the limits compile() / the interpreter enforce. Never throws. { authoring: true } accepts the builder-only AUTHORING_FIELDS (slot/image argValues, image.scene, a root pinnedDep, and _-prefixed design-time keys) without an issue.

Source: chainc/node-schema.ts

nodeJsonSchema

function nodeJsonSchema(opts: { authoring?: boolean } = {}): JsonSchema

The strict JSON Schema (draft 2020-12) of the tree compile() consumes. The node def is recursive. Limits that JSON Schema cannot express (total nodes, depth, encoded byte lengths, pinnedDep only at the root) are enforced by checkNode(). { authoring: true } also admits the builder-only AUTHORING_FIELDS.

Source: chainc/node-schema.ts

fieldsOf

function fieldsOf(type: NodeType): FieldSpec[]

Every field compile() reads for a node type, in emit order (type fields, then a11y, then behaviour, then the VERSION_5 presentation fields).

Source: chainc/node-schema.ts

NODE_TYPES

const NODE_TYPES = [ … ] as const

Element types (everything but ref).

Source: chainc/node-schema.ts

NODE_ENUMS

const NODE_ENUMS = { … } as const

compile() silently drops what it does not read (unknown fields, bad enum values, a11y on images, batch args); checkNode() reports each with its path, and nodeJsonSchema() is the same rules as a JSON Schema an AI tool or MCP server hands to a model. Drift-locked to compile() by tsc (_coverage) and by test/node-schema.ts.

Source: chainc/node-schema.ts

TYPE_FIELDS

const TYPE_FIELDS: Record<NodeType, FieldSpec[]> = { … }

Type-specific fields, in compile()'s emit order.

Source: chainc/node-schema.ts

A11Y_FIELDS

const A11Y_FIELDS: FieldSpec[] = [ … ]

Accessibility fields: every element type except image (which uses alt) and ref.

Source: chainc/node-schema.ts

BEHAVIOR_FIELDS

const BEHAVIOR_FIELDS: FieldSpec[] = [ … ]

Behaviour fields: every element type except ref (images included).

Source: chainc/node-schema.ts

AUTHORING_FIELDS

const AUTHORING_FIELDS = { … } as const

Authoring fields: read by the visual builder / grade(), never by compile(). A builder tree may carry them; a tree handed to compile() should not (the builder's encodeBindings() turns them into compiled fields or drops them). checkNode reports them as authoring-field unless called with { authoring: true }; with it, image.scene is checked against SCENE_FIELDS and SCENE_BINDS (0.11.0), while argValues / pinnedDep contents stay the builder's to validate. Grounded in builder/index-next.html: - slot/image argValues the human-typed resolver args, keyed by arg name; encodeBindings() encodes them into arg per the kind's descriptor (abi.encode, or packed when argsEncoding says so) - image.scene the client-side sketch that runs ABOVE the on-chain floor (builder "Scene" panel) - root pinnedDep the pinned-dependency declaration grade() reads (grade(tree, { pinnedDep: tree.pinnedDep })) - any _-prefixed key design-time metadata (_multiview, _view, _mvId for multi-view tabs) 0.10.0 listed only image.scene and root pinnedDep, so a builder tree with argValues was wrongly flagged.

Source: chainc/node-schema.ts

AUTHORING_PREFIX

const AUTHORING_PREFIX = "_"

Keys starting with this prefix are builder design-time metadata on any element (see AUTHORING_FIELDS).

Source: chainc/node-schema.ts

SCENE_FIELDS

const SCENE_FIELDS: FieldSpec[] = [ … ]

The fields of image.scene, exactly as the builder's Scene panel and rich-media deploy read them (builder/index-next.html). An empty string means "not set" for seed / libHash / entry, as in the builder's inputs. At deploy the builder stores source in SourceStore (chunked if large) and registers the scene in SceneComponentRegistry with the binding (libHash, seed, SourceStore id[, app metadata]) — see chainc/depscene.ts.

Source: chainc/node-schema.ts

SCENE_BINDS

const SCENE_BINDS = [ … ] as const

The bind values that make an image's scene a rich-media sketch. The builder only treats image.scene as a sketch when the image's bind is one of these (builder/index-next.html: findScene / runAboveFloorPreview / the rich-media deploy all test bind === "p5" || bind === "three").

Source: chainc/node-schema.ts

IGNORED_BY_COMPILE

const IGNORED_BY_COMPILE: Partial<Record<NodeType, string[]>> = { … }

Fields the TypeScript Node type allows but compile() never encodes. The checker reports them; the runtime drift test proves compile() really ignores them (setting one leaves the bytes unchanged).

Source: chainc/node-schema.ts

IGNORED_NESTED

const IGNORED_NESTED: Record<string, string[]> = { … }

Nested fields the type allows but compile() drops: a batch member's args is not part of the encoded to|sig|value|label member, so it never reaches the wallet.

Source: chainc/node-schema.ts

NODE_LIMITS

const LIMITS = { … } as const  (exported as NODE_LIMITS)

compile() silently drops what it does not read (unknown fields, bad enum values, a11y on images, batch args); checkNode() reports each with its path, and nodeJsonSchema() is the same rules as a JSON Schema an AI tool or MCP server hands to a model. Drift-locked to compile() by tsc (_coverage) and by test/node-schema.ts.

Source: chainc/node-schema.ts

v0.16.0: one review for every surface (client/review.ts, docs/190)

reviewTree

function reviewTree(tree: unknown, opts: ReviewOptions = {}): Review

Review a tree: check + grade + compile + honesty, and the pass/fail verdict every surface reports.

Source: client/review.ts

reviewText

function reviewText(r: Review, title = "ChainRender review"): string

The review as plain text — what the builder's "Copy for AI" button and the command line print. An AI that cannot run the review itself is given this text, and fixes what it lists.

Source: client/review.ts

v0.14.0: honesty and privacy findings (chainc/honesty.ts, docs/188)

honestyFindings

function honestyFindings(root: unknown, opts: HonestyOptions = {}): HonestyFinding[]

Honesty and privacy findings for a Node tree. Empty array = nothing to fix.

Source: chainc/honesty.ts

publicInputNames

function publicInputNames(args: string | readonly string[] | undefined | null): string[]

The $name placeholders in an action's args — a comma-separated template ("$amount,0xabc…") or a list.

Source: chainc/honesty.ts

publicInputNotice

function publicInputNotice(names: readonly string[]): string

The sign-panel line for an action whose args take these input names; "" when it takes none.

Source: chainc/honesty.ts

PUBLIC_INPUT_NOTICE

const PUBLIC_INPUT_NOTICE = "Values you enter here become public on-chain, permanently: anyone can read them."

The line every surface that signs an action with typed-in values shows (viewer sign panel, apps, AI-built UIs).

Source: chainc/honesty.ts

ONCHAIN_P5_VERSION

const ONCHAIN_P5_VERSION = "2.3.2"

The p5 every ChainRender chain registers in its DependencyRegistry (deployment/genesis-libraries*.json: p5@2.3.2 is the only p5 on Sepolia, Robinhood and Arc).

Source: chainc/honesty.ts

p5V1ApiUses

function p5V1ApiUses(source: string):

Where a p5 sketch uses the p5 1.x API the on-chain p5 2.3.2 does not have. Each item: what, the line (1-based, in the sketch source) of its first use, how many uses, and the 2.x replacement. Empty = none found.

Source: chainc/honesty.ts

signMessageProblems

function signMessageProblems(sign: AnyNode): string[]

What is wrong with an EIP-712 sign object's message: a $name (never substituted), or a value that does not fit its declared type (address, bool, uintN/intN, bytesN, string; nested struct types are followed). Empty = fine.

Source: chainc/honesty.ts

v0.20.0: VERSION_5 presentation — style tokens, hints, lang/dir, heading levels, WAI-ARIA roles (docs/202)

STYLE_FAMILIES

const STYLE_FAMILIES: readonly StyleFamily[] = [ … ] as const

Enhanced mode only: compile(tree, { mode: "enhanced" }) / compileComponent(tree, { mode: "enhanced" }) / checkNode(tree, { mode: "enhanced" }) / reviewTree(tree, { mode: "enhanced" }) / vocabulary({ mode: "enhanced" }). The default (classic) is exactly the pre-V5 behaviour. VERSION_5 renders only where the chain's RenderRouter.interpreterFor(5) is the V5 HTML interpreter (doc 202 phase 2).

Source: chainc/style-tokens.ts

STYLE_TOKENS

const STYLE_TOKENS: ReadonlyMap<string, StyleFamily> = new Map(STYLE_FAMILIES.flatMap((f) => f.values.map((v) => [f.token(v), f] as const)))

Every registered token, by token string -> its family.

Source: chainc/style-tokens.ts

STYLE_TOKEN_RE

const STYLE_TOKEN_RE = /^[a-z][a-z0-9]{0,15}(-[a-z0-9]{1,15}){0,3}$/

One wire token: a lowercase word, then up to three -segments. docs/202 §4.1 (the V5 interpreter enforces the same).

Source: chainc/style-tokens.ts

STYLE_REGISTRY_VERSION

const STYLE_REGISTRY_VERSION = 1

Enhanced mode only: compile(tree, { mode: "enhanced" }) / compileComponent(tree, { mode: "enhanced" }) / checkNode(tree, { mode: "enhanced" }) / reviewTree(tree, { mode: "enhanced" }) / vocabulary({ mode: "enhanced" }). The default (classic) is exactly the pre-V5 behaviour. VERSION_5 renders only where the chain's RenderRouter.interpreterFor(5) is the V5 HTML interpreter (doc 202 phase 2).

Source: chainc/style-tokens.ts

styleFamily

const styleFamily = (name: string): StyleFamily | undefined => …

Enhanced mode only: compile(tree, { mode: "enhanced" }) / compileComponent(tree, { mode: "enhanced" }) / checkNode(tree, { mode: "enhanced" }) / reviewTree(tree, { mode: "enhanced" }) / vocabulary({ mode: "enhanced" }). The default (classic) is exactly the pre-V5 behaviour. VERSION_5 renders only where the chain's RenderRouter.interpreterFor(5) is the V5 HTML interpreter (doc 202 phase 2).

Source: chainc/style-tokens.ts

styleFamiliesFor

const styleFamiliesFor = (type: NodeType): StyleFamily[] => …

Enhanced mode only: compile(tree, { mode: "enhanced" }) / compileComponent(tree, { mode: "enhanced" }) / checkNode(tree, { mode: "enhanced" }) / reviewTree(tree, { mode: "enhanced" }) / vocabulary({ mode: "enhanced" }). The default (classic) is exactly the pre-V5 behaviour. VERSION_5 renders only where the chain's RenderRouter.interpreterFor(5) is the V5 HTML interpreter (doc 202 phase 2).

Source: chainc/style-tokens.ts

styleStringOf

function styleStringOf(node: { type: string } & Record<string, unknown>): string | undefined

The ATTR.STYLE string for a node: its family fields in registry order, then raw style tokens (sorted, de-duplicated, grammar-valid only). Deterministic, so the same tree always gives the same hash. Families not allowed on the node's type and values not in the family are left out (checkNode reports them). Returns undefined when there are none.

Source: chainc/style-tokens.ts

isValidStyleList

function isValidStyleList(s: string): boolean

Whether a wire style list passes the V5 grammar (what the interpreter checks; anything else is dropped whole).

Source: chainc/style-tokens.ts

structureCss

function structureCss(opts: { scope?: string } = {}): string

The structure CSS: one rule per token, the heading levels, the app container. Only elements carrying cr-t or aria-level (VERSION_5 output) match, so it has no effect on V2–V4 apps. scope is the app root's selector.

Source: chainc/style-tokens.ts

structureCssProblems

function structureCssProblems(css: string): string[]

What the honesty rules (docs/202 §11) forbid in the structure CSS. Empty = fine. Exceptions are by name: overflow only in the scroll family, content only as "" (marker shapes), a literal colour only as a var() fallback, font sizes only as max(12px, calc(var(--cr-…) * k)) with k >= FONT_FLOOR.

Source: chainc/style-tokens.ts

STRUCTURE_SCOPE

const STRUCTURE_SCOPE = ".cr-root"

The default app root the structure CSS is scoped to (the SDK themes and the builder preview use .cr-root).

Source: chainc/style-tokens.ts

styleRegistry

function styleRegistry()

For vocabulary({ mode: "enhanced" }) and the docs.

Source: chainc/style-tokens.ts

HINTS

const HINTS: readonly HintSpec[] = [ … ]

No doc comment in the source.

Source: chainc/hints.ts

HINTS_REGISTRY_VERSION

const HINTS_REGISTRY_VERSION = 1

No doc comment in the source.

Source: chainc/hints.ts

hintSpec

const hintSpec = (key: string): HintSpec | undefined => …

No doc comment in the source.

Source: chainc/hints.ts

hintStringOf

function hintStringOf(hints: unknown): string | undefined

The ATTR.HINTS string for a node's hints object: known keys in registry order, then other grammar-valid keys sorted. Pairs whose key or value break the grammar are left out (checkNode reports them). Undefined when there are none.

Source: chainc/hints.ts

hintProblems

function hintProblems(type: NodeType, hints: unknown): string[]

Problems with a node's hints (empty = fine): grammar, unknown keys, wrong node type, values that do not fit.

Source: chainc/hints.ts

hintRegistry

function hintRegistry()

No doc comment in the source.

Source: chainc/hints.ts

presentationFieldsOf

function presentationFieldsOf(type: NodeType): FieldSpec[]

VERSION_5 presentation fields for a node type (docs/202), in compile()'s emit order: the style families its type allows (chainc/style-tokens.ts), raw style, hints, lang, dir, and level (not on images). Each opts the component into VERSION_5.

Source: chainc/node-schema.ts

PRESENTATION_KEYS

const PRESENTATION_KEYS = [ … ] as const

Runtime half (test/style-tokens.ts): equals the registry's families + style/hints/lang/dir/level.

Source: chainc/node-schema.ts

presentationFindings

function presentationFindings(tree: unknown, opts: PresentationReviewOptions = {}): PresentationFinding[]

No doc comment in the source.

Source: client/presentation-review.ts

PRESENTATION_RULES

const PRESENTATION_RULES: readonly { rule: PresentationRule; severity: "warn" | "error"; when: string }[] = [ … ]

For the docs and the builder: the rules and what each checks.

Source: client/presentation-review.ts

THEME_LABEL_HOOKS

const THEME_LABEL_HOOKS: readonly string[] = [ … ]

The aria-label values the default theme styles by (a frozen list for existing hashes, docs/202 §1.2, §12) that read as machine names: lowercase ("dash-row", "alert-*", "tooltip"). The capitalised ones the theme also matches ("Addresses", "Ownership", "Records") are real names a person would give the element, so they are not flagged.

Source: client/presentation-review.ts

v0.19.0: the viewer's own wallet data and transfer histories (chainc/viewer-context.ts, docs/201)

VIEWER_PLACEHOLDER

const VIEWER_PLACEHOLDER = "$viewer"

The placeholder an author writes for the viewer's own address.

Source: chainc/viewer-context.ts

VIEWER_KINDS

const VIEWER_KINDS: readonly ViewerKind[] = [ … ]

A viewer read is a client slot whose account arg is "$viewer"; a transfer history is a client slot bound to "transfers". The on-chain render shows their fallback text to everyone; a ChainRender viewer fills them only after the person chooses to show their own data, with this chain's published resolvers (⚙ above the floor).

Source: chainc/viewer-context.ts

VIEWER_READS

const VIEWER_READS = { … } as const

For vocabulary(): what an author (or an AI) needs to write one.

Source: chainc/viewer-context.ts

VIEWER_FALLBACK

const VIEWER_FALLBACK = "Connect your wallet to see this"

What a viewer slot shows until the person chooses to show their data (the builder uses it when content is empty).

Source: chainc/viewer-context.ts

HISTORY_BIND

const HISTORY_BIND = "transfers"

The bind of a transfer-history slot.

Source: chainc/viewer-context.ts

HISTORY_KINDS

const HISTORY_KINDS = [ … ] as const

ChainRenderFeed kinds a history may read (no raw logs, and no chain-wide transfers mix).

Source: chainc/viewer-context.ts

HISTORY_LIMITS

const HISTORY_LIMITS = { … } as const

A viewer read is a client slot whose account arg is "$viewer"; a transfer history is a client slot bound to "transfers". The on-chain render shows their fallback text to everyone; a ChainRender viewer fills them only after the person chooses to show their own data, with this chain's published resolvers (⚙ above the floor).

Source: chainc/viewer-context.ts

HISTORY_FALLBACK

const HISTORY_FALLBACK = "Recent transfers load in a ChainRender viewer"

A viewer read is a client slot whose account arg is "$viewer"; a transfer history is a client slot bound to "transfers". The on-chain render shows their fallback text to everyone; a ChainRender viewer fills them only after the person chooses to show their own data, with this chain's published resolvers (⚙ above the floor).

Source: chainc/viewer-context.ts

VIEWER_HISTORY_FALLBACK

const VIEWER_HISTORY_FALLBACK = "Connect your wallet to see your recent transfers"

A viewer read is a client slot whose account arg is "$viewer"; a transfer history is a client slot bound to "transfers". The on-chain render shows their fallback text to everyone; a ChainRender viewer fills them only after the person chooses to show their own data, with this chain's published resolvers (⚙ above the floor).

Source: chainc/viewer-context.ts

SAMPLE_ACCOUNT

const SAMPLE_ACCOUNT = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"

The address the builder previews viewer slots with when no wallet is connected — labelled a sample everywhere.

Source: chainc/viewer-context.ts

viewerFallback

function viewerFallback(node: unknown): string | null

The fallback text (the floor) a viewer slot shows to everyone until the viewer fills it.

Source: chainc/viewer-context.ts

viewerKind

const viewerKind = (kind: unknown): ViewerKind | undefined => …

A viewer read is a client slot whose account arg is "$viewer"; a transfer history is a client slot bound to "transfers". The on-chain render shows their fallback text to everyone; a ChainRender viewer fills them only after the person chooses to show their own data, with this chain's published resolvers (⚙ above the floor).

Source: chainc/viewer-context.ts

viewerReadArg

function viewerReadArg(kind: string, values: Record<string, unknown>): string

The client-slot arg for a viewer read: cr:viewer;token=0x…;account=$viewer. Throws on anything the viewer would refuse.

Source: chainc/viewer-context.ts

historyArg

function historyArg(values: Record<string, unknown>): string

The client-slot arg for a transfer history: cr:history;kind=token-transfers;account=$viewer;token=0x…;blocks=5000;limit=20.

Source: chainc/viewer-context.ts

parseCrArg

function parseCrArg(text: unknown): CrArg

Parses a cr: arg. Strict: one mode, known keys, no repeats, bounded. Does not check the fields against a kind.

Source: chainc/viewer-context.ts

viewerReadProblems

function viewerReadProblems(kind: unknown, fields: Record<string, unknown>): string[]

Problems with a viewer read for kind given its fields (empty = fine).

Source: chainc/viewer-context.ts

historyProblems

function historyProblems(fields: Record<string, unknown>): string[]

Problems with a transfer history's fields (empty = fine).

Source: chainc/viewer-context.ts

viewerNodeMode

function viewerNodeMode(node: unknown): "viewer" | "history" | null

Whether argValues (or an already-encoded arg) make this node a viewer read or a transfer history.

Source: chainc/viewer-context.ts

v0.11.0: presentation context (render-time theme / palette / size, doc 106)

presentationContext

function presentationContext(o: { themeId?: `0x${string}`; palette?: ContextPalette; // chart/image palette override tokens?: ThemeTokens; // OR derive the palette from a full token set chartW?: number; chartH?: number; overrideTokens?: ThemeTokens; // doc 109: full token override (regenerates component CSS at render time) ext?: `0x${string}`; }): PresentationContext

Build a present context from optional overrides — the viewer's ergonomic entry (theme/palette/dims).

Source: chainc/presentation-context.ts

emptyContext

function emptyContext(): PresentationContext

The empty context — everything falls back to the component's baked defaults (== renderHash behavior).

Source: chainc/presentation-context.ts

PRESENTATION_CONTEXT_ABI

const PRESENTATION_CONTEXT_ABI = { … } as const

The ABI tuple for PresentationContextLib.Context — field order MUST match the Solidity struct exactly.

Source: chainc/presentation-context.ts

PRESENTATION_CONTEXT_VERSION

const PRESENTATION_CONTEXT_VERSION = 1

Build the context renderComponentWithContext() (@chainrender/client/runtime) passes to RenderRouter.renderHashWithContext. Skin only: never identity, behaviour or grade.

Source: chainc/presentation-context.ts

v0.11.0: rich-media scene binding (chainc/depscene.ts)

encodeSceneBinding

function encodeSceneBinding(b: SceneBinding): `0x${string}`

abi-encode a binding: 3 fields, or 4 when meta is a non-empty string (the builder's rich-media deploy form).

Source: chainc/depscene.ts

decodeSceneBinding

function decodeSceneBinding(kind: SceneKind, value: `0x${string}`): SceneBinding

Decode either form; meta is present only for a 4-field binding.

Source: chainc/depscene.ts

sceneIdOf

function sceneIdOf(floorContract: `0x${string}`, floorSelector: `0x${string}`, seed: `0x${string}`, binding: `0x${string}`): `0x${string}`

SceneComponentRegistry.idOf: keccak256(abi.encode(floorContract, floorSelector, seed, binding)).

Source: chainc/depscene.ts

sceneNamespaceId

const namespaceId = (kind: SceneKind): `0x${string}` => …  (exported as sceneNamespaceId)

namespace id the ComponentAnnotationRegistry keys on (keccak of the namespace string)

Source: chainc/depscene.ts

SCENE_NS

const SCENE_NS = { … } as const

The binding a p5/three app carries: the on-chain library by DependencyRegistry hash, the seed, and the sketch (a SourceStore id once deployed), optionally with app metadata — exactly what the builder's rich-media deploy registers in SceneComponentRegistry. Previously documented but not exported.

Source: chainc/depscene.ts

SCENE_FLOOR_SELECTORS

const SCENE_FLOOR_SELECTORS = { … } as const

The on-chain floors SceneFloor ships (contracts/SceneFloor.sol), by name → 4-byte selector. A registered scene's floor is floorContract.<selector>(seed); the builder's rich-media deploy uses sigil.

Source: chainc/depscene.ts

First-party on-chain resolver kinds (oracle feeds, selective-disclosure credentials)

kinds (namespace)

Not part of the closed tag vocabulary — the resolver mechanism is extensible — but the kinds ChainRender ships as first-party, surfaced with their KIND constants + arg encoders (re-exported from the drift-locked mirrors) so an app, a builder, an MCP server, or an AI can discover and encode them. Also in vocabulary().resolverKinds.

Source: chainc/resolverkinds.ts

Member Signature Summary
kinds.oracle namespace chainc mirror for OracleFeedResolver — the binding kind + argument encoding, drift-locked against the on-chain resolver (see test/oracle.ts).
kinds.oracle.KIND_FEED const KIND_FEED = stringToHex("oracle-feed", { size: 32 }) Binding kind, right-padded into bytes32 — mirrors OracleFeedResolver.KIND_FEED.
kinds.oracle.encodeFeedArgs function encodeFeedArgs(a: FeedArgs): '0x${string}' abi.encode(address feed, uint8 fracDigits, uint256 maxStaleSeconds) — the resolver's args layout.
kinds.credential namespace chainc mirror for CredentialResolver — the binding kind, the MVP statement id, and the argument encoding, drift-locked against the on-chain resolver (see test/credential.ts).
kinds.credential.KIND_CREDENTIAL const KIND_CREDENTIAL = stringToHex("credential", { size: 32 }) Binding kind, right-padded into bytes32 — mirrors CredentialResolver.KIND_CREDENTIAL.
kinds.credential.STMT_MEMBER_OF_SET const STMT_MEMBER_OF_SET = stringToHex("member-of-set", { size: 32 }) MVP statement id — "the prover is a member of the set with this public root", revealing nothing about which member.
kinds.credential.encodeCredentialArgs function encodeCredentialArgs(x: CredentialArgs): '0x${string}' abi.encode(bytes32 statementId, uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[] pub) — the resolver's args layout.
kinds.credentialBound namespace chainc mirror for BoundCredentialResolver + NullifierRegistry — the binding kind, the statement id, and the argument encoding, drift-locked against the on-chain contracts (see test/credential-bound.ts).
kinds.credentialBound.KIND_CREDENTIAL_BOUND const KIND_CREDENTIAL_BOUND = stringToHex("credential-bound", { size: 32 }) Binding kind, right-padded into bytes32 — mirrors BoundCredentialResolver.KIND_CREDENTIAL_BOUND.
kinds.credentialBound.STMT_MEMBER_BOUND const STMT_MEMBER_BOUND = stringToHex("member-bound", { size: 32 }) Statement id for the bound, single-use member-of-set credential.
kinds.credentialBound.BOUND_PUBLIC_ORDER const BOUND_PUBLIC_ORDER = [ … ] as const Public-signal layout of the bound statement (nPublic === 4), in snarkjs order.
kinds.credentialBound.encodeBoundCredentialArgs function encodeBoundCredentialArgs(x: BoundCredentialArgs): '0x${string}' abi.encode(bytes32 statementId, uint256[2] a, uint256[2][2] b, uint256[2] c, uint256[4] pub) — mirrors BoundCredentialResolver._verify's abi.decode.
kinds.ens namespace chainc/ens.ts — first-party ENS resolver kinds, mirrored + drift-locked to EnsRecordResolver.sol and EnsV2Resolver.sol.
kinds.ens.KIND_ADDR const KIND_ADDR = stringToHex("ensAddr", { size: 32 }) bytes32 KIND constants — mirror the on-chain resolvers.
kinds.ens.KIND_TEXT const KIND_TEXT = stringToHex("ensText", { size: 32 })
kinds.ens.KIND_NAME const KIND_NAME = stringToHex("ensName", { size: 32 })
kinds.ens.KIND_ENS_V2 const KIND_ENS_V2 = stringToHex("ensV2", { size: 32 })
kinds.ens.encodeAddrArgs function encodeAddrArgs(node: '0x${string}'): '0x${string}' node is the ENS namehash (bytes32).
kinds.ens.encodeTextArgs function encodeTextArgs(node: '0x${string}', key: string): '0x${string}'
kinds.ens.encodeNameArgs function encodeNameArgs(who: '0x${string}'): '0x${string}' ensName takes the ACCOUNT ADDRESS as exactly 20 raw bytes — not a namehash and not a 32-byte abi.encode.
kinds.ens.SEL_ADDR const SEL_ADDR = "0x3b3b57de" as const addr(bytes32) selector — the inner call for an address record.
kinds.ens.SEL_TEXT const SEL_TEXT = "0x59d1d43c" as const text(bytes32,string) selector — the inner call for a text record.
kinds.ens.v2AddrCall function v2AddrCall(node: '0x${string}'): '0x${string}' The inner record call for ensV2: addr(node).
kinds.ens.v2TextCall function v2TextCall(node: '0x${string}', key: string): '0x${string}' The inner record call for ensV2: text(node, key).
kinds.ens.encodeV2Args function encodeV2Args(resolver: '0x${string}', inner: '0x${string}', isText: boolean): '0x${string}' ensV2 args: abi.encode(address resolver, bytes inner, bool isText).
kinds.attestation namespace chainc/attestation.ts — first-party identity/attestation resolver kinds, mirrored + drift-locked to IdentityResolver.sol.
kinds.attestation.KIND_VERIFIED const KIND_VERIFIED = stringToHex("identityVerified", { size: 32 })
kinds.attestation.KIND_CLAIM const KIND_CLAIM = stringToHex("identityClaim", { size: 32 })
kinds.attestation.encodeVerifiedArgs function encodeVerifiedArgs(subject: '0x${string}', schema: '0x${string}', uid: '0x${string}'): '0x${string}'
kinds.attestation.encodeClaimArgs function encodeClaimArgs(uid: '0x${string}', schema: '0x${string}', subject: '0x${string}'): '0x${string}'
kinds.por namespace chainc mirror for ProofOfReserveResolver — binding kinds + argument encoding, drift-locked against the on-chain resolver (contracts/examples/ProofOfReserveResolver.sol, docs/131).
kinds.por.KIND_RESERVES const KIND_RESERVES = stringToHex("por-reserves", { size: 32 }) Binding kinds, right-padded into bytes32 — mirror ProofOfReserveResolver.KIND_*.
kinds.por.KIND_SUPPLY const KIND_SUPPLY = stringToHex("por-supply", { size: 32 })
kinds.por.KIND_COVERAGE const KIND_COVERAGE = stringToHex("por-coverage", { size: 32 })
kinds.por.encodePorArgs function encodePorArgs(a: PorArgs): '0x${string}' abi.encode(address reserveFeed, address token, uint8 fracDigits, uint256 maxStaleSeconds) — all three kinds.
kinds.erc3643 namespace chainc mirror for Erc3643PermissionAdapter — binding kinds + argument encoding, drift-locked against the on-chain adapter (contracts/examples/Erc3643PermissionAdapter.sol, docs/133).
kinds.erc3643.KIND_VERIFIED const KIND_VERIFIED = stringToHex("erc3643-verified", { size: 32 }) Binding kinds, right-padded into bytes32 — mirror Erc3643PermissionAdapter.KIND_*.
kinds.erc3643.KIND_FROZEN const KIND_FROZEN = stringToHex("erc3643-frozen", { size: 32 })
kinds.erc3643.KIND_STATUS const KIND_STATUS = stringToHex("erc3643-status", { size: 32 })
kinds.erc3643.KIND_CANTX const KIND_CANTX = stringToHex("erc3643-can-transfer", { size: 32 })
kinds.erc3643.encodeHolderArgs function encodeHolderArgs(a: HolderArgs): '0x${string}' abi.encode(address token, address holder) — for erc3643-verified / -frozen / -status.
kinds.erc3643.encodeCanTransferArgs function encodeCanTransferArgs(a: CanTransferArgs): '0x${string}' abi.encode(address token, address from, address to, uint256 amount) — for erc3643-can-transfer.
kinds.credlife namespace chainc mirror for CredentialLifecycleResolver — binding kinds + argument encoding, drift-locked against the on-chain resolver (contracts/examples/CredentialLifecycleResolver.sol, docs/134).
kinds.credlife.KIND_STATUS const KIND_STATUS = stringToHex("cred-status", { size: 32 }) Binding kinds, right-padded into bytes32 — mirror CredentialLifecycleResolver.KIND_*.
kinds.credlife.KIND_VALID const KIND_VALID = stringToHex("cred-valid", { size: 32 })
kinds.credlife.encodeCredLifecycleArgs function encodeCredLifecycleArgs(a: CredLifecycleArgs): '0x${string}' abi.encode(address registry, bytes32 credentialId, address expectedIssuer) — both kinds.
kinds.efp namespace chainc mirror for EfpResolver — binding kinds + argument encoding, drift-locked against the on-chain resolver (contracts/examples/EfpResolver.sol, docs/149).
kinds.efp.KIND_FOLLOWS const KIND_FOLLOWS = stringToHex("efp-follows", { size: 32 }) Binding kinds, right-padded into bytes32 — mirror EfpResolver.KIND_*.
kinds.efp.KIND_TAG const KIND_TAG = stringToHex("efp-tag", { size: 32 })
kinds.efp.KIND_STATE const KIND_STATE = stringToHex("efp-state", { size: 32 })
kinds.efp.KIND_LIST_SIZE const KIND_LIST_SIZE = stringToHex("efp-list-size", { size: 32 })
kinds.efp.encodeForwardArgs function encodeForwardArgs(a: ForwardArgs): '0x${string}' abi.encode(address listRecords, uint256 slot, address target) — for efp-follows / efp-state.
kinds.efp.encodeTagArgs function encodeTagArgs(a: TagArgs): '0x${string}' abi.encode(address listRecords, uint256 slot, address target, string tag) — for efp-tag.
kinds.efp.encodeListSizeArgs function encodeListSizeArgs(a: ListSizeArgs): '0x${string}' abi.encode(address listRecords, uint256 slot) — for efp-list-size (raw op count; NOT a follower count).
kinds.addressrep namespace chainc mirror for AddressReputationResolver — binding kinds + argument encoding, drift-locked against the on-chain resolver (contracts/examples/AddressReputationResolver.sol) and its registry (AddressAttestationRegistry.sol, docs/149).
kinds.addressrep.KIND_VOUCH const KIND_VOUCH = stringToHex("rep-vouch", { size: 32 }) Binding kinds, right-padded into bytes32 — mirror AddressReputationResolver.KIND_*.
kinds.addressrep.KIND_TALLY const KIND_TALLY = stringToHex("rep-tally", { size: 32 })
kinds.addressrep.topic function topic(label: string): '0x${string}' Encode a caller-chosen topic label as bytes32 (e.g.
kinds.addressrep.encodeVouchArgs function encodeVouchArgs(a: VouchArgs): '0x${string}' abi.encode(address registry, address attester, address subject, bytes32 topic) — for rep-vouch.
kinds.addressrep.encodeTallyArgs function encodeTallyArgs(a: TallyArgs): '0x${string}' abi.encode(address registry, address[] attesters, address subject, bytes32 topic) — for rep-tally.
kinds.repagg namespace chainc mirror for ReputationAggregateResolver — binding kind + argument encoding, drift-locked against the on-chain resolver (contracts/examples/ReputationAggregateResolver.sol, docs/149).
kinds.repagg.KIND_AGGREGATE const KIND_AGGREGATE = stringToHex("rep-aggregate", { size: 32 }) Binding kind, right-padded into bytes32 — mirror ReputationAggregateResolver.KIND_AGGREGATE.
kinds.repagg.encodeAggregateArgs function encodeAggregateArgs(a: AggregateArgs): '0x${string}' abi.encode(address subject, address[] sources, bytes[] ctxs) — for rep-aggregate.
kinds.repagg.encodeEfpSourceCtx function encodeEfpSourceCtx(a: { listRecords: '0x${string}'; slot: bigint; requiredTag?: string; // "" (default) => follow alone is the signal excludeBlockedMuted?: boolean; // default false }): '0x${string}' ctx for an EfpReputationSource: abi.encode(address listRecords, uint256 slot, string requiredTag, bool excludeBlockedMuted).
kinds.repagg.encodeVouchSourceCtx function encodeVouchSourceCtx(a: { registry: '0x${string}'; attester: '0x${string}'; topic: '0x${string}'; // bytes32 (use addressreputation.topic() to build from a string) }): '0x${string}' ctx for a VouchReputationSource: abi.encode(address registry, address attester, bytes32 topic).
kinds.ccip namespace chainc mirror for CcipResolver — binding kinds + argument encoding, drift-locked against the on-chain resolver (contracts/examples/CcipResolver.sol, docs/154/155).
kinds.ccip.KIND_SUPPORTED const KIND_SUPPORTED = stringToHex("ccip-supported", { size: 32 }) Binding kinds, right-padded into bytes32 — mirror CcipResolver.KIND_*.
kinds.ccip.KIND_FEE const KIND_FEE = stringToHex("ccip-fee", { size: 32 })
kinds.ccip.encodeSupportedArgs function encodeSupportedArgs(a: SupportedArgs): '0x${string}' abi.encode(address router, uint64 destSelector) — for ccip-supported.
kinds.ccip.encodeFeeArgs function encodeFeeArgs(a: FeeArgs): '0x${string}' abi.encode(address router, uint64 destSelector, address feeToken, address receiver, uint256 gasLimit, uint8 feeDecimals, uint8 fracDigits) — for ccip-fee.
kinds.messaging namespace chainc/messaging.ts — first-party MESSAGING + note-privacy resolver kinds and client-side decoders, mirrored + drift-locked to the on-chain resolvers (contracts/examples/Sig1271Resolver.sol, StealthMetaResolver.sol, ShieldedPoolViewResolver.sol) and grounded in the authoritative specs (ERC-1271, ERC-6538/5564, ERC-3722, EIP-712; see docs/157).
kinds.messaging.KIND_SIG_1271 const KIND_SIG_1271 = stringToHex("sig-1271", { size: 32 }) ───────────────────────────────────────────────────────────────────────────────────────────────────────────── Binding kinds, right-padded into bytes32 — mirror the on-chain KIND_* constants (≤ 32 ASCII chars each).
kinds.messaging.KIND_STEALTH_META const KIND_STEALTH_META = stringToHex("stealth-meta", { size: 32 })
kinds.messaging.KIND_SHIELDED_ROOT const KIND_SHIELDED_ROOT = stringToHex("shielded-root", { size: 32 })
kinds.messaging.KIND_SHIELDED_SET const KIND_SHIELDED_SET = stringToHex("shielded-set", { size: 32 })
kinds.messaging.KIND_SHIELDED_NULLIFIER const KIND_SHIELDED_NULLIFIER = stringToHex("shielded-nullifier", { size: 32 })
kinds.messaging.KIND_MSG_712 const KIND_MSG_712 = stringToHex("msg-712", { size: 32 }) client-side / off-chain kinds (≤ C by construction — see the render/adapter helpers below)
kinds.messaging.KIND_POSTER_FEED const KIND_POSTER_FEED = stringToHex("poster-feed", { size: 32 })
kinds.messaging.KIND_STEALTH_SCAN const KIND_STEALTH_SCAN = stringToHex("stealth-scan", { size: 32 })
kinds.messaging.encodeSig1271Args function encodeSig1271Args(account: '0x${string}', hash: '0x${string}', signature: '0x${string}'): '0x${string}' abi.encode(address account, bytes32 hash, bytes signature) — for sig-1271.
kinds.messaging.encodeStealthMetaArgs function encodeStealthMetaArgs(registry: '0x${string}', registrant: '0x${string}', schemeId: bigint = 1n,): '0x${string}' abi.encode(address registry, address registrant, uint256 schemeId) — for stealth-meta.
kinds.messaging.encodeShieldedArgs function encodeShieldedArgs(pool: '0x${string}', callData: '0x${string}'): '0x${string}' abi.encode(address pool, bytes callData) — shared by shielded-root / shielded-set / shielded-nullifier.
kinds.messaging.renderTyped712 function renderTyped712(t: Typed712): RenderedMessage Render an EIP-712 typed message honestly.
kinds.messaging.decodePrivacyLeaks function decodePrivacyLeaks(action: ShieldedAction):
kinds.messaging.POSTER_NEWPOST_TOPIC0 const POSTER_NEWPOST_TOPIC0 = keccak256(toBytes("NewPost(address,string,string)")) keccak topic0 for NewPost(address,string,string) — DERIVED from the signature (no hardcoded constant).
kinds.messaging.posterFeedFilter function posterFeedFilter(poster: '0x${string}', tagTopic?: '0x${string}'): PosterLogFilter Build an eth_getLogs filter for a Poster contract, optionally filtered by an indexed tag (keccak of the tag).
kinds.skeletal namespace chainc/skeletalanim.ts — DECLARATIVE SKELETAL ANIMATION as on-chain DATA (doc 158/159).
kinds.skeletal.POS_SCALE const POS_SCALE = 16 ── fixed-point scales (deterministic, lossless within quantization) ──
kinds.skeletal.ANG_SCALE const ANG_SCALE = 32768
kinds.skeletal.MAGIC const MAGIC = 0x4352434c
kinds.skeletal.PACK_VERSION const PACK_VERSION = 1
kinds.skeletal.KIND_CLIP_COUNT const KIND_CLIP_COUNT = k32("clip-count")
kinds.skeletal.KIND_CLIP_SLICE const KIND_CLIP_SLICE = k32("clip-slice")
kinds.skeletal.encodePack function encodePack(lib: ClipLibrary, ceilingHint = 0): Uint8Array Encode a library to its canonical bytes.
kinds.skeletal.decodePack function decodePack(bytes: Uint8Array): ClipLibrary Decode canonical bytes back to a library.
kinds.skeletal.evalPose function evalPose(lib: ClipLibrary, clipIndex: number, frame: number): Pt[] Evaluate world joint positions for a clip on its rig at a given frame.
kinds.skeletal.renderPuppetSVG function renderPuppetSVG(lib: ClipLibrary, clipIndex: number, frame: number, o: PuppetOpts = {}): string Render a pose as an SVG "vector puppet" — bones as round-capped lines, head as a circle.
kinds.skeletal.packReport function packReport(lib: ClipLibrary, ceiling: number): PackReport
kinds.skeletal.HUMANOID const HUMANOID: Rig = { … } A 15-joint humanoid (hip root → spine → head; two arms hanging from shoulders; two full legs).
kinds.skeletal.QUADRUPED const QUADRUPED: Rig = { … } A 13-joint side-view QUADRUPED (dog/horse-like), facing +x.
kinds.skeletal.AVIAN const AVIAN: Rig = { … } A 13-joint side-view AVIAN (bird), facing +x: body → chest → neck → head → beak; one wing (shoulder/mid/tip); one leg (hip/knee/foot); tail.
kinds.skeletal.INSECTOID const INSECTOID: Rig = { … } A 13-joint side-view INSECTOID (ant/beetle), facing +x: thorax root, head + antenna forward, abdomen rear, and THREE legs (front/mid/rear) each hip→knee→foot.
kinds.skeletal.MARINE const MARINE: Rig = { … } A 9-joint side-view MARINE (fish), facing +x: an undulating spine (tail-base root → mid1 → mid2 → head), a caudal fin (top/bottom), a dorsal fin, and a pectoral fin.
kinds.skeletal.buildReferenceLibrary function buildReferenceLibrary(): ClipLibrary Build a varied reference library.
kinds.settlement namespace chainc mirror for SettlementCardResolver — binding kinds + argument encoding, drift-locked against the on-chain resolver (contracts/examples/SettlementCardResolver.sol, docs/172 §8/§9).
kinds.settlement.KIND_STATUS const KIND_STATUS = stringToHex("settle-status", { size: 32 }) Binding kinds, right-padded into bytes32 — mirror SettlementCardResolver.KIND_*.
kinds.settlement.KIND_REPAID const KIND_REPAID = stringToHex("settle-repaid", { size: 32 })
kinds.settlement.KIND_PRINCIPAL const KIND_PRINCIPAL = stringToHex("settle-principal", { size: 32 })
kinds.settlement.SETTLEMENT_STATUS const SETTLEMENT_STATUS = { … } as const The agreement status enum, mirroring AttestedLoanChannel/LoanChannel Status (docs/172 §9).
kinds.settlement.SETTLEMENT_GRADE const SETTLEMENT_GRADE = { … } as const The honest grade boundary the settlement framework renders (docs/172 §5).
kinds.settlement.encodeSettlementArgs function encodeSettlementArgs(a: SettlementArgs): '0x${string}' abi.encode(address agreement, uint8 assetDecimals, uint8 fracDigits) — shared by all three kinds.
kinds.trustFacets namespace chainc mirror for TrustDisclosureResolver + the shared TrustFacets library (docs/174) — the declarative trust-disclosure vocabulary every ChainRender card composes instead of hand-writing honesty prose.
kinds.trustFacets.KIND_FACETS const KIND_FACETS = stringToHex("trust-facets", { size: 32 }) Binding kind, right-padded bytes32 — mirror TrustDisclosureResolver.KIND_FACETS.
kinds.trustFacets.CUSTODY const CUSTODY = { … } as const enum ordinals — mirror TrustFacets.{Custody,Exit,RelayerBinding,Artifact}
kinds.trustFacets.EXIT const EXIT = { … } as const
kinds.trustFacets.RELAYER_BINDING const RELAYER_BINDING = { … } as const
kinds.trustFacets.ARTIFACT const ARTIFACT = { … } as const
kinds.trustFacets.relayerIsBound function relayerIsBound(b: number): boolean True iff a relayer/submitter CANNOT rewrite the bound payload — mirror TrustFacets.relayerIsBound.
kinds.trustFacets.custodyWord const custodyWord = (c: number) => …
kinds.trustFacets.exitWord const exitWord = (e: number) => …
kinds.trustFacets.relayerWord const relayerWord = (b: number) => …
kinds.trustFacets.artifactWord const artifactWord = (a: number) => …
kinds.trustFacets.renderTrustFacetsLine function renderTrustFacetsLine(f: TrustFacets): string The compact one-line honest summary — mirror TrustFacets.line (joined by " · ").
kinds.trustFacets.encodeTrustArgs function encodeTrustArgs(subject: '0x${string}'): '0x${string}' abi.encode(address subject) — the resolver's args for KIND_FACETS.
kinds.trustFacets.trustFacetsVocabulary function trustFacetsVocabulary() Machine-readable vocabulary for the SDK/MCP/AI: the facet dimensions and their allowed values.
kinds.door namespace chainc mirror for the "door" capability (docs/174) — the zipcoin Doorstep learning, ChainRender-native and split honestly across the two grade axes: • door-knocks — ON-CHAIN aggregate (total burned, knock count, loudest knock) read from a DoorRegistry via a view → Grade A.
kinds.door.KIND_DOOR_KNOCKS const KIND_DOOR_KNOCKS = stringToHex("door-knocks", { size: 32 }) Binding kinds, right-padded bytes32 — door-knocks mirrors DoorResolver.KIND_DOOR_KNOCKS.
kinds.door.KIND_DOOR_FEED const KIND_DOOR_FEED = stringToHex("door-feed", { size: 32 })
kinds.door.doorTargetFromAddress function doorTargetFromAddress(addr: '0x${string}'): '0x${string}' A door key: an address left-padded to 32 bytes.
kinds.door.encodeDoorArgs function encodeDoorArgs(registry: '0x${string}', target: '0x${string}', assetDecimals: number, fracDigits: number,): '0x${string}' abi.encode(address registry, bytes32 target, uint8 assetDecimals, uint8 fracDigits) — for door-knocks (Grade A).
kinds.door.KNOCK_TOPIC0 const KNOCK_TOPIC0 = keccak256(toBytes("Knock(bytes32,address,uint256,string)")) topic0 for Knock(...) — DERIVED from the signature (no hardcoded constant), mirroring DoorRegistry's event.
kinds.door.doorFeedFilter function doorFeedFilter(registry: '0x${string}', target?: '0x${string}'): DoorLogFilter Build an eth_getLogs filter for a DoorRegistry, optionally scoped to one target (the first indexed topic).
kinds.door.rankKnocks function rankKnocks(knocks: Knock[]): Knock[] Rank decoded knocks loudest-first (the weight-sorted message list).
kinds.proofBadge namespace chainc mirror for the artifact-pinning badge (docs/174, zipcoin learning #3) — honestly split: • proof-setup — ON-CHAIN: a digest is pinned in a SetupPinRegistry (content-addressed).
kinds.proofBadge.KIND_PROOF_SETUP const KIND_PROOF_SETUP = stringToHex("proof-setup", { size: 32 }) Binding kinds — proof-setup mirrors ProofBadgeResolver.KIND_PROOF_SETUP.
kinds.proofBadge.KIND_ARTIFACT_VERIFY const KIND_ARTIFACT_VERIFY = stringToHex("artifact-verify", { size: 32 })
kinds.proofBadge.pinId function pinId(sha256Digest: '0x${string}', uri: string): '0x${string}' Content-addressed pin id — mirror SetupPinRegistry.idOf: keccak256(abi.encode(bytes32 sha256, string uri)).
kinds.proofBadge.encodeProofSetupArgs function encodeProofSetupArgs(registry: '0x${string}', id: '0x${string}'): '0x${string}' abi.encode(address registry, bytes32 id) — for proof-setup (Grade A).
kinds.proofBadge.verifyArtifact function verifyArtifact(bytes: Uint8Array, expectedSha256: '0x${string}'): ArtifactVerdict ≤ C client check: SHA-256 the FETCHED artifact bytes and compare to the on-chain-pinned digest.
kinds.proofBadge.renderArtifactBadge function renderArtifactBadge(v: ArtifactVerdict): string A short honest badge string for the ≤ C verdict.
kinds.computeCredit namespace chainc mirror for the play-key metered-compute adapter (docs/174 §6 #4) — drift-locked to contracts/examples/ComputeCreditVault.sol + ComputeCreditResolver.sol.
kinds.computeCredit.KIND_COMPUTE_CREDIT const KIND_COMPUTE_CREDIT = stringToHex("compute-credit", { size: 32 }) Binding kind — mirror ComputeCreditResolver.KIND_COMPUTE_CREDIT.
kinds.computeCredit.encodeComputeCreditArgs function encodeComputeCreditArgs(vault: '0x${string}', playKey: '0x${string}', assetDecimals: number, fracDigits: number,): '0x${string}' abi.encode(address vault, address playKey, uint8 assetDecimals, uint8 fracDigits) — for compute-credit (A).
kinds.computeCredit.usageReceiptTypedData function usageReceiptTypedData(params: { vault: '0x${string}'; chainId: number; playKey: '0x${string}'; provider: '0x${string}'; cumulativeSpent: bigint; }) The EIP-712 typed data a PLAY-KEY signs to authorize the provider to draw down to cumulativeSpent.
kinds.computeCredit.splitSig function splitSig(sig: '0x${string}'): Split a 65-byte signature into the (v, r, s) the vault's claim() takes.
kinds.xchain namespace chainc mirror for the doc 175 / docs/176 Milestone 1 cross-chain balance stack — drift-locked to contracts/xchain/{CanonicalTokenLayout,CanonicalTokenFactory,XchainBalanceCache,XchainBalanceResolver}.sol.
kinds.xchain.KIND_XCHAIN_BALANCE const KIND_XCHAIN_BALANCE = stringToHex("xchain-balance", { size: 32 }) Binding kind, right-padded bytes32 — mirror XchainBalanceResolver.KIND_XCHAIN_BALANCE.
kinds.xchain.CANONICAL_TOKEN_NAMESPACE const CANONICAL_TOKEN_NAMESPACE = "chainrender.xchain.CanonicalToken.v1" Approved storage namespace (2026-10-06) — mirror CanonicalTokenLayout.CANONICAL_TOKEN_NAMESPACE.
kinds.xchain.erc7201Base function erc7201Base(id: string): Hex ERC-7201: keccak256(abi.encode(uint256(keccak256(id)) - 1)) & ~0xff.
kinds.xchain.CANONICAL_TOKEN_BASE const CANONICAL_TOKEN_BASE = erc7201Base(CANONICAL_TOKEN_NAMESPACE) Mirror CanonicalTokenLayout.CANONICAL_TOKEN_BASE (recomputed, never typed in).
kinds.xchain.balanceSlot function balanceSlot(holder: Hex, base: Hex = CANONICAL_TOKEN_BASE): Hex Slot of balances[holder] in a CanonicalToken — mirror ICanonicalState.balanceSlot.
kinds.xchain.recordSlot function recordSlot(token: Hex): Hex Slot of the factory's recordOf[token] (slot 0 mapping) — mirror CanonicalTokenFactory.recordSlot.
kinds.xchain.definitionId function definitionId(p: { name: string; symbol: string; decimals: number; homeChainId: bigint; layoutHash: Hex; issueHash: Hex; }): Hex Mirror CanonicalTokenFactory.definitionIdOf / XchainBalanceCache._definitionId.
kinds.xchain.layoutHash function layoutHash(tokenCreationCodeHash: Hex, base: Hex = CANONICAL_TOKEN_BASE): Hex layoutHash = keccak256(abi.encode(tokenCreationCodeHash, anchorMode=0, adapter="erc20", privacyMode=0, base)).
kinds.xchain.issueHash function issueHash(creator: Hex, supply: bigint, recipient: Hex): Hex issueHash = keccak256(abi.encode(creator, supply, recipient)).
kinds.xchain.encodeXchainBalanceArgs function encodeXchainBalanceArgs(token: Hex, holder: Hex, maxAgeSeconds: bigint, fracDigits: number): Hex abi.encode(address token, address holder, uint64 maxAgeSeconds, uint8 fracDigits) — the resolver's args.
kinds.xchain.MAX_SYMBOL_LENGTH const MAX_SYMBOL_LENGTH = 11 Mirror XchainBalanceCache.MAX_SYMBOL_LENGTH / MAX_DECIMALS (also enforced by the factory and the resolver).
kinds.xchain.MAX_DECIMALS const MAX_DECIMALS = 77
kinds.xchain.isValidSymbol function isValidSymbol(s: string): boolean Mirror XchainBalanceCache.isValidSymbol: [A-Za-z0-9]{1,11}.
kinds.xchain.MAX_HOST_LABEL_LENGTH const MAX_HOST_LABEL_LENGTH = 32 Mirror XchainBalanceResolver.MAX_HOST_LABEL_LENGTH / isValidHostLabel: [A-Za-z0-9 .-]{1,32}, no edge spaces.
kinds.xchain.isValidHostLabel function isValidHostLabel(s: string): boolean
kinds.xchain.MAX_HOST_FACET_LENGTH const MAX_HOST_FACET_LENGTH = 48 Mirror XchainBalanceResolverV2.MAX_HOST_FACET_LENGTH / isValidHostFacet: [A-Za-z0-9 .,:-]{1,48}, no edge spaces.
kinds.xchain.isValidHostFacet function isValidHostFacet(s: string): boolean
kinds.xchain.formatFixed function formatFixed(value: bigint, decimals: number, fracDigits: number): string Mirror DecimalStrings.formatFixed (truncating; scales up when decimals < fracDigits).
kinds.xchain.gradeWord function gradeWord(g: number): string
kinds.xchain.pickEntry function pickEntry(v: XchainBalanceView, maxAgeSeconds: bigint): Mirror XchainBalanceResolver._pick: fresh beats stale; then highest grade; then newest.
kinds.xchain.renderXchainBalance function renderXchainBalance(v: XchainBalanceView, maxAgeSeconds: bigint, fracDigits: number): string Mirror XchainBalanceResolver.render — the exact string the on-chain resolver produces.
kinds.xchain.readXchainView async function readXchainView(cache: any, token: Hex, holder: Hex, now: bigint, host: string, facet = ""): Promise<XchainBalanceView> Read everything renderXchainBalance needs from a deployed cache (for off-chain previews and drift tests).
kinds.xchain.encodeHeader function encodeHeader(raw: Record<string, string>): Hex RLP-encode a block header from the raw eth_getBlockByNumber JSON.
kinds.xchain.waitUntilProvable async function waitUntilProvable(client: Requester, number: bigint, opts: { pollMs?: number; timeoutMs?: number; mine?: () => Promise<unknown> } = {}): Promise<bigint> A SAME-CHAIN root for block number exists only once block number + 1 exists: BLOCKHASH(n) is zero while n is the current block, and SameChainRootSource reverts RootUnavailable(n) for n >= block.number.
kinds.xchain.headerFor async function headerFor(client: Requester, number: bigint): Promise<{ rlpHeader: Hex; hash: Hex }> Fetch + encode block number's header, verifying it hashes to the block hash (fail closed).
kinds.xchain.buildBalanceProof async function buildBalanceProof(client: Requester, token: Hex, holder: Hex, number: bigint, base: Hex = CANONICAL_TOKEN_BASE) Proof bundle for XchainBalanceCache.refresh.
kinds.xchain.buildRecordProof async function buildRecordProof(client: Requester, factory: Hex, token: Hex, number: bigint) Proof bundle for XchainBalanceCache.registerToken.
kinds.xchain.ARB_ALIAS_OFFSET const ARB_ALIAS_OFFSET = 0x1111000000000000000000000000000000001111n Arbitrum L1→L2 alias offset (protocol constant of the Arbitrum stack; Arbitrum docs) — mirror ArbParentRootSource.
kinds.xchain.l1ToL2Alias function l1ToL2Alias(address: Hex): Hex The address a parent-chain CONTRACT appears as on the child chain: address + offset, mod 2^160.
kinds.xchain.ARB_PRECOMPILES const ARB_PRECOMPILES = { … } Arbitrum precompile addresses (Arbitrum docs) — config, overridable per chain.
kinds.xchain.retryableParams async function retryableParams(opts: { parent: any; child: any; inbox: Hex; sender: Hex; receiver: Hex; data: Hex; refund: Hex; margin?: bigint; nodeInterface?: Hex; }): Promise<RetryableParams> Fees for one ArbRootSender.deliver.
kinds.xchain.waitForRoot async function waitForRoot(receiver: any, n: bigint, opts: { pollMs?: number; timeoutMs?: number } = {}): Promise<Hex> Poll the child-chain ArbParentRootSource until block n's root has arrived.
kinds.xchain.assertResolverForHost function assertResolverForHost(resolver: "XchainBalanceResolver" | "XchainBalanceResolverV2", homeChainId: bigint, hostChainId: bigint, facet = ""): void docs/177 L-3 — which resolver may render a cache on a given host.
kinds.scopeDisclosure namespace chainc mirror for ScopeDisclosureResolver + IScopeDisclosure (doc 175 X7, docs/176 §3.8 / §4.2): what a subject's trust grade does NOT establish.
kinds.scopeDisclosure.KIND_SCOPE_DISCLOSURE const KIND_SCOPE_DISCLOSURE = stringToHex("scope-disclosure", { size: 32 }) Binding kind, right-padded bytes32 — mirror ScopeDisclosureResolver.KIND_SCOPE_DISCLOSURE.
kinds.scopeDisclosure.SCOPE_DISCLOSURE_INTERFACE_ID const SCOPE_DISCLOSURE_INTERFACE_ID: Hex = toFunctionSelector("doesNotEstablish()") ERC-165 id of IScopeDisclosure (single function).
kinds.scopeDisclosure.NOT_DISCLOSED const NOT_DISCLOSED = "scope not disclosed"
kinds.scopeDisclosure.MAX_ITEMS const MAX_ITEMS = 16 Mirror ScopeDisclosureResolver bounds: a longer list, or a longer item, renders NOT_DISCLOSED.
kinds.scopeDisclosure.MAX_ITEM_BYTES const MAX_ITEM_BYTES = 160
kinds.scopeDisclosure.encodeScopeArgs function encodeScopeArgs(subject: Hex): Hex abi.encode(address subject) — the resolver's args.
kinds.scopeDisclosure.renderScopeDisclosure function renderScopeDisclosure(list: string[] | null): string Mirror ScopeDisclosureResolver.render for a subject that returned list (null = not implemented / failed).
kinds.scopeDisclosure.scopeDisclosureVocabulary function scopeDisclosureVocabulary() Machine-readable note for the SDK/MCP/AI.
kinds.xsnap namespace chainc mirror for docs/178 Mode A (snapshot balances) — drift-locked to contracts/xchain/{BalanceSnapshotter, SnapshotBalanceCache,SnapshotBalanceResolver}.sol.
kinds.xsnap.KIND_XCHAIN_SNAPSHOT_BALANCE const KIND_XCHAIN_SNAPSHOT_BALANCE = stringToHex("xchain-snapshot-balance", { size: 32 }) Binding kind, right-padded bytes32 — mirror SnapshotBalanceResolver.KIND_XCHAIN_SNAPSHOT_BALANCE.
kinds.xsnap.encodeSnapshotBalanceArgs function encodeSnapshotBalanceArgs(token: Hex, holder: Hex, maxAgeSeconds: bigint, fracDigits: number): Hex
kinds.xsnap.snapshotCommitment function snapshotCommitment(value: bigint, decimals: number, codeHash: Hex, snapBlock: bigint, snapTime: bigint): Hex
kinds.xsnap.metadataCommitment function metadataCommitment(name: string, symbol: string, codeHash: Hex, metaBlock: bigint): Hex
kinds.xsnap.metaSlot function metaSlot(token: Hex): Hex metaOf[token] — slot 0.
kinds.xsnap.snapSlot function snapSlot(token: Hex, holder: Hex): Hex snapOf[token][holder] — slot 1.
kinds.xsnap.isValidName function isValidName(s: string): boolean Mirror BalanceSnapshotter/SnapshotBalanceCache.isValidName: printable ASCII, 1..64 bytes.
kinds.xsnap.buildSnapshotProof async function buildSnapshotProof(client: Requester & LogReader, snapshotter: Hex, token: Hex, holder: Hex, n: bigint, opts: { fromBlock?: bigint } = {}) Arguments for SnapshotBalanceCache.refresh: the latest snapshot of (token, holder) as of home block n, its preimage read from the snapshotter's Snapshot events (relies on the RPC serving those logs — docs/178 §3.3) and checked against the slot at n before anything is returned (fail closed).
kinds.xsnap.buildMetadataProof async function buildMetadataProof(client: Requester & LogReader, snapshotter: Hex, token: Hex, n: bigint, opts: { fromBlock?: bigint } = {}) Arguments for SnapshotBalanceCache.registerToken (latest metadata as of block n), checked against the slot.
kinds.xsnap.renderSnapshotBalance function renderSnapshotBalance(v: SnapshotView, maxAgeSeconds: bigint, fracDigits: number): string Mirror SnapshotBalanceResolver.render.
kinds.xsnap.readSnapshotView async function readSnapshotView(cache: any, token: Hex, holder: Hex, now: bigint, host: string, facet = ""): Promise<SnapshotView> Read everything renderSnapshotBalance needs from a deployed SnapshotBalanceCache + resolver host settings.
kinds.xadopt namespace chainc mirror for docs/178 Mode B (storage-layout adoption of existing tokens) — drift-locked to contracts/xchain/{TokenAdoptionRegistry,AdoptedBalanceCache,AdoptedBalanceResolver}.sol and the adapters in contracts/xchain/adapters/.
kinds.xadopt.KIND_XCHAIN_ADOPTED_BALANCE const KIND_XCHAIN_ADOPTED_BALANCE = stringToHex("xchain-adopted-balance", { size: 32 }) Binding kind, right-padded bytes32 — mirror AdoptedBalanceResolver.KIND_XCHAIN_ADOPTED_BALANCE.
kinds.xadopt.ADOPTED_GRADE_CEILING const ADOPTED_GRADE_CEILING = 1
kinds.xadopt.ADOPTED const ADOPTED = 1
kinds.xadopt.CONFIRMED const CONFIRMED = 2
kinds.xadopt.encodeAdoptedBalanceArgs function encodeAdoptedBalanceArgs(claimId: Hex, holder: Hex, maxAgeSeconds: bigint, fracDigits: number): Hex
kinds.xadopt.ADOPTION_RECORD_ABI const ADOPTION_RECORD_ABI = { … } as const
kinds.xadopt.adoptionClaimId function adoptionClaimId(r: AdoptionRecord): Hex claimId = keccak256(abi.encode(record)) — mirror TokenAdoptionRegistry.claimIdOf.
kinds.xadopt.registryStateSlot function registryStateSlot(claimId: Hex): Hex stateOf[claimId] — slot 0 of the registry.
kinds.xadopt.shortClaimId function shortClaimId(claimId: Hex): string 0x + first 8 hex + "…" + last 8 hex — mirror AdoptedBalanceResolver._shortId.
kinds.xadopt.plainPinningParams const plainPinningParams = (): Hex => …
kinds.xadopt.slotProxyPinningParams function slotProxyPinningParams(implSlot: Hex, implementation: Hex, implCodeHash: Hex): Hex
kinds.xadopt.mappingWordLayoutParams function mappingWordLayoutParams(keyOrder: 0 | 1, baseSlot: bigint | Hex, valueBits: number): Hex keyOrder 0 = Solidity keccak256(abi.encode(holder, baseSlot)); 1 = keccak256(abi.encode(baseSlot, holder)).
kinds.xadopt.mappingWordLayout const mappingWordLayout = { … } as const
kinds.xadopt.DELEGATING const DELEGATING = new Set([0xf2, 0xf4])
kinds.xadopt.PURE_ALLOWED const PURE_ALLOWED: Set<number> = (() => …
kinds.xadopt.firstReachable function firstReachable(code: Hex, refused: (op: number) => boolean): First reachable opcode for which refused(op) is true — mirror CodeScan.firstReachable.
kinds.xadopt.hasPush function hasPush(code: Hex, width: number, immediate: Hex): boolean Mirror CodeScan.hasPush (immediate as a 0x hex string of exactly width bytes).
kinds.xadopt.isPureAdapterCode const isPureAdapterCode = (code: Hex) => …
kinds.xadopt.planFor async function planFor(client: Reader, c: Claim, holder: Hex, n: bigint): Promise<Plan> What the on-chain core will prove for holder (AdoptedStateLib.plan), asked of the claim's adapters at block n.
kinds.xadopt.buildAdoptedStateProof async function buildAdoptedStateProof(client: Reader, c: Claim, holder: Hex, n: bigint): Promise<{ proof: StateProof; value: bigint; plan: Plan }> A StateProof for holder under claim c at home block n (for confirmWitness at the adoption block, or refresh at any block the root source vouches for): one eth_getProof per account with that account's slots.
kinds.xadopt.buildRegistryProof async function buildRegistryProof(client: Requester, registry: Hex, claimId: Hex, n: bigint) A RegistryProof (AdoptedBalanceCache.register): the registry account and stateOf[claimId] at block n.
kinds.xadopt.ADOPTED_EVENT const ADOPTED_EVENT = parseAbiItem("event Adopted(bytes32 indexed claimId, address indexed token, address indexed by, ((address token, bytes32 codeHash, (address adapter, bytes32 codeHash, bytes para…
kinds.xadopt.recordOf async function recordOf(client: Reader, registry: Hex, claimId: Hex, opts: { fromBlock?: bigint; toBlock?: bigint } = {}): Promise<AdoptionRecord> The AdoptionRecord of claimId from the registry's Adopted event; checked against the id (fail closed).
kinds.xadopt.renderAdoptedBalance function renderAdoptedBalance(v: AdoptedView, maxAgeSeconds: bigint, fracDigits: number): string Mirror AdoptedBalanceResolver.render.
kinds.xadopt.readAdoptedView async function readAdoptedView(cache: any, claimId: Hex, holder: Hex, now: bigint, host: string, facet = ""): Promise<AdoptedView> Read everything renderAdoptedBalance needs from a deployed AdoptedBalanceCache + the resolver's host settings.
kinds.xswap namespace chainc mirror for docs/179 Milestone 4 — the bridge-free cross-chain swap (timelock-swap, doc 175 §5.5): HashTimelockSwap (same code on every chain), SwapLockProofCache (proves a home lock on another chain and guards the second lock) and SwapLockResolver ("swap-lock").
kinds.xswap.KIND_SWAP_LOCK const KIND_SWAP_LOCK = stringToHex("swap-lock", { size: 32 }) Binding kind, right-padded bytes32 — mirror SwapLockResolver.KIND_SWAP_LOCK.
kinds.xswap.SWAP_OPEN const SWAP_OPEN = 1
kinds.xswap.SWAP_CLAIMED const SWAP_CLAIMED = 2
kinds.xswap.SWAP_REFUNDED const SWAP_REFUNDED = 3
kinds.xswap.SWAP_TERMS_ABI const SWAP_TERMS_ABI = { … } as const
kinds.xswap.swapId function swapId(chainId: bigint, swap: Hex, t: SwapTerms): Hex Mirror HashTimelockSwap.idOf / SwapLockProofCache.homeIdOf: keccak256(abi.encode(chainId, swap, terms)).
kinds.xswap.hashlockOf function hashlockOf(secret: Hex): Hex Mirror HashTimelockSwap.hashOf: sha256 of the 32-byte secret.
kinds.xswap.swapStateSlot function swapStateSlot(id: Hex): Hex Mirror HashTimelockSwap.stateSlot: keccak256(abi.encode(id, uint256(0))).
kinds.xswap.encodeSwapLockArgs function encodeSwapLockArgs(id: Hex, maxAgeSeconds: bigint, fracDigits: number): Hex abi.encode(bytes32 id, uint64 maxAgeSeconds, uint8 fracDigits) — the resolver's args.
kinds.xswap.guardVerdict function guardVerdict(counterpart: { state: number; terms: SwapTerms; tokenRegistered: boolean } | null, mine: SwapTerms, guard: Hex, nowTs: bigint, minGap: bigint, minWindow: bigint): string | null The guard rule SwapLockProofCache.checkLock enforces, for clients that want to explain a refusal before sending.
kinds.xswap.shortAddress function shortAddress(a: Hex): string Mirror SwapLockResolver._short: "0x" + first 4 bytes + "…" + last 4 bytes, lowercase.
kinds.xswap.renderSwapLock function renderSwapLock(v: SwapLockView, maxAgeSeconds: bigint, fracDigits: number): string Mirror SwapLockResolver.render — the exact string the on-chain resolver produces.
kinds.xswap.readSwapLockView async function readSwapLockView(locks: any, balances: any | null, id: Hex, now: bigint, homeLabel: string, host: string, facet = ""): Promise<SwapLockView> Read everything renderSwapLock needs from deployed contracts (previews and drift tests).
kinds.xswap.buildLockProof async function buildLockProof(client: Requester, swap: Hex, id: Hex, number: bigint) Proof bundle for SwapLockProofCache.proveLock: home header + home swap account proof + stateOf[id] proof.
kinds.xswap.tokenCreationCodeHashFromFactory function tokenCreationCodeHashFromFactory(factoryRuntime: Hex, artifactCreation: Hex): Hex keccak256 of the CanonicalToken creation code AS EMBEDDED IN A DEPLOYED FACTORY — the input of the factory's layoutHash.
kinds.xswap.confirmCreationCodeHash function confirmCreationCodeHash(creationCodeHash: Hex, t: { name: string; symbol: string; decimals: number; homeChainId: bigint; creator: Hex; supply: bigint; recipient: Hex; definitionId: Hex }): boolean True when creationCodeHash reproduces a real token's definition id (factory.definitionIdOf, chainc mirror).
kinds.RESOLVER_KINDS const RESOLVER_KINDS: ResolverKindDescriptor[] = [ … ] The first-party on-chain resolver kinds ChainRender ships, drift-locked to their mirrors.
kinds.assertEdgeHonesty function assertEdgeHonesty(kinds: ResolverKindDescriptor[] = RESOLVER_KINDS): void Invariant R2 (edge honesty by construction).
kinds.edgeCeiling function edgeCeiling(k: ResolverKindDescriptor): "A" | "C" The honest grade CEILING a kind's data edge implies: off-chain → "C" (Live), on-chain → "A" (Trustless).
kinds.HOST_CHAIN_ENTRY const HOST_CHAIN_ENTRY = "anything beyond the host chain's own consensus (host-chain grade)" Doc 175 host-chain facet every X7 list must carry.
kinds.assertCrosschainHonesty function assertCrosschainHonesty(kinds: ResolverKindDescriptor[] = RESOLVER_KINDS): void Doc 175 X1 + X7 (cross-chain honesty by construction).
kinds.xchainCeiling function xchainCeiling(k: ResolverKindDescriptor, source: string): "A" | "C" The grade ceiling of an xchain kind fed by source: min(edge ceiling, that source's ceiling).

reads (namespace)

v0.11.0: generic on-chain reads — arg encoders for the staticread (CallResolver: any view function on any co-located contract, STATICCALL-only) and multiread (MultiCallResolver) slots; the most common way an app shows its own contract's state. reads.staticReadSlot(resolver, { target, callData: reads.callData("totalSupply()") }).

Source: chainc/callresolver.ts

Member Signature Summary
reads.STATICREAD_KIND const STATICREAD_KIND = "staticread"
reads.STATICREAD_KIND_HEX const STATICREAD_KIND_HEX = stringToHex("staticread", { size: 32 })
reads.RET const RET = { … } as const How CallResolver decodes the target's return bytes.
reads.FMT const FMT = { … } as const How CallResolver formats the decoded value.
reads.callData function callData(signature: string, args: readonly unknown[] = []): '0x${string}' Build the STATICCALL calldata from a human signature + args.
reads.staticReadArg function staticReadArg(spec: StaticReadSpec): '0x${string}' Encode the CallResolver arg bytes for a slot.
reads.staticReadSlot function staticReadSlot(resolver: '0x${string}', spec: StaticReadSpec, fallback = "\u2014") Build a ready-to-drop slot node that reads spec via the deployed CallResolver at resolver.
reads.STATICREAD_DESCRIPTOR const STATICREAD_DESCRIPTOR = { … } as const Machine-readable descriptor for SDK / builder / assistant discovery (generic, extensible kind).
reads.MULTIREAD_KIND const MULTIREAD_KIND = "multiread" ── multi-read (contracts/MultiCallResolver.sol) ──
reads.COMBINE const COMBINE = { … } as const Combine modes.
reads.multiReadArg function multiReadArg(reads: ReadItem[], mode: number, opts: MultiReadOpts = {}): '0x${string}' Encode the MultiCallResolver arg bytes: N reads + a combine mode + separator/format.
reads.multiReadSlot function multiReadSlot(resolver: '0x${string}', reads: ReadItem[], mode: number, opts: MultiReadOpts = {}) Build a slot that reads several co-located view fns via the deployed MultiCallResolver and combines them.
reads.COMPUTE_KIND const COMPUTE_KIND = "compute" ── compute / expression (contracts/ComputeResolver.sol) ──
reads.OP const OP = { … } as const Opcodes for the bounded RPN stack machine.
reads.encodeProgram function encodeProgram(steps: Step[]): '0x${string}' Encode an RPN program to bytes.
reads.computeArg function computeArg(reads: ComputeRead[], steps: Step[], opts: ComputeOpts = {}): '0x${string}' Encode the ComputeResolver arg bytes: the input reads + the RPN program + output format.
reads.computeSlot function computeSlot(resolver: '0x${string}', reads: ComputeRead[], steps: Step[], opts: ComputeOpts = {}) Build a slot that computes a derived value from co-located reads via the deployed ComputeResolver.

appmeta (namespace)

App metadata: the single source of truth for on-chain app titles/authors/etc. (see chainc/appmeta.ts).

Source: chainc/appmeta.ts

Member Signature Summary
appmeta.APP_META_VERSION const APP_META_VERSION = 1 as const Bump when the metadata SHAPE changes in a way readers should be aware of.
appmeta.KNOWN_KEYS const KNOWN_KEYS = [ … ] as const Documentation of the keys this version knows about.
appmeta.MAX_META_BYTES const MAX_META_BYTES = 4096 Hard cap on the serialized metadata size (bytes).
appmeta.encodeAppMeta function encodeAppMeta(meta: Partial<AppMeta> | null | undefined): string Serialize an app-metadata object to the compact string that goes on-chain.
appmeta.decodeAppMeta function decodeAppMeta(raw: string | null | undefined): AppMeta Parse an on-chain metadata string into an AppMeta object.
appmeta.getTitle function getTitle(meta: AppMeta | null | undefined, fallback = ""): string The display title, or the provided fallback (e.g.
appmeta.getAuthor function getAuthor(meta: AppMeta | null | undefined): string The author, or "" if none.
appmeta.getDescription function getDescription(meta: AppMeta | null | undefined): string The description, or "" if none.
appmeta.getKind function getKind(meta: AppMeta | null | undefined, fallback = ""): string The app kind, or the provided fallback.
appmeta.getIcon function getIcon(meta: AppMeta | null | undefined, fallback = ""): string The card icon name, or the provided fallback (e.g.
appmeta.getCategory function getCategory(meta: AppMeta | null | undefined, fallback = ""): string The category for grouping, or the provided fallback (e.g.
appmeta.getGrade function getGrade(meta: AppMeta | null | undefined, fallback = ""): string The trust grade letter ("A"|"B"|"C"|"gear"), or the provided fallback.
appmeta.getGradeWord function getGradeWord(meta: AppMeta | null | undefined): string The grade word ("Trustless"|"Pinned"|"Live"|"Above-floor"), or "".
appmeta.gradeLocks function gradeLocks(gradeLetter: string): string Render a lock string for a grade letter: A=3 locks, B=2, C=1, gear=the gear glyph.
appmeta.getTags function getTags(meta: AppMeta | null | undefined): string[] The tag list, or [] if none/malformed.
appmeta.hasMeta function hasMeta(meta: AppMeta | null | undefined): boolean True if the metadata carries any meaningful field beyond the version stamp.

RESOLVER_KINDS

const RESOLVER_KINDS: ResolverKindDescriptor[] = [ … ]

The first-party on-chain resolver kinds ChainRender ships, drift-locked to their mirrors.

Source: chainc/resolverkinds.ts

v0.4.0: Naming / submission helpers (docs 72/86)

labelHashOf

function labelHashOf(label: string): `0x${string}`

labelHash = keccak256(utf8 bytes of the subname label) — mirrors SubnameStakeRegistrar.labelHashOf.

Source: chainc/submission.ts

SPAM_TOPIC

const SPAM_TOPIC = stringToHex("spam", { size: 32 })

The topic an attester publishes to flag spam (right-padded into bytes32) — mirrors SPAM_TOPIC.

Source: chainc/submission.ts

SubmissionStatus

enum SubmissionStatus

Submission status — mirrors SubnameStakeRegistrar.Status. Enum order is load-bearing (matched on-chain).

Source: chainc/submission.ts

isLive

function isLive(status: SubmissionStatus): boolean

A submission is live (resolves to its component) only when Active or Refunded — mirrors resolves().

Source: chainc/submission.ts

v0.4.0: Theming (design tokens + CSS generation)

defaultTokens

function defaultTokens(): ThemeTokens

── DEFAULT tokens — grounded in the LIVE seeded theme (not invented), extended to the full surface with sane fail-closed defaults for the axes the CSS didn't previously tokenize. This is _defaultTokens()'s mirror. ──

Source: chainc/theme-tokens.ts

darkDefaults

function darkDefaults(): ThemeTokens

A standard DARK preset (doc 102) — EXACT mirror of ThemeTokens.darkDefaults(). Drift-locked.

Source: chainc/theme-tokens.ts

highContrastDefaults

function highContrastDefaults(): ThemeTokens

doc 107 gap #1 — high-contrast preset (WCAG AAA). Maximum legibility: near-pure black text on pure white, saturated accents chosen for >=7:1, thicker borders/focus for the non-text indicator floor (1.4.11). A THIRD preset alongside light/dark — the standard accessibility trio. Drift-locked + contrast-invariant-checked.

Source: chainc/theme-tokens.ts

toCss

function toCss(t: ThemeTokens): string

Generate the .cr-root CSS from tokens — the SAME values the palette inlines, so components + image renderers can't disagree. (On-chain, ThemeCssView produces this exact string; this is the mirror for the drift-lock.)

Source: chainc/theme-tokens.ts

toPalette

function toPalette(t: ThemeTokens)

The inlined palette image renderers use — literal values (never var()). Colors + the font scale + fonts.

Source: chainc/theme-tokens.ts

THEME_TOKENS_VERSION

const THEME_TOKENS_VERSION = 1

chainc/theme-tokens.ts — the SINGLE SOURCE OF TRUTH for ChainRender's design-token system (doc 98). From this one token set derive BOTH outputs, so components (CSS) and image renderers (inlined palette) can never diverge: • toCss(tokens) → the .cr-root CSS string (what components consume via the shadow root / ThemeCssView) • toPalette(tokens) → literal color/font values image renderers INLINE into SVG (never var(), which is inert inside an — the bug doc 98 fixes) Complete to the W3C Design Tokens taxonomy (color/dimension/fontFamily/fontWeight/number/duration/cubicBezier + composite typography/border/shadow/transition/gradient/strokeStyle) plus layering + breakpoints. Closed core + additive extension + version byte (fail-closed on unknown) — expandable, robust, upgradable, fully on-chain.

Source: chainc/theme-tokens.ts

LEGIBILITY_FLOOR

const LEGIBILITY_FLOOR = 12

The token model + the on-chain-identical CSS generators, so an SDK consumer (or a visual builder) can theme an app: pick a preset, edit tokens, and produce the exact .cr-root CSS the on-chain ThemeCssView produces.

Source: chainc/theme-tokens.ts

fullThemeCss

function fullThemeCss(tokens: ThemeTokens): string

The complete .cr-root CSS for a token set: the token variables (as ThemeCssView produces on-chain) plus the shared component rules.

Source: client/runtime/default-theme.ts

lightThemeCss

function lightThemeCss(): string

fullThemeCss() of the default light tokens.

Source: client/runtime/default-theme.ts

darkThemeCss

function darkThemeCss(): string

fullThemeCss() of the default dark tokens.

Source: client/runtime/default-theme.ts

v0.4.0: Verified-subname preflight (SubnameStakeRegistrarV2, docs 72/86 §5)

expectedEnsNode

function expectedEnsNode(label: string): `0x${string}`

/ The ENS node a VERIFIED claim of label must prove ownership of: namehash(<label>.eth) = / keccak256(namehash("eth"), keccak256(label)). Equals SubnameStakeRegistrarV2.expectedEnsNode(label) and / viem's namehash(label + ".eth"). Use it to build the registerVerified call and preflight the binding.

Source: chainc/submission-v2.ts

isValidLabel

function isValidLabel(label: string): boolean

/ True iff label passes the on-chain charset/normalization gate: non-empty, <= MAX_LABEL_LEN, lowercase ASCII / [a-z0-9-], no leading/trailing hyphen, no consecutive hyphens. Mirrors SubnameStakeRegistrarV2.isValidLabel — / categorically excludes homoglyph/confusable/whitespace/mixed-case spoofs. Preflight before register().

Source: chainc/submission-v2.ts

ETH_NODE

const ETH_NODE = "0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae" as const

/ namehash("eth") — the parent under which a verified label's name must exist (mirrors ETH_NODE in the contract).

Source: chainc/submission-v2.ts

MAX_LABEL_LEN

const MAX_LABEL_LEN = 63

/ The maximum label length the registrar accepts (mirrors MAX_LABEL_LEN).

Source: chainc/submission-v2.ts

Types

TypeScript types exported here (type-only: import type { … }):

Type Definition Source
Compiled interface Compiled { bytes: Uint8Array; hex: '0x${string}'; hash: '0x${string}'; byteSize: number; } chainc/index.ts
Node type Node = | ({ type: "text"; content?: string; children?: Node[] } & A11y & Presentation) | ({ type: "box"; direction?: DirectionName; children?: Node[] } & A11y & Presentation) | ({ type: "button"; content?: string; variant?: VariantName; children?: Node[]; /** A declarative submit action: the t… chainc/compile.ts
Decompiled interface Decompiled { tree: Node; version: number; mode: "classic" | "enhanced"; nodeCount: number; } chainc/decompile.ts
BehaviorDescriptor interface BehaviorDescriptor { requiredCapabilities: string[]; declaredCapabilities: string[]; capabilitiesHonest: boolean; actions: BehaviorAction[]; batchedActionGroups: number; signatureRequests: number; chainReads: number; media: { provenance: string; onChain: boolean }[]; gpu: boolean; offChainFetch: boolean; summary: string[]; } chainc/describe.ts
CompositionFloor interface CompositionFloor { sceneSummary: string; placedComponents: { hash: string; anchor: string; summary: string[] }[]; aggregatedCapabilities: string[]; escalationFree: boolean; summary: string[]; } chainc/describe.ts
ValidationReport interface ValidationReport { ok: boolean; checks: ValidationCheck[]; } chainc/validate.ts
ValidationCheck interface ValidationCheck { name: string; ok: boolean; detail?: string; } chainc/validate.ts
Collected interface Collected { actions: CollectedAction[]; resolvers: Set<string>; refs: Set<string>; media: CollectedMedia[]; batches: CollectedAction[][]; signs: Record<string, unknown>[]; } chainc/validate.ts
Part interface Part { caps: number; presentation: number; dependency: number; escapeHatch?: boolean; fetchIsEnhancement?: boolean; } chainc/trustgrade.ts
Analysis interface Analysis { envelope: number; grade: number; deviations: Deviation[]; } chainc/trustgrade.ts
Result interface Result { refused: boolean; reason: number; envelope: number; grade: number; deviations: Deviation[]; } chainc/trustgrade.ts
Action interface Action { cap: number; carriesValue: boolean; to: string; selector: string; } chainc/trustgrade.ts
Target interface Target { to: string; selector: string; } chainc/trustgrade.ts
Deviation interface Deviation { part: number; axis: number; reason: number; grade: number; } chainc/trustgrade.ts
WriteAction interface WriteAction { cap: number; to: string; selector: string; value: bigint; args: ArgSlot[]; } chainc/actionvocab.ts
ArgSlot interface ArgSlot { source: number; argType: number; value: string; } chainc/actionvocab.ts
Constructed interface Constructed { ok: boolean; reason: number; to: string; value: bigint; data: string; } chainc/actionvocab.ts
BuiltManifest interface BuiltManifest { encoded: '0x${string}'; appHash: '0x${string}'; manifest: Required<AppManifestInput>; } chainc/manifest.ts
AppManifestInput interface AppManifestInput { root: '0x${string}'; components: '0x${string}'[]; contracts?: ContractBinding[]; resolvers?: '0x${string}'[]; capabilities?: number; name: string; version: string; attestationSchema?: '0x${string}'; parent?: '0x${string}'; } chainc/manifest.ts
ContractBinding interface ContractBinding { target: '0x${string}'; chainId: bigint | number; methods: string[]; } chainc/manifest.ts
GradeResult interface GradeResult { grade: number; letter: string; word: string; locks: string; envelope: number; refused: boolean; reason: number; deviations: Deviation[]; aboveFloor?: { kinds: string[]; word: "Above-floor"; locks: "\u2699" }; } client/grade.ts
GradeOptions interface GradeOptions { fetchIsEnhancement?: boolean; presentation?: number; dependency?: number; pinnedDep?: PinnedDep | null; } client/grade.ts
PinnedDep interface PinnedDep { protocol: "ipfs"; cid: string; ens?: string; codec?: string; hash?: string; verify?: string; } chainc/pinneddep.ts
VocabularySchema interface VocabularySchema { version: string; nodeTypes: VocabNode[]; a11y: VocabField[]; behavior: VocabField[]; scene: { binds: string[]; fields: VocabField[]; note: string }; enums: Record<string, string[]>; capabilities: Record<string, number>; kinds: Record<string, Record<string, number>>; resolverKinds: ResolverKindDescriptor[]; authoringBinds: Record<string, typeof CHART_AUTHORING>; viewerReads: typeof VIEWER_READS; mode: VocabMode; presentation?: { requires: string; fieldsByType: Record<string, VocabField[]>; style: ReturnType<typeof styleRegistry>; hints: ReturnType<typeof hintRegist… client/vocabulary.ts
VocabNode interface VocabNode { type: string; summary: string; fields: VocabField[]; } client/vocabulary.ts
VocabField interface VocabField { name: string; kind: string; required?: boolean; enum?: string; of?: string; values?: string[]; note?: string; } client/vocabulary.ts
NodeCheck interface NodeCheck { ok: boolean; issues: NodeIssue[]; nodeCount: number; depth: number; } chainc/node-schema.ts
NodeIssue interface NodeIssue { path: string; code: "unknown-field" | "ignored-field" | "authoring-field" | "required" | "type" | "enum" | "format" | "limit" | "mode"; message: string; } chainc/node-schema.ts
FieldSpec interface FieldSpec { name: string; kind: FieldKind; required?: boolean; enum?: NodeEnumName; fields?: FieldSpec[]; values?: "typedFields" | "scalar"; family?: string; since?: number; note?: string; } chainc/node-schema.ts
FieldKind type FieldKind = | "string" | "bool" | "integer" // whole number >= 1 | "number|string" // a positive number, or the same as a decimal string | "address" // 0x + 20 bytes | "bytes32" // 0x + 32 bytes | "hex" // 0x + whole bytes | "arg" // slot/image arg: hex bytes when a 'resolver' is set, otherwis… chainc/node-schema.ts
NodeType type NodeType = (typeof NODE_TYPES)[number] chainc/node-schema.ts
NodeEnumName type NodeEnumName = keyof typeof NODE_ENUMS chainc/node-schema.ts
Review interface Review { pass: boolean; verdict: string; check: ReturnType<typeof checkNode>; grade: { letter: string; word: string; deviations: unknown; aboveFloor?: unknown; error?: string }; compiled: { hash?: string; size?: number; error?: string }; honesty: (HonestyFinding | PresentationFinding)[]; counts: { checkIssues: number; errors: number; warnings: number }; } client/review.ts
ReviewOptions interface ReviewOptions { authoring?: boolean; pinnedDep?: unknown; knownAddresses?: Iterable<string>; codeSizes?: Record<string, number> | Map<string, number>; chainLabel?: string; mode?: "classic" | "enhanced"; v5Available?: boolean; langRequired?: boolean; } client/review.ts
HonestyFinding interface HonestyFinding { rule: HonestyRule; severity: "error" | "warn"; path: string; message: string; fix: string; address?: string; } chainc/honesty.ts
HonestyRule type HonestyRule = "public-input" | "public-secret" | "live-claim" | "unknown-address" | "unbacked-claim" | "stage-touch" | "stage-pinch" | "stage-own-toggle" | "stage-safe-area" | "p5-v1-api" | "sign-message" | "viewer-read" | "transfer-history" chainc/honesty.ts
HonestyOptions interface HonestyOptions { knownAddresses?: Iterable<string>; codeSizes?: Record<string, number> | Map<string, number>; chainLabel?: string; } chainc/honesty.ts
StyleFamily interface StyleFamily { family: string; nodes: readonly NodeType[]; values: readonly string[]; token: (v: string) => string; css: (v: string) => string; extra?: (v: string, sel: string) => string; summary: string; since: number; } chainc/style-tokens.ts
HintSpec interface HintSpec { key: string; nodes: readonly NodeType[]; value: RegExp; summary: string; viewer: string; since: number; } chainc/hints.ts
PresentationFinding type PresentationFinding = Omit<HonestyFinding, "rule"> & { rule: PresentationRule } client/presentation-review.ts
PresentationRule type PresentationRule = "style-token" | "label-as-style" | "heading-order" | "scroll-region" | "lang-missing" | "v5-unavailable" client/presentation-review.ts
PresentationReviewOptions interface PresentationReviewOptions { v5Available?: boolean; langRequired?: boolean; chainLabel?: string; } client/presentation-review.ts
ViewerKind interface ViewerKind { kind: string; kindHex: '0x${string}'; contract: string; args: ResolverKindArg[]; accountArg: string; encoding: "abi" | "packed"; image: boolean; canonicalEns: boolean; } chainc/viewer-context.ts
CrArg type CrArg = | { ok: true; mode: "viewer" | "history"; fields: Record<string, string> } | { ok: false; error: string } chainc/viewer-context.ts
PresentationContext interface PresentationContext { version: number; present: boolean; themeId: '0x${string}'; overridePalette: boolean; palette: ContextPalette; overrideDims: boolean; chartW: number; chartH: number; overrideTokens: boolean; tokens: ReturnType<typeof tokensToOnchain>; ext: '0x${string}'; } chainc/presentation-context.ts
ContextPalette interface ContextPalette { bg: string; surface: string; fg: string; mutedFg: string; border: string; primary: string; primaryFg: string; danger: string; fontFamily: string; monoFamily: string; scale: { title: number; heading: number; body: number; label: number; legend: number }; weightBold: number; strokeStyle: string; radius: string; borderWidth: string; series: [string, string, string, string, string, string]; } chainc/presentation-context.ts
SceneBinding interface SceneBinding { kind: SceneKind; libHash: '0x${string}'; seed: '0x${string}'; entry: string; meta?: string; } chainc/depscene.ts
SceneKind type SceneKind = keyof typeof SCENE_NS chainc/depscene.ts
ResolverKindDescriptor interface ResolverKindDescriptor { kind: string; kindHex: '0x${string}'; summary: string; capability: number; consumeCapability?: number; dataEdge: "on-chain" | "off-chain"; args: ResolverKindArg[]; argsEncoding?: "abi" | "packed"; statements?: string[]; firstParty: true; extensible: true; note?: string; xchain?: { rootSources: string[]; ceilingBySource: Record<string, "A" | "C">; hostFacetRequired?: boolean; instantUpgrades?: Record<string, boolean>; createsHomeClaim?: boolean; hostFacetResolver?: string; adopted?: boolean; }; contracts?: string[]; doesNotEstablish?: string[]; } chainc/resolverkinds.ts
ResolverKindArg interface ResolverKindArg { name: string; type: string; note?: string; } chainc/resolverkinds.ts
ThemeTokens interface ThemeTokens { version: number; color: { bg: string; surface: string; fg: string; mutedFg: string; muted: string; border: string; primary: string; primaryFg: string; accent: string; accentFg: string; success: string; successFg: string; warning: string; warningFg: string; danger: string; dangerFg: string; info: string; infoFg: string; hover: string; active: string; focus: string; disabled: string; selected: string; series1: string; series2: string; series3: string; series4: string; series5: string; series6: string; gradient?: Gradient; }; type: { fontFamily: string; monoFamily: string… chainc/theme-tokens.ts
FontScale interface FontScale { title: number; heading: number; body: number; label: number; legend: number; } chainc/theme-tokens.ts
Gradient interface Gradient { kind: "linear" | "radial" | "conic"; angle: number; stops: GradientStop[]; } chainc/theme-tokens.ts
GradientStop interface GradientStop { color: string; pos: number; } chainc/theme-tokens.ts

@chainrender/client/runtime

Off-chain runtime: render a deployed component with a free eth_call, fill its slots, turn declared actions into wallet requests, events, themes, local state.

import { renderComponent } from "@chainrender/client/runtime";

Exports

renderComponent

async function renderComponent(dep: Deployment, hash: string): Promise<string>

Renders a stored component by its content hash through the RenderRouter (free eth_call). Returns the on-chain interpreter's HTML string — already escaped and safe to insert into an isolated container (a shadow root or sandboxed iframe under a strict CSP).

Source: client/runtime/core.ts

enumerate

async function enumerate(dep: Deployment): Promise<ComponentMeta[]>

Enumerates the registry (proof-of-concept on-chain list; a production app would use an event indexer — see the Explorer README). Returns each component's hash + basic metadata.

Source: client/runtime/core.ts

decodeAbiString

function decodeAbiString(hex: string): string

Decodes an ABI-encoded dynamic string return value (offset, length, data).

Source: client/runtime/core.ts

splitArgs

function splitArgs(raw: string): string[]

Splits an args template on top-level commas only, so bracketed/parenthesised groups (arrays, tuples) stay intact: "0xabc,[1,2,3],(x,y)" -> ["0xabc","[1,2,3]","(x,y)"].

Source: client/runtime/core.ts

SELECTORS

const SELECTORS = { … } as const

Function selectors for the RenderRouter / ComponentRegistry view functions used here. Precomputed (keccak of the signature, first 4 bytes) so the client needs no crypto lib.

Source: client/runtime/core.ts

bindSlots

async function bindSlots(root: ParentNode, resolvers: SlotResolvers): Promise<void>

Fills every [data-cr-bind] slot under root using the matching resolver, except cr: slots (see isCrArg). root can be a shadow root, an element, or a document fragment. For <img> slots the resolved value is a validated image src set on the element; for all other slots it is inserted as textContent (never parsed as HTML). Filled slots get the cr-filled class; slots with no matching resolver keep their on-chain fallback.

Source: client/runtime/bind.ts

readAction

function readAction(el: Element): ActionDeclaration | null

Reads a declarative submit action off a rendered button (its data-cr-* attributes), or null if the element carries no action.

Source: client/runtime/bind.ts

readActions

function readActions(root: ParentNode): ActionDeclaration[]

Collects every declared submit action under root.

Source: client/runtime/bind.ts

isValidImageSrc

function isValidImageSrc(src: string): boolean

Validates an image src the same way the on-chain interpreter does: only base64 data URIs for svg/png/jpeg, whose body is pure base64. Refuses javascript:, data:text/html, external URLs, and any body containing quotes/brackets — defense in depth on the client side.

Source: client/runtime/bind.ts

isCrArg

const isCrArg = (arg: string | null | undefined): boolean => …

No doc comment in the source.

Source: client/runtime/bind.ts

renderComponentWithContext

async function renderComponentWithContext(dep: Deployment, hash: `0x${string}`, ctx: PresentationContext): Promise<string>

Render a stored component through the RenderRouter with a presentation context (free eth_call). Returns the on-chain interpreter's HTML — escaped and safe to insert into an isolated container, as with renderComponent().

Source: client/runtime/context.ts

renderWithContextCalldata

function renderWithContextCalldata(hash: `0x${string}`, ctx: PresentationContext): `0x${string}`

The eth_call data for renderHashWithContext(hash, ctx).

Source: client/runtime/context.ts

RENDER_WITH_CONTEXT_ABI

const RENDER_WITH_CONTEXT_ABI = [ … ] as const

The RenderRouter function this calls (contracts/RenderRouter.sol).

Source: client/runtime/context.ts

staticResolvers

const staticResolvers: SlotResolvers = { … }

Resolvers that need no chain access — safe defaults that work offline.

Source: client/runtime/resolvers.ts

makeProviderResolvers

function makeProviderResolvers(provider: EnsBalanceProvider): SlotResolvers

Builds resolvers backed by a provider (e.g. a viem PublicClient), for the bindings that need live data. Merge over staticResolvers for full coverage:

Source: client/runtime/resolvers.ts

resolveArgs

function resolveArgs(action: ActionDeclaration, inputs: Record<string, string> = {}): string[]

Resolves $name argument references against form inputs; literals pass through unchanged.

Source: client/runtime/submit.ts

buildActionRequest

function buildActionRequest(action: ActionDeclaration, inputs: Record<string, string> = {}): TxRequest

Builds the calldata + tx request for a declared action, filling $input refs from inputs.

Source: client/runtime/submit.ts

describeAction

function describeAction(action: ActionDeclaration, inputs: Record<string, string> = {}): string

A plain-language description of what a declared action would do, for user review before signing. Always show this — never trust the button's own label.

Source: client/runtime/submit.ts

events (namespace)

EventSource deferred-lock-in family + readEvents — doc 94. Namespaced to avoid the custom collision with the ThemeSource family (both families ship a custom escape hatch).

Source: client/runtime/events.ts

Member Signature Summary
events.eventTopic0 function eventTopic0(eventSig: string): '0x${string}' topic0 = the event selector (keccak of the canonical signature).
events.eventTopics function eventTopics(eventSig: string, indexedArgs?: Record<string, unknown>): ('0x${string}' | null)[] The eth_getLogs topics: [topic0, …indexed-arg matches].
events.getLogs function getLogs(rpc: string): EventSource on-chain via eth_getLogs (grade A).
events.indexer function indexer(query: (spec: EventSpec, opts?: { limit?: number }) => Promise<LogRecord[]>): EventSource off-chain (grade C).
events.custom function custom(read: EventSource["read"]): EventSource the always-available escape hatch — any log source.
events.readEvents async function readEvents(spec: EventSpec, opts: { rpc: string; source?: EventSource; limit?: number },): Promise<LogRecord[]> Convenience: read an EventSpec's feed.

MULTICALL3

const MULTICALL3 = "0xcA11bde05977b3631167028862bE2a173976CA11" as const

Canonical deterministic Multicall3 (mds1/multicall3) — same address on every chain that has it deployed.

Source: client/runtime/batch.ts

batchRead

async function batchRead(specs: readonly CallSpec[], opts: { rpc: string; multicall?: `0x${string}` },): Promise<BatchResult[]>

Execute specs via Multicall3.aggregate3 in one eth_call. Order-preserving; each call fails closed independently.

Source: client/runtime/batch.ts

themes (namespace)

The on-chain theme render path — ThemeSource family (sourceStore/bundled/custom) + applyTheme + renderToShadow (doc 90, Phase 3). Namespaced as a sibling of events.

Source: client/runtime/theme.ts

Member Signature Summary
themes.sourceStore function sourceStore(cssHash: '0x${string}', opts: { rpc: string; sourceStore: '0x${string}' }): ThemeSource On-chain: read CSS from SourceStore.read(cssHash) — content-addressed, immutable.
themes.bundled function bundled(css: string): ThemeSource On-chain-equivalent: a baked, inert CSS string (the doc-90 baked model).
themes.custom function custom(load: () => Promise<string>, opts?: { dataEdge?: "on-chain" | "off-chain" }): ThemeSource Escape hatch: a developer-supplied loader (may reach a CDN/server).
themes.applyTheme async function applyTheme(root: ShadowRoot | HTMLElement, source: ThemeSource): Promise<AppliedTheme> Inject a ThemeSource's CSS into a shadow root (or element) as a single scoped <style data-cr-theme>.
themes.renderToShadow async function renderToShadow(host: HTMLElement, html: string, source?: ThemeSource): Promise<ShadowRender> The full on-chain theme render path (doc 90): the component's on-chain HTML → a shadow root wrapped in a single .cr-root, with theme CSS applied.

DEFAULT_THEME_CSS

const DEFAULT_THEME_CSS = ".cr-root{display:block;box-sizing:border-box;padding:var(--cr-space-md,12px);line-height:1.5;text-align:left;letter-spacing:normal;\n font-family:var(--cr-font, system-ui, …

client/runtime/default-theme.ts — the COMPLETE bundled default theme (Phase 3, theme-finish). BASE component theme (.wrap block: buttons/inputs/slots/headings/images/alerts/timeline/steps) + a11y INTERACTION states, --cr--tokenized, scoped under .cr-root. Explicit inherited-property resets (line-height/text-align/letter-spacing) for shadow isolation WITHOUT all:initial (which was found to interfere with the --cr- token override / theming). Highlighted states filled + contrast-robust. 13 vars.

Source: client/runtime/default-theme.ts

local (namespace)

LocalStore family (memory/localStorage/indexedDB/custom) + settle — optimistic-local-state + on-chain settlement (doc 94, Phase 3 sub-step 4). Namespaced (custom collides with events/themes families).

Source: client/runtime/local.ts

Member Signature Summary
local.memory function memory(): LocalStore In-memory (Map).
local.localStorage function localStorage(namespace = "cr"): LocalStore localStorage, namespaced + JSON-serialized.
local.indexedDB function indexedDB(dbName = "chainrender", storeName = "cr"): LocalStore IndexedDB — the persistent async store for larger/structured local state (game move logs, drafts).
local.custom function custom(impl: LocalStore): LocalStore The escape hatch — any developer-supplied store (a library, a server-backed store, whatever).
local.settle function settle(action: ActionDeclaration, selectiveData: Record<string, string> = {}): SettleResult Settle selected local results on-chain via the existing buildActionRequest.

Types

TypeScript types exported here (type-only: import type { … }):

Type Definition Source
Deployment interface Deployment { rpc: string; router?: string; registry?: string; } client/runtime/core.ts
ComponentMeta interface ComponentMeta { hash: string; chunkCount: number; attestationSchema: string; } client/runtime/core.ts
SlotResolver type SlotResolver = (arg: string | null, kind: string) => string | Promise<string> client/runtime/core.ts
SlotResolvers type SlotResolvers = Record<string, SlotResolver> client/runtime/core.ts
ActionDeclaration interface ActionDeclaration { to: string | null; sig: string; value: bigint; args: string[]; } client/runtime/core.ts
EnsBalanceProvider interface EnsBalanceProvider { getEnsName(args: { address: '0x${string}' }): Promise<string | null>; getEnsAvatar(args: { name: string }): Promise<string | null>; getBalance(args: { address: '0x${string}' }): Promise<bigint>; getChainId?(): Promise<number>; } client/runtime/resolvers.ts
BatchResult interface BatchResult { success: boolean; returnData: '0x${string}'; } client/runtime/batch.ts

@chainrender/client/react

React adapter over the runtime (react is a peer dependency).

import { useChainRenderComponent } from "@chainrender/client/react";

Exports

useChainRenderComponent

function useChainRenderComponent(deployment: Deployment, hash: string): UseComponentResult

Fetches a component's on-chain-rendered HTML by hash. Re-fetches when hash/deployment change or when refetch() is called.

Source: client/react/react.ts

ChainRenderView

function ChainRenderView(props: ChainRenderViewProps)

Renders a ChainRender component into a style-isolated shadow root and fills its slots. The interpreter's HTML is already escaped; rendering into a shadow root keeps the host page's styles out and the component's markup contained.

Source: client/react/react.ts

Types

TypeScript types exported here (type-only: import type { … }):

Type Definition Source
UseComponentResult interface UseComponentResult { html: string | null; loading: boolean; error: Error | null; refetch: () => void; } client/react/react.ts
ChainRenderViewProps interface ChainRenderViewProps { deployment: Deployment; hash: string; resolvers?: SlotResolvers; styleSheet?: string; className?: string; } client/react/react.ts

@chainrender/client/miniapp

Farcaster Mini App distribution: manifest, embed tags, identity, wallet, notifications — all fail-closed outside a Farcaster host.

import { capabilitiesForEnvelope } from "@chainrender/client/miniapp";

Exports

capabilitiesForEnvelope

function capabilitiesForEnvelope(envelope: number): string[]

Map a ChainRender capability envelope (the honesty bits) to the Mini App SDK capabilities the host must support. This carries ChainRender's capability honesty through to the Mini App layer: if the app declares on-chain writes/value/signing, it declares it needs a wallet provider here too.

Source: client/miniapp/manifest.ts

buildManifest

function buildManifest(cfg: MiniAppConfig, accountAssociation?: AccountAssociation): Record<string, unknown>

Build the /.well-known/farcaster.json manifest. Serve it at that path on homeUrl's domain. Without an accountAssociation the app still runs as a standard web app / unverified Mini App; with it, the domain is provably owned by your FID and the app is discoverable + can notify.

Source: client/miniapp/manifest.ts

buildEmbed

function buildEmbed(embed: EmbedConfig): Record<string, unknown>

Build the embed object placed in the fc:miniapp meta tag on any page that shares the app.

Source: client/miniapp/manifest.ts

buildEmbedMetaTags

function buildEmbedMetaTags(embed: EmbedConfig): string

Render the embed as HTML meta tags — emits fc:miniapp plus the legacy fc:frame alias for hosts still on the older tag. Inject the result into the page <head>.

Source: client/miniapp/manifest.ts

inMiniAppHost

async function inMiniAppHost(): Promise<boolean>

Whether we're running inside a Mini App host (a Farcaster client webview). False for a plain page.

Source: client/miniapp/runtime.ts

signalReady

async function signalReady(opts?: { disableNativeGestures?: boolean }): Promise<void>

Signal to the host that the app has finished loading and can be shown. MUST be called once the ChainRender render is on screen, or the host shows an infinite splash. No-op outside a host.

Source: client/miniapp/runtime.ts

mountChainRenderApp

async function mountChainRenderApp(render: () => void | Promise<void>): Promise<void>

Render the ChainRender floor first, then signal ready. render is your own mount (e.g. inject the HTML from an eth_call into the DOM). The floor is visible even if the host/SDK never resolves.

Source: client/miniapp/runtime.ts

currentUser

async function currentUser(): Promise<FarcasterUser | null>

The current Farcaster user from host context (no signature), or null outside a host. Use this for a lightweight FID read; use signInWithFarcaster to get a verifiable SIWF credential.

Source: client/miniapp/runtime.ts

signInWithFarcaster

async function signInWithFarcaster(nonce: string): Promise<FarcasterUser | null>

Sign In With Farcaster: returns the FID + a SIWF message/signature to verify on your server, or null outside a host. nonce should come from your server to bind the session. Fails closed.

Source: client/miniapp/runtime.ts

enableNotifications

async function enableNotifications(): Promise<boolean>

Prompt the user to add the app, which enables notifications (the host then delivers a notification token to your manifest webhookUrl — send with sendMiniAppNotification server-side). Returns whether the prompt was shown; false outside a host.

Source: client/miniapp/runtime.ts

miniAppWalletProvider

async function miniAppWalletProvider(): Promise<unknown | null>

The host's embedded EIP-1193 wallet provider — the final gate for a ChainRender WRITE_CHAIN action when embedded — or null outside a host (fall back to the user's own injected wallet).

Source: client/miniapp/runtime.ts

sendMiniAppNotification

async function sendMiniAppNotification(n: NotificationSend): Promise<Response>

POST a Mini App notification to the host. Returns the raw Response; inspect it for the per-token result (delivered / rate-limited / invalid) per the Mini App spec. Server-side only.

Source: client/miniapp/notify.ts

Types

TypeScript types exported here (type-only: import type { … }):

Type Definition Source
AccountAssociation interface AccountAssociation { header: string; payload: string; signature: string; } client/miniapp/manifest.ts
MiniAppConfig interface MiniAppConfig { name: string; homeUrl: string; iconUrl: string; splashImageUrl?: string; splashBackgroundColor?: string; webhookUrl?: string; subtitle?: string; description?: string; primaryCategory?: string; tags?: string[]; requiredChains?: string[]; requiredCapabilities?: string[]; } client/miniapp/manifest.ts
EmbedConfig interface EmbedConfig { imageUrl: string; buttonTitle: string; appUrl: string; appName?: string; splashImageUrl?: string; splashBackgroundColor?: string; } client/miniapp/manifest.ts
FarcasterUser interface FarcasterUser { fid: number; username?: string; displayName?: string; pfpUrl?: string; siwf?: { message: string; signature: string }; } client/miniapp/runtime.ts
NotificationSend interface NotificationSend { url: string; tokens: string[]; notificationId: string; title: string; body: string; targetUrl: string; } client/miniapp/notify.ts