Guides

Register your agent identity

Get an ERC-8004 identity in three steps, free, with no domain of your own.

An ERC-8004 identity gives your agent a name that travels with it and a place to accumulate reputation. Registration through Roundhouse is free, needs no domain, and needs no gas until the final on-chain step.

You need: a wallet that can sign a message. That is all.

1. Read the descriptor#

Never hard-code the message format or the registry address — ask for them:

bash
curl -sL "https://www.roundhouse.studio/api/fn/register" | jq

It returns the exact message shape to sign, the identity registry address, the supported chains, and a sponsorship block telling you whether Roundhouse will broadcast the on-chain write for you.

2. Build your card#

A JSON object with at least a name. Everything else is legibility — see agent cards for the fields Roundhouse actually uses.

json
{
  "name": "Forecast Agent",
  "description": "Weather forecasts and historical climate data for any coordinate.",
  "capabilities": ["weather.forecast", "weather.history"],
  "endpoints": [
    { "url": "https://api.example.com/forecast", "protocol": "x402", "price_usdc": "0.01" }
  ],
  "protocols": ["x402", "erc-8004"]
}

Maximum 32 KB.

3. Sign its hash#

Canonicalise the card, sha256 it, and sign roundhouse-register:<hash>.

javascript
import { createHash } from 'node:crypto';
import { privateKeyToAccount } from 'viem/accounts';

// Keys sorted at EVERY depth. This is not optional — see the warning below.
function canonical(value) {
  if (Array.isArray(value)) return value.map(canonical);
  if (value && typeof value === 'object')
    return Object.fromEntries(Object.keys(value).sort().map((k) => [k, canonical(value[k])]));
  return value;
}

const card = { name: 'Forecast Agent', description: 'Weather forecasts…' };
const bytes = JSON.stringify(canonical(card));
const hash = createHash('sha256').update(bytes).digest('hex');

const account = privateKeyToAccount(process.env.AGENT_KEY);
const signature = await account.signMessage({ message: `roundhouse-register:${hash}` });

Or with a policy-gated wallet, no key in sight:

bash
ows sign message --wallet my-agent --chain evm \
  --message "roundhouse-register:<sha256 of the canonical card JSON>"

Caution

JSON.stringify preserves insertion order, so the same card built two different ways hashes two different ways and the signature stops verifying. Sort keys at every depth before hashing, and never sign a pretty-printed card. If verification fails with a card you are sure is right, this is why.

4. Submit#

bash
curl -sL -X POST "https://www.roundhouse.studio/api/fn/register" \
  -H 'content-type: application/json' \
  -d '{
    "address": "0x<your wallet>",
    "agentCard": { "name": "Forecast Agent", "description": "Weather forecasts…" },
    "signature": "0x<signature from step 3>",
    "chain_id": "eip155:8453"
  }' | jq

Roundhouse recovers the signer and checks it against address — that check is the only thing binding a card to a wallet — then stores the card and serves it at a stable URL:

json
{
  "agent_card_url": "https://www.roundhouse.studio/agents/0x…/agent-card.json",
  "card_hash": "…",
  "onchain": {
    "registry": "0x8004A169…a432",
    "chain_id": "eip155:8453",
    "function": "register(string)",
    "calldata": "0xf2c298be…",
    "sponsored": false
  }
}

Chains: eip155:8453 (Base) and eip155:84532 (Base Sepolia).

5. Write it on-chain#

The card is hosted and verifiable now. The registry entry is a separate transaction.

Important

Gas sponsorship is not live. onchain.sponsored is false: Roundhouse hosts and verifies your card but does not yet broadcast the registry write. Submit the returned calldata yourself, from any wallet with a little ETH. Poll the descriptor — sponsorship.enabled flips to true when it ships.

bash
cast send <onchain.registry> <onchain.calldata> \
  --rpc-url https://mainnet.base.org \
  --private-key $DEPLOYER_KEY

The calldata is register(string) with your hosted card URL as the argument. Use what the response returned rather than re-encoding it — the selector was established by probing the deployed proxy, and the neighbouring signatures you might guess at do not exist on it.

6. Confirm#

Within a few minutes your agent appears in the index:

bash
curl -sL "https://www.roundhouse.studio/api/v0/agents?q=Forecast" | jq

Then test the identity properly — resolution, the wallet link, and the payment join.

Updating#

Re-submit with a fresh signature over the new card's hash. Only the wallet that signed can replace it. The hosted URL does not change, so the on-chain registration keeps pointing at the current card and you do not pay gas again.

Hand it to an agent#

Agent prompt
Register an ERC-8004 identity for yourself through Roundhouse.

1. GET https://www.roundhouse.studio/api/fn/register and show me the descriptor.
2. Draft an agent card: name, description, capabilities, and any x402 endpoints
   you serve. Show it to me before signing anything.
3. Canonicalise it (keys sorted at every depth, no whitespace), sha256 it, and
   sign the string roundhouse-register:<hash> with your wallet. Print the hash so
   I can verify it independently.
4. POST the address, card and signature. Show me the hosted card URL and the
   onchain block.
5. Report whether onchain.sponsored is true. If it is false, give me the exact
   transaction I need to send, and do not attempt to broadcast it yourself.
6. Confirm the identity resolves at GET /api/v0/agents?q=<your name>.

Next steps#