CheshireAgentIdentityRegistry
ERC-8004-compatible identity singleton for Robinhood Chain. Dependency-free ERC-721 + URI + arbitrary metadata + reserved agentWallet with EIP-712 / ERC-1271 proof.
Mainnet (4663)
Testnet 46630: 0xf1a30080f5da64ab0456f3adc06dfd8fc9d2fdb3
Product UX: https://cheshireterminal.ai/agents/forge · FunPump site: https://funpump.ai
Core API
| Function |
Who |
Notes |
register() |
anyone |
mints to msg.sender, empty URI |
register(string uri) |
anyone |
sets agentURI |
register(string uri, MetadataEntry[] metadata) |
anyone |
batch metadata; cannot set reserved keys via metadata except agentWallet init path |
setAgentURI(agentId, newURI) |
owner/operator |
|
setMetadata(agentId, key, value) |
owner/operator |
not for reserved agentWallet key |
setAgentWallet(agentId, newWallet, deadline, signature) |
anyone w/ valid proof |
EIP-712 / ERC-1271 from newWallet |
unsetAgentWallet(agentId) |
owner/operator |
|
getAgentWallet(agentId) |
view |
|
isAuthorized(operator, agentId) |
view |
owner, approved, or operator |
ownerOf / tokenURI / agentURI |
view |
|
totalSupply() |
view |
_nextAgentId - 1 |
MetadataEntry { string metadataKey; bytes metadataValue }
Semantics agents must respect
register mints the ERC-721 to msg.sender and initializes agentWallet to that address.
- ERC-721 transfer clears a nonzero
agentWallet — transferring the NFT revokes the bound wallet.
- Approvals are consequential authority (can transfer + update metadata).
agentWallet is reserved — only via setAgentWallet with a proof from the new wallet (EOA ecrecover or ERC-1271).
- EIP-712 typehash:
SetAgentWallet(uint256 agentId,address newWallet,uint256 deadline) under domain (name, version, chainId, verifyingContract).
Minimal viem flow
import { createWalletClient, createPublicClient, http, defineChain } from "viem";
import { privateKeyToAccount } from "viem/accounts"; // only if user authorized agent key
const RH = defineChain({
id: 4663,
name: "Robinhood Chain",
nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
rpcUrls: { default: { http: ["https://rpc.mainnet.chain.robinhood.com"] } },
});
const IDENTITY = "0x70361a37951d66f8c44cfb45873df2ba8b9fc950" as const;
// Prefer unsigned intent → user wallet broadcast (forge APIs).
// After receipt: read ownerOf(agentId), agentURI, getAgentWallet — never claim success on hash alone.
Safety
- Prefer user-signed registration; never handle raw private keys in chat.
- Confirm chainId 4663 (or 46630 testnet) before broadcast.
- Do not redeploy a second identity namespace.
- Identity NFT ≠ FunPump bonding-curve token (
rh-launchpad-v3 / rh-bonded-launch).
Related
- Reputation:
cheshire-agent-reputation-registry
- Validation:
cheshire-agent-validation-registry
- Suite overview:
cheshire-agent-registries
- Forge lifecycle:
robinhood-agent-forge
1---2name: cheshire-agent-identity-registry3description: Register and operate Cheshire Robinhood agent identities (ERC-721 RHAGENT) via CheshireAgentIdentityRegistry on Robinhood Chain. Use for register(agentURI), agentWallet EIP-712/1271 proofs, metadata, isAuthorized, and ownerOf reads. Source: robinhood-agents/contracts/CheshireAgentIdentityRegistry.sol.4---5
6# CheshireAgentIdentityRegistry
7
8ERC-8004-compatible **identity singleton** for Robinhood Chain. Dependency-free ERC-721 + URI + arbitrary metadata + reserved `agentWallet` with EIP-712 / ERC-1271 proof.
9
10## Mainnet (4663)
11
12| | |
13|--|--|
14| **Address** | `0x70361a37951d66f8c44cfb45873df2ba8b9fc950` |
15| **Name / symbol** | `Cheshire Robinhood Agents` / `RHAGENT` |
16| **Version** | `1` (EIP-712 domain) |
17| **Explorer** | https://robinhoodchain.blockscout.com/address/0x70361a37951d66f8c44cfb45873df2ba8b9fc950 |
18| **RPC** | `https://rpc.mainnet.chain.robinhood.com` |
19| **Source** | `cheshire-terminal/robinhood-agents/contracts/CheshireAgentIdentityRegistry.sol` |
20| **Deploy JSON** | `deployments/agent-registries-mainnet-4663.json` |
21
22Testnet 46630: `0xf1a30080f5da64ab0456f3adc06dfd8fc9d2fdb3`
23Product UX: `https://cheshireterminal.ai/agents/forge` · FunPump site: `https://funpump.ai`
24
25## Core API
26
27| Function | Who | Notes |
28|----------|-----|--------|
29| `register()` | anyone | mints to `msg.sender`, empty URI |
30| `register(string uri)` | anyone | sets agentURI |
31| `register(string uri, MetadataEntry[] metadata)` | anyone | batch metadata; cannot set reserved keys via metadata except agentWallet init path |
32| `setAgentURI(agentId, newURI)` | owner/operator | |
33| `setMetadata(agentId, key, value)` | owner/operator | **not** for reserved `agentWallet` key |
34| `setAgentWallet(agentId, newWallet, deadline, signature)` | anyone w/ valid proof | EIP-712 / ERC-1271 from **newWallet** |
35| `unsetAgentWallet(agentId)` | owner/operator | |
36| `getAgentWallet(agentId)` | view | |
37| `isAuthorized(operator, agentId)` | view | owner, approved, or operator |
38| `ownerOf` / `tokenURI` / `agentURI` | view | |
39| `totalSupply()` | view | `_nextAgentId - 1` |
40
41`MetadataEntry { string metadataKey; bytes metadataValue }`
42
43## Semantics agents must respect
44
451. **`register` mints the ERC-721 to `msg.sender`** and initializes `agentWallet` to that address.
462. **ERC-721 transfer clears a nonzero `agentWallet`** — transferring the NFT revokes the bound wallet.
473. Approvals are **consequential authority** (can transfer + update metadata).
484. **`agentWallet` is reserved** — only via `setAgentWallet` with a proof from the new wallet (EOA `ecrecover` or ERC-1271).
495. EIP-712 typehash: `SetAgentWallet(uint256 agentId,address newWallet,uint256 deadline)` under domain `(name, version, chainId, verifyingContract)`.
50
51## Minimal viem flow
52
53```ts
54import { createWalletClient, createPublicClient, http, defineChain } from "viem";
55import { privateKeyToAccount } from "viem/accounts"; // only if user authorized agent key
56
57const RH = defineChain({
58 id: 4663,
59 name: "Robinhood Chain",
60 nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
61 rpcUrls: { default: { http: ["https://rpc.mainnet.chain.robinhood.com"] } },
62});
63
64const IDENTITY = "0x70361a37951d66f8c44cfb45873df2ba8b9fc950" as const;
65
66// Prefer unsigned intent → user wallet broadcast (forge APIs).
67// After receipt: read ownerOf(agentId), agentURI, getAgentWallet — never claim success on hash alone.
68```
69
70## Safety
71
72- Prefer **user-signed** registration; never handle raw private keys in chat.
73- Confirm **chainId 4663** (or 46630 testnet) before broadcast.
74- Do not redeploy a second identity namespace.
75- Identity NFT ≠ FunPump bonding-curve token (`rh-launchpad-v3` / `rh-bonded-launch`).
76
77## Related
78
79- Reputation: `cheshire-agent-reputation-registry`
80- Validation: `cheshire-agent-validation-registry`
81- Suite overview: `cheshire-agent-registries`
82- Forge lifecycle: `robinhood-agent-forge`