Skip to content

About

Let your agent pay, only for what tallies. An AI agent may pay only for an item a merchant signed, at the signed price, to the registered merchant, inside your rules.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Tally

Pocket money that can't be talked into the wrong purchase.

Family tops up a student's allowance from anywhere, in about a second, for cents.
It only buys what a counter signed, at the signed price, inside the family's rules.
The student's AI agent can order, but a Monad contract (not the model) makes it take the cheapest match.

▶ Live app · Android APK v2.0.0 · Demo video (4:48) · Counter QR · Contract · Verify it

Monad Testnet Contract tests App tests Envio Mera Android License

Monad Metropolis · Consumer Products & Payments


Welcome, Home, the agent's pick and Second Look, recorded on Monad Testnet

Paid, red team, receipts and keys, recorded on Monad Testnet

Videos

Video Length What it shows
Demo 4:48 The story, real evidence for the problem, every feature on testnet, how it works, sponsor proof
Agora: cross-border payments 1:59 Passkey onboarding on two phones, an AUSD balance, Mom sends $20 from Pune and Riya's balance goes from $40 to $60 in one block, with the explorer and decoded Funded event as proof
Envio: end to end 1:48 The RPC's 100-block limit, then a real payment → Monad → HyperSync → HyperIndex handler → live GraphQL (same tx hash) → Receipts in the app
Mera: UX 1:25 Face ID sign-up, PRF → three keys (owner, agent, café), a fresh Face ID for Second Look, the passkey signing a café menu
Ad 0:30 The 30-second product spot

Contents

Videos · The problem · What Tally does · See it · How it works · Proof: sponsor integrations · Why Monad · Try it · Repo · Honest status

The problem

Meet Riya. She studies in Toronto. Her parents in Pune send her lunch money, and her AI assistant now orders for her.

Parents at a bank counter, money leaking away A menu sign whispering to Riya's AI agent
Money from home is slow and leaky. A bank transfer takes days, about 6% disappears in fees, and once it lands nobody can say what it was spent on. One line of menu text and the agent upsells. "Regular is sold out", so it buys the large. Every spending cap says yes, because caps check the amount, not the item.

It isn't a feeling. These are the sources the video shows:

Source What it says
World Bank, Remittance Prices Worldwide Sending money costs 6.36% of the amount on average
ICEF Monitor / India MEA More than 1.2 million Indian students in higher education abroad (about 1.88M in total, per MEA)
AgentLAB, arXiv 2602.16901 LLM agents are highly susceptible to injected instructions in long-horizon tasks, including shopping
Greenlight help Teen cards block a store or merchant category, not an item
Stripe shared payment tokens Agent tokens cap a max_amount and a seller, not the item

Greenlight controls the store. AP2 controls the cart. Tally controls the item, and the agent's choice of it. Full competitor table and gap analysis: docs/MARKET-GAP.md

Agent wallets today Caps & allowlists Tally
How much? ✅ ✅
To whom? ✅ ✅
Which item? — ✅
At the signed price? — ✅
Cheapest match, or ask you? — ✅
Family can fund it from abroad? — ✅

What Tally does

  1. One passkey, no seed phrase. Riya signs up with Face ID. Mera turns one passkey into three keys: her account, her agent's capped key, and a menu key if she runs a café.
  2. Rules on Monad. Coffee and food, $10 a purchase, $25 a day. They live in the Tally contract, and only her key can change them.
  3. Scan. Ask. Pay. The café's QR is a menu it signed. She says "oat latte". Her agent, behind a context firewall, sees only items and prices and picks the cheapest match. The contract checks everything, then pays the counter's registered account. Settled in under a second.
  4. Second look. If the agent is talked into the large one, it's $1.40 more than the cheapest coffee, so the contract won't let it pay alone. It waits for her Face ID.
  5. Family, from anywhere. Mom opens a link in Pune, uses her fingerprint and sends $20 in AUSD with a note, "For lunches this week". It arrives in about a second with a fee of $0.00, and can only be spent the way the rules allow.
  6. Attack your own agent. A fake counter, a phantom fee, a doubled price and an upsell all reach the contract, and all four are refused.
  7. On the record. Receipts, family top-ups, blocked attempts and Tally Points (real purchases only), indexed by Envio.
  8. Any café can join. The same passkey opens a counter. Its Face ID signs the menu, and a bond anyone can slash keeps it honest.

See it

Real recordings of the live app on Monad Testnet (passkey, payments and top-ups are all on-chain):


Face ID sign-up
Mera passkey, $50 test credit

Scan → agent → Paid
cheapest match, 0.6 s

Second look
pricier pick waits for Face ID

Mom tops it up
AUSD + note, in a second

Red team
4 attacks, 4 reverts

Receipts & keys
from Envio, CSV export

Open a counter
passkey signs the menu

Android app
APK on a Moto G34

How it works

Phone, café, agent, Tally contract on Monad, payout and Envio

Three proofs, one transaction. payOffer in contracts/src/Tally.sol:

# Check Stops
1 Caller is the allowance's agent or owner; not paused or expired; counter active Stolen keys, kill switch
2–3 ECDSA.recover(EIP-712 menu digest) == counter's registered key (domain binds chain + contract) Fake counters, forged menus
4 issuedAt ≤ now ≤ expiresAt; ≤ 60 s autonomous, ≤ 1 h only with the owner Replayed old QRs
5 Payout from the registry, never from the QR Payee swap
6 The contract hashes the leaf itself and checks the Merkle proof Price inflation, phantom add-ons
7 Category bitmap, per-purchase cap, rolling 24 h cap, balance Out-of-policy spend
8 Cheapest match: price > floor (or under-bonded counter, or printed menu) needs the owner's EIP-712 Cosign Whisper upsells
9 Receipt nullifier keccak(capsule, counter, nonce, item) Double charges
10 transfer, then exact balance deltas on both sides Hidden drains

Plus trustless slashing: anyone can slash 20% of a counter's bond when its own signed menu lists an item cheaper than the floor it certified. This works even after a key rotation, because every key the counter ever registered counts.

Proof: sponsor integrations

Everything below is real output from this repo and the live deployment. Raw text is in video/public/proof/; regenerate the images with python3 video/scripts/proof_png.py.

Monad: contract, tests and a real cosigned payment

Sourcify exact match 32 contract tests Receipt of a cosigned payment

Lesson we built for: Monad's reserve balance (10 MON, 3-block window) reverted our sponsor's second transfer. Drip.welcome now sends every welcome as one transaction:

Envio: hosted HyperIndex powers Receipts, top-ups, points and merchant sales

Monad's public RPC caps eth_getLogs at about 100 blocks, so history can't come from RPC. The indexer handles Paid, Funded, CapsuleCreated, MerchantRegistered and Slashed (handlers) and is hosted on Envio Cloud. The app queries it in web/lib/activity.ts.

envio-cloud indexer get Live GraphQL query

Endpoint: https://indexer.dev.hyperindex.xyz/a8a78bb/v1/graphql

Mera: one passkey, three keys

web/lib/mera.ts: createPasskeyWithPrfOutput / getPasskeyPrfOutput → PRF → BIP-32 paths for the owner, a capped agent and a café menu signer → createSecp256k1SigningSession → toViemAccount. There's no seed phrase, extension or custody backend.

Agora AUSD: purpose-bound family top-ups

fund(id, amount, note) emits Funded(..., note), so the money arrives with its purpose. The testnet uses a 6-decimal AUSD stand-in, because AUSD is deployed only on mainnet (0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a). The token is a constructor argument.

Kimi: the agent behind a context firewall

/api/agent sends Kimi only item ids, categories, prices, floors and dictionary words. The server re-filters the payload, and the reply must be one item id in an allowed category. A deterministic rule is the fallback.

Model list Agent route

Android: a real installable app

A Trusted Web Activity over the live app (so Mera passkeys run in Chrome), verified with Digital Asset Links. See android/ and the release.

APK + release Digital Asset Links

Why Monad

  • Sub-second settlement makes tap-and-go honest: about 0.6 s from tap to a settled payment on testnet.
  • Fees small enough for a $2 chai, and sponsored, so users never see gas.
  • Built for Monad's rules: reserve-balance-safe one-transaction welcomes, gas from estimateGas × 1.2 (Monad bills the limit), and Envio for history.

Judges: try it in two minutes

Use a phone: install the Android app, or open tally-monad.vercel.app on any phone with synced passkeys (Google Password Manager, iCloud Keychain or 1Password).

  1. On a laptop, open tally-monad.vercel.app/counter, the demo café's live, re-signing QR.
  2. Phone: Get started → name → Create with Face ID. A $50 test credit arrives.
  3. Set up my allowance → Create allowance.
  4. Scan the laptop QR (or Use the demo café) → "oat latte" → Find the cheapest match → Pay.
  5. Try "large oat latte" → Second look → Approve with Face ID.
  6. Ask family on Home shares a top-up link; open it on another device and send $20.
  7. Red team tab → Run 4 attacks.

No test credentials are needed: the passkey is the account.

Deployed (Monad Testnet, chain 10143)

Contract Address
Tally 0xe7d22F222a799218908997f837CF3e0Fd1c1e40a (Sourcify verified)
AUSD (test) 0xad4B854A7eF968FDC53D4C8CC6590Dc24Cb536F1
Drip 0xafA3C3598E2051BDd615Fd7b7df8018fE22B625E

Repo

Path What
contracts Foundry: Tally.sol, MenuMerkle.sol, Drip.sol, MockAUSD.sol; 32 tests including the attack suite
web Next.js app in the original Tally design; 65 vitest tests + 1 live testnet run
indexer Envio HyperIndex, hosted on Envio Cloud
android Android app (Trusted Web Activity + Digital Asset Links)
video Remotion demo video: storyboard, recorder, evidence capture, voice, music
docs Market gap, Monad notes, verify guide, submission kit, plan
cd contracts && forge test                    # 32 tests
cd web && pnpm install && pnpm test           # 65 tests
cd indexer && pnpm install && pnpm test       # handler tests
E2E=1 pnpm -C web vitest run test/e2e.live.test.ts   # live Monad Testnet run
cd video && npx remotion render Tally out/tally-monad-demo.mp4   # the demo video

Honest status

  • Testnet only. AUSD is a stand-in token on testnet; the mainnet address is documented.
  • Not audited. Welcome credits and fees come from a sponsor wallet; on mainnet that becomes a paymaster or a fee in AUSD.
  • Bonds and the compensation pool can't be withdrawn yet.
  • Ported from Tally on Solana. Research figures are other teams' published results, not our measurements.

License

Apache-2.0

About

Let your agent pay, only for what tallies. An AI agent may pay only for an item a merchant signed, at the signed price, to the registered merchant, inside your rules.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages