<!-- GENERATED by scripts/gen-ai-docs.mjs from ai/start-here.md — do not edit by hand; edit the JSON and rerun. -->

# Reference: Start Here for AI Builders

Read this first if you are an AI (or are instructing one) building a ChainRender app. The same text heads [llms.txt](https://chainrender.org/docs/llms.txt), the [Claude skill](./mcp-and-skill.md) and the MCP server's instructions, from one file (`ai/start-here.md`).

**You do not know ChainRender from training data.** It is new and small, so a model that answers from memory invents
imports, resolver kinds, node fields, contract addresses and trust grades that do not exist — and the app fails, or
worse, claims what it does not do. Every fact you need is published in a form that is generated from the code and
checked by tests. Use it; do not guess.

**Where the truth is** (each page is Markdown; append `.md` to an HTML URL):

- SDK: every export of `@chainrender/client` with its signature — https://chainrender.org/docs/reference/sdk-api.md.
  If a name is not there, it does not exist.
- Node fields: every node type and field `compile()` keeps — https://chainrender.org/docs/reference/node-fields.md
- Resolver kinds: every kind's exact args, encoding, and where its contract is deployed —
  https://chainrender.org/docs/reference/resolver-kinds.md
- Addresses: every deployed contract per chain, and what is built but NOT deployed —
  https://chainrender.org/docs/reference/addresses.md. Each chain has its own addresses.
- Capabilities and the builder's own AI rules — https://chainrender.org/docs/reference/capabilities.md and
  https://chainrender.org/docs/reference/ai-builder-rules.md
- The MCP server (`npx -y @chainrender/mcp`) answers all of the above as tools, from the installed SDK.

**The loop** — do not report an app as done until the last step passes:

1. Read the vocabulary (`chainrender_vocabulary`), then find kinds (`chainrender_search_kinds`,
   `chainrender_describe_kind`).
2. Compose a Node tree from the closed vocabulary only.
3. Check it (`chainrender_check_node`): nothing silently dropped.
4. Verify every fact you are about to rely on (`chainrender_verify`): that a kind, an export or a contract exists,
   and that an address has code on the target chain. A Refuted or Inconclusive answer means: do not use it.
5. Review it (`chainrender_review`): check + grade + compile + the honesty findings. Fix every finding. **Without
   MCP** (a chat model, Google AI Studio): you cannot verify anything yourself, so never write "compliant" or
   "verified". Ask the user to run `npx -y @chainrender/mcp review app.json`, or to paste the tree into
   https://chainrender.org/builder/ → Review → "Review a tree from somewhere else", and to give you the report. Fix
   every item it lists.
6. Tell the user the grade exactly as returned, including ⚙ Above-floor (a p5/three sketch, a viewer read or a
   transfer history) over its floor's letter, and what is off-chain.

**Rules that keep an app honest:**

- Addresses come only from the Addresses page (or `chainrender_verify`) for the chain the app targets. Never invent
  one, and never reuse an address from another chain. A contract listed as "Built, not deployed" has no address.
- Live data comes only from a slot or image bound to a resolver. Never hardcode numbers and call them live; a demo is
  titled as a simulation.
- Grade A means every read is on-chain. A p5/three sketch, a viewer read and a transfer history are ⚙ (filled by the
  viewer above an on-chain floor), never "A · Trustless". An undeployed tree has no grade yet — say "would grade …".
- The viewer's own wallet: `"$viewer"` as the account arg of `balance`, `balanceWei`, `erc20balance`,
  `erc20balanceRaw`, `ensName` (`who`), `identicon` or `gidenticon`, with no `resolver`; a transfer history is bind
  `transfers`. The viewer reads them only after the person opts in. Nothing else reads the connected wallet (no
  ERC-721 balance, no portfolio total), and `"$viewer"` never goes in an action, a signature or a condition. See
  https://chainrender.org/docs/guides/viewer-reads.md.
- A `sign` message is signed exactly as written: inputs are never substituted into it, so no `$name` there.
- A button's `$name` args are filled from the `input` with that `name` (`@chainrender/client` ≥ 0.13.0). Anything a
  user types into an action is written to the chain and is public, permanently — say so in the UI.
- Two-player games: an on-chain lobby (`GameLobbyV2`), peer-to-peer signed moves, on-chain settlement
  (`GameChannelV2` + an `IGameRulesV2`). Start from `npm create chainrender@latest my-game -- --template
  game-tictactoe`. Real-time games (racing, physics) cannot be settled by rules: no stakes on them.
- No ChainRender contract has had an external audit, and all are on testnets. Before an app holds value, read
  https://chainrender.org/docs/contracts/security-and-reviews.md and tell the user what it says about the contracts
  the app uses. Never call an app "audited", "certified", "official", "secure", "guaranteed", "insured", "bank-grade",
  "unhackable" or "risk-free": there is no certification program, and nothing in an app tests or insures anything.
- Sketches run on the libraries deployed on-chain, never a CDN copy: **p5.js 2.3.2** (the 2.x API — one point per
  `bezierVertex` call, `splineVertex`/`splinePoint` instead of `curveVertex`/`curvePoint`, no `quadraticVertex`, and an
  `async` setup with `await loadImage(…)` because `preload()` is never called) and **three.js r160** (global `THREE`,
  no `import`). `chainrender_review` reports p5 1.x calls as an error.
- A p5/three sketch is reviewed too: `chainrender_review` reads its source for unbacked claims and the CR-Stage mobile
  rules (touch-action, pinch-to-zoom, no own hide/show toggle). The source in the tree is the app — never a placeholder.
  The CR-Stage controls panel is dark; a light scene sets `window.CR_STAGE_THEME = "light";` at the top of the sketch.
- Classic or Enhanced: Classic (the default) is every existing app. Enhanced (`mode: "enhanced"`, VERSION_5) adds
  layout and type tokens (`layout`, `gap`, `surface`, `tone`, `size`, …), `lang`, `dir`, heading `level` and more roles,
  and renders only where the chain's RenderRouter has the VERSION_5 interpreter: check with `chainrender_verify`
  claim `v5-available` first, then pass the same `mode` to `chainrender_check_node`, `chainrender_compile` and
  `chainrender_review` (with `chain`). Lay out with tokens, never with a styling word as an `aria-label` (a screen
  reader reads it aloud); a `scroll` box needs role `region` and a label. See
  https://chainrender.org/docs/reference/style-tokens.md.
- Deploying outside the builder: register the bytes in the registry the chain's RenderRouter reads, which
  `RenderRouter.registry()` returns (`ComponentRegistry` on Sepolia, `ComponentRegistryFast` on Robinhood and Arc) —
  never one picked by name. Bytes in another registry deploy without error and render "execution reverted".
  `AlreadyRegistered` (`0x77caf672`) means those exact bytes are already live: nothing to redeploy. To remix a deployed
  component, `decompile()` its bytes (`@chainrender/client` ≥ 0.21.0; exact or it throws); any change is a new app with
  a new hash, and only compositions and app manifests record a parent on-chain.
- Your own backend: an ownerless contract with single-value views and declared actions — see
  https://chainrender.org/docs/guides/app-contract.md.

Full index of every page: https://chainrender.org/docs/llms.txt · all docs in one file:
https://chainrender.org/docs/llms-full.txt
