
Gabhru
Pay AI agents privately by ENS name — stealth addresses, any wallet, no setup.
Demo
About
Every payment to an AI agent today is public and permanent. ERC-8004 gives agents an on-chain identity, but that makes their revenue, customer list, and payment schedule readable by any competitor with a block explorer. Gabhru gives each agent a free ENS subname (alice.gabhru.eth). When anyone resolves that name, they get a fresh, single-use stealth address — never the same one twice. The sender pays exactly like they'd pay any ENS name, from any wallet, with no plugin and no special flow. The agent sees the USDC land in its dashboard about two seconds later. No observer can link two payments to the same agent, count its customers, or total its revenue. Agents get privacy without asking their users to do anything differently.
How it's made
A custom ENS wildcard resolver is deployed and verified on Ethereum mainnet (0x6c11e3cb958c84cfd339123a2b9c4196c755f777), set as the resolver for gabhru.eth. It implements IExtendedResolver (ENSIP-10) and reverts with OffchainLookup (ERC-3668 / CCIP-Read), so every *.gabhru.eth name resolves through our gateway with zero L1 writes per agent. The gateway is a Hono service on Vercel. It reads the agent's ERC-5564 stealth meta-address from Postgres, derives a fresh stealth address per query, and signs the EIP-712 response the resolver verifies. Key derivation uses @fluidkey/stealth-account-kit — spend and view keys come deterministically from one wallet signature, so nothing is stored that can't be regenerated. The view key is encrypted at rest; the spend key never leaves the browser. On Base mainnet: ERC-8004 IdentityRegistry mints the agent ID, the ERC-5564 Announcer publishes the ephemeral pubkey and view tag, and each agent gets a Safe as its treasury. Stealth receiving addresses are CREATE2-predicted Safes, so they support gas sponsorship. A scanner tails Announcer logs on Base, matches them against each agent's view key, and streams matches to the dashboard over SSE — payment visible in about two seconds. Frontend is Next.js 16 + RainbowKit + Tailwind; auth is SIWE + JWT; data is Drizzle + Postgres; the resolver is Foundry. Records served over CCIP-Read include ENSIP-18 profile keys, ENSIP-25 agent-registration verification records, and ENSIP-26 agent-context. The fiddly part was making a stateless CCIP-Read gateway return a *stable* address within one payment cycle but a fresh one across cycles — a wallet re-resolves the name several times before broadcasting, and a different address each read would send funds nowhere. Solved with a per-agent issuance cycle serialized by a Postgres advisory lock.