⚠️ 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

Testing ChainRender (Two-Layer Harness)

ChainRender ships a two-layer test harness that catches the two distinct classes of bug in an on-chain-rendering system: the deterministic class (selectors, encoding, exports, config) and the live class (CSP, iframe, WebGL, wallet). Run both around every deploy.

Layer 1 -- headless integration harness

npm run test:integration      # node scripts/integration-harness.mjs

Runs headless (no wallet/browser/chain needed), exits non-zero on any failure (CI-usable). It verifies the parts that are pure functions of the code:

  • SDK bundle exports -- catches a stale bundle (e.g. a missing buildComposition).
  • All hardcoded on-chain selectors vs their canonical signatures -- catches a wrong metaOf/exists/etc.
  • Encoding (sceneId, composition, multi-view hashes) vs viem -- catches ABI/encoding drift.
  • Config addresses -- catches a stale registrar (V2 vs v1).
  • No-CDN invariant -- catches a CDN dependency that a strict CSP would block.
  • Wallet-call shape -- catches wallet.sendTransaction (viem) vs the EIP-1193 wallet.request.

It is proven to catch regressions: injecting a wrong selector makes it fail.

Layer 2 -- browser smoke test

Open chainrender-smoke-test.html on the deployed server after each deploy. It checks the live-only surface a headless harness cannot:

  • The SDK bundle loads in a real browser and exports what it should.
  • CSP behaviour -- whether external CDN scripts are blocked (they should be; on-chain libraries are the path).
  • Sandboxed-iframe execution -- inline JS draws a canvas (the on-chain-p5 path); the three.js UMD-global path; WebGL (page + sandbox); inline SVG + SMIL animation.
  • Storage -- IndexedDB round-trip (project store + encryption), localStorage.
  • Chain -- window.ethereum.request present + chainId; raw fetch to the RPC; native DecompressionStream; WebCrypto.

Together the two layers cover roughly the whole path. Neither alone is "full path" -- Layer 1 is the CI gate, Layer 2 is the post-deploy live check.

The rule

Run npm run test:integration before every deploy (it fails the build if anything drifted), and open the smoke test after every deploy (it confirms the live environment). This is the safety net around the deploy workflow.

Related