Skip to content

israelolrunfemi/Monad-pay

 
 

Repository files navigation

Monad Pay

Monad Pay is a consumer payments app built on Monad testnet. It combines a self-custodial wallet flow, a virtual card onboarding flow, token approvals for settlement, collaborative vaults, and an on-chain points system.

The main idea is simple:

  • users connect a wallet
  • approve spending of supported tokens, with USDC as the settlement asset
  • receive a virtual card
  • spend through the card while the app settles the equivalent value on Monad
  • earn on-chain points and use vaults for savings goals

What the project does

Monad Pay has three core product flows.

1. Wallet onboarding and card setup

Users connect a Monad wallet, complete signup details, and approve USDC for settlement. The backend then creates a virtual card record through the configured card-issuing provider and stores the provider card identifiers in Postgres.

2. Card spending and settlement

When a card transaction is reported by the card provider, Monad Pay records the payment and then collects the equivalent amount of USDC from the user on Monad using the approval granted during signup. The collected funds are sent to the treasury wallet.

3. Collaborative vaults and points

Users can create vaults backed by smart contracts and share them with other contributors. Separate contracts track Monad Pay points and a leaderboard, allowing rewards for onboarding and card activity.

Main features

  • Self-custodial wallet onboarding on Monad testnet
  • Virtual card signup flow
  • USDC approval and settlement flow
  • Portfolio view for Monad balances and supported ERC-20s
  • Transaction history
  • Collaborative vault creation and contribution
  • On-chain points and leaderboard contracts
  • PWA-style mobile-friendly UI

Architecture

Frontend

  • Next.js App Router
  • TypeScript
  • Tailwind CSS
  • wagmi + viem for chain interactions
  • thirdweb wallet UX integration

Backend

  • Next.js route handlers for signup, funding, payments, webhooks, and card retrieval
  • Drizzle ORM for database access
  • Postgres for persistence

On-chain

  • Monad testnet
  • Vault factory and vault contracts
  • Points token
  • Admin leaderboard/minter contract
  • ERC-2771 forwarder

External services

  • Stripe Issuing for cardholder and virtual card flows
  • 0x for swap quoting
  • Hypersync / Envio endpoint for transaction-style data queries

Current card-provider status

The codebase is currently wired for Stripe Issuing. That means local and deployed card creation requires:

  • a valid STRIPE_SECRET_KEY
  • a valid NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY
  • Stripe Issuing enabled on the Stripe account
  • a configured STRIPE_WEBHOOK_SECRET for transaction webhooks

If Stripe Issuing is not enabled on the account, cardholder creation will fail even if the API keys are valid.

Local setup

1. Install dependencies

bun install

2. Create your env file

cp .env.example .env.local

3. Fill in .env.local

Required values:

  • DATABASE_URL
  • NEXT_PUBLIC_THIRDWEB_CLIENT_ID
  • THIRDWEB_SECRET_KEY
  • NEXT_PUBLIC_MONAD_RPC_URL
  • MONAD_RPC_URL
  • EXECUTOR_PRIVATE_KEY
  • TREASURY_ADDRESS
  • USDC_ADDRESS
  • NEXT_PUBLIC_USDC_ADDRESS
  • NEXT_PUBLIC_VAULT_FACTORY_ADDRESS
  • NEXT_PUBLIC_POINTS_TOKEN_ADDRESS
  • NEXT_PUBLIC_AML_ADDRESS
  • NEXT_PUBLIC_SERVER_WALLET_ADDRESS
  • NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY
  • STRIPE_SECRET_KEY

Recommended values:

  • STRIPE_WEBHOOK_SECRET
  • STRIPE_ISSUING_CURRENCY=gbp
  • ENVIO_URL=https://monad-testnet.hypersync.xyz/query
  • ZEROX_API_KEY

4. Prepare the database

bun run drizzle:push

If you want Postgres in Docker first:

bun run docker:db

5. Start the app

bun run dev

6. Configure webhooks if you are testing provider-driven payments

Expose your app with a tunnel:

ngrok http 3000

Then configure the provider webhook URL to point at:

https://your-public-url/api/webhook-stripe

Important routes

  • /signup: wallet onboarding and token approval flow
  • /: home dashboard with card, balance, and portfolio
  • /transactions: activity and settlement history
  • /vaults: vault list and vault creation flow

Key backend routes:

  • /api/create-user
  • /api/get-user
  • /api/get-user-card
  • /api/get-card
  • /api/fund-mon
  • /api/execute-payment
  • /api/webhook-stripe

Smart contracts

This project includes contracts for:

  • vault deployment and contribution
  • points minting
  • leaderboard tracking
  • forwarder support for gasless-style flows

Contract addresses are expected through environment variables for frontend and backend use.

Common local issues

@next/swc version mismatch

If local dev shows a mismatch between next and @next/swc, your dependency install is stale. Reinstall dependencies cleanly so the compiled binary version matches the app version.

Database connection errors

If Drizzle or the app cannot connect to Postgres, verify DATABASE_URL and confirm the database is running.

Cardholder creation fails on Stripe

If Stripe returns a message saying the account is not set up for Issuing, the API keys are valid but the Stripe account does not have Issuing enabled yet.

Webhook signature failures

Make sure the configured STRIPE_WEBHOOK_SECRET matches the endpoint secret for the exact webhook destination you are testing.

Tech stack

  • Next.js
  • TypeScript
  • Tailwind CSS
  • wagmi
  • viem
  • thirdweb
  • Drizzle ORM
  • Postgres
  • Solidity
  • Foundry
  • Stripe Issuing

About

Monad Blitz Lagos

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • TypeScript 91.8%
  • Solidity 5.6%
  • CSS 1.8%
  • Other 0.8%