Roam
Autonomous travel agent that plans your day and pays every stop on Base mainnet ! one ERC-7715 permission, EIP-7702 smart account, 1Shot relayer, zero wallet popups.
Videos




Tech Stack
Description
Roam is an autonomous travel agent that plans your day and pays for every stop on Base mainnet — one signature, zero wallet popups, fully on-chain.
✅ Live on Base Mainnet • Real USDC Transactions Executed • EIP-7702 Smart Account Upgrade Implemented • ERC-7710 Delegated Payments Powered by 1Shot • 1Shot Webhooks as Source of
DEPLOYED ON BASE MAINNET
Contract address: 0x63c0c19a282a1B52b07dD5a65b58948A07DAE32B (EIP7702StatelessDeleGatorImpl on Base mainnet)
Deployed link: https://basescan.org/address/0x63c0c19a282a1B52b07dD5a65b58948A07DAE32B
EIP-7702 upgrade tx as supporting proof: https://basescan.org/tx/0x37ed6002ba81ad017b2df6eac354a1cb3e9c90c24d62334160e3969e97495c85
Deployed app link : https://roam-jet-gamma.vercel.app
ERC-7715 + EIP-7702 — the one signature
When the user clicks "Sign Once", Roam calls requestExecutionPermissions via @metamask/smart-accounts-kit. MetaMask Flask 13.9+ atomically upgrades the EOA to a smart account (EIP-7702) and issues a signed ERC-7710 delegation — budget-capped in USDC, time-expiring, and scoped to the 1Shot target address. One signature. That's all the user ever does.
ERC-7710 + 1Shot — every payment, no signer
The moment the AI agent produces an itinerary, payments fire automatically. Each one calls relayer_send7710Transaction on the 1Shot permissionless mainnet relayer. The relayer redeems the ERC-7710 delegation and executes the transaction on Base mainnet with gas paid entirely in USDC — no ETH, no second signature, no popup.
1Shot webhooks as source of truth
Every relay call includes a destinationUrl. On production, /api/status receives 1Shot webhook callbacks — type 4 (submitted), type 0 (confirmed), type 1 (failed) — and uses them as the authoritative source of truth for payment status updates.
This is not polling as a fallback — webhooks drive the UI on the deployed app, exactly as the bounty criteria specifies.
What makes this novel
Most demos stop at "the transaction was submitted." Roam closes the full loop:
Permission grant → Smart account upgrade → AI-generated itinerary → Sequential delegated payments → Webhook-confirmed receipts → Downloadable on-chain proof with Basescan links and QR codes per activity
The user experience is simple: set a budget, sign once, put your phone away. The AI agent and the 1Shot relayer handle the rest.
Stack
ERC-7715 · EIP-7702 · ERC-7710 · 1Shot Permissionless Relayer · relayer_send7710Transaction · destinationUrl webhooks · Base Mainnet · USDC gas · @metamask/smart-accounts-kit · Next.js · wagmi · viem
Progress During Hackathon
Step 1 — Architecture + Foundation
Designed the full stack around a single core idea: one ERC-7715 permission grant should be enough to power an entire day of autonomous payments. Scaffolded the Next.js app, wired wagmi + viem to Base mainnet, and built the onboarding flow with city, vibe, budget, and time window inputs.
Step 2 — Permission Layer + EIP-7702
Implemented requestExecutionPermissions via @metamask/smart-accounts-kit.
Hit the first major blocker: AccountTypeNotSupportedError from attempting manual signAuthorization. After extensive debugging, discovered that MetaMask Flask 13.9+ handles EIP-7702 atomically within the permission grant flow. No manual signing required.
This unlocked the complete ERC-7715 → EIP-7702 → ERC-7710 delegation flow.
Step 3 — Payment Engine + 1Shot Integration
Built the ERC-7710 delegation decoder using decodeDelegations() from @metamask/delegation-toolkit.
Integrated the 1Shot permissionless relayer using relayer_send7710Transaction on Base mainnet, with USDC gas execution included in every transaction.
Configured destinationUrl webhooks to receive payment status updates.
Successfully executed and confirmed the first USDC payment on Base mainnet.
Step 4 — AI Agent + Streaming Experience
Built the AI agent route with Server-Sent Events (SSE), allowing itineraries to stream directly into the browser in real time.
Connected the payment queue so payments automatically execute as soon as the itinerary becomes available.
Built the live experience with:
Agent activity feed
Payment timeline
Budget tracker
Permission expiry countdown
Step 5 — Deployment + Production Reliability
Hit the second major blocker: in-memory pub/sub failed on Vercel because serverless functions do not share state across instances.
Solved it by:
Streaming agent responses directly from the route body
Creating a dedicated /api/relay-status endpoint
Proxying relayer_getStatus for transaction tracking
Keeping 1Shot webhooks active on the deployed production URL
Verified the complete end-to-end autonomous payment flow on Base mainnet.
Final State
- Live on Vercel
- Real USDC spent on Base mainnet
- EIP-7702 smart account upgrade executed on-chain
- ERC-7710 delegated transactions executed via 1Shot
- 1Shot webhooks driving payment confirmations
- AI-generated itineraries triggering autonomous payments
- Downloadable itinerary with Basescan proofs and QR codes for every activity
Hackathon Feedback
MetaMask Smart Accounts Kit + ERC-7715
The Smart Accounts Kit was central to this project and worked well overall.
One area that could be made clearer is the EIP-7702 flow. Initially, I assumed the account upgrade needed to be handled manually and spent some time exploring signAuthorization() before discovering that MetaMask Flask 13.9+ performs the upgrade automatically within requestExecutionPermissions.
A small note highlighting this behavior near the EIP-7702 documentation would help builders get started faster.
Another helpful addition would be a short example showing how to extract and decode the permissionsContext returned by requestExecutionPermissions before passing it to a relayer.
1Shot Permissionless Relayer
The 1Shot relayer was one of the smoothest parts of the build. The JSON-RPC interface was straightforward, relayer_send7710Transaction worked as expected, and the webhook payloads were easy to integrate.
One suggestion would be to add a note that destinationUrl callbacks require a publicly accessible URL. During local development, a brief recommendation to use tools such as ngrok would make webhook testing easier.
It would also be helpful if commonly used Base Mainnet addresses were surfaced directly in the quickstart documentation instead of only through relayer_getCapabilities.
Vercel Deployment
One challenge I encountered was adapting the architecture for Vercel's serverless environment, where functions do not share in-memory state.
I eventually solved this by streaming responses directly from the agent route and moving transaction status updates to a dedicated endpoint. A short deployment guide covering this pattern could be useful for teams building agent-based applications with real-time updates.
Overall Experience
The hackathon was well structured, and the technical requirements were clear.
I especially appreciated the guidance in the 1Shot bounty around using webhooks as the source of truth for transaction status. That kind of directional feedback helped shape architectural decisions early and made it easier to understand what would strengthen a submission beyond the minimum requirements.
Overall, the experience was excellent and gave me the opportunity to explore ERC-7715, EIP-7702, ERC-7710, and delegated execution patterns in a real-world application.
Fundraising Status
Nil.