Deposit Tracking System
Overview
This system tracks wallet-connected deposits from pending to confirmed status, automatically crediting users' accounts once blockchain confirmations are complete.
Architecture
1. Database Schema
New Enum: DepositStatus
pending- Transaction sent but not confirmedconfirmed- Transaction confirmed on blockchainfailed- Transaction failed or rejected
Updated Model: OpportunityDeposit
model OpportunityDeposit {
// ... existing fields
status DepositStatus @default(pending)
confirmations Int @default(0)
requiredConfirmations Int @default(12)
confirmedAt DateTime?
failedReason String?
}
2. Flow Diagram
User sends transaction
↓
Frontend records pending deposit → API: POST /api/opportunities/{id}/deposits/pending
↓
Deposit saved with status='pending'
↓
┌─────────────────────────────────────┐
│ Two confirmation paths (Hybrid): │
│ │
│ A. Manual Check (User-triggered) │
│ POST /api/opportunities/{id}/ │
│ deposits/{depositId}/check │
│ │
│ B. Automated (Background Job) │
│ runs every 2-5 minutes │
│ POST /api/admin/jobs/ │
│ process-deposits │
└─────────────────────────────────────┘
↓
Check blockchain for confirmations
↓
Confirmations >= Required?
↓ YES
Update status='confirmed'
Credit capitalAvailable
Send notification (TODO)
↓
Done! User's balance updated
3. Key Components
A. API Endpoints
POST /api/opportunities/[id]/deposits/pending
- Called immediately after user sends blockchain transaction
- Records deposit with
status='pending' - Stores transaction hash, network, amount, currency
- Generates descriptive message
POST /api/opportunities/[id]/deposits/[depositId]/check
- Manual deposit status check (user can click "Check Status" button)
- Queries blockchain for confirmation count
- Updates deposit if confirmed
- Credits user's
capitalAvailable
POST /api/admin/jobs/process-deposits
- Admin-only endpoint to trigger background job
- Processes all pending deposits
- Returns summary of results
B. Background Job
lib/jobs/processDeposits.ts
- Standalone script that can be run via cron or API
- Queries all
pendingdeposits - For each deposit:
- Connects to blockchain RPC
- Gets transaction confirmations
- Updates database
- Credits user if confirmed
- Supports BSC, Ethereum, Polygon
Cron Setup Example:
# Run every 3 minutes
*/3 * * * * cd /path/to/reprise && npx tsx lib/jobs/processDeposits.ts >> /var/log/deposit-processor.log 2>&1
C. Frontend Integration
Updated: app/opportunities/[id]/page.tsx
- After sending transaction, calls pending deposit endpoint
- Shows user message about pending confirmation
- Displays tx hash
- Auto-reloads after 7 seconds to show status
4. Confirmation Requirements
| Network | Required Confirmations |
|---|---|
| BSC | 12 |
| Ethereum | 20 |
| Polygon | 12 |
| Default | 12 |
5. Descriptive Messages
Pending:
Wallet deposit of 100.00 USDT on BSC - Pending confirmation (Tx: 0x123...)
Confirmed:
Wallet deposit of 100.00 USDT on BSC - Confirmed (Tx: 0x123...)
Setup Instructions
Step 1: Run Database Migration
# Run the SQL migration
psql YOUR_DATABASE_URL < prisma/manual_migrations/add_deposit_status_tracking.sql
# Generate Prisma client
npx prisma generate
Step 2: Set Up Background Job (Recommended)
Option A: Systemd Service (Recommended for production)
# Navigate to systemd directory
cd systemd
# Run the setup script
./setup.sh
# The script will:
# 1. Install service and timer files
# 2. Enable auto-start on boot
# 3. Start the timer immediately
View logs:
# Follow live logs
sudo journalctl -u opportunitydao-deposit-processor -f
# View last 50 lines
sudo journalctl -u opportunitydao-deposit-processor -n 50
# View logs for specific date
sudo journalctl -u opportunitydao-deposit-processor --since "2025-10-08"
Useful commands:
# Check timer status
sudo systemctl status opportunitydao-deposit-processor.timer
# Check last run
sudo systemctl status opportunitydao-deposit-processor.service
# Run immediately (manual trigger)
sudo systemctl start opportunitydao-deposit-processor.service
# Stop the timer
sudo systemctl stop opportunitydao-deposit-processor.timer
# Disable auto-start
sudo systemctl disable opportunitydao-deposit-processor.timer
# List all timers
systemctl list-timers
Option B: Cron Job (Alternative)
# Add to crontab
crontab -e
# Add this line (runs every 3 minutes):
*/3 * * * * cd /var/www/opportunitydao && /usr/bin/npx tsx lib/jobs/processDeposits.ts >> /var/log/deposit-processor.log 2>&1
Option C: Manual Trigger (For development)
- Admins can call
POST /api/admin/jobs/process-depositsmanually - Use Postman, curl, or create an admin UI button
Step 3: Configure RPC Endpoints (Optional)
The system uses public RPC endpoints by default. For better reliability, add your own:
// In lib/jobs/processDeposits.ts
const rpcUrls = {
BSC: [
process.env.BSC_RPC_URL || 'https://bsc-dataseed.binance.org/',
// ...fallbacks
],
// ...
}
User Experience
Deposit Flow
- User clicks "Add Fresh Capital"
- Selects amount and clicks "Send Deposit"
- MetaMask/wallet prompts for approval
- Transaction sent to blockchain
- User sees: "Transaction sent! Hash: 0x123... Your deposit is pending confirmation."
- Behind the scenes:
- Deposit recorded as
pending - Background job checks confirmations every 3 minutes
- OR user can manually click "Check Status" (if you add this button)
- Deposit recorded as
- Once confirmed:
- Status →
confirmed - Amount added to
capitalAvailable - User can now participate in cycles
- Status →
Manual Check (Optional UI Addition)
You can add a "Check Status" button on pending deposits:
{deposit.status === 'pending' && (
<button onClick={() => checkDepositStatus(deposit.id)}>
Check Status ({deposit.confirmations}/{deposit.requiredConfirmations})
</button>
)}
Future Enhancements (TODOs)
Notification System
- @TODO: Implement notification bell for Admins and Investors
- Alert admins when new pending deposits are created
- Alert investors when deposits are confirmed or failed
- Alert admins of failed deposits requiring investigation
UI Improvements
- Show pending deposits on dashboard
- Display confirmation progress bar
- Add "Check Now" button for manual verification
- Show estimated time until confirmation
Advanced Features
- Email notifications on confirmation
- Webhook support for external integrations
- Support for Cardano and Solana
- Automatic retry for failed RPC connections
- Admin dashboard for deposit monitoring
Troubleshooting
Deposit not confirming?
- Check transaction on block explorer (BSCScan, Etherscan, etc.)
- Verify transaction was successful
- Check confirmation count vs. required
- Run manual check:
POST /api/opportunities/{id}/deposits/{depositId}/check - Check background job logs
Background job not running?
- Verify cron job is active:
crontab -l - Check log file:
tail -f /var/log/deposit-processor.log - Test manually:
npx tsx lib/jobs/processDeposits.ts - Verify database connectivity
RPC connection issues?
- Try different RPC URL from the fallback list
- Add your own RPC endpoint (Infura, Alchemy, etc.)
- Check rate limits on public RPCs
Security Considerations
- Only authenticated users can create deposits
- Only deposit owners can check their deposit status
- Only admins can trigger background job via API
- All deposit amounts are validated
- Duplicate transaction hashes are rejected
- Description field is auto-generated (not user-controlled)
Testing
# Test recording a pending deposit
curl -X POST http://localhost:3000/api/opportunities/1/deposits/pending \
-H "Content-Type: application/json" \
-d '{
"transactionHash": "0x123...",
"amount": 100,
"network": "BSC",
"currency": "USDT"
}'
# Test manual check
curl -X POST http://localhost:3000/api/opportunities/1/deposits/1/check
# Test background job (admin only)
curl -X POST http://localhost:3000/api/admin/jobs/process-deposits
Performance
- Background job processes ~100 deposits in < 30 seconds
- RPC calls are parallelised
- Failed RPC connections fall back to alternatives
- Database queries are indexed on
statusandtransactionHash
Monitoring
Recommended metrics to track:
- Number of pending deposits
- Average confirmation time
- Failed deposit rate
- Background job execution time
- RPC success rate per network