A modern web application for certifying identities and sending payments on the MessageBox network built on Bitcoin SV (BSV). Features a Next.js frontend with persistent wallet connections and a Node.js backend with session management.
- Overview
- Features
- Architecture
- Prerequisites
- Quick Start
- Configuration
- Usage
- API Documentation
- Project Structure
- Wallet Session Management
- Troubleshooting
- License
This platform provides a complete solution for:
- Identity Certification: Certify your identity with the MessageBox network via blockchain-backed transactions
- Payment Interface: Send BSV payments to certified users with persistent wallet connections
- Session Management: Connect your wallet once and reuse for multiple operations
The system leverages the MessageBox ecosystem:
@bsv/message-box-clientfor messaging and payment functionality@bsv/sdkfor BSV blockchain integration- SHIP overlay network for identity-to-host discovery
- MongoDB for certified user storage
- Session-based wallet management for seamless UX
- ✅ Modern UI - Built with Next.js 15, React 19, and Tailwind CSS
- ✅ Persistent Wallet Connection - Stays connected across page reloads
- ✅ Session Management - 30-minute sessions, no repeated wallet approvals
- ✅ Type-Safe - Full TypeScript coverage
- ✅ Responsive Design - Mobile-friendly interface
- ✅ Visual Status Indicators - Real-time connection status with animated indicators
- ✅ Wallet Session Manager - Server-side wallet connection pooling
- ✅ RESTful API - Clean API endpoints for all operations
- ✅ MongoDB Integration - Persistent storage for certified users
- ✅ MessageBox SDK - Full integration with BSV ecosystem
- ✅ Session Validation - Automatic session expiration and cleanup
- Identity Certification Page - Certify identity with optional alias
- Payments Page - Browse, search, and pay certified users
- Automatic Reconnection - Wallet reconnects on page reload
- Multiple Payments - Send many payments without re-approving wallet
- Session Persistence - 30-minute wallet sessions survive page navigation
┌─────────────────────────────────────────────────────────────┐
│ Frontend (Next.js + React + TypeScript) │
│ │
│ ┌──────────────────────┐ ┌──────────────────────┐ │
│ │ / (Certification) │ │ /payments │ │
│ │ - Connect wallet │ │ - Browse users │ │
│ │ - Certify identity │ │ - Send payments │ │
│ └──────────────────────┘ └──────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ WalletProvider (React Context) │ │
│ │ - Session state management │ │
│ │ - localStorage persistence │ │
│ │ - Auto-reconnection on load │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
│ HTTP/REST API
│ X-Session-Id header
▼
┌─────────────────────────────────────────────────────────────┐
│ Backend (Express + TypeScript + MongoDB) │
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Wallet Session Manager │ │
│ │ - Singleton wallet instances │ │
│ │ - 30-minute session timeout │ │
│ │ - Automatic cleanup │ │
│ └────────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Routes │ │
│ │ • POST /api/wallet/connect │ │
│ │ • GET /api/wallet/status │ │
│ │ • POST /api/wallet/disconnect │ │
│ │ • POST /api/certify │ │
│ │ • GET /api/certified-users │ │
│ │ • POST /api/initiate-payment │ │
│ └────────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ MessageBox SDK Integration │ │
│ │ • WalletClient (session-based) │ │
│ │ • MessageBoxClient (identity certification) │ │
│ │ • PeerPayClient (payment initiation) │ │
│ └────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ MongoDB Storage │
│ Collection: certified_users │
│ • identityKey (string, unique) │
│ • alias (string, optional) │
│ • certificationDate (Date) │
│ • certificationTxid (string) │
│ • host (string) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ BSV Blockchain & Overlay Network │
│ • SHIP protocol for identity advertisement │
│ • MessageBox servers for message routing │
│ • Bitcoin SV for payment settlement │
└─────────────────────────────────────────────────────────────┘
- Node.js (v18 or higher)
- npm (v8 or higher)
- MongoDB (v6 or higher)
- Local: MongoDB Community Server
- Cloud: MongoDB Atlas
- BSV Wallet (Desktop wallet or browser extension with WalletClient support)
# From the root directory
npm run install:allThis installs dependencies for both server and frontend.
Create .env file in the root:
cp .env.example .envEdit .env:
# Server Configuration
PORT=3000
NODE_ENV=development
# MessageBox Configuration
MESSAGEBOX_HOST=https://messagebox.babbage.systems
BSV_NETWORK=mainnet
# MongoDB Configuration
MONGO_URI=mongodb://localhost:27017
MONGO_DB=messagebox_certifier# macOS (with Homebrew)
brew services start mongodb-community
# Verify it's running
mongosh --eval "db.adminCommand('ping')"Terminal 1 - Start Backend:
npm run dev:serverTerminal 2 - Start Frontend:
npm run dev:frontend- Frontend: http://localhost:3001
- API: http://localhost:3000
| Variable | Description | Default |
|---|---|---|
PORT |
Backend server port | 3000 |
NODE_ENV |
Environment mode | development |
MESSAGEBOX_HOST |
MessageBox server URL | https://messagebox.babbage.systems |
BSV_NETWORK |
BSV network (mainnet/testnet) | mainnet |
MONGO_URI |
MongoDB connection string | mongodb://localhost:27017 |
MONGO_DB |
Database name | messagebox_certifier |
# macOS
brew services start mongodb-community
# Linux
sudo systemctl start mongod
# Verify
mongosh --eval "db.adminCommand('ping')"- Create free cluster at MongoDB Atlas
- Get connection string
- Update
MONGO_URIin.env:MONGO_URI=mongodb+srv://username:[email protected]/
- Click "Connect Wallet" in the header
- Approve wallet connection in your wallet app
- (Optional) Enter display name
- Click "Certify My Identity"
- View certification results with transaction ID
Behind the scenes:
- Wallet session created on backend (30-minute duration)
- Session ID saved to localStorage
- Identity certified on BSV blockchain
- Certification stored in MongoDB
- Wallet automatically reconnects from session
- Click "Show All" to load certified users
- Search by display name (optional)
- Click "Select for Payment" on a user
- Enter amount in satoshis
- Click "Send Payment"
- Payment sent instantly (no wallet re-approval needed!)
Behind the scenes:
- Frontend includes session ID in request header
- Backend reuses existing wallet connection
- Payment sent via MessageBox PeerPay protocol
- Session extended for another 30 minutes
1. First Connection:
User clicks "Connect Wallet" → Wallet prompts → Session created →
Session ID saved to localStorage
2. Page Reload:
Page loads → Session ID loaded from localStorage →
Session validated with backend → Wallet reconnected ✓
3. Sending Payments:
User sends payment → Session ID included in request →
Backend reuses wallet → Payment sent (no approval needed) ✓
4. Session Expiration (30 min):
Session expires → User notified → Click "Connect Wallet" →
New session created
http://localhost:3000/api
Create a new wallet session.
Response:
{
"success": true,
"sessionId": "abc123...",
"identityKey": "0277a2b...",
"message": "Wallet connected successfully"
}Check session validity.
Headers:
X-Session-Id: abc123...
Response:
{
"success": true,
"connected": true,
"identityKey": "0277a2b...",
"connectedAt": "2025-01-27T10:30:00.000Z"
}Destroy wallet session.
Headers:
X-Session-Id: abc123...
Response:
{
"success": true,
"disconnected": true,
"message": "Wallet disconnected successfully"
}Certify identity on MessageBox network.
Headers:
X-Session-Id: abc123... (optional - creates new wallet if not provided)
Request:
{
"alias": "John Doe"
}Response:
{
"success": true,
"identityKey": "0277a2b...",
"txid": "abc123...",
"alias": "John Doe",
"message": "Identity successfully certified"
}List all certified users.
Response:
{
"success": true,
"users": [
{
"identityKey": "0277a2b...",
"alias": "John Doe",
"certificationDate": "2025-01-27T10:30:00.000Z",
"host": "https://messagebox.babbage.systems"
}
]
}Search users by alias.
Query Params:
q: Search query
Send payment to certified user.
Headers:
X-Session-Id: abc123... (required)
Request:
{
"recipient": "0277a2b...",
"amount": 50000
}Response:
{
"success": true,
"messageId": "Payment sent successfully"
}Error Response (No Session):
{
"success": false,
"error": "No wallet session. Please connect your wallet first."
}messagebox-platform/
├── README.md # This file
├── QUICKSTART.md # Quick start guide
├── .env.example # Environment template
├── package.json # Root scripts
│
├── server/ # Backend
│ ├── src/
│ │ ├── index.ts # Main server
│ │ ├── types.ts # Type definitions
│ │ ├── wallet/
│ │ │ └── WalletSessionManager.ts # Session manager
│ │ ├── routes/
│ │ │ ├── walletSession.ts # Wallet session routes
│ │ │ ├── certify.ts # Certification route
│ │ │ ├── payment.ts # Payment route
│ │ │ └── listCertified.ts # User listing
│ │ └── storage/
│ │ └── CertificationStorage.ts # MongoDB layer
│ └── package.json
│
└── frontend-next/ # Frontend (Next.js)
├── app/
│ ├── layout.tsx # Root layout
│ ├── page.tsx # Certification page
│ ├── payments/
│ │ └── page.tsx # Payments page
│ └── globals.css # Global styles
├── components/
│ ├── WalletProvider.tsx # Wallet context
│ ├── WalletStatus.tsx # Connection UI
│ └── Navigation.tsx # Header nav
├── lib/
│ └── walletManager.ts # Session manager
└── package.json
-
Session Creation
- User clicks "Connect Wallet"
- Backend creates
WalletClientinstance - Generates unique session ID (32 bytes hex)
- Stores wallet instance in memory (Map)
- Returns session ID to frontend
-
Session Persistence
- Frontend saves session ID to localStorage
- Session ID included in all API requests via
X-Session-Idheader - Backend retrieves wallet from session Map
- Same wallet reused for all operations
-
Session Validation
- Sessions expire after 30 minutes of inactivity
- Each request extends session lifetime
- Expired sessions automatically cleaned up every 5 minutes
- Frontend validates session on app load
-
Session Termination
- User clicks "Disconnect"
- Session deleted from backend Map
- localStorage cleared on frontend
- User can reconnect anytime
✅ Connect Once - Single wallet approval for multiple operations ✅ Persistent - Survives page reloads and navigation ✅ Secure - Session IDs are random, no private keys stored ✅ Automatic - Reconnects on app load ✅ Clean - Expired sessions auto-cleanup
Problem: "Failed to connect wallet" error
Solution:
- Ensure you have a BSV wallet installed (desktop or browser extension)
- Check wallet supports
WalletClientprotocol - Verify wallet is unlocked
- Check browser console for detailed errors
Problem: "Wallet session expired. Please reconnect."
Solution:
- Sessions last 30 minutes of inactivity
- Click "Connect Wallet" to create new session
- To extend: Perform any action within 30 minutes
Problem: "No wallet session" or payment errors
Solution:
- Check wallet connection status (green dot = connected)
- Click "Connect Wallet" if disconnected
- Ensure recipient is certified
- Verify sufficient BSV balance
- Check backend logs for detailed errors
Problem: MongoServerError: connection refused
Solution:
# Check MongoDB is running
mongosh --eval "db.adminCommand('ping')"
# Start MongoDB if not running
brew services start mongodb-community # macOS
sudo systemctl start mongod # LinuxProblem: EADDRINUSE: port 3000
Solution:
# Kill process on port 3000
lsof -ti:3000 | xargs kill -9
# Or change PORT in .envCreate start.sh in root:
#!/bin/bash
npm run dev:server &
npm run dev:frontend &
waitThen:
chmod +x start.sh
./start.sh-
Build both applications:
npm run build:server npm run build:frontend
-
Use process manager (PM2):
pm2 start npm --name "certifier-server" -- run start:server pm2 start npm --name "certifier-frontend" -- run start:frontend
-
Use reverse proxy (Nginx) for production routing
Open BSV License
For issues:
- Check Troubleshooting
- Review MessageBox documentation:
Built with Next.js, React, and the MessageBox ecosystem on Bitcoin SV