
PayPilot
PayPilot — B2B treasury: invoice emails in, quorum-approved payouts onchain, bank-grade controls.
Demo
About
PayPilot is a B2B treasury and payout platform built on Base, where companies run payroll, vendor and bounty payments from multi-signature organization wallets. Anyone can sign in with Privy and self-serve create their own organization with named wallets (Treasury, Payroll, Bug Bounty Rewards, Ops) — each wallet carries its own onchain policy: a vendor address allowlist plus a per-transaction spending cap that Privy enforces inside the signing enclave, not in our app code. The core workflow is a real dual-control loop: a vendor simply emails an invoice (e.g. "Please pay 0xAbC… 0.02 USDC") to our receiving address — a Resend webhook parses the recipient and amount, checks the vendor against the allowlist, and creates a payout request backed by a Privy intent on the org wallet. The request needs quorum approval: an authorized team member clicks Approve, and the app's quorum signing key submits a real ECDSA authorization signature to Privy — when the threshold is met, Privy broadcasts the transfer onchain and the payout flips to Executed with the transaction hash. On top of that, PayPilot ships: role-based access (Owner, Treasurer, Finance Officer, Viewer), amount-tiered approvals (small payouts route to a single-approver Ops wallet, larger ones require the full quorum threshold), pre-generated employee wallets by email, scheduled recurring payments, and balance-condition automations. It's a finance team's controls — allowlist, caps, quorum, roles — running onchain instead of in a bank's database. Stack: Next.js, MongoDB, Privy (auth, organizations, wallets, key quorums, policies, intents, authorization signatures), Resend for the email pipeline, deployed on Vercel and live on Base Sepolia testnet.
How it's made
PayPilot is a Next.js 16 (App Router, TypeScript, Tailwind) app deployed on Vercel, with MongoDB Atlas as a pure UI-state mirror — deliberately. Every money-critical operation runs through Privy: @privy-io/node drives organizations, wallets, key quorums, policies, condition sets and intents server-side, while @privy-io/react-auth handles embedded email auth in the browser. The architecture's core principle: authority lives in Privy, never in our database. Even a fully compromised app server can't move funds — quorum thresholds, policy gates and intent execution all live in Privy's enclave. The genuinely hacky/notable bits: 1. Amount-tiered approvals done wallet-level. A quorum has exactly one threshold, so instead of bolting logic on top, each org runs two quorums: a main quorum (owner-settable 1-of-N…N-of-N) governing Treasury etc., and a single-signer ops quorum governing an Ops wallet whose Privy policy cap equals the org's amount tier. Payouts ≤ $300 auto-route to Ops; bigger ones need the full quorum. The tier is enforced at signature time by the policy, not just by routing logic. 2. Governance that can't change itself solo. Once the main threshold is ≥2, adding a signer or changing the threshold is itself an async Privy intent that the quorum must approve — the same signing pipeline as payouts. 3. Vendors as condition sets. Onboarding a vendor adds their address to a Privy condition set that every wallet policy references — allowlists enforced in the enclave. (We store both checksummed and lowercase forms after discovering calldata comparisons are case-sensitive.) 4. Pregenerated employee wallets. Inviting by email creates the employee's Privy user + embedded wallet up front, so it's waiting the moment they first log in. 5. Email-triggered payouts with policy replies. Resend webhooks carry metadata only, so we fetch the full email body via resend.emails.receiving.get, regex-parse the invoice, create the payout, and reply to the vendor — "received, pending approval" or "blocked by policy" for a spoofed address. The fraud-beat plays out in email, fully automated. 6. Automation with human rules. Scheduled sends (daily/weekly/monthly) and balance-condition rules (sweep excess, notify on thresholds) fire through the same pipeline as manual requests — policy gates apply to automation exactly as they apply to humans, and a policy failure pauses the automation with an audit trail. 7. Sponsored gas everywhere — org wallets never hold ETH, every transfer is Privy-sponsored. Partner technologies: Privy (the entire security story), Resend (inbound invoice inbox + outbound approval emails), Vercel (deploy + cron), MongoDB Atlas (org-scoped app state), viem (calldata encoding, balance reads). The build also taught us the hard way: Privy's env vars are newline-sensitive, its intent members report user IDs without the did:privy: prefix, and its webhook secrets are base64 — all three are now documented in the repo and handled.