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

The Render Pipeline

What actually happens when an app renders, start to finish.

The path

renderHash(hash)
  → the registry reads the app's bytes (stored on-chain via SSTORE2)
  → the interpreter walks the byte-encoded component tree
  → for each node: emit its HTML/SVG from the closed vocabulary
  → for each data slot: call the bound resolver (a view call) and inline the result (escaped)
  → for each image slot: resolve on-chain media (or fall back to a poster floor)
  → return the assembled HTML string

Every step is a view — no state changes, no gas, fully reproducible.

Key properties

  • Deterministic. The same hash always yields the same output. This is what content addressing guarantees.
  • Fail-closed. A reverting resolver, a missing source, a gas-bomb, or an unknown node never breaks the render — it degrades to an honest fallback ("unavailable", an axes-only chart, a poster image). An app can't be made to render a lie by a failing dependency.
  • Escaped by construction. Any value a resolver returns is re-escaped before it enters the output — a resolver can never inject markup. Safety isn't a runtime check you might forget; it's structural.
  • Paginated when large. Big outputs (an atlas, a long table) support chunked reads that concatenate byte-identically to the whole — so even large apps stay within call limits.

Two render entry points

  • renderHash(hash) — the plain render; baked defaults.
  • renderHashWithContext(hash, ctx) — the same app with a presentation context (theme, palette, chart dimensions) applied at render time. Same app, same hash, different appearance — zero gas, no redeploy. See Presentation & Theming.

Related