Sending a friend 20 USDC should not require copying a hex string from a chat app, checking the chain, and hoping the network matches. The @cai.com directory replaces wallet addresses with handles. Type the name, pick the handle, and the money moves.
This post covers the @cai.com address directory, how it resolves handles to wallets, and how person-to-person payments work without the user ever seeing a hex string.
The directory
The @cai.com directory maps every registered user to their custodial wallet addresses across six chains. When you sign up at cai.com/app, you get a handle like alice@cai.com and a wallet address on each supported chain. The directory stores the mapping.
The directory is not a blockchain itself. It is a lookup table that CAI maintains. The agent that needs to pay someone calls resolve-transfer-recipient with the recipient's email or handle, and gets back the canonical address on the requested chain.
The API call is straightforward:
curl -sS https://api.cai.com/functions/v1/resolve-transfer-recipient \
-H "Authorization: Bearer ***" \
-H "Content-Type: application/json" \
-d '{"chain": "BASE", "to_email": "friend@cai.com"}'
Response:
{
"canonical_email": "friend@cai.com",
"to_address": "0x..."
}
How payments work through the directory
Once the address is resolved, the agent initiates the transfer. The user confirms on a hosted-action page, and CAI executes the custodial transfer on the requested chain.
curl -sS https://api.cai.com/functions/v1/wallet-custodial-transfer \
-H "Authorization: Bearer ***" \
-H "Content-Type: application/json" \
-d '{
"chain": "BASE",
"token": "usdc",
"amount": "20.00",
"to_email": "friend@cai.com"
}'
Notice the to_email field. The agent never touches a wallet address. It resolves the handle, then passes the handle back to the transfer endpoint. CAI handles the address resolution internally on the second call.
The public surface
The directory also has a public facing side. The cai.com/.well-known/agent.json file is the A2A Agent Card that lets other agents discover how to interact with CAI. The cai.com/capabilities.html page lists which features are live, which are in beta, and which carry gap IDs.
For the @cai.com address directory specifically:
- Live (per capabilities.html): The directory is operational. All registered users are discoverable by their @cai.com handle.
- Chain support: ETH, BASE, POLYGON, SOLANA, ARBITRUM, and OPTIMISM.
- Gap ID: GAP_RESOLVE_V1 — signals that the resolution is live but may not cover every edge case (e.g., unregistered handles return a clear error, not a silent fail).
What this means for agents
An agent that needs to pay someone does not need to ask for a wallet address. It asks for the person's @cai.com handle. The agent resolves it, checks the balance, and initiates the transfer. The user confirms with one tap.
This is the same flow whether the agent is paying a freelancer, settling a split bill, or sending a recurring payment to a landlord. The directory abstracts the chain complexity. The agent works with names, not addresses.
The end-to-end
A complete payment flow through the directory:
- Agent calls
get-identityto confirm the user has a CAI account. - Agent asks the user for the recipient's @cai.com handle.
- Agent calls
resolve-transfer-recipientwith the handle and the preferred chain. - Agent calls
get-wallet-balancesto confirm sufficient funds. - Agent calls
wallet-custodial-transferwith the recipient's handle. - User confirms on the hosted-action page.
- Agent confirms the payment landed via
wallet-activity-list.
Every step works with the handle. The agent never sees a private key, never copies a hex address, and never asks which network the recipient is on.
Documentation: cai.com/skill.md · cai.com/developers.html · cai.com/app to sign up.
If you tried this flow and hit a bug, comment below with the command you ran, what you expected, and what you got. Bug reports get replied to within 24 hours.
Top comments (0)