A decentralized platform for invoice financing using blockchain technology. Investors deposit USDC to receive Senior or Junior tranche tokens, and returns are distributed via a waterfall mechanism.
rwa-platform/
βββ contracts/ # Solidity smart contracts (Hardhat)
βββ backend/ # Node.js + Express + MongoDB API
βββ frontend/ # Next.js 14 + Wagmi + RainbowKit
βββ README.md # This file
- InvoiceNFT (ERC-721): Represents real-world invoices as NFTs
- SeniorTrancheToken (ERC-20): Senior tranche positions (priority returns)
- JuniorTrancheToken (ERC-20): Junior tranche positions (higher risk/reward)
- RwaVault: Manages deposits, 2% origination fee, and waterfall distribution
- MockUSDC: Testing token (6 decimals like real USDC)
- POST /kyc/request: Simulated KYC approval
- GET /config: Returns platform configuration (2% fee)
- Dashboard: View TVL and tranche supplies
- Invest: Connect wallet, complete KYC, deposit USDC
- Portfolio: View positions and claimable amounts
- Node.js 18+ and pnpm
- MongoDB (local or Atlas)
- MetaMask or compatible Web3 wallet
# Install all workspace dependencies
pnpm install
# Or install each package separately
pnpm --filter contracts install
pnpm --filter backend install
pnpm --filter frontend installcd contracts
# Compile contracts
pnpm compile
# Run tests (34 tests should pass)
pnpm test
# Start local Hardhat node (in a separate terminal)
pnpm node
# Deploy contracts to local network
pnpm deployThe deployment script will output contract addresses - save these for the frontend configuration.
cd backend
# Create .env file
cp .env.example .env
# Edit .env and add your MongoDB URL
# MONGO_URL=mongodb://localhost:27017/rwa-platform
# PORT=4000
# Start development server
pnpm devBackend will run on http://localhost:4000
cd frontend
# Create environment file
cp .env.local.example .env.local
# Edit .env.local with contract addresses from step 2
# NEXT_PUBLIC_VAULT_ADDRESS=0x...
# NEXT_PUBLIC_USDC_ADDRESS=0x...
# NEXT_PUBLIC_SENIOR_ADDRESS=0x...
# NEXT_PUBLIC_JUNIOR_ADDRESS=0x...
# NEXT_PUBLIC_BACKEND_URL=http://localhost:4000
# Also get a WalletConnect Project ID from https://cloud.walletconnect.com
# and update it in lib/wagmiConfig.ts
# Install dependencies
npm install
# Start development server
npm run devFrontend will run on http://localhost:3000
- Connect Wallet: Click "Connect Wallet" button
- Complete KYC: On the Invest page, complete the simulated KYC check
- Get Test USDC: Use the deployed MockUSDC contract to mint test tokens
- Choose Tranche:
- Senior: Lower risk, priority in waterfall, fixed ~8% APY
- Junior: Higher risk, gets remainder after senior paid, variable returns
- Deposit USDC:
- Enter amount
- Approve USDC spending
- Confirm deposit transaction
- 2% origination fee is automatically deducted
- View Portfolio: Check your tranche balances and claimable amounts
# Mint test USDC to users
npx hardhat console --network localhost
> const usdc = await ethers.getContractAt("MockUSDC", "USDC_ADDRESS")
> await usdc.mint("USER_ADDRESS", ethers.parseUnits("10000", 6))
# Mint Invoice NFTs
> const invoiceNFT = await ethers.getContractAt("InvoiceNFT", "INVOICE_ADDRESS")
> const faceValue = ethers.parseUnits("50000", 6)
> const dueDate = Math.floor(Date.now() / 1000) + 30 * 24 * 60 * 60
> const debtorHash = ethers.keccak256(ethers.toUtf8Bytes("Debtor123"))
> await invoiceNFT.mintInvoice("RECIPIENT_ADDRESS", faceValue, dueDate, debtorHash)
# Distribute returns (simulating invoice repayment)
> const vault = await ethers.getContractAt("RwaVault", "VAULT_ADDRESS")
> const yieldAmount = ethers.parseUnits("5000", 6)
> await usdc.approve(vault.address, yieldAmount)
> await vault.distributeReturns(yieldAmount)cd contracts
pnpm testAll tests validate:
- β 2% origination fee calculation
- β Senior/Junior tranche token minting
- β Waterfall distribution (senior paid first)
- β Invoice NFT minting with metadata
- β Transfer restrictions on invoices
- Deploy contracts to local Hardhat network
- Start backend server
- Start frontend
- Mint USDC to test wallet
- Connect wallet on frontend
- Complete KYC
- Approve USDC and deposit into Senior tranche
- Check portfolio shows correct balance
- Admin distributes returns
- Portfolio shows claimable amount
After running pnpm deploy in the contracts directory, update these in frontend/.env.local:
NEXT_PUBLIC_VAULT_ADDRESS=
NEXT_PUBLIC_USDC_ADDRESS=
NEXT_PUBLIC_SENIOR_ADDRESS=
NEXT_PUBLIC_JUNIOR_ADDRESS=
NEXT_PUBLIC_INVOICE_NFT_ADDRESS=
Addresses are saved in contracts/deployments/latest.json
| Layer | Technology |
|---|---|
| Smart Contracts | Solidity 0.8.24, OpenZeppelin, Hardhat |
| Backend | Node.js, Express, MongoDB, Mongoose, TypeScript |
| Frontend | Next.js 14, React 18, TypeScript, Tailwind CSS |
| Web3 | Wagmi v2, Viem, RainbowKit v2 |
| Testing | Hardhat (Chai, Ethers) |
1. Investor deposits USDC β Vault
2. Vault deducts 2% fee
3. Vault mints tranche tokens (1:1 with net deposit)
4. Invoice payments received β Vault
5. Vault distributes via waterfall:
- Senior tranche paid first (principal + yield)
- Junior tranche gets remainder
6. Investors can claim/withdraw their returns
- No on-chain KYC verification
- Simplified default handling
- No invoice NFT secondary trading
- No governance mechanism
- Mock USDC (not real USDC)
For production deployment:
- Implement proper KYC/AML
- Add pause mechanism
- Conduct full security audit
- Add emergency withdrawal
- Implement proper access controls
- Use real USDC on mainnet
- β Investors can deposit USDC and receive tranche tokens
- β Invoices can be minted with correct metadata (faceValue, dueDate, debtorHash)
- β Waterfall distribution functions correctly (Senior β Junior)
- β 2% fee is deducted and visible in transactions
- β Backend APIs respond correctly
- β Frontend displays deposits, portfolio, and claims accurately
- β All 34 contract tests pass
- Contracts: See
contracts/README.md(if exists) or contract inline comments - Backend: See
backend/src/for API route implementations - Frontend: See
frontend/README.md,SETUP.md, andQUICK_REFERENCE.md
- Make sure you've minted test USDC to your wallet
- Check your wallet is connected to the correct network (Localhost/Hardhat)
- Ensure you've approved USDC spending before depositing
- Check contract addresses in
.env.localare correct - Verify Hardhat node is still running
- Update WalletConnect Project ID in
lib/wagmiConfig.ts - Clear browser cache and reconnect wallet
- Check wallet is on correct network (chainId: 31337)
- Ensure MongoDB is running
- Check
MONGO_URLinbackend/.env - Verify port 4000 is not in use
Screen.Recording.2025-10-06.at.10.42.31.AM.mov
This is a demonstration project following the PRD specifications. For improvements:
- Test thoroughly
- Follow existing code style
- Add tests for new features
- Update documentation
MIT
- Security Audit: Conduct comprehensive smart contract audit
- Testnet Deployment: Deploy to Sepolia
- Real KYC Integration: Integrate with KYC provider (Persona, Onfido, etc.)
- Enhanced Backend: Add proper authentication, rate limiting, logging
- Analytics: Add transaction history, APY tracking, charts
- Mobile Responsive: Optimize mobile experience
- Gas Optimization: Optimize contract gas usage
- Mainnet Prep: Use real USDC, configure proper network settings
Built following the RWA Platform PRD specifications.