Lock SOL with spend-limited withdrawals. On-chain payroll, allowances, and vesting — with guardrails.
A sender deposits SOL into a PDA-controlled vault and defines how much a receiver can withdraw per time window.
No custodians. No trust required.
- Rate-Limited Withdrawals — Enforce a maximum spend per configurable time window (hourly, daily, weekly, monthly)
- Non-Custodial Escrow — All funds are held in PDA-controlled vaults; no private keys, no intermediaries
- Instant Cancellation — Senders can close an escrow at any time and reclaim all remaining SOL
- Multiple Escrows — A single sender/receiver pair can run multiple independent vaults via unique seeds
- Modern Frontend — Next.js 16 dashboard with wallet adapter, live countdown timers, and real-time balance tracking
stateDiagram-v2
[*] --> Initialized : sender calls initialize
Initialized --> Active : funds deposited to vault
Active --> Active : withdraw within limit
Active --> WindowReset : window expires
WindowReset --> Active : counter resets
Active --> Cancelled : sender calls cancel
Active --> Depleted : vault fully drained
Cancelled --> [*] : SOL returned to sender
Depleted --> [*] : escrow can be closed
flowchart TD
subgraph Create Escrow
A1(Sender) -->|"initialize(seed, amount, spend_limit, window)"| B1(Program)
B1 -->|create account + store config| C1(EscrowState PDA)
B1 -->|transfer SOL from sender| D1(Vault PDA)
end
subgraph Withdraw Funds
A2(Receiver) -->|"withdraw(amount)"| B2(Program)
B2 -->|check window + validate limits| C2(EscrowState PDA)
B2 -->|update counters| C2
D1 -->|transfer SOL to receiver| A2
end
subgraph Cancel Escrow
A3(Sender) -->|"cancel()"| B3(Program)
D1 -->|drain remaining SOL| A3
B3 -->|close account + return rent| C1
end
flowchart TD
A("Receiver calls withdraw(amount)") --> B{Is amount > 0?}
B -- "No" --> C1[Error: InvalidAmount]
B -- "Yes" --> D{Is window expired?}
D -- "Yes" --> E[Reset window start + withdrawn counter]
D -- "No" --> F{Is withdrawn + amount <= spend_limit?}
E --> F
F -- "No" --> G1[Error: SpendLimitExceeded]
F -- "Yes" --> H{Is vault balance >= amount?}
H -- "No" --> I1[Error: InsufficientFunds]
H -- "Yes" --> J[Update state first]
J --> K[CPI: transfer SOL to receiver]
K --> L[Success]
| Layer | Technology |
|---|---|
| Smart Contract | Anchor 0.32.1 / Rust |
| Blockchain | Solana (Devnet) |
| Frontend | Next.js 16 / React 19 / TypeScript |
| UI Components | Tailwind CSS 4 + shadcn/ui + Radix UI |
| Wallet | Solana Wallet Adapter |
| Animations | Motion (Framer Motion) |
| Forms & Validation | React Hook Form + Zod |
| Testing | Mocha + Chai + ts-mocha |
| Package Manager | Bun |
flowvault/
├── backend/ # Solana program (Rust/Anchor)
│ ├── programs/flowvault/ # Smart contract source
│ ├── tests/ # Integration tests
│ ├── scripts/ # Deployment scripts
│ ├── Anchor.toml # Anchor config
│ ├── Cargo.toml # Rust workspace
│ └── package.json # Test dependencies (bun)
│
├── frontend/ # Next.js web application
│ ├── src/ # App source (components, hooks, lib, idl)
│ ├── package.json # Frontend dependencies (bun)
│ ├── next.config.ts # Next.js config
│ └── .env.local # Environment variables
│
└── README.md # This file
Each folder has its own detailed README:
- backend/README.md — Program setup, build, test, deploy, account structure, error codes
- frontend/README.md — Frontend setup, commands, environment variables, component structure
| Tool | Version | Install |
|---|---|---|
| Rust | 1.89+ | rustup.rs |
| Solana CLI | 2.x | docs.solanalabs.com |
| Anchor CLI | 0.32.1 | anchor-lang.com |
| Node.js | 20+ | nodejs.org |
| Bun | latest | bun.sh |
# Clone
git clone https://github.com/yourusername/flowvault.git
cd flowvault
# Backend — install deps + build program
cd backend
bun install
anchor build
# Frontend — install deps + start dev server
cd ../frontend
bun install
bun devThe FlowVault program is already deployed on Solana Devnet. The current program address is:
5eyT6xJEG3Qen3QD59zNEdiE4vkYgJdnNtwjSQYCnbyb
You can share or verify this value by:
- Looking at the
programs.devnet.flowvaultentry inbackend/Anchor.toml. - Running
anchor keys listafter a build/deploy; the scriptbackend/scripts/deploy-devnet.shprints theProgram IDand a link to the Solana Explorer:PROGRAM_ID=$(anchor keys list | grep flowvault | awk '{print $2}') echo "Program ID: $PROGRAM_ID"
- Rerunning the deploy script – it always reuses the same devnet address and outputs the ID.
When you bump to a new program version or deploy from a different keypair, update the README accordingly or include the new address in communication to collaborators.
Terminal 1 — Start local Solana validator
solana-test-validatorTerminal 2 — Deploy program
cd backend
anchor deploy --provider.cluster localnetTerminal 3 — Start frontend
cd frontend
bun dev- Turbin3 — Builder cohort and capstone program
- Anchor Framework — Solana development framework
- Solana Foundation — Blockchain infrastructure
