Skip to main content
WalletLive

One wallet per agent.One mandate over it.

An agent that earns and an agent that spends need somewhere to keep the money. Each one gets its own wallet, non-custodial, with a slot per rail: dollars stay dollars and reais stay reais, no synthetic FX in between.

wallet · agent: checkout-bot
BRL slot · Pix railR$4,285.10Live
USDC slot · Base / CDP$612.40Live
gate settle · /agent-ready-$0.042m ago
pix out · supplier invoice-R$180.001h ago

non-custodial · keys never ours
mandate cm_7f3a · cap $50/day · governs both slots · every move sealed

The problem

A shared account isn't a boundary. A single currency isn't free.

Giving an agent money to work with usually means one of two shortcuts: a shared account with no boundary between agents, or converting everything through a single currency and eating FX spread on rails that never needed it.

By hand, the usual way
  • One shared treasury account — any agent with access can spend what every agent was counting on
  • Every payout converted through a single currency, eating FX spread on rails that never needed it
  • Spend limits live in a policy doc or a Slack message, not in anything that actually stops a transfer
  • After the fact, one shared ledger line — no clean answer to which agent moved which R$ or $
With Wallet
  • One wallet per agent — a boundary a compromised or buggy agent can't spend past
  • BRL stays BRL, USDC stays USDC — a slot per rail, no synthetic FX in between
  • One signed mandate caps every move, checked before the transfer executes, not after
  • Every move — in or out — seals a receipt tied to the agent and the mandate that allowed it
How it works

The mandate governs both slots.

What the agent may spend, and where, is decided before the money moves, not after. The same signed mandate that caps a USDC settlement on the gateway also caps a Pix payout — one policy, both slots, every time.

ReceiveTransferAdd fundsPix outBridge

Illustrative balances from a sandbox agent, same as the panel above. What matters: the wallet belongs to the agent, the mandate belongs to you, and neither one is us holding your money.

In code

Two calls: a wallet, then the mandate that governs it.

Creating the wallet and attaching its mandate are two calls, not two systems. The cap is signed once, before it's ever checked, and it governs the BRL slot and the USDC slot the same way — raising a limit on one rail never quietly raises it on the other.

create-agent-wallet.ts
const session = await codespar.sessions.create();

// one wallet per agent — non-custodial, a slot per rail
const wallet = await codespar.wallets.create({ agentId: "checkout-bot" });

// the cap is signed once, before any money can move on either slot
const mandate = await codespar.mandates.create({
  walletId: wallet.id,
  caps: [
    { rail: "pix", currency: "BRL", perTxCap: 18000, dailyCap: 500000 },
    { rail: "usdc-onchain", currency: "USDC", perTxCap: 5000, dailyCap: 20000 },
  ],
});

await session.execute("codespar_wallet", {
  walletId: wallet.id,
  mandateId: mandate.id,
  op: "pix_out",
  amount: 18000, // minor units — inside the BRL per-tx cap above
});
wallet_7f3a · mandate cm_7f3a sealed · pix_out cleared

The same mandate, enforced

wallet · mandate check
Pix out · supplier invoiceR$180.00cleared
USDC settle · gateway call$0.04cleared
Pix out · ad-hoc requestR$620.00blocked · over cap
Transfer · engineering → ops walletR$0.00no fee

Same sandbox agent as the panel above. The third row is the point: a request past the mandate's per-transaction cap is rejected before it reaches the rail, not flagged after.

Architecture

Two rails live today. Built to carry more.

The wallet spans rail-aware slices, not one shared balance — each rail keeps its own slot so nothing gets converted behind your back. Today that's a BRL sub-account and a USDC slot on Base. The architecture is built so a new rail becomes another slice under the same mandate, not a special case bolted on top.

Rails live now

BRL
Pix rail
USDC
Base · CDP
Live now
  • BRL sub-account over the Pix rail
  • USDC slot on Base via Coinbase CDP
  • One signed mandate caps both slots — no per-rail setup
Architecture-ready
  • More rail-aware slices as new rails come online
  • Same mandate model extends to each one automatically
  • No fixed list or date yet — this is how the wallet is built, not a promise of what ships next
Pricing

The wallet itself is free. Moving money out isn't.

Creating a wallet, holding a balance, running as many wallets as you have agents, transfers inside the same org — all R$0, always. The only thing that bills is money leaving the wallet under mandate, and it bills once, on the Pay line: 10 bps, floor R$0.05, cap R$2.00 per transaction.

R$0
Create & hold
Wallet plus balance, always
R$0
Org transfers
Between your own agents
10bps
Pay line rate
Only outbound, under mandate
R$2.00
Cap per transaction
Floor R$0.05
Honest status

Live, in production, non-custodial.

LiveThis isn't a preview. Wallets are the same mechanism live agents use today to hold funds between a Gate settlement and a Pix payout — open the dashboard and you'll see a real one, not a mockup.

Getting started

Give your agent a wallet

No separate setup per rail: the mandate you sign governs the USDC slot and the BRL slot the same way.

  1. Create a wallet for the agent
  2. Sign a mandate that caps what it can spend
  3. Every move — in or out — seals a receipt automatically
Where this shows up

See it inside a real business case

Wallet isn't a demo product. It's the mandate underneath money that's already moving in production, like this one.

FAQ

Wallet, answered

No. Keys are never ours. The wallet belongs to the agent's org; we govern movement through the mandate, we don't hold the funds.

No synthetic FX. Each rail stays in its own slot — dollars stay dollars, reais stay reais.

R$0 to create, hold, or run as many as you need. Only outbound movement under mandate bills, on the Pay line.

The mandate — a signed, capped, revocable authority checked before every move, not after.

One wallet per agent is the default shape; talk to us if your setup needs something different.

Yes — it's the same wallet mechanism live agents use in production, not a preview.

Not yet. Two are live today — a BRL sub-account over Pix and a USDC slot on Base. The architecture is built to carry more rail-aware slices as new rails come online; we're not naming or dating what comes next.

It's rejected before it moves. The cap is checked against the mandate the moment a transfer is requested — a blocked attempt never reaches the rail, so there's nothing to reverse.

Yes — open /dashboard/wallets for your org and you'll see the live BRL and USDC slots for every agent, not a demo account.

Give your agent a wallet.

Non-custodial, multi-slot, one mandate over everything it can move.

wallet: Live.

Wallet — one wallet per agent, one mandate over it | CodeSpar | CodeSpar