Vault — Our story
What inspired us
We’re watching agents gain the ability to spend: delegated keys, stablecoins, and tool calls that finalize on-chain in seconds. Most “security” still stops at authentication—proving who controls a wallet. That isn’t enough when a model can be prompt-injected, misread instructions, or drift into a payment the user never approved.
We were inspired by a concrete question:
How do you keep a human safe when an autonomous system is allowed to move money?
We wanted explicit intent (caps and allowlists), cryptographic evidence (manifests, decision traces, signed attestations), and recourse when execution violates policy—so safety isn’t a vibe-check, it’s something you can audit and dispute.
What we built (features)
On-chain guardrails
- Intent registry: Users commit an intent: USDC-only policy, per-day spend envelope, allowlisted counterparties, expiry, and a manifest URI tying policy to human-readable intent.
- Delegated execution: Users approve agent delegates per
agentIdso only approved keys can submit guarded executions. - Guarded executor: Validates (among other checks) delegate approval, token = USDC, target ∈ allowlist, not expired, daily spend limits, and a valid TraceAck linking execution to an infra-attested trace.
- Receipts & memory: Successful executions emit receipts the UI and indexer can show; policy details feed post-execution flows.
- Challenges & stake: For certain violations (e.g. amount vs. per-tx manifest cap), users can file deterministic challenges; operator stake in a vault backs slash / payout logic so recourse isn’t purely social.
Off-chain infra
- Manifest & trace handling: Pinning / storage for manifests and traces, EIP-712–style trace acknowledgements signed by a dedicated infra key so the contract can bind execution to evidence.
- Indexer & APIs: Subscribes to chain events, builds a feed for the dashboard, and exposes endpoints for auth, feed, traces, challenge preparation, and reviewer stubs.
- Flexible storage: Local SQLite for dev; Supabase-oriented paths for a production-shaped deployment.
Web application
- Onboarding & wallet UX: Connect wallet (e.g. injected / MetaMask, Coinbase, WalletConnect via Privy), optional email sign-in, SIWE session against infra for API calls.
- Intent builder: Review/edit demo caps, counterparties, and expiry; sign
commitIntenton-chain. - Delegation: Bind agent id and delegate address;
setAgentDelegateflows. - Dashboard: Activity feed, posture/summary, quick actions driven by live or mock data (
NEXT_PUBLIC_USE_MOCKS). - Agent theater / demo: Theater UI to run scripted scenarios (legit, blocked, overspend) against demo-control, with status and evidence-oriented presentation.
- Receipts & challenges: Receipt detail pages; challenge CTA with infra-prepared calldata, USDC approvals, and on-chain
AmountViolation-style flows where implemented.
Agent & demo runtime
- Scripted agents (
legit/blocked/overspend) building decision traces, uploading to infra, constructing execution requests, callingpreflightCheck/executeWithGuard. - Demo-control service (HTTP): triggers scenarios, tracks last outcome, exposes status for the UI.
How we built it (technologies)
| Layer | Stack |
|---|---|
| Smart contracts | Solidity 0.8.x, Hardhat + Ignition for deploys, OpenZeppelin patterns where applicable; artifacts under deployments/ and ABIs for the app. |
| Chain | Base Sepolia (chain id 84532), USDC test token from deployment/env. |
| Web | Next.js (App Router), React, TypeScript, Tailwind-style UI; wagmi v2/v3 + viem for reads/writes and signing; TanStack Query for server state; optional Privy (@privy-io/react-auth, @privy-io/wagmi) for unified login + wallet connectors. |
| Auth | SIWE in the browser → infra /v1/auth/nonce + /v1/auth/verify → JWT for authenticated API calls. |
| Infra | Node + Express (or similar HTTP layer), Zod for env validation, dotenv; optional IPFS-compatible pinning; Vitest for tests. |
| Monorepo | npm workspaces; shared trace package for agent/build helpers; single root .env / .env.local loaded via scripts/load-root-env.ts and aligned Next + infra config. |
Challenges we faced
- Two classes of rules — Some limits are hard-checked at execution (e.g. daily envelope, allowlist); per-tx policy can participate in challenge / slash paths. Communicating that without sounding like we “approve bad txs” was a product and narrative challenge.
- Cross-stack consistency — Wallet address, SIWE session, infra JWT, and on-chain
msg.sendermust agree; env misconfiguration shows up as confusing “partially connected” states. - End-to-end demos — A single story depends on RPC, deployed contracts, infra, demo-control, and the browser; startup order and fresh
.envbecame part of reliability. - Scope discipline — Shipping reason codes, frozen demo constants, and honest docs so “security” stays tied to what the contracts actually enforce.
What we learned
- Safety for money-moving agents is as much evidence design (hashes, URIs, signed acks) as model quality.
- Operator and developer UX are part of security: unclear env or delegation flows become user risk.
- Testnets and scripted agents are enough to prove intent → execution → receipt → dispute; production will stress RPC, key custody, stake, and storage at scale.
Math (deterministic guard intuition)
UTC day bucket (on-chain style):
$$ \text{dayBucket} = \left\lfloor \frac{t}{86400} \right\rfloor $$
Let $(S_{\text{day}})$ be spend already accumulated in that bucket, $(a)$ the proposed transfer amount, and $(C_{\text{day}})$ the committed per-day cap. A typical hard guard rejects when:
$$ S_{\text{day}} + a > C_{\text{day}} $$
For a committed per-tx ceiling $(C_{\text{tx}})$, post-execution analysis may compare $(a)$ to $(C_{\text{tx}})$ for challenge eligibility; stake $(S)$ bounds practical payout:
$$ \text{payout} \le \min(S,\, a) $$
(Exact semantics follow your deployed ChallengeArbiter / StakeVault rules.)
Closing
We set out to give human intent a real seat at the table when machines can spend: enforceable rules before and around execution, evidence that survives hype, and paths to make users whole when the chain moves faster than human attention. That thread runs from inspiration through architecture—and it’s what we’ll carry forward.
LaTeX in Markdown
- Inline:
$S_{\text{day}} + a \le C_{\text{day}}$ - Display: use
$$ ... $$on their own lines (as above).
Note: Some hosts (e.g. plain Devpost) don’t render $...$; use GitHub, Notion with math, MDX + KaTeX, or export to PDF for math-heavy submissions.
Built With
- agno
- base
- blockchain
- circle
- coinbase
- express.js
- gemini
- github
- mcp
- metamask
- next.js
- node.js
- privy
- react
- solidity
- supabase
- typescript
- wagmi
Log in or sign up for Devpost to join the conversation.