Search projects, hackathons, sponsors and tech

    ← All projects

    Izanagi

    A wallet for AI agents that checks every payment, and can still stop one after it's been signed

    Demo

    About

    AI agents are starting to pay for things on their own. With x402, an agent hits an API, gets a price, signs, and pays. That's great until it pays the wrong person. Every tool we found for this checks the payment before the agent signs, and after that the money is gone. Izanagi is a wallet for your AI agent where every payment gets checked, and where "no" is still possible after the agent has paid. Before anything is signed, we check who's getting paid. Intercepta scans the seller's address, the token (real USDC or a fake lookalike), and the payment itself. How much? Every tab has a limit. Anything over the limit goes to your phone, and a real human has to approve it with World ID. If you say no, the approval expires, or you cancel, no valid signature ever exists. Then there's the part nobody else can do. We use x402's batch-settlement scheme, where the agent signs vouchers as it goes and the seller cashes them in later through Coinbase's escrow. Before paying out, that escrow asks our wallet contract whether the voucher is still good. So if a seller turns out to be a scammer after your agent already paid, we revoke them and their claim just fails on chain. Busy sellers on Base cash in every 1 to 5 minutes. Quiet ones can take days. That gap is your safety net. This is live on Base mainnet with real USDC. We didn't deploy a fake escrow, we used Coinbase's real one. Our wallet has paid real third-party sellers (hyperextend for Bitcoin prices, onesource for block numbers) and neither of them had to change anything. You own the wallet from the block it's created, through your own MetaMask, and we hold no key that can move your money. You can plug it into Claude over MCP and ask your AI to buy something.

    How it's made

    The heart of it is one Solidity contract, Countersign.sol. It becomes the "payer" on Coinbase's deployed x402 batch-settlement escrow (0x4020...0003 on Base). Because we set payerAuthorizer to zero, the escrow has to ask our contract through EIP-1271 isValidSignature every time a seller tries to claim. Our contract says yes only if all five hold: the agent signed it, our risk oracle countersigned it, that countersignature hasn't expired, the seller hasn't been revoked, and the wallet isn't paused. The last two are read live at claim time, and that's the whole trick. Nothing pre-sign can do that. The backend is all Rust (axum, tokio, alloy): - countersigner: the brain. It calls Intercepta, runs the World ID flow, holds the oracle key, and keeps re-scanning open tabs. When a seller's risk score crosses the line, it revokes them on chain. - tab: the server behind the website, plus an MCP endpoint (rmcp) so Claude can use your wallet directly. - seller: our own x402 seller for the demo. It goes rogue on purpose so you can watch the stop happen, and it screens its buyers with Intercepta too. - common: EIP-712 types byte-identical to the escrow, and the x402 v2 wire format. The frontend is React + Vite on Vercel, with MetaMask for creating and funding your wallet. Intercepta: we use three endpoints (address quick-scan, token risks, signature analysis), and their verdict maps straight to our four outcomes: pay, refuse, cap the amount, or ask a human. Without the verdict there's no countersignature, so the voucher can't be claimed. There's no mock mode. If the API key is missing, everything fails closed. World ID: we used the OIDC device flow on World's sandbox, so a headless agent can show a short code and a human approves on their phone. Each approval is tied to one exact voucher, so it can't be reused for a different seller, a bigger amount, or a second payment. We verify the id_token on the backend, and the agent never sees the secret. Hacky and notable bits: - We tested everything against the real escrow on mainnet forks of Base, Optimism and Arbitrum: 40 contract tests and 137 Rust tests. - Real sellers list several payment schemes in their 402 responses, so we echo back their chosen offer exactly as they sent it. That's how our wallet worked with them without them changing anything. - While testing on a fork of the real escrow, we found two ways a stranger could drain a wallet: an open collector, and opening a channel in the wallet's name using its standing allowance. We fixed both, and tests keep them closed. Now the wallet approves exactly one deposit and resets the allowance to zero. - A claim through EIP-1271 costs about 164k gas (under half a cent on Base), and the revoke kill switch costs about $0.0005.