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

Guide: ENS Names & Integration

ChainRender integrates deeply with ENS — for naming apps, resolving them, and rendering ENS identity. This guide covers all three, and the important design choice behind how it uses ENS.

The design choice: the registrar is truth, ENS is a projection

ChainRender does not put your app's trust in ENS's ownership/governance model. Instead, apps are named via subnames under chainrender.eth, managed by an ownerless on-chain registrar (SubnameStakeRegistrar). An ENSIP-10 wildcard resolver then reflects that registrar into ENS, so *.chainrender.eth resolves normally in any ENS-aware tool — but the source of truth is the on-chain registrar, not an ENS name someone could transfer or a registry someone controls.

Why: using a top-level ENS name directly would inherit ENS's own trust and governance surface. By making the registrar authoritative and ENS a read-only projection, ChainRender keeps naming ownerless and verifiable while still being fully ENS-compatible.

1. Naming your app (register a subname)

Register myapp.chainrender.eth by staking (refundable) in the registrar:

SubnameStakeRegistrar.register("myapp", appComponentHash)   // + a refundable stake

Your app is now resolvable at myapp.chainrender.eth through the wildcard resolver — no per-name ENS transaction needed. The stake is a spam cost, not a fee; it's refundable.

2. Resolving an app by name

Any ENS-aware client resolves myapp.chainrender.eth to your app's current component hash via the wildcard resolver, which reads the registrar (and, if versioned, the current version). You render that hash the usual way.

3. Versioned names (safe updates through the name)

If you use the versioned registry, myapp.chainrender.eth resolves to your app's current version, with append-only history and a timelock on updates. Updating is queueVersion(...) — a public, delayed, observable event, never a silent swap. See Concepts → Versioning.

4. Rendering ENS identity in your UI

Separately from naming apps, ChainRender can render users' ENS identity as live on-chain UI via the EnsProfile resolver — name, avatar, records, reverse-resolution (with forward-verification). Bind a data slot:

compose.slot("ensProfile", { resolver: "0x<ens-profile-resolver>", arg: encode(address)  }) // slot(bind, { resolver, arg });

This reads ENS on-chain at render time; it's Grade A (an on-chain read) and fails closed if the name doesn't resolve. The resolver refuses a reverse name whose forward record points elsewhere — no spoofed identities.

5. ENS from a rich-media sketch (window.CR_CHAIN)

The EnsProfile resolver above is the declarative path (a data slot, resolved on-chain, Grade A). A rich-media p5/three sketch can also resolve ENS imperatively through the injected window.CR_CHAIN bridge — useful for turning raw hex addresses into readable names inside a live visualization:

CR_CHAIN.ensName(addr)      // reverse-resolve an address -> "vitalik.eth" (or null)
CR_CHAIN.ensAddr(name)      // forward-resolve a name -> address (or null)
CR_CHAIN.ensText(name, key) // read a text record: avatar, url, com.twitter, …

Each is a direct on-chain read against the ENS registry and resolver (the namehash is computed client-side with a vetted keccak), fails closed to null, and should be cached per address — never re-resolve the same address, and never call it every frame. When ensName returns null (common on testnets, where few addresses have a reverse record), fall back to a shortened hex address.

var ensCache = {};
function nameFor(addr) {
  var k = addr.toLowerCase();
  if (ensCache[k] !== undefined) return ensCache[k] || shorten(addr);
  ensCache[k] = "pending";
  CR_CHAIN.ensName(addr).then(function (n) { ensCache[k] = n || null; });
  return shorten(addr); // show hex until the name resolves
}

This is a client-side enhancement (Grade ⚙) over the on-chain floor — the same trust level as any CR_CHAIN read. For a verifiable, forward-checked identity rendered as part of the app itself, use the EnsProfile resolver in section 4. See Rich Media → Reading live on-chain data.

6. Multichain extras: app manifest (ensApp) + chain-aware name (ensNameChain)

Two additive ENS reads go beyond records and reverse-resolution, via the EnsMultichainResolver (ownerless, immutable, view-only, fails closed to "-"; the ENS registry is supplied at construction, never hardcoded):

kind args renders
ensApp abi.encode(node) the chainrender.app text record a name points its app to
ensNameChain abi.encode(who, coinType) the ENSIP-19 primary name for an address on a given chain, forward-verified

ensApp reads a conventional chainrender.app text key off a name — ENS as ChainRender's own naming layer, so a name can point at the app it represents (dogfood: chainrender.eth names its own apps). Grade A, an on-chain text read.

ensNameChain is the ENSIP-19 multichain verified reverse: the primary name for an address per chain, not just mainnet. The reverse namespace is per-coinType (an EVM chain's coinType is 0x80000000 | chainId; mainnet is the special 60), and the resolver requires the forward round-trip — addr(namehash(name), coinType) must equal the address — so an unverified reverse record can never be shown. Grade A, pure on-chain reads.

// bind the chain-aware primary name for `who` on Sepolia (coinType 0x80aa36a7 = 0x80000000 | 11155111)
compose.slot("ensNameChain", { resolver: "0x<ens-multichain-resolver>", arg: encode(["address","uint256"], [who, 0x80aa36a7]) });

Both render a live value wherever the records exist on the chain's registry, and fail closed to "-" otherwise. The Explorer's ENS extras card demonstrates them over an immutable demo ENS source (records anchored at seed); re-point the resolver at the real chainrender.eth registry with no code change to read the live name.

Summary

Use Mechanism Trust property
Name your app SubnameStakeRegistrar + ENSIP-10 wildcard Ownerless; registrar is truth, ENS is a projection
Safe updates via the name SubnameVersionRegistry Append-only + timelock; no silent swap
Render a user's ENS identity EnsProfile resolver On-chain read, Grade A, forward-verified
App a name points to EnsMultichainResolver · ensApp On-chain chainrender.app text read, Grade A
Chain-aware primary name EnsMultichainResolver · ensNameChain ENSIP-19 per-coinType reverse, forward-verified, Grade A

Related