One-liner: Shared family wallets for Nigeria remittance — send, request, and settle up in ₦. Crypto stays under the hood.
Monad Metropolis · Track 02 — Consumer Products & Payments · deadline 13 Oct 2026
Settle is a consumer remittance UX for Nigerian families: one shared wallet, clear ₦ balances, Send money / Request / Settle up in everyday language. Built for Metropolis Track 02 (Consumer Products & Payments) on Monad — users never see chain jargon on the primary path. Demo: seed a Lagos family → fund → send → request → settle even.
Settle is a hackathon codename only. Final consumer brand TBD.
Deploy URL: https://settlefinance.vercel.app
Judges path: Login → Seed Lagos family → Send money → Request → Settle up → Optional cash-out demo
This walkthrough demonstrates how judges (or anyone) can explore the core features in under 5 minutes. Hide-crypto stays on the primary UI throughout.
- Open the app in your browser
- Click Get Started
- Enter your email or phone number
- Complete the verification code flow
- You're in — no passwords, no seed phrases
For the hackathon demo, we provide a one-click Lagos family scenario:
- On the Home tab, find the "Try the Demo" banner
- Click Load Demo
- The "Adeyemi Family" wallet loads automatically with:
- 3 family members (you play "Mama Funke")
- Pre-seeded balances in Naira
- Sample transaction history
- Pending money requests
- The app navigates to your Adeyemi Family group
- See the Group Balance displayed in ₦ (Nigerian Naira)
- View each member's balance:
- Mama Funke (you): ₦198,290
- Chidi: ₦123,635
- Ngozi: ₦331,800
- Tap Send Money in Quick Actions
- Enter an amount (e.g., ₦15,000)
- Select a family member (e.g., Chidi)
- Tap Send
- See the success screen: "₦15,000 is on the way to Chidi"
- Return to the group — balances update instantly
- Tap Request in Quick Actions
- Enter an amount (e.g., ₦25,000)
- Select who to ask (e.g., Ngozi)
- Add a note ("Market money")
- Tap Request
- The request appears in Activity
- Notice the Pending Requests card shows Chidi's request for generator fuel
- Tap Settle Up or tap the pending request directly
- Review the request details
- Tap Mark as paid
- The request is settled and balances adjust
- Tap Invite in Quick Actions
- Copy the 6-character code or shareable link
- Share via WhatsApp, SMS, or email
- When they join, they appear in your group (max 3 members)
- Scroll down to see Activity
- Each entry shows:
- Type (Sent, Received, Requested, Paid)
- Amount in ₦
- The other person involved
- Date and optional note
- Node.js 18+ (recommended: 20+)
- npm 9+
git clone https://github.com/Savitura/settle.git
cd settle
npm install
cp .env.example .envEdit .env with your configuration:
# Required: Get your Privy App ID from https://dashboard.privy.io
NEXT_PUBLIC_PRIVY_APP_ID=your-privy-app-id-here
PRIVY_APP_SECRET=your-privy-app-secret-here
# Required: Neon Postgres connection string from https://console.neon.tech
DATABASE_URL=postgresql://user:password@host.neon.tech/dbname?sslmode=require
# Monad Testnet (defaults provided)
NEXT_PUBLIC_MONAD_CHAIN_ID=10143
NEXT_PUBLIC_MONAD_RPC_URL=https://testnet-rpc.monad.xyz
MONAD_RPC_URL=https://your-primary-monad-rpc.example
MONAD_RPC_FALLBACK_URLS=https://testnet-rpc.monad.xyz
NEXT_PUBLIC_MONAD_BLOCK_EXPLORER=https://testnet-explorer.monad.xyz
NEXT_PUBLIC_USDC_CONTRACT_ADDRESS=0x_your_usdc_contract
NEXT_PUBLIC_NGN_PER_USDC=1580
NGN_PER_USDC=1580
NEXT_PUBLIC_SPONSOR_GAS=true
ENABLE_TESTNET_FAUCET=false
NEXT_PUBLIC_ENABLE_TESTNET_FAUCET=false
TESTNET_FAUCET_PRIVATE_KEY=0x_your_testnet_only_private_key
TESTNET_FAUCET_USDC_AMOUNT=25
ENABLE_DEMO_MODE=false
NEXT_PUBLIC_ENABLE_DEMO_MODE=falseProduction mode fails closed: API calls require a verified Privy access token, sends require a confirmed USDC transfer, and direct balance mutation/demo imports are disabled. Run npm run db:migrate after upgrading so transfer protection, group roles, notifications, lifecycle metadata and audit records are applied.
For the gasless hackathon flow, enable gas sponsorship for Monad in the Privy dashboard and set NEXT_PUBLIC_SPONSOR_GAS=true. The app then submits USDC transfers through Privy's sponsored transaction API and labels the network fee as covered by Settle. Configure MONAD_RPC_URL with a dedicated provider endpoint and list comma-separated backups in MONAD_RPC_FALLBACK_URLS; server-side balance reads and receipt verification automatically fail over.
The optional testnet faucet is authenticated, capped at 100 USDC per claim, and limited to one successful claim per wallet. Keep ENABLE_TESTNET_FAUCET=false unless TESTNET_FAUCET_PRIVATE_KEY belongs to a testnet-only wallet holding the configured demo USDC. Apply the faucet claim migration before enabling it.
The NGN quote is configuration-driven but is not yet a live FX feed. Before handling customer funds, replace it with a regulated, expiring quote source and complete the required licensing, KYC/AML, transaction-monitoring, reconciliation and fiat off-ramp integrations.
After setting DATABASE_URL, create the database tables:
npm run db:pushNote: For SMS/phone login, enable Phone authentication in your Privy Dashboard (Settings → Login Methods → Phone). Email login works by default.
npm run devOpen http://localhost:3000 in your browser.
npm run build
npm run startThe fastest way to deploy Settle:
npm i -g vercel
vercel login
vercel --prod- Push to GitHub
- Import at vercel.com/new
- Add environment variable:
NEXT_PUBLIC_PRIVY_APP_ID - Deploy
In your Vercel project settings, add:
| Variable | Value |
|---|---|
NEXT_PUBLIC_PRIVY_APP_ID |
Your Privy App ID |
DATABASE_URL |
Neon Postgres connection string |
Tip: Create a Neon database at console.neon.tech and copy the connection string.
src/
├── app/
│ ├── api/
│ │ ├── demo/route.ts # Demo data management
│ │ ├── groups/ # Group CRUD + join + balance
│ │ ├── migrate/route.ts # localStorage migration
│ │ ├── requests/route.ts # Money requests
│ │ └── transactions/route.ts
│ ├── join/page.tsx # Join group via invite link
│ ├── globals.css # Tailwind + global styles
│ ├── layout.tsx # Root layout
│ └── page.tsx # Main app with auth + shell
├── components/
│ ├── CreateGroupModal.tsx # Create family wallet
│ ├── DemoBanner.tsx # One-click demo loader
│ ├── GroupCard.tsx # Group card in list
│ ├── GroupDetail.tsx # Group detail + actions
│ ├── InviteModal.tsx # Share invite code
│ ├── JoinGroupModal.tsx # Join with code
│ ├── RequestMoneyModal.tsx # Request from member
│ ├── SendMoneyModal.tsx # Send to member
│ └── SettleRequestModal.tsx # Pay pending request
└── lib/
├── currency.ts # NGN/USD conversion helpers
├── db.ts # API client for persistence
├── db/
│ ├── connection.ts # Neon Postgres connection
│ └── schema.ts # Drizzle ORM schema
├── demoData.ts # Demo scenarios + seed data
├── monad.ts # Chain configuration
└── types.ts # TypeScript types
| Feature | Status | Description |
|---|---|---|
| Email/Phone Sign-In | ✅ | Privy-powered, no passwords |
| Family Wallets | ✅ | Create shared wallet, invite 2-3 members |
| Send Money | ✅ | Send within group, Naira display |
| Request Money | ✅ | Ask group members, optional note |
| Settle Up | ✅ | Pay pending requests |
| Activity Feed | ✅ | Transaction + request history |
| Demo Mode | ✅ | One-click Lagos family scenario |
| Invite Flow | ✅ | 6-char code + shareable link |
| Off-Ramp Mock | ✅ | "Cash out to Naira" demo toggle |
- ✅ Scaffold (Next.js) + Privy email/phone login + Monad testnet wallet
- ✅ Shared group wallet — create / invite 2–3 members + balances
- ✅ Send USDC remittance UX (NGN framing; off-ramp mocked)
- ✅ Settle-up / request inside the group
- ✅ Demo pack (seed data, walkthrough, deploy URL)
npm run dev # Start dev server
npm run build # Production build
npm run start # Start production server
npm run lint # Run ESLint
npm run typecheck # Run TypeScript type check- Neon Postgres persistence: Groups, transactions, and requests persist in a shared Neon Postgres database via Next.js API routes. Data is accessible across devices/browsers.
- Hide-crypto UX: All primary flows use Naira (₦) amounts. Crypto terminology only appears in footer disclaimers or demo mode labels.
- Demo rate: ≈ $1 = ₦1,580 (static mock rate for demo purposes)
- Max 3 members: Per MVP requirements, family wallets cap at 3 members.
- API authentication: API callers are verified with Privy server tokens; group and transaction access is checked against the authenticated embedded wallet.
- Family controls: Owners can rotate invite codes and remove members with settled balances. Members can leave after settling their balance. These actions are recorded in the audit log.
- Notifications: Requests, transfers and membership changes produce in-app notifications. Email, SMS, WhatsApp and push delivery still require external providers.
- Operations:
GET /api/operationsexposes counts, recent audit activity and failed transactions only to wallets listed inADMIN_WALLETS. - Security: APIs have basic per-instance rate limiting, production responses omit framework branding, and global anti-sniffing, anti-framing, permissions and referrer headers are enabled. Distributed rate limiting should replace the in-memory limiter when running across multiple server instances.
Technical details for judges: Settle runs on Monad testnet using USDC for transfers. Privy handles embedded wallet creation. All balances shown in Nigerian Naira (₦) are converted from USD stablecoin amounts at a demo rate. In a production version, real off-ramps would connect to local payment rails (bank transfers, mobile money).
MIT