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

Messaging & Note-Privacy Capabilities

ChainRender renders on-chain messages and private-payment discovery honestly, and declares the sends — it never becomes a messaging protocol, an inbox, a relay, or an indexer, and it never custodies a key. Everything here is graded by the same rule as the rest of the system: a re-computable view is Grade A; an event-log feed or a client-side render is ≤ C and labelled; a send is a declared action. (Full strategy: doc 157.)

The one rule that decides the grade

Where the work happens Example Treatment
Re-computable eth_call view ERC-1271 validity, ERC-6538 lookup, shielded-pool invariants Grade A
On-chain data via eth_getLogs / indexer ERC-3722 Poster feed, ERC-5564 announcement scan ≤ C, labelled
Client-side / RPC crypto (never on-chain) EIP-712 signing, ERC-5630 encrypt, stealth derivation declared / local
A state change ERC-5564 announce, ERC-3722 post declared action

An event-log feed is not Grade A: logs are verifiable but read via eth_getLogs, not a view a component can re-run — so Poster feeds and stealth scans render at ≤ C with a labelled off-chain edge (the same posture as EFP follower counts).

Public messaging

  • ERC-1271 signature validity (sig-1271, Grade A) — "is this message hash validly signed by contract account X?" A pure view against the account's own logic. Validity only — the meaning of the message is rendered client-side (see msg-712), never asserted here.
  • Render what you sign (msg-712, client-side, ≤ C) — an honest render of the EIP-712 / EIP-191 message you are about to sign: every field named and typed, and fail-closed on anything opaque ("this field is raw bytes we can't interpret — do not sign blind"), with an A-hint only when the message is fully typed and bound to a verifyingContract. Anti-phishing infrastructure, framed as "marketing ≤ code" — it never says "safe to sign."
  • ERC-3722 Poster feed (poster-feed, ≤ C) — public posts. Content lives only in NewPost event logs (no state), so it's an indexer read, labelled off-chain. Declaring a post() is a user action.

Private messaging & payments

  • ERC-6538 stealth discovery (stealth-meta, Grade A) — "is this address reachable via stealth payments, and what is its published stealth meta-address?" This discovery read is the only on-chain (Grade A) part of a private payment. The ERC-5564 announce send is a declared action; scanning announcements (stealth-scan, ≤ C) is an off-chain log read; deriving which announcements are yours uses your viewing key, client-side. ChainRender never holds a key or derives your address server-side.
  • ERC-5630 encryption is client/RPC-side by construction (eth_getEncryptionPublicKey / ECIES) — rendered + declared, never a chain read, never custodied.

Shielded pools / note privacy (Aztec / zk.money-style)

Render the privacy boundary honestly — the publicly-provable invariants, revealing nothing about ownership:

  • shielded-root (Grade A) — the pool's current Merkle root.
  • shielded-set (Grade A) — the anonymity-set size, i.e. how private the pool actually is right now. A small set is weak privacy — the card grades it WEAK / moderate / healthy and says so, instead of hiding a thin set.
  • shielded-nullifier (Grade A) — is a nullifier spent (double-spend / already-claimed) without revealing identity.

The decrypted balance is a client-side, viewing-key-gated enhancement (≤ C, local) that fails closed to this public floor. Shield / unshield / transfer are declared actions whose privacy leaks are labelled, never hidden: deposit reveals the amount + your L1 address; the internal transfer is private; withdrawing to a reused address re-links you — use a fresh one. This reuses the same commitment+nullifier DNA already shipped (Groth16 credentials + the ownerless NullifierRegistry).

Honest boundaries

  • No key custody. Never a messaging protocol, inbox, relay, or indexer.
  • No plaintext private content on-chain. Off-chain delivery (hubs, CCIP-Read, ciphertext stores) is ≤ C and labelled.
  • A rendered signable message is a render, not an endorsement — it states what the message is and where it's opaque.
  • A weak anonymity set is rendered as weak. Marketing ≤ code.

For developers

Kinds are discoverable via RESOLVER_KINDS / vocabulary(); encode args with the helpers in @chainrender/client (chainc/messaging.ts): encodeSig1271Args, encodeStealthMetaArgs, encodeShieldedArgs, plus the client-side renderTyped712, decodePrivacyLeaks, and posterFeedFilter. On-chain resolvers: Sig1271Resolver, StealthMetaResolver, ShieldedPoolViewResolver (caller-supplied addresses; fail-closed; ownerless).

Related