
Agent Bank
Agent Bank: Humans set the rules, AI move the money. AI pays bills and invests idle cash in DeFi
Demo
About
Agent Bank is business banking where a company delegates bill payments and the investment of surplus funds to an AI agent, and the agent can act only within the scope a World-verified human approved. Banks fear losing deposits to stablecoins and DeFi, crypto exchanges need recurring revenue beyond trading, and businesses are held back by hacks and key management. Agent Bank gives them a familiar bank account whose idle cash earns DeFi yield, run by an agent, with no keys to manage. The customer verifies with World and grants the agent access to specific invoice emails and specific card statements, as two separate scopes: email access alone cannot read card data. The agent extracts payee, amount and due date, forecasts recurring spend from payment history, and proposes one concrete plan: schedule every payment and invest the idle deposit in Aave until each due date. The human approves that plan once. From then on, the bank's policy engine re-checks the approved rules and balance before every action. Payments settle in tokenized deposits on a private chain, surplus is exchanged for stablecoins and invested in Aave on a public chain, and on each due date the agent redeems exactly what that bill needs while the rest keeps earning. The core rule is separating human approval of specific terms, delegation to the agent with scope and limits, and bank-side execution checks. Model output never grants permissions. Approvals are bound to account, content, version and auth generation, and replayed or expired approvals are rejected. Only the human can stop or revoke the agent, and wider scope needs a new approval. The live demo runs one month for a small business: two vendor invoices (Oct 1 and Oct 10) and a corporate card bill (Oct 20). The whole deposit is invested until needed, each bill is paid on its due date, and replaying a date never double-pays. How it's made The app is a single Next.js 16 / React 19 TypeScript application with SQLite via Drizzle ORM for invoices, rules, delegations, intents and execution records, and viem for chain access. Features are plain modules (approvals, delegations, rules, invoices, cards, payments, investment, redemption) behind a small HTTP boundary. That boundary separates the human session (HttpOnly cookie) from the agent's dedicated credential: a human cookie cannot call agent APIs, and an agent credential alone grants nothing until a human delegates scope and limits. Payee, amount and operation are re-validated server-side before execution, with per-account execution locks. Private chain: Solidity contracts on OpenZeppelin, a Tokenized Deposit token (BankTD, 1 TD = 1 JPY) and a lock vault (TDLockVault), built and tested with Hardhat. A non-fork local Anvil chain stands in for the bank's private chain and is the source of truth for settled balances. To invest, TD is locked in the vault and the bank deploys matching stablecoin from its own inventory; locking never mints public tokens, and locked TD is never double-counted with invested assets. Redemption unlocks TD only after the stablecoin return is confirmed. Public chain: Aave on Base Sepolia with a test USDC-like token (not Circle USDC). Custody wallets are generated server-side and encrypted with a master key, bound to environment, account and chain, and never silently overwritten. Public sends are off unless explicitly enabled. AI: Gemini classifies requests and extracts invoice and card data. The model is treated as untrusted input, never as a source of authority. A deterministic stub mode runs the whole demo without external APIs. World: login and plan approval use World ID via IDKit 4 with Orb proofs verified through the Developer Portal. The signal is bound to account, operation and approved terms, with a per-operation nonce and expiry, so one proof cannot be reused for different terms. Nullifier reuse for the same person is expected, so replay protection lives in the challenge, not the nullifier. We also built a standalone World ID for Agents OIDC flow with openid-client: authorization code + PKCE S256, state, nonce, RS256 signature with non-repudiation checks enabled, issuer, audience, expiry, acr/amr and auth_time. It is the base for step-up approval of risky agent actions. Hosting: Cloudflare Containers behind a Worker. Each visitor gets a disposable container running the app, a local Anvil and SQLite, isolated from everyone else and put to sleep after 2 hours idle. The public demo uses stub assets; the Base Sepolia Aave path runs in local setups. The app stays bound to loopback, and a small proxy forwards only same-origin requests. Notable hacks: a bank-internal "change date" control fast-forwards through due dates without touching OS or chain time, re-verifying delegation and approval at every step, refusing to go backwards and halting on failure. IDKit 4.2.3/4.3.0 returned proof shapes that differed from what we had hard-coded, so we split SDK format checks from Portal cryptographic verification. We first built on IDKit sessions, but verification came back as verification_rejected regardless of credential type and we couldn't isolate the cause, so we switched to Orb + IDKit.request with a fresh, per-operation request bound to the exact terms being approved. The Agents OIDC callback only works when the same HTTPS origin starts and finishes the flow, because the auth cookie and the DB must match.
How it's made
Agent Bank lets users delegate everyday money management to AI while retaining control over what it can do. The agent reviews invoices, proposes payment schedules, and helps keep funds invested until they are needed. Users approve the plan, and the bank checks each action against that approval before execution. We integrated World ID into login and approval flows using IDKit. The backend verifies proofs and binds approvals to the user’s account and the specific action being authorized, rejecting expired or reused proofs. World ID supplies the proof-of-humanity layer; our bank application manages account access and financial permissions. Our World ID for Agents flow extends this model to external agents. After World authentication and bank account connection, users can grant scoped, revocable access for balance checks. They can also authorize a specific redemption to return invested funds to their original account. The agent receives a credential to execute that approved request, without the ability to change its amount or destination. The key implementation detail is that authentication and delegation remain separate. Connecting an agent does not automatically grant permission to move funds. The bank validates the credential, the user’s delegation, and the approved operation at execution time, with expiration and revocation checks throughout redemption. This makes World verification part of a concrete product flow: a human approves, an agent acts within that permission, and the bank enforces the boundaries.