Claim an ENS name, watch it become a live AI agent you can talk to. ENSv2 + ERC-8004 + 0G.
namesake turns an ENS name into a live AI agent.
claim <label>.namesake.eth on ENSv2 (Sepolia), and the system provisions a working agent behind it. the free tier is gated by World ID: one verified human, one free agent.
from there, the orchestrator does the full setup in 18 steps:
• mints the subname to the operator • writes the forward address • binds an ERC-8004 agent identity • publishes the ENSIP-25 identity link and agent-ids index • publishes an ENSIP-26 agent-context record • writes a services[message] endpoint • then transfers the name’s NFT to the agent’s own wallet
behind the name is a real container with its own MetaMask wallet, so the agent can sign as itself. it runs on 0G Compute using GLM-5, with TEE attestation.
the point is discovery: resolve the name, read services[message], POST to it, and get a response.
if the agent moves, the record is republished, so the pointer stays current. beyond the free tier, strangers pay per message via x402.
Built in TypeScript end to end, with viem handling every chain call.
ENSv2 introduced one subtle but important wrinkle: reads for subnames are now two-hop. you go from the root registry via getSubregistry(parent) to the parent’s subregistry, then call getState(labelhash(leaf)). anything that assumed a simple 2LD lookup broke on 3LDs — availability checks, binding verification, even bits of UI copy.
provisioning is handled by an orchestrator that runs as a step machine, with per-step timings exposed through a JSON API that the React/Vite/wagmi frontend polls. the agents themselves run as OpenClaw containers on Railway, with MetaMask Agent Wallet baked into the image so they can sign as themselves.
the hackiest part is messaging. OpenClaw’s gateway speaks WebSocket RPC; there’s no plain HTTP /message endpoint. so there’s a relay shim that SSHes from one Railway service into a sibling container and drives the actual turn driver. yes: nested Railway CLI inside Railway. ugly, but effective. importantly, it shares a ContainerTarget seam with local Docker, so the code we prove locally is the same code that ships.
0G was the clean part — basically just a base_url swap, no SDK required. a Vercel function injects the bearer token server-side, so the browser never sees it.

