The wallet is gated by the
payments primitive, which is opt-in: it is
disabled in a fresh AccountKit and must be enabled explicitly — see
Account Kits. It is also per-agent: there is no
company-level fallback mount, so every CLI and API call needs a subject
(naive use <alice>).CLI First
Tools
The admin verbs (
create, fund, transfer, policy, sweep) are deliberately
not MCP tools and not in the SDK — they are operator-surface only. See
Governance.The wallet object
naive wallet show (GET /v1/wallet) returns the agent’s wallet. Fields are
camelCase; the wallet holds no key material.
custody is the backend holding the key (cdp, local, or fake), network
is a CAIP-2 chain id (eip155:8453 is
Base mainnet), and policy is the spend policy described below.
Reading the balance
GET /v1/wallet/balances returns a bare array (not { balances: [...] }):
Provisioning (operator)
POST /v1/users/<user_id>/wallet. Provisioning is idempotent — re-running
returns the existing wallet rather than minting a second one. --smart-account
provisions the wallet as a smart account. When a --per-tx-max is supplied at
create it is written into the custody plane as a static account policy (see
below); otherwise the wallet gets the tenant default of 0.50 USDC.
You can also declare the wallet in Agents as code so it is
provisioned as part of a deploy.
Funding (operator)
POST /v1/users/<user_id>/wallet/fund. faucet works on testnets only;
treasury moves USDC from the tenant treasury into the agent’s wallet. The
balance is the agent’s real budget, so fund only what you can afford to lose.
Transfer (operator)
POST /v1/users/<user_id>/wallet/transfer. --to accepts a raw address or
another agent’s id (to target that agent’s wallet). --purpose is recorded on
the transfer for audit. Transfers are bounded by the same perTxMax that bounds
agent payments.
Spend control
This is the part most worth reading. Unlike Cards and Trading, the wallet has no approval workflow — nopending_approval, no approval queue — and that is deliberate. Three controls
bound every payment and transfer instead:
Why no approval prompt?
perTxMax is enforced twice: once at runtime in
the pay flow, and again as a static account policy inside the custody plane,
checked when the payment is signed. That second check holds even if the agent
runtime is fully compromised — a guarantee an approval prompt cannot make, since
a compromised runtime can simply stop asking. If the custody plane can’t be
reached, wallet policy fails rather than storing a cap that isn’t really
enforced.lowBalanceThreshold (defaults to perTxMax) emits a
wallet.balance.low event when the balance drops below it after a
balance-changing op — observability only, it never blocks a spend.
Decommissioning
POST /v1/users/<user_id>/wallet/sweep moves the funds out but does not
delete the wallet — the agent simply has nothing left to spend.
Governance
The wallet splits into two surfaces. Per spec §3.7 the admin verbs are operator-surface only — not agent tools:
The operator verbs are gated server-side by
enforceWalletAdmin, and the CLI
refuses them client-side too. An agent key is refused. They are also absent
from the MCP tool list and the SDK entirely — non-exposure plus an explicit gate,
because the cheapest way to stop an agent moving the float is to give it no way
to ask.
An AccountKit can additionally deny wallet administration for a user by listing
the payments.wallet.admin capability in
primitives_config.payments.capabilities.deny.
Spending
An agent spends its wallet through Payments — the x402 buy-side flow — never by moving funds directly:min(--max-amount, perTxMax), checked (with the
balance and dailyBudget) before anything is signed. See
Payments for the full flow.
SDK
The SDK wallet client is read-only — it mirrors the operator/agent split. Available on the root (default user) andnaive.forUser(id):
fund, transfer, policy, or sweep in the SDK —
those are operator-only and reachable only over REST with an operator credential.
Agents as code
Declare a wallet on an agent withhas.crypto. This implies the payments slug
in the allowlist and adds a crypto_wallet provisioning step.
Configuration
Network: USDC on Base (
eip155:8453).
When
WALLET_ENABLED is false, the crypto_wallet provisioning step resolves to
needs_action — it never fails the deployment. With WALLET_PROVIDER=cdp,
credentials are BYO from the tenant vault; missing creds produce a typed
WalletNotConfigured error and a “connect your CDP account” prompt rather than an
opaque failure.