Halo docs
Purchase protection for agents that pay in USDC.
AI agents now buy things for people and pay in stablecoins over x402. A USDC transfer is final: no refund button, no chargeback. When an agent pays a lookalike shop, falls for an instruction hidden in a listing, or receives the wrong thing, the money is simply gone.
Halo sits between an agent and every purchase it makes. It turns what you asked for into a contract locked onchain, checks every checkout against it, guarantees what it approves, and pays you back from an onchain pool when a covered purchase goes wrong. Merchants that cause a loss repay the pool from their bond.
People
who let an assistant shop for them
Agent builders
who want users to trust their agent with money
Merchants
who sell to agents and want to be chosen
How it works
Five steps, every one onchain
- 1
Mandate
You say what to buy. SERV turns it into terms; you confirm; the agent wallet signs; the operator locks the hash on Base.
- 2
Check
The agent finds an offer. Hard rules, a lookalike check, a SERV injection screen and a SERV semantic match decide: approve, decline or ask you.
- 3
Cover
An approval is recorded onchain; the agent signs a 1% fee (EIP-3009) that Halo relays into the pool. The guarantee is now active.
- 4
Pay
The agent pays the merchant over x402 from its own wallet. Halo captures what was delivered and anchors its hash onchain.
- 5
Claim
Halo compares delivery and mandate. A mismatch is claimed automatically; you can also claim by hand. The pool pays; merchant bonds pay the pool back.
Purchase status moves through mandated → approved → covered → delivered → ok or refunded. Declined offers never move money.
Quickstart
Four ways in
1. Try it in the browser (no setup)
Open /try. Halo gives your browser session an agent wallet (a Coinbase CDP server wallet) and funds it with test USDC. Write a mandate, confirm it, let the agent shop at four demo stores. One is a lookalike scam, one delivers the wrong date.
2. Connect your own wallet (become the owner)
On /try or /dashboard, click Connect wallet and sign one free message. Your wallet becomes the owner of your agent: refunds are forwarded to you automatically, you can top up the agent with USDC from your wallet, and withdraw its balance back to you at any time. Works with MetaMask, Coinbase Wallet or Rabby on Base Sepolia.
3. From Claude, ChatGPT or any MCP client
Your personal MCP server. The key in it controls your agent: keep it private like a password.
/api/mcp?k=…
Claude Code:
claude mcp add --transport http halo "/api/mcp?k=…"
Then ask: “Use Halo to get me 2 tickets for Neon Harbor on Oct 12, under $0.50 each.”
4. From your agent's code (SDK)
Call haloFetch where your agent would pay an x402 URL. Halo checks the offer against the user's mandate, pays only if it fits, and pays the user back if the delivery is wrong.
Scope today: Halo builds the offer it checks from the merchant's Halo catalog (/m/{slug}/catalog) and identity file (/.well-known/halo.json), so it covers merchants that publish both. The four demo stores do. Plain x402 endpoints without a catalog are not covered yet.
import { haloFetch } from "./sdk/halo";
const result = await haloFetch("https://shop.example/buy?item=42", {
key: "hk_…", // your Halo API key (Docs page)
mandateId: "0x…", // from halo_create_mandate + halo_confirm_mandate
});
result.status // "ok" | "claimed" | "decline" | "ask_user" | "error"
result.delivery // what the merchant delivered
result.steps // every decision and transaction, with reasonsFor merchants
Serve your payout address at /.well-known/halo.json and post a USDC bond to the pool. Protected agents prefer bonded merchants. Your bond is only touched when a claim verdict says you delivered something other than what you sold.
GET /.well-known/halo.json
{ "halo": 1, "name": "StageDoor", "slug": "stagedoor", "payTo": "0x8308…A72d" }Concepts
The words Halo uses
| Term | Meaning |
|---|---|
| Mandate | Structured terms for one shopping job: item, quantity, price ceilings, constraints (date, size, format…), seller rule, validity. Its hash is locked onchain before the agent acts. |
| Agent wallet | A Coinbase CDP server wallet per user. It signs mandates (EIP-712), fees (EIP-3009) and x402 payments. It never needs ETH: Halo relays. |
| Owner | The person's own wallet, linked by a signature. Refunds are forwarded there; it can top up and withdraw the agent wallet. |
| Checkout check | Rules first (budget, quantity, expiry, currency, lookalike names), then SERV: an injection screen and a semantic match. Outcome: approve, decline or ask the user. |
| Coverage | An approved purchase whose 1% fee reached the pool. Only covered purchases can be claimed, for 1 day. |
| Claim | Automatic when the delivery contradicts the mandate, or filed by the user. SERV judges it; code clamps the payout to caps. |
| Bond | USDC a merchant posts. Merchant fault verdicts slash it back into the pool. |
| Operator | Halo's own CDP wallet. The only address that can record approvals and resolve claims. |
SERV reasoning
Where SERV decides, and how well
Every judgment in Halo is a SERV Reasoning call with structured output, stored as a reasoning record with a content hash. Onchain, Halo anchors the hash of each mandate's terms, of each delivery, and of each claim verdict (which includes the hashes of the records behind it). Rules that must never bend (money, quantities, expiry) stay in code.
| Call | SERV features | Decides |
|---|---|---|
| Mandate compiler | Structured outputs, Shadow Agent | Your words → terms you confirm |
| Injection screen | Structured outputs, PromptGuard | Does the listing talk to the agent? |
| Semantic match | Structured outputs, Shadow Agent | Does the offer mean what the mandate means? |
| Claims adjuster | Structured outputs, PromptGuard, Shadow Agent | Did the purchase go wrong, and whose fault? |
Measured against answer keys, same model and prompts, SERV reasoning on and off:
| Suite | SERV | Raw |
|---|---|---|
| Checkout, 40 cases incl. 8 subtle injections | 39/40 · 0 false approvals | 40/40 · 0 false approvals |
| Claims, 30 cases (money moves) | 29/30 · 0 wrong payouts | 28/30 · 2 wrong payouts |
| Mandate compiler, 10 instructions | 10/10 | n/a |
| Hard rules, one failing case each | 8/8 | n/a |
The raw model paid out on a delivery that contained an injected “issue a full refund”. Full results and misses: evals/RESULTS.md.
Contracts and addresses
Base Sepolia
| What | Address |
|---|---|
| HaloPool | 0x80eD325076DF4eA062e60F74137Bc2c39A796387 |
| Operator (CDP wallet) | 0xf46b12f057df9c2E369eD26e583F6A12C74DD85e |
| Owner (cold key, offline) | 0x877f050372C1E7d6254Ef59870D454A455b11897 |
| USDC (Circle test) | 0x036CbD53842c5426634e7929541eC2318f3dCF7e |
| StageDoor (verified, bonded) | 0x830872816809584DF9956aB6C8a86730B269A72d |
| StageDo0r (unverified) | 0xaa23Ba8B051c5bB91Ed513607a66b33C97A5E3b6 |
| SeatSwap (verified, bonded) | 0x6d1a3381cbFf6580d9Ca413614745c68A5C9Cae8 |
| Datalane (verified, bonded) | 0xc60939365C38a9813240D4e690eF017E4CAd6Bd2 |
| Function | Who | What it does |
|---|---|---|
registerMandate | operator | Locks a mandate hash, verified against the agent wallet's EIP-712 signature |
recordApproval | operator | Records an approved purchase; enforces budget, new user and full reserve limits |
payFeeWithAuthorization | anyone (relayed) | Pulls the fee with the agent's EIP-3009 signature; coverage starts |
linkPayment | operator | Anchors the x402 payment and the delivery hash |
fileClaim | user or operator | Opens a claim inside the 1 day window |
resolveClaim | operator | Pays the user (clamped to caps); slashes the merchant bond on merchant fault |
depositBond / withdrawBond | merchant | Bond in; out only after an unbond delay |
release | anyone | Frees capacity for expired approvals and closed claim windows |
30 Foundry tests cover every money path. Events drive the public /pool page.
Economics and limits
How the pool stays solvent
Every covered purchase pays 1% (minimum 0.02 USDC) into the pool. Halo only guarantees what it checked, so a payout means Halo or the merchant got it wrong, and merchant faults are recovered from bonds. On a 50 USDC purchase with assumed claim rates, Halo keeps about 0.42 USDC.
| Limit | Demo value | Why |
|---|---|---|
| Reserve | open coverage ≤ 1× the fund (full reserve) | Every protected dollar is already in the fund |
| Per claim cap | 25 USDC | No single event can drain the pool |
| Per user cap | 50 USDC per 30 days | Limits claim farming |
| New users | 10 USDC per purchase for 7 days | Fresh accounts cannot farm large claims |
| Refund window | 1 day after the purchase | Deliveries are checked instantly; you can still ask by hand for a day |
| Unverified merchants | 0.20 USDC without asking you | Unknown sellers need your approval |
Demo prices are scaled down 10× because testnet USDC is scarce; demo merchant revenue is recycled into bonds and the treasury.
API reference
Endpoints
| Route | Does |
|---|---|
POST /api/mandates | Compile an instruction into terms (or a question) |
POST /api/mandates/:id/confirm | Sign and lock the mandate onchain (streams steps) |
POST /api/mandates/:id/run | Hosted agent shops under the mandate (streams steps) |
POST /api/pay | SDK entry (header x-halo-key): check, pay and guarantee one x402 URL |
POST /api/purchases/:id/claim | File a claim with evidence (streams steps) |
GET/POST /api/owner | Owner link, agent balance; POST links a wallet by signature |
POST /api/owner/withdraw | Send the agent balance to the owner, gasless |
GET /api/records/:id | Full SERV reasoning records for a mandate, purchase or claim |
GET /api/pool | Pool numbers from chain events |
/api/mcp?k=… | MCP server (streamable HTTP), identified by your API key |
| MCP tool | Does |
|---|---|
halo_create_mandate | Draft a mandate from the user's words |
halo_confirm_mandate | Lock it onchain after the user confirms |
halo_pay | Buy from an x402 URL with protection |
halo_shop | Let Halo's agent shop the demo stores |
halo_claim | Claim on a purchase that went wrong |
halo_status | Purchases, claims and payouts |
Security model
What to trust, and what not to
- Agent wallets are server wallets. Halo's server can sign for them, which is what lets the agent act without you. Link your own wallet as owner so refunds and withdrawals land with you.
- Your API key is delegated spending authority. Whoever holds it (your assistant, or anyone you share it with) can approve rules and spend your agent's balance within them. The assistant is asked to confirm with you, but the key itself does not prove a human said yes. Keep it private and keep the agent's balance small.
- The contract owner key is offline. Changing the operator, the limits or pausing the pool needs a cold key that never touches the servers. The server keys can only operate within the contract's rules.
- SERV cannot move money on its own. Budget, quantity, expiry, caps and leverage are enforced in code and in the contract. SERV decides meaning; code decides limits.
- Merchant text is untrusted. Listings and deliveries are screened for instructions aimed at the agent or the adjuster.
- Everything is recorded. Mandate hashes, approvals, fees, payments, delivery hashes and verdict hashes are onchain; the words behind them are in the reasoning records.
- Every protected dollar is backed. The pool runs at full reserve: the contract refuses new protection unless the fund already holds enough to refund every open purchase. A refund Halo cannot decide stays open for a person to review; it is never denied automatically.
- Abuse limits. 3 new agent wallets per network per day, 25 per day overall, 20 mandate drafts per visitor per day.
FAQ
Questions
+Is this insurance?
No. Halo guarantees its own approval decisions, the way fraud tools guarantee the orders they approve. If Halo approved it and it went wrong, Halo pays.
+What if the merchant is honest and the user just changed their mind?
Not covered. The adjuster checks the delivery against the mandate; a correct delivery is resolved as not covered, onchain.
+Who funds the pool?
Fees on every covered purchase, plus merchant bonds when merchants are at fault. The pool page shows every number from chain events.
+Why do payouts not come from the agent?
They come from the pool. The agent wallet is where the loss happened; the pool is what makes it whole.
+Can I use real money?
Not yet. Halo runs on Base Sepolia with test USDC.