Docs: OVERVIEW (source of truth) · DECISIONS (why things are the way they are) · RUNBOOK (ops + gotchas) · ROADMAP
Dead-simple Uniswap v4 liquidity positions on Base (8453) and Robinhood Chain (4663), for people new to DeFi. Log in with email, pick a pair (blue-chip crypto, ETH-quoted pairs, or Robinhood stock tokens), type a dollar amount, and one tap turns the chain's stablecoin (USDC / USDG) into a Uniswap v4 LP position in your own wallet. Self-custodial via Privy embedded + ERC-4337 smart wallets; gas sponsored on Base.
vaults.cash has no contracts of its own. It is a zap layer: the app builds a batch of calls to Uniswap's official contracts, shows every step in words, and the user's wallet signs it. See /trust for what that does and doesn't let us do.
Deposit (one atomic userOp, built in src/lib/zap.ts):
- Platform fee (
NEXT_PUBLIC_FEE_BPS, 0.6% in prod) → fee wallet, split 50/50 with the referrer's wallet when there is one (plain ERC-20 transfers) - Stablecoin → Permit2 → UniversalRouter approvals
V4_SWAPexact-in: stablecoin → quote token when the pair isn't stablecoin-quoted (e.g. cbBTC/ETH), then quote → base for the range ratio- Permit2 approvals for the PositionManager
modifyLiquiditiesmint (or add to an existing tokenId) — slippage-bounded; the whole batch reverts together
Withdraw (src/lib/withdraw.ts) burns the position, unwinds both legs back to the stablecoin (fee on the converted output only), and leaves everything in the user's wallet. Minimum deposit: $5 (src/lib/limits.ts).
All addresses come from src/lib/registries/ (one file per chain; markets are every live pool, listed as pairs), written
by npx tsx scripts/verify-chain.ts, which asserts against mainnet RPC:
token metadata (USDG, stock tokens + ERC-8056 uiMultiplier), Uniswap v4/v3
bytecode, and live v4 pool ids via StateView. Re-run it before every deploy
(pools drain and new ones appear). scripts/test-zap.ts dry-runs deposit and
withdraw plans against live pools without sending.
npm install- Copy
.env.example→.env.localand fill in:NEXT_PUBLIC_PRIVY_APP_ID— from dashboard.privy.io. Enable embedded wallets and smart wallets (Kernel); add Base (CDP bundler + paymaster) and Robinhood Chain as a custom chain (Alchemy bundler); login methods email / SMS / Google / passkey.NEXT_PUBLIC_FEE_RECIPIENT— where the platform fee goes (published on/trust).ALCHEMY_API_KEY— server-side RPC + NFT indexer (optional locally; public RPCs work for reads).DATABASE_URLandPRIVY_APP_SECRET— only needed for the referral API.
npm run dev
Docs: docs/OVERVIEW.md (architecture), docs/RUNBOOK.md (ops + gotchas), docs/DECISIONS.md (why), ROADMAP.md.
Robinhood stock tokens are listed as stock markets; disclosures at
/disclosures cover both chains. There is no jurisdiction gate today. Get
legal review before public marketing.
Agents (MCP hosts, bots, LLM tools) use the same engine without the UI — discovery at /llms.txt:
- MCP (Streamable HTTP):
https://vaults.cash/api/mcp/mcp— eight tools (markets, balances, quote, deposit, add, positions, withdraw, collect) GET /api/agent/markets·GET /api/agent/quote— read-onlyPOST /api/agent/zap-plan·POST /api/agent/withdraw-plan— executable, fee-inclusive call batches signed by the agent's own wallet;refpays half the fee on-chain to a referral code's wallet,tokenIdadds to an existing positionGET /api/agent/positions?owner=0x…
Two modes. Bring-your-own-wallet: the agent signs the returned calls and
pays its own gas (a plain EOA sends them sequentially, a smart account
batches them). Account-linked: a user turns on "Agent access" on their
Account page (a Privy session signer scoped by policy) and mints an account
key; with Authorization: Bearer vc_… the deposit/add/withdraw/collect tools
execute from the user's own smart wallet server-side
(src/lib/executor.ts), with the app's sponsored gas and atomic batches.
End-to-end harness for the first mode: scripts/agent-e2e.ts.
No contracts, no custody, no admin keys. See SECURITY.md for what's in scope and how to report privately.
MIT.