Search projects, hackathons, sponsors and tech

    ← All projects

    Takarabako

    Takarabako helps turn your leftover travel cash into dollar savings

    Demo

    About

    Leftover travel cash becomes dollar savings. Every trip ends the same way: a few foreign banknotes in your pocket. Too little to be worth exchanging, too much to throw away, and useless once you're home. Takarabako (宝箱, "treasure box" in Japanese) gives that cash somewhere to go. HOW IT WORKS FOR A TRAVELER Sign up with just an email. You get a wallet without a seed phrase or an app, plus a personal ENS name like alice-1a2b.takarabako.eth. For example, at the Takarabako kiosk in Tokyo, scan your QR code and feed in your banknotes. Each note is converted at the live exchange rate and becomes a US-dollar balance on Ethereum, which earns a small base yield. You watch a lacquered treasure box on screen fill with gold as each deposit confirms. You don't need to know anything about crypto: the kiosk does the work, and your cash keeps its value after you fly home. For every dollar deposited you also receive tkCASH, a token worth one US dollar of the banknotes inside that specific machine. tkCASH is created only when a note goes in and destroyed when cash comes out, so the total supply always matches the cash the kiosks hold. WHY YOU CAN TRUST THE MACHINE The kiosk is a verifiable machine. Its ENS name, tokyo-01.takarabako.eth, publishes the key it signs every note with, and that key was generated on the device itself. A deposit only counts if the signature matches the kiosk's name, so a fake box or a replayed signature can't create money. Every receipt shows "✓ tokyo-01.takarabako.eth". When an operator counts the cash box, the count is recorded on-chain. If it doesn't match, that kiosk stops accepting deposits until a human resolves it. You can always cash out, even from a paused kiosk. WHAT YOU CAN DO WITH YOUR SAVINGS - Grow: put your balance to work as 1inch Aqua liquidity. Pick one of three beginner tiers (Steady, Balanced, Bold), each explained in one sentence, or draw your own price range on a chart. - Send: pay anyone by their ENS name instead of a hex address. - Give: every savings position has its own name, and sending that name hands the whole position to someone else. - Cash out: take your money out as cash at the kiosk, or as USDC to your own wallet. Accounts can be verified as one real person with a World ID selfie check. Unverified accounts can move up to $1,000 a day. Verified customers have no daily limit and can log in at the kiosk with World ID. FOR OPERATORS Every kiosk becomes a verifiable financial machine. A live proof-of-reserve dashboard shows the cash each kiosk holds, how fully tkCASH is backed, the banknotes coming in, daily cash flows, and who holds the token. An AI treasury agent answers operators' questions from live on-chain data and proposes actions (topping up the yield reserve, adjusting the base rate, pausing a kiosk, or adding USDC float). It can't execute anything: hard limits in code reject unsafe proposals, and a human approves every action. The agent also runs automatically when something looks wrong, like a reserve count that doesn't match. Takarabako turns the cash you forgot from your trip into savings you can actually use.

    How it's made

    Takarabako has four parts: a physical kiosk, a Node/TypeScript backend, a Next.js 16 web app, and five Solidity contracts on Ethereum Sepolia (all verified on Etherscan). THE KIOSK (HARDWARE) A Raspberry Pi 4 with a touchscreen drives a TB74 bill acceptor on its serial port (ICT protocol, 9600 8E1). A Python listener accepts a note only while a customer is logged in. Otherwise it refuses the note and the acceptor hands it back. It also reports unrecognized notes so the screen can tell the customer to try again. A small Node bridge on the Pi turns each accepted note into a deposit and signs it with a key generated on the Pi itself (EIP-712 NoteAccepted: kiosk, amount, currency, session, nonce, time). The Python code never sees account IDs or talks to the backend directly. CONTRACTS (Solidity, Foundry) - TakarabakoVault: an ERC-4626-style vault holding each customer's USDC balance, with a base APY that accrues over time. - TakarabakoCashReceipt (tkCASH): the cash in the box as a token. The treasury mints it in recordCashIn and burns it in redeem, updating that kiosk's on-chain reserve each time, so supply always equals total reserves. We fuzz-test this in Foundry. attestReserve records an operator's physical count and freezes the kiosk on any mismatch. Transfers between holders require both wallets to be allowlisted, stay under a $500/day limit, and stop when the contract is paused. Minting and burning skip those rules, so redemption is never blocked. - Mock USDC and mock ETH (testnet stand-ins), plus mock risk tokens. BACKEND (Node, Express, TypeScript) - Postgres for records. Redis with BullMQ for the deposit queue: each deposit is written to Postgres first, then a BullMQ worker credits the vault, mints tkCASH, retries failures, and streams pending to confirmed on the browser over server-sent events. If Redis is down, the Postgres row still records the cash we received, so no note is lost. - Notes are converted from local currency to USD using live rates (open.er-api.com), cached for an hour. A fixed-rate override keeps the numbers from moving mid-demo. - The backend creates each customer's wallet itself, so every account has a real wallet from its first login. FRONTEND (Next.js 16) One app serves three audiences: - Customer app: a 3D treasure box, yield with a draggable price-range chart, Send (pay by ENS name), History, a personal deposit QR, World ID verification, and Withdraw. - Kiosk screen (/kiosk), which runs on the Pi's touchscreen, and a public deposit page (/deposit), where customers log in with their wallet QR or World ID. - /ops: the operator dashboard. Session tokens live in httpOnly cookies, so browser JavaScript never sees them. The treasure box is React Three Fiber + GSAP with custom GLSL shaders, and every animation is driven by real data: notes falling in on deposit.pending, melting into gold on deposit.confirmed, one orbiting gem per open position. Visitors who prefer reduced motion, or have no WebGL, get a plain layout. PARTNER TECHNOLOGIES AND WHAT THEY GAVE US 1) Curvegrid MultiBaas: Our contract layer and indexer. Every tkCASH write and every approved agent action is built by MultiBaas as an unsigned transaction, signed locally with the treasury key and submitted, so the key never leaves our backend and we don't need a hosted wallet. Saved Event Queries (cash in by kiosk and by note type, holders rebuilt from Transfer events, reserve attestations) power the dashboard. HMAC-signed webhooks, with replay protection, stream every event into Postgres, which feeds the live feed and wakes the AI agent when something looks wrong. One idempotent script (npm run mb:setup) uploads the ABIs, links the contract addresses, saves the queries and registers the webhook. 2) ENS v2: Our names live under takarabako.eth on the official ENS v2 Sepolia deployment, with our own registry (subnames are ERC-1155 tokens) and resolver, so any ENS-aware app can resolve them. ENS gave us three features: verifiable kiosks (the name resolves to the Pi's key, and the backend recovers the signer and compares), sending money by name, and positions as transferable deeds (aqua-<id>.takarabako.eth). When a kiosk is retired, it's marked as retired in ENS, and notes signed with the old name stop verifying. 3) 1inch Aqua + SwapVM: Customers provide ETH/USDC liquidity as SwapVM strategies registered in Aqua, using the Aqua and SwapVM SDKs. The advanced mode splits a customer's chosen price range into up to five concentrated strategies. Strategies entirely below the price hold only USDC and strategies entirely above hold only ETH, so a range below the current price becomes a "buy the dip" ladder. Token amounts come from SwapVM's liquidity maths, so every strategy starts at the market price. Because Aqua tracks virtual balances, the treasury can act as the market maker for every customer without moving tokens around. 4) World ID: A Selfie Check tied to the customer's wallet address. We store the nullifier uniquely (one human, one account), and the same proof also works as a kiosk login. 5) Privy: Login with Google or an email code in the browser, so travelers never see a seed phrase. 6) Claude: We use two models for two jobs. - Haiku 4.5 explains each beginner yield tier in one sentence, and can never change the tier the customer picked. - Opus runs the treasury agent, which calls tools in a loop. It has read tools (vault state, reserve status, treasury balances, MultiBaas event queries) and can only file proposals. The limits (APY ≤ 20%, ≤ $500/day of reserve funding, ≤ 10,000/day of minted float) are enforced in code and checked again at approval time, so a prompt injection can't get past them. If a request is declined, it runs again on Anthropic's fallback model instead of failing. HACKY BITS WORTH MENTIONING - 1inch's SDK doesn't list Sepolia, and its hosted Swap API doesn't serve it. We found Aqua's SwapVM router still live at its previous address (v1.0.2) and talk to the contracts directly. - Nobody trades on Sepolia, so our positions would never earn fees. We built a demo market maker: every 10 minutes the treasury trades against its own strategies, pulling mispriced ones back toward the live ETH price. Mock ETH is priced off the live ETH/USD rate. - The Pi's default serial port can't do parity, which the bill acceptor needs. We disabled Bluetooth to free up the Pi's full serial port. - World ID 4.0 isn't in most people's World App yet, so we request the 3.0 Selfie Check. The requested credential level isn't covered by the request signature, so the backend rejects weaker credentials, sandbox proofs in production, and proofs made for a different wallet. - MultiBaas's free tier allows only five ABIs, so we designed around exactly five contracts. - We started on Uniswap v3 (real LP positions), then moved to 1inch Aqua mid-hackathon. Our Uniswap and Aqua integration notes are in FEEDBACK.md. - The kiosk moved from kl-sentral-01 to tokyo-01 on-chain: the old kiosk's reserve can still be cashed out, while its ENS record marks it as retired. Testing: 18 Foundry tests, including the supply == reserve fuzz test, and 78 backend tests (webhook signatures, policy limits, proposal lifecycle, monitor rules, World ID checks).