Purpose-locked USDC savings vaults on Arc. Save small-small toward a real goal; anyone anywhere tops up your vault; when it fills it doesn't hand you cash — it executes its purpose (pays the school, the bill, the rent).
contracts/ Solidity vaults + factory — compiled clean, 24/24 e2e passing
backend/ NestJS — Arc indexer, auto-executor, settlement pipeline, REST API
frontend/ your UI goes here
# 1. Contracts — compile & test locally
cd contracts && npm install && npm run compile
anvil --chain-id 5042002 & # https://getfoundry.sh
npm test # 24 assertions, 6 scenarios
# 2. Deploy factory to Arc Testnet
cp .env.example .env # PRIVATE_KEY (fund at faucet.circle.com)
npm run deploy:arc # prints factory address + arcscan link
# 3. Backend — infra, then run
cd .. && docker compose up -d # postgres + redis
cd backend && npm install
cp .env.example .env # FACTORY_ADDRESS + EXECUTOR_PRIVATE_KEY
npm run prisma:generate && npm run prisma:migrate
npm run start:dev # API :3001 + indexer + workers
# 4. Point the factory's executor at the backend key (once, from owner key):
# factory.setExecutor(<backend executor address>)UI → POST /purpose-ref (bill payload → purposeRef) → user signs
factory.createVault(...) → funding link shared → contributors approve +
contribute (or relayer contributeFor for cross-chain) → indexer sees goal
reached → executor auto-calls execute() → funds hit settlement treasury →
settlement worker pays the bill via BillerAdapter → funding page shows
SETTLED with biller reference.
Full architecture, invariants and conventions: CLAUDE.md (Claude Code reads it automatically).