Wallets, branches and keys#
Give your agent a wallet, and it can buy any x402 resource with one call.
POST https://api.mechawallet.com/v1/spending-wallets/research/pay
Authorization: Bearer mw_wallet_…
{"url": "https://any-site.example/x402-resource"}
The answer is the resource:
{"paid": true, "url": "…", "goods": {"…": "what the URL returned"},
"receipt": {"tx_hash": "0x…", "amount_usd": "0.25"}, "fee": {"fee_usd": "0.000"}}
Over MCP the same call is pay_x402(url). No ceiling to compute, no chain
to pick, no address to hold. The wallet's balance is the budget, and the
wallet's key never leaves us.
What this costs
The first three wallets are free; from the fourth on, a wallet owes the opening fee, taken from the wallet itself the first time it holds a dollar. A thousand payments a month are free, then a fraction of a cent each, quoted before anything is signed. Every number is on the price list.
What a wallet is#
A small burner holding USDC that mechawallet keeps the key to, so your agent can pay an x402 challenge without holding crypto, a chain or gas. It is bounded on purpose:
- The balance is the budget. There are no standing limits to set. Fund what the job may spend; a refusal names the balance, never a setting.
- One wallet per job. Wallets are cheap and instant, so the safe default is a fresh one for each task, burned when the task is done.
- Free wallets pay from the first cent. Your first wallets owe nothing, so
they are ready the moment they hold the price. A wallet that owes the opening
fee waits until it has held one dollar once, so the fee has something to come
out of; until then it can receive money and rehearse on
/testcheckouts. - A wallet can change branch. Drag its row onto another branch in the
dashboard, or use Move to on its card. Nothing on chain moves: the wallet
keeps its key, address, balance and history. What changes is said before
you confirm: which branch key pays from it, the rules it inherits, its
place in a ranked order, and where its change goes when it is closed.
A person's action, manager or owner; over the API it is
POST /v1/spending-wallets/{wallet}/movewith adry_runfirst. - No withdrawal button, and no withdrawal flow. Money leaves by your agent spending it, by a transfer to another of your wallets, or by burning the wallet to your burn address. Keep the float small.
Opening one#
Sign in and the first screen is the wallet screen: chain, a label, three
lines, the not-storage checkbox, Open my wallet. The line you tick is
recorded once per account and the wallet opens in the same call
(POST /v1/spending-wallets with {"chain": "base", "label": "research",
"acknowledge": true}); the API refuses to open a wallet without it. It
opens in Main with its own key, shown on the card.
After the first, Open a wallet in the rail opens another, in Main or in
a branch. Over MCP an agent opens one with spending_open_wallet(chain,
label, branch) once you have acknowledged; nothing opens by itself.
Branches#
Every wallet lives in a branch: Main, which every account has and
cannot delete, or one you open for a job. A branch groups the wallets of one
job and decides which of them pays when the branch as a whole is asked to
(POST /v1/spending-branches/{branch}/pay, or pay_x402 with branch):
| Rule | Who pays |
|---|---|
lifo |
the wallet added most recently, with enough balance |
fifo |
the wallet added first, with enough balance |
ranked |
the first in your order, with enough balance |
Main has no rule and no cap; a made branch holds at most ten active wallets,
because paying through it may read every balance before choosing. Branches
are opened under Branches or with spending_open_branch; the rule and
order change with spending_set_branch or PATCH /v1/spending-branches/{branch}.
A whole branch burns with spending_burn_branch.
Name a wallet by its id, its label, its address, or its chain when you have one wallet on that chain; the same resolver serves REST and MCP.
Keys#
Three kinds, each doing one thing:
| Key | Looks like | Pays from | May also |
|---|---|---|---|
| Wallet key | mw_wallet_… |
that wallet only | read its balance and events, use its funding link, write to support |
| Branch key | mw_branch_… |
the branch, through its rule | open more wallets in the branch, under the cap |
| Account key | mw_live_… |
any wallet | open and burn wallets and branches, list everything |
A wallet's key is on its card the moment it opens and again whenever you ask (Key on the card); a branch's key is on the branch. Both are revealed in the dashboard only, never over the API or to an agent, and each wallet and branch has one active key at a time: Rotate stops the old one at once, Revoke stops it without a replacement. Keys in the dashboard lists all three kinds in three sections, wallet keys, branch keys and account keys, each tagged with its kind; account keys are minted there and shown once, and in an organization they carry the role of the member who minted them.
No key can reveal a private key, set a burn address or take money out. The credential that spends is never the credential that exfiltrates.
Connecting an agent#
Connect your agent in the rail has four doors, each with a key picker:
- Claude (claude.ai): a connector approved once, over OAuth. It renews itself.
- Claude Code: one command, with the key in the header.
- MCP configuration: the JSON for Cursor, Windsurf, Claude Desktop or any
MCP client: a streamable HTTP server at
/mcpwith the key in theAuthorizationheader. - Plain HTTP: the one request at the top of this page.
Every action in the dashboard shows From your agent underneath it: the MCP call and the curl for the same thing, with the real ids filled in.
The tools your agent gets#
| Tool | |
|---|---|
pay_x402 |
{url, max_usd?, wallet?, branch?, params?, method?, body?}. Pays any x402 URL and returns the goods. max_usd caps one call; branch lets a branch's rule pick the wallet |
search_endpoints |
{query?, chain?, max_price_usd?, category?}. What the agent can buy right now, with verified prices and reviews. No account needed |
spending_budget |
What this key pays from, ready or still loading its first dollar, the fee rule, the free payments left |
list_spending_wallets, spending_branches |
The wallets by branch, with addresses, and the branches with their rules |
spending_wallet_balance, spending_branch_balance |
What a wallet or a branch holds, read from the chain |
spending_wallet_events, spending_stats |
What happened, newest first; spent, payments, fees and last paid per wallet and branch, with CSV |
spending_funding_link |
A wallet's Send money to link: relay it to whoever funds |
spending_transfer |
Move money between your own wallets |
spending_open_wallet, spending_open_branch, spending_set_branch |
Open and shape, once you have acknowledged |
spending_burn, spending_burn_branch |
Return what is left to the burn address and close |
spending_costs |
The price list and what this account has been charged |
spending_signup, spending_claim |
An agent opens an account and a wallet for itself with no person, then hands it to one by email; the person signs in and owns it. Until then the account gets no free wallets: the wallet owes the opening fee from its first dollar |
spending_statement |
One month's numbered statement: every payment, fee, funding, transfer and burn with receipts and totals; without a month, the months that have one |
review_endpoint |
Rate an endpoint the account paid |
support_open_thread, support_threads, support_reply |
Ask a person |
There is no reveal tool, and there never will be one. When a tool needs you,
it says so: the answer carries needs_person with the step, why an agent
cannot do it, and the dashboard link. Three things are yours alone:
acknowledging how this works, setting a burn address, and revealing a key.
Why there is no gas#
A wallet holds USDC and nothing else; it never needs ETH or SOL.
- On Base, USDC supports signed transfer authorizations (EIP-3009). The wallet signs an authorization off-chain, and the endpoint being paid submits it to the chain and pays the network fee: it is the party that wants the money to land.
- On Solana, the endpoint builds the transaction with itself as the fee payer and the wallet signs only its own transfer inside it. The client checks the transaction before signing: two transfers, to the quoted wallets, for the quoted amounts, no other instruction.
- Burns, transfers between your wallets and fee collection go through our relayer, which pays the gas.
What a refusal looks like#
A payment over the balance, over the agent's own ceiling, from a sleeping
wallet or from a frozen account answers 402 or 403 with one sentence
naming the bound and the fix, and is recorded on the wallet:
- "insufficient balance: this wallet holds $0.25 spendable. Send USDC to 0x… on base"
- "over the $0.05 cap on this call: the endpoint asks $0.20"
- "insufficient balance: this wallet holds $0.60 and sleeps until it has held $1.00 once" (only a wallet that owes the opening fee)
A mw_test_ key cannot spend at all: the money is real and someone else's
endpoint has no rehearsal face. Use a wallet key or a live key.
Who may do what#
| Session (dashboard) | Wallet or branch key | Account key | |
|---|---|---|---|
| List wallets, balances, events | yes | its own | yes |
| Pay an x402 URL | no | yes | yes |
| Rehearse on a /test URL | no | yes | yes |
| Open a wallet | yes | branch key, in its branch | yes |
| Use a funding link, transfer | yes | yes | yes |
| Burn | yes | wallet key, its own wallet | yes |
| Set a burn address | yes | no | no |
| Reveal a key or phrase | yes | never | never |
What is recorded#
Every wallet keeps its own stream: created, funded, activated,
opening_fee, connected, rehearsed, spent (amount and URL),
refused and dormant_refused (reason), transferred, received,
fee, fee_collected, flagged, revealed, key_created,
key_rotated, key_revoked, burned, each with the credential that did
it. The dashboard shows it under Activity and Archive;
GET /v1/spending-wallets/{wallet}/events and spending_wallet_events
return the same list, and /events.csv exports it.
The stream is the wallet's own. It is never joined to anything you sell, and no figure anywhere adds the two together.
Rules for a wallet#
The balance is the budget; a rule narrows what it may buy. Three knobs,
each optional, on the card under Rules for this wallet or with
PUT /v1/spending-wallets/{wallet}/policy:
allow_hosts: the only hosts the wallet may pay..example.comcovers a host and its subdomains.max_per_call_usd: the most one call may cost, price and wallet fee together.approve_over_usd: above this price a call needs a person. The agent is refused withneeds a person:and the person pays it from the dashboard or raises the line.
A branch carries a rule its wallets inherit; a wallet's own rule overrides
field by field. Rules are a person's: session only, manager or owner for a
team, and no key can loosen them. The agent sees the effective rule in
spending_budget and in GET /v1/spending-wallets/{wallet}/policy; a
refusal a rule causes starts with policy: and names the fix.
Alerts#
You hear by email, at most once an hour per wallet, when the agent is refused (no balance, a rule, or a person's line) and when a payment leaves the wallet under a dollar. A team's alerts go to its owner. Nothing else mails you.
Who did what#
Every statement line carries by_label: the key that paid, named by its
prefix, the Claude connector, a person in the dashboard, or the service.
The month carries by_who, spent and payments per person and key, and the
CSV ends with the same breakdown. That is how a team files a month against
the people and keys that spent it.