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

Every ChainRender app carries a trust grade — a single letter (A / B / C) that tells a user, before they interact, exactly how trustless the app is. It is computed on-chain, and the SDK computes an identical grade locally (they are drift-locked), so you can see your app's grade as you build it.

What the grades mean

Grade Word Meaning
A Trustless Fully on-chain, no external dependencies. Everything you see is computed from chain state.
B Pinned Depends on an immutable, content-pinned external asset (e.g. an IPFS hash). Verifiable, but off-chain.
C Live Depends on something that can change — a live off-chain fetch, a mutable pointer, or an unproven asset.

The grade is the worst link: one Grade-C part sets the headline, because a chain is only as trustless as its weakest dependency. But the grade is never just a letter — it comes with an itemized breakdown naming every deviation, so the user (and you) can see exactly why a grade was assigned.

Why a grade instead of a checkmark

A binary "safe / unsafe" badge would be dishonest — trust is a spectrum, not a boolean. An app that renders a chart from live on-chain data (Grade A) and an app that embeds an image from a random web server (Grade C) are both "functional," but they are not equally trustworthy, and pretending otherwise would violate ChainRender's core discipline: marketing must never exceed what the code enforces.

The grade makes the trust cost legible. A user who wants maximum assurance uses only Grade-A apps. A user who accepts a pinned dependency uses Grade-B. Nobody is surprised, because the grade — and its reasons — are visible up front.

How it's computed (the reasoning)

The grade derives from the app's capability envelope — the union of everything the app can do and everything it depends on. The enforcer walks the composition and, for each part, classifies its dependencies along several axes (is data on-chain or fetched? is an asset immutable, attested, or mutable? does an action stay within the declared envelope?). Each axis has an honest floor:

  • On-chain computation → contributes nothing negative (Grade A).
  • A fail-closed enhancement (e.g. a GPU effect that degrades to an on-chain poster, or a fetch that falls back to complete on-chain data) → stays Grade A, because the trustless floor is intact even if the enhancement fails.
  • A pinned/attested dependency (a raw-CIDv1 IPFS asset, pointer anchored on-chain, client-verified, fail-closed) → Grade B. See the guide Grade B — a Pinned-IPFS Dependency for how to declare it (grade(app, { pinnedDep })).
  • A live fetch or mutable pointer that the output actually depends on → Grade C.

Crucially, the enforcer is conservative and fails closed: anything it cannot analyze is treated as unsafe (refused or downgraded), never optimistically passed. An unknown vocabulary token is refused, not rendered.

The relationship to safety-by-construction

The grade describes trust; the enforcer enforces safety. They're related but distinct:

  • Some things are refused outright — an arbitrary-code escape hatch, an action that moves value while the app never declared it can, a {to, selector} not in the declared call set. These don't get a bad grade; they're rejected at registration. See The Capability Enforcer.
  • Everything that passes gets an honest grade reflecting its real dependencies.

So a registered ChainRender app is always safe (it can't smuggle a hidden transaction), and its grade tells you how trustless it is on top of that baseline safety.

Using the grade as a developer

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

const g = grade(myApp);
console.log(g.letter);      // "A"
console.log(g.word);        // "Trustless"
console.log(g.breakdown);   // itemized deviations, if any

Watch the grade as you build. If adding a feature drops you from A to C, the breakdown tells you exactly which dependency did it — and you can decide whether that trade-off is worth it, before your users ever see it.

Resolvers and the grade (an important distinction)

Not all resolvers are equal for the grade:

  • A client-side resolver — a JS function that fetches with viem/ethers in the browser (e.g. getBalance, getBlock) — is an off-chain fetch. It grades C (Live). Routing data through a resolver function does not make it on-chain.
  • An on-chain resolver contract — a resolver address referenced by a Slot — reads and renders the value on-chain during the eth_call. It grades A (Trustless).

So a Slot bound to an on-chain resolver contract is Grade A; a Slot filled by a client-side JS resolver is Grade C. The grade tells the truth either way — an app using client-side resolvers is not "fully on-chain," and the grade correctly reflects that.

Related