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_CHAINread. 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
- Contracts → Registries · Concepts → Versioning
- Reference → Resolver Catalog (EnsProfile · EnsMultichain)