How it works
- A human scans their passport or ID in the Self app. The zero-knowledge proof is generated on the phone; no personal data leaves the device.
- The Self Hub verifies the proof on Celo and calls the registry.
- The registry mints a soulbound NFT that links the agent’s key to the human’s unique nullifier. One human can back a bounded number of agents — the default sybil limit is one.
- The agent signs every outbound request with its key. The service verifies the signature against the registry and reads the human-proof flags (age, OFAC, freshness) it needs.
Contracts
All addresses below were checked witheth_getCode on 2026-08-21; the identity registry reports name() = "Self Agent ID", symbol() = "SAID".
Prerequisites
- Node.js 18+ (TypeScript SDK) — Python (
pip install selfxyz-agent-sdk) and Rust (cargo add self-agent-sdk) SDKs exist too - The Self app on a phone, to scan the registration QR code
- A Celo RPC endpoint:
https://forno.celo.org(mainnet) orhttps://forno.celo-sepolia.celo-testnet.org(Celo Sepolia)
Register an agent
The CLI ships with the SDK. Registration is a browser handoff: the terminal creates a session, you scan a QR code with the Self app, the proof is verified on-chain, and the agent NFT is minted.AGENT_PRIVATE_KEY below). Never commit it. Use --network mainnet for a production agent.
Registration modes
All modes work on both networks and produce the same soulbound NFT. Details: Registration modes.
Call a service as an agent
agent.fetch() is fetch() with three signed headers added to every request: x-self-agent-address, x-self-agent-signature, and x-self-agent-timestamp.
Verify agents in your service
The verifier checks the signature, looks the address up in the registry, and enforces the human-proof rules you configure. The Express middleware rejects anything that fails before your handler runs.verifier.verify({ signature, timestamp, method, url, body }) with the values from the three headers and the request.
Defaults: sybil limit 1, replay protection on, and requests older than 300 seconds are rejected.
Troubleshooting
- The Self app refuses the document on mainnet. Mainnet accepts real passports and IDs only. Develop against
--network testnet(Celo Sepolia), where mock documents are accepted. - Registration never completes. Check the session state with
self-agent register status --session .self/session.json; states runinitialized → handoff_opened → callback_received → onchain_verified. If it stalls athandoff_opened, the QR code was not scanned or the app is on the other network. register exportprints no private key. Add--unsafe --print-private-key; the key is withheld by default.- Requests are rejected by the verifier although the agent is registered. The timestamp window is 300 seconds — keep the agent host’s clock in sync. Also confirm both sides use the same network; a Celo Sepolia agent is unknown to a mainnet registry.
userDefinedDatais garbled on-chain. The SDK passes it as a UTF-8 string; use ASCII characters, not raw bytes.
Celo Agent Visa
Celo Agent Visa is a tiered soulbound NFT that records an agent’s on-chain activity on Celo. Claims are gasless — the Self relayer pays. Tracked metrics are transaction count and stablecoin volume in USDT, USDC and USDm.
Flow: register → transact on Celo → check eligibility → claim (tiers 1–2 directly, tier 3 after approval). Contract addresses are in the table above; the claim API is
https://agent-api.self.xyz. Details: Celo Agent Visa.
How this relates to ERC-8004
Self Agent ID implements all three ERC-8004 registry roles — identity (SelfAgentRegistry), reputation (SelfReputationRegistry) and validation (SelfValidationRegistry) — and extends the identity registry with registerWithHumanProof(), revokeHumanProof(), proof-validity queries, and nullifier-based sybil detection. The extension is provider-agnostic through an IHumanProofProvider interface, so any zero-knowledge identity system can plug in.
These are Self’s own deployments. The reference ERC-8004 registries on Celo (0x8004A169… mainnet) listed on the ERC-8004 page are separate contracts; an agent can be registered in both.
Resources
Related
- ERC-8004 - The trust standard Self Agent ID implements
- Build with Self - Verify humans, not agents, with the same proofs
- x402 - Let a verified agent pay per request
- MPP - Charge agents per API call in USDC
- Fee abstraction - Pay gas in stablecoins from the agent wallet