Set up
Wallets and agent keys
Each agent gets a wallet and an ed25519 keypair. The wallet holds the public key and the agent holds the private key. How to create both, and how to look after them.
One wallet per agent
A wallet holds money and belongs to your workspace. An agent wallet also holds the public key that its payment proofs are checked against. Give each agent its own wallet:
- a compromised or misbehaving agent can only spend what its own wallet holds;
- purchase history and receipts stay separate per agent;
- the MCP packages can find the wallet from your key automatically, but only when the workspace has exactly one agent wallet. With several, you name the one to use.
Create one in the console
Buyer → Agents → New agent. The console generates the keypair, creates the wallet, and shows the private key once as a download. It also keeps a copy in that browser, so the console can make test calls.
Create one with the API
Generate a keypair
openssl genpkey -algorithm ed25519 -out agent-key.pem
chmod 600 agent-key.pem
openssl pkey -in agent-key.pem -pubout # the public half, for the next stepimport { generateEd25519KeyPair } from "@zanora/sdk";
const { publicKeyPem, privateKeyPem } = generateEd25519KeyPair();
// Store privateKeyPem somewhere only the agent can read.node -e 'const {generateKeyPairSync}=require("node:crypto");
const {publicKey,privateKey}=generateKeyPairSync("ed25519");
require("node:fs").writeFileSync("agent-key.pem",privateKey.export({type:"pkcs8",format:"pem"}),{mode:0o600});
console.log(publicKey.export({type:"spki",format:"pem"}))'Register the wallet
curl -s -X POST https://api.zanora.dev/v1/wallets -H "x-api-key: $WKEY" \
-H 'content-type: application/json' \
-d '{"ownerType":"agent","ownerId":"invoice-bot","publicKeyPem":"-----BEGIN PUBLIC KEY-----\n…\n-----END PUBLIC KEY-----\n"}'ownerId is your label for the agent. It appears in payment proofs, so use something plain like invoice-bot. The response is the wallet, including its id (wal_…).
Looking after the private key
It's the spending authority, and it can't be recovered
Whoever has agent-key.pem can spend that wallet's balance, within your policies. Zanora never had the private key, so a lost key can't be reissued. The wallet keeps its balance but can never spend it. Treat the key like a wallet seed phrase.
- Keep it in a file with mode
0600, or in your secrets manager. In MCP configs, point to it withZANORA_AGENT_KEY_FILErather than pasting it in, because config files get shared and appear in screen-shares. - Only fund a wallet with what you'd accept losing to that agent.
- If a key leaks: freeze the wallet (
POST /v1/wallets/:id/freeze), create a new wallet with a new key, and move future funding there.
Reading a wallet
| Call | Returns |
|---|---|
GET /v1/wallets | every wallet in your workspace |
GET /v1/wallets/:id/balance | { balanceMinor, availableMinor, currency }. Available excludes money on hold |
GET /v1/wallets/:id/ledger | every entry, oldest first: funding, charges, refunds |
POST /v1/wallets/:id/freeze / unfreeze | stop or allow outgoing payments |
Next: fund the wallet.