Inspiration

Money I had on deposit at a bank moved without my authorization, and then the bank failed. I had done nothing wrong. I had trusted an institution to hold my funds, the institution had the ability to move them, and it did. There was no one to appeal to and nothing I could have signed that would have stopped it.

That is the friction I brought to this hackathon: every system where a third party can move your money is a system where you are hoping they don't. Deals between strangers on Telegram run on that same hope — someone pays first, someone delivers first, one of them gets burned. Existing "escrow" bots just move the hope to a middleman who holds the funds.

I wanted custody without a custodian. Because hope isn't a payment method.

What it does

Cubbyz is a non-custodial escrow that lives where deals actually happen — inside Telegram — with a crew of Gemini agents that do the judging, never the holding.

  • Funds lock in a smart contract on Base Sepolia. Buyer and seller agree on terms in the bot; the buyer funds the CubbyzEscrow contract with test USDC by signing in their own wallet. Cubbyz never holds keys or funds. There is no API that can mark an escrow funded, delivered, or released — on-chain evidence is the only route to a status change. Detection jobs read the chain every 60 seconds and update the record; nothing else is allowed to.
  • The whole lifecycle stays in Telegram. The bot walks both parties through create → fund → deliver → release with DMs and status cards. Sellers deliver through an in-Telegram mini app: upload files, preview them in-app, caption each one, hit Send. The buyer gets exactly one DM per batch, edited in place as files are added, so the file count they see is always the count in the database.
  • Autonomous agents watch the deal in the background. Four agents run on Google Cloud Run and reason with Gemini 3.5 Flash via Vertex AI. A3 Verification is the TaskMaster: every 30 minutes it sweeps funded escrows with submitted work, inspects the actual artifacts (including images), compares them to what was agreed, and writes a verdict to the database — with no human asking it to. A1 Support answers either party's questions from live escrow state. A2 Ops handles operational checks. A5 Adjudicator weighs evidence when a dispute is opened, treating seller captions as untrusted input rather than fact.

The agents have authority over facts — what was delivered, whether it matches — and none over funds. That split is the whole design.

Three kinds of counterparty, one contract

The escrow doesn't care what's on either side of it. Because every state change is a signed transaction and every judgment comes from on-chain and database evidence, the same contract and the same rules serve three paradigms:

  • Human ↔ Human (live today). Two people who don't trust each other. Proven end to end on Base Sepolia with database evidence: funded, delivered, released.
  • Human ↔ Agent (built for, next). A person delegates work to an AI agent and locks payment against the outcome. The agent gets paid when A3 verifies delivery — not when it says it's done. Payment is tied to evidence, not to the agent's own claim.
  • Agent ↔ Agent (built for, next). Autonomous agents hire, pay, and verify each other under machine-readable terms, with A3 as the neutral verifier and A5 as the escalation path when verification is ambiguous. No agent holds the funds, so no agent can be socially engineered into releasing them.

This is why the non-custodial rule matters more for agents than for people: an AI counterparty can be prompt-injected into paying, but it can't be prompt-injected into moving money it never controls. Nothing in the contract, the detection jobs, or the agent layer changes when a counterparty is an agent instead of a person — the same escrow, the same evidence rules, the same verifier. What an agent needs is an entry point that isn't a Telegram account, which is the API/SDK layer on the roadmap. The human-to-human lifecycle is the first paradigm we've proven, not the boundary of the system.

How we built it

Mandatory technologies, stated explicitly:

  1. Gemini 3.5 Flash (gemini-3.5-flash) via Vertex AI (location global).
  2. Google GenAI SDK (@google/genai, vertexai: true).
  3. Google Cloud Run hosting cubbyz-agent-service (Node/TypeScript), called by the bot with bearer-token auth under a dedicated service account.

Around that core:

  • Telegram bot + API — TypeScript/Node on Fly.io (two machines), backed by Fly Postgres for escrows, artifacts, captions, and agent verdicts.
  • Composer — Next.js on Vercel. Every wallet action (fund, deliver, release, refund, dispute) is a client-side signed transaction. The server never signs anything.
  • Chain — Base Sepolia. CubbyzEscrow contract, canonical test USDC, dedicated Alchemy RPC with public fallback. Phantom wallet.
  • Discipline — a strict evidence hierarchy for calling anything "done": chain/DB state beats logs beats CLI output beats screenshots. Every claim in this submission has a database row or a cross-device screen behind it.

Challenges we ran into

  • Making "non-custodial" real, not a slogan. The hard rule — no API mutates escrow status — meant every convenience feature had to be redesigned around reading the chain rather than trusting a write. It also meant deleting things that worked: the custodial key-derivation path, the "I've Paid" button.
  • Stale RPC reads on irreversible steps. A public RPC node served a stale token allowance, so the first fund attempt reverted. The fix was a dedicated endpoint plus a bounded self-heal: approve, wait for the receipt, retry exactly once — and only when the receipt proves the revert, never on a timeout, so a backgrounded mobile webview can't double-fund.
  • Telegram webview auth. Artifact previews 401'd when opened outside Telegram. We rebuilt the mini app around authenticated in-app previews and a proxied download that never exposes an unauthenticated URL.
  • Keeping the buyer's inbox honest. Batched uploads produced stale "Files: N" counts and orphaned messages. One DM per batch, edited in place, fixed it.
  • Google's edge ate our health check. /healthz on Cloud Run returned Google's own 404 before reaching the container. Renaming the route is queued; the lesson was to prove every endpoint from the container's logs, not the URL.
  • Evidence under a deadline. Fly log retention is minutes. We learned to treat the database as ground truth and capture proof the moment it exists.

Accomplishments that we're proud of

  • Full escrow lifecycle proven on Base with database evidence — funded, delivered, released — with the on-chain deliveredAt + 24h auto-release timestamp matching the DB row exactly.
  • The agent leg proven end to end: bot log shows the support call going to Cloud Run (path: "remote", model: "gemini-3.5-flash"), Cloud Run log shows POST 200 one second earlier.
  • A3 running unattended: a seller uploaded a 4.6 MB image, the 30-minute sweep fired on its own, Gemini inspected the image, and a verdict row landed in the database with its reasoning.
  • Two real devices, two real accounts: seller on a phone, buyer on a laptop, against the deployed stack — uploads, captions, Send, one true-count DM.
  • An agent layer that adds judgment without adding custody.

What we learned

  • Trust-minimization is mostly subtraction. The strongest guarantee we ship is an API that doesn't exist.
  • Background agents are most valuable at the edges of a transaction — verification, support, adjudication — and only when their inputs are labeled by trust level. A caption is evidence to weigh, not a fact to believe.
  • A clean type-check proves less than it looks. One import pointed at the wrong chain module and compiled fine; only a database probe caught it.

What's next

  • Telegram Mini App with in-chat WalletConnect signing (TRD written, prototype built and audited, five Phase-0 blockers fixed).
  • A3 acting on uncertain verdicts instead of staying silent; refund and dispute detection proven the same way funding was.
  • Agents as counterparties: H2A and A2A escrows on the same contract, entering through the API/SDK layer.
  • A developer API/SDK so any bot or agent framework can embed the escrow.
  • Mainnet, once the audit surface is closed.

Pre-existing code disclosure

Cubbyz builds on scaffolding that predates the submission window: the original Telegram bot and escrow concept began as a Solana project in February 2026. Built entirely within the submission window: the migration to Base (EVM), the non-custodial rewrite (client-side signing, chain-evidence-only status, removal of every status-mutating API), the entire Google Cloud agent layer (Cloud Run cubbyz-agent-service, Vertex AI Gemini 3.5, GenAI SDK, agents A1/A2/A3/A5), and the artifact submission mini app (uploads, previews, captions, batched buyer notifications).

Built With

Share this project:

Updates

Submission history