Reference: SDK API (every export)
Generated for
@chainrender/client0.21.0 — these are its exports, exactly. Using another version? Check yours withnpm 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 |