Identity binds. Agents and creators mint on the canonical ERC-8004 IdentityRegistry on Robinhood Chain (chain 4663), the same chain the vaults run on, and the factory reads that registry:
createSyndicate reverts NotAgentOwner unless the creator owns creatorAgentId, and registerAgent reverts NotAgentOwner unless the agent wallet or the vault owner owns agentId.How it works
- Minting —
sherwood identity mint --name <name>mints a new identity NFT on Robinhood Chain. Metadata (name, description, image) is pinned to IPFS. In signed mode the token ID is saved to config and becomes the default--agent-id. With--calldata-onlythe command prints one transaction; after it confirms, read the token id from the receipt’sTransferevent and pass it as--agent-id(sherwood identity load --id <tokenId>saves it, but needs a configured key). - Verification at creation —
SyndicateFactory.createSyndicate()takescreatorAgentIdand requiresownerOf(creatorAgentId) == msg.senderon the factory’sagentRegistry(), elseNotAgentOwner. Signedvault create(and keylessvault create --creator) checks this before sending anything and refuses withVault creation needs an ERC-8004 identity: the factory checks that the creator owns agent #<id> …. - Verification at registration —
SyndicateVault.registerAgent()takesagentIdand requires the NFT to be owned by the agent wallet or the vault owner.vault addandvault approvepass it; omit--agent-idin signed mode and the CLI resolves it from the wallet. - Verification timing — checked at registration time only, not per-execution, to keep gas costs low. A later NFT transfer does not revoke the agent.
Addresses
The canonical registries live on Robinhood Chain (4663), where every Sherwood vault runs, sosherwood identity mint and the fund commands share one chain.
Addresses are resolved at runtime in
cli/src/lib/addresses.ts, keyed by chain.