Docs & SDK.
The .agent registry is a set of Solidity contracts for Robinhood Chain (Arbitrum Orbit / EVM). Interact with it directly using viem or ethers — the namehash scheme is ENS-compatible, so existing tooling just works.
Overview
HOODLE (Hoodle NS) is a namespace protocol on Robinhood Chain that assigns persistent, human-readable identities to AI agents. Each name is an ERC-721 token whose tokenId = uint256(namehash(name)), backed by a registry Record storing resolver, metadata URI, expiry and verification.
The namehash is ENS-compatible (EIP-137): node = keccak256(parentNode ‖ keccak256(label)), folded right-to-left. Forward resolution is "compute the node, read the record" — no indexer needed.
Contracts
Four dependency-free Solidity 0.8.24 contracts live in onchain/, covered by 20 passing forge tests (pricing tiers, fee split, grace period, ERC-5192 locking, staking revenue share, EIP-137 vectors):
Live on Robinhood Chain mainnet (chain id 4663, RPC rpc.mainnet.chain.robinhood.com):
Install
One real dependency — everything else lives in the contracts repo.
npm install viem
Resolve a name (read on-chain)
Compute the node, call resolve. Works against any deployed HoodleRegistry.
import { createPublicClient, http, namehash } from 'viem';
const client = createPublicClient({ transport: http(process.env.ROBINHOOD_RPC) });
const REGISTRY = process.env.HOODLE_REGISTRY; // 0x…
const [node, owner, resolver, metadataURI, expiry, verified] =
await client.readContract({
address: REGISTRY,
abi: registryAbi,
functionName: 'resolve',
args: ['scout.agent'],
});
console.log({ owner, resolver, metadataURI, expiry, verified });
// reverse resolution:
const primary = await client.readContract({
address: REGISTRY, abi: registryAbi,
functionName: 'reverseResolve', args: [owner],
}); // → 'scout.agent'Register a name (send a tx)
One payable call. Premium labels (1–4 chars) cost 0.2 ETH and never expire; standard 0.04 ETH; accessible 0.004 ETH — 25% off for $HOODLE stakers.
import { createWalletClient, http, parseEther } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
const account = privateKeyToAccount(process.env.AGENT_KEY);
const wallet = createWalletClient({ account, transport: http(RPC) });
const hash = await wallet.writeContract({
address: REGISTRY,
abi: registryAbi,
functionName: 'register',
args: ['scout.agent', account.address, 'ar://<manifest>'],
value: parseEther('0.04'),
});
// then mint the capability manifest:
await wallet.writeContract({
address: AGENT_CARD,
abi: cardAbi,
functionName: 'mint',
args: [namehash('scout.agent'), 'ar://<manifest>', true], // soulbound
});On-chain record
Each registered node stores exactly this struct:
struct Record {
address resolver; // wallet/contract the name resolves to
string metadataURI; // ar:// AgentCard JSON manifest
uint64 expiry; // unix seconds, 0 = permanent (premium)
bool verified; // 0.002 ETH protocol flag
string fqn; // "scout.defi.agent"
}
// ownership = ERC-721: ownerOf(uint256(node))
// linked wallets: proposeLink(node, wallet) + acceptLink(node)The AgentCard manifest (capabilities, chains, endpoints, payment terms, EAS attestation, reputation) lives at metadataURI on Arweave/IPFS — immutable once written.
Registry functions
REST API
The resolver API mirrors the protocol spec (cd.md §7.3):