make_post_sell/docs/CRYPTO.rst
Russell Ballestrini 04583ace53 Clean up Makefile sweep commands and documentation
- Remove error messages from sweep/sweep-check Makefile targets
- Keep commands functional for developers/admins in local environments
- Simplify documentation to focus on automatic sweeping behavior
- Maintain separation between end-user docs and dev tools
2025-09-30 20:54:50 -04:00

450 lines
15 KiB
ReStructuredText

Cryptocurrency Payment System Documentation
===========================================
This document provides detailed information about the cryptocurrency payment system in Make Post Sell, including wallet management, security considerations, and operational procedures.
Introduction
------------
The cryptocurrency payment system in Make Post Sell works like a digital cash register that can accept Monero (and eventually other cryptocurrencies). Here's the key concepts:
**Why You Can't Use External Wallets (like Cake Wallet):**
The system needs to generate a unique address for each customer payment (like giving each customer a different invoice number). Only the wallet owner can create these subaddresses, and external wallets can't provide this functionality via API.
**How Money Flows:**
1. Customer pays → Your hot wallet receives it
2. Payment is detected and order is fulfilled automatically
3. You manually move funds to cold storage periodically
**Security Reality:**
- Your server holds the wallet keys (like leaving cash register unlocked)
- If server is hacked = funds at risk
- Best practice: Keep minimal funds, move to cold storage often
**The Architecture:**
- **monero-wallet-rpc**: The "cash register" software
- **crypto_watcher**: The "cashier" watching for payments
- **CryptoPayment**: The "receipt book" tracking who paid what
Think of it like running a physical store - you need your own cash register (can't use someone else's), you periodically empty it to a safe (cold wallet), and you keep receipts (database records) of all transactions.
Overview
--------
Make Post Sell supports cryptocurrency payments through a modular system designed to handle multiple coins. Currently, Monero (XMR) is implemented, with the architecture ready for Bitcoin, Litecoin, and other cryptocurrencies.
Architecture
------------
The crypto payment system consists of several components:
1. **CryptoPayment Model** - Database model tracking payment details
2. **Crypto Client Library** - RPC client for communicating with wallet daemons
3. **Crypto Views** - Web endpoints for payment flow
4. **Crypto Watcher** - Background service monitoring blockchain for payments
5. **Auto-Sweep** - Automatically transfers funds to cold storage after each payment
How Payments Work
-----------------
1. Customer selects "Pay with Crypto" at checkout
2. System generates a unique subaddress for the payment
3. Current exchange rate is locked for the quote duration
4. Customer sends payment to the generated address
5. Crypto watcher monitors for incoming transfers
6. Order is fulfilled when payment is confirmed
7. **Funds are immediately swept to shop's cold wallet** (keeps only 0.001 XMR for fees)
Per-Shop Wallet Configuration
-----------------------------
Each shop can have its own hot wallet account and cold storage address:
1. **Hot Wallet Account**: Automatically assigned when shop configures a cold wallet
2. **Cold Wallet Address**: Shop owner's secure wallet for receiving swept funds
To enable Monero payments for a shop:
1. Go to Shop Settings
2. Enter your cold wallet address in the Monero section
3. System automatically assigns a unique account index (one-time)
4. Shop is now ready to accept Monero payments
**Changing Cold Wallet Address**:
- You can update your cold wallet address anytime
- Your account index stays the same (no funds lost)
- Future sweeps will go to the new address
- Existing balance (0.001 XMR reserve) remains available
**Security Design**:
- Account indices are hidden from users to prevent confusion
- Each shop gets one permanent account index (doesn't change with cold wallet updates)
- Each shop's funds are isolated in separate accounts
- **Auto-sweep is mandatory** - funds move to cold storage immediately after confirmation
- Hot wallet never holds more than 0.001 XMR per account
Transaction Lifecycle Example
-----------------------------
Let's follow a complete user journey for a $10 digital product purchase:
**Customer Journey Begins**
**1. Product Discovery**
- Customer visits shop.example.com
- Browses products, finds a $10 digital guide
- Clicks "Add to Cart"
- Cart shows: 1 item, $10.00
**2. Checkout Process**
- Customer clicks "Checkout"
- Enters email: customer@email.com
- Sees payment options: "Pay with Stripe" or "Pay with Monero"
- Chooses "Pay with Monero"
**3. Payment Quote Generation** (T+0 seconds)
- System fetches current XMR/USD rate: 1 XMR = $300 USD
- Calculates price: $10 ÷ $300 = 0.03333333 XMR
- Displays to customer:
```
Amount Due: 0.03333333 XMR
Exchange Rate: $300.00/XMR
Quote Valid For: 15 minutes
```
**4. Payment Address Generation** (T+1 second)
- System assigns subaddress from shop's account (e.g., account 5, subaddress 147)
- Displays QR code and address: 87BqQYkugEzh6Tg3gmfDPD6u7w6rNwJrTZXSdWgMHMfT...
- CryptoPayment record created:
- Shop's cold wallet stored for later sweep
- Expected amount: 0.03333333 XMR
- Quote expiry timestamp set
**5. Customer Sends Payment** (T+2 minutes)
- Customer opens mobile Monero wallet
- Scans QR code or copies address
- Enters amount: 0.03333333 XMR
- Confirms transaction (network fee ~0.00001 XMR)
- Transaction broadcasts to Monero network
**6. Payment Detection** (T+2-3 minutes)
- crypto_watcher polls every 20 seconds
- Detects incoming transaction in mempool
- Status changes: "pending" → "received"
- Customer sees: "Payment received! Awaiting 10 confirmations..."
- Progress bar shows: 0/10 confirmations
**7. Confirmation Progress** (T+2 to T+22 minutes)
- Monero blocks average 2 minutes each
- Customer refreshes page, sees progress:
- 2 confirmations (T+6 min): "2/10 confirmations"
- 5 confirmations (T+12 min): "5/10 confirmations"
- 8 confirmations (T+18 min): "8/10 confirmations"
**8. Payment Fully Confirmed** (T+22 minutes)
- 10th confirmation reached
- Status changes: "received" → "confirmed"
- Customer sees: "Payment confirmed! ✓"
- Invoice finalized:
- Digital download link appears
- Email sent: "Your purchase from Shop Name"
- Shop owner notified: "New sale: $10.00 (0.03333333 XMR)"
**9. Customer Downloads Product** (T+23 minutes)
- Customer clicks download link
- Gets their digital guide PDF
- Happy customer, transaction complete from their perspective
**Behind the Scenes - Shop Gets Paid**
**10. Automatic Sweep Triggers** (T+22 minutes, 5 seconds)
- Immediately after confirmation, auto-sweep initiates
- Balance check: Account 5 has 0.03333333 XMR
- Sweep calculation: 0.03333333 - 0.001 (keep for fees) = 0.03233333 XMR
- Transfer initiated to shop's cold wallet: 4A1s7n9...
**11. Sweep Complete** (T+24 minutes)
- Sweep transaction confirmed
- Hot wallet account 5 balance: 0.001 XMR (ready for next customer)
- Shop's cold wallet receives: 0.03233333 XMR
- At $300/XMR, shop owner has $9.70 (after fee reserve)
**Total Timeline**:
- Customer experience: ~23 minutes (browse to download)
- Full settlement: ~24 minutes (payment to cold storage)
**Financial Summary**:
- Product price: $10.00
- Customer paid: 0.03333333 XMR ($10.00)
- Network fee: ~0.00001 XMR ($0.003)
- Shop received: 0.03233333 XMR ($9.70)
- Fee reserve kept: 0.001 XMR ($0.30)
**Key Points**:
- Customer experience is smooth - they get their product in ~23 minutes
- Shop gets paid automatically with no manual intervention
- Hot wallet exposure: maximum 22 minutes, only 0.033 XMR
- Each shop's funds stay completely isolated
- System handles everything: quote, payment detection, fulfillment, sweep
**What Could Go Wrong**:
1. **Customer Underpays**: Sends 0.03 instead of 0.03333333 XMR
- Payment detected but never confirms
- Manual intervention needed or customer adds missing amount
2. **Quote Expires**: Customer takes 20 minutes to send
- Quote expired after 15 minutes
- Customer needs new quote at potentially different rate
3. **Network Congestion**: Monero network is busy
- Confirmations take 3-4 minutes per block instead of 2
- Customer waits longer but system handles it
4. **Wrong Copy/Paste**: Customer sends to wrong address
- Funds lost (no recovery possible)
- Importance of QR codes to avoid this
5. **Shop Misconfiguration**: Shop entered wrong cold wallet
- Sweep succeeds but funds go to wrong wallet
- Unrecoverable - emphasizes importance of testing
Wallet Configuration
--------------------
**Creating a Wallet**
For production use, create a dedicated wallet::
# Create new wallet
monero-wallet-cli --generate-new-wallet=/path/to/mps-wallet
# IMPORTANT: Save the 25-word mnemonic seed securely!
# This is your only way to recover funds if the wallet file is lost
**Running the Wallet RPC**
The wallet must be accessible via RPC. You have two options:
**Option 1: Production Setup (Run Your Own Node)**
This is the most secure and reliable setup::
# Terminal 1: Start your own Monero node (daemon)
# This downloads ~150GB blockchain and uses P2P to stay synced
monerod --data-dir=/path/to/blockchain \
--rpc-bind-ip=127.0.0.1 \
--rpc-bind-port=18081 \
--confirm-external-bind
# Terminal 2: Start wallet RPC (after daemon syncs)
monero-wallet-rpc \
--rpc-bind-ip=127.0.0.1 \
--rpc-bind-port=18083 \
--disable-rpc-login \
--wallet-file=/path/to/mps-wallet \
--daemon-address=127.0.0.1:18081 \
--trusted-daemon
**Option 2: Development Setup (Use Remote Node)**
Quicker to start but less private and relies on external service::
monero-wallet-rpc \
--rpc-bind-ip=127.0.0.1 \
--rpc-bind-port=18083 \
--disable-rpc-login \
--wallet-file=/path/to/mps-wallet \
--daemon-address=node.moneroworld.com:18089 \
--trusted-daemon
**Using the Makefile**
The included Makefile provides convenient targets::
# First time setup
make monero-wallet-create # Create a new wallet
# Production (your own node)
make monero-node # Terminal 1: Start blockchain node
make monero-wallet # Terminal 2: Start wallet RPC
# Development (remote node)
make monero-wallet-remote # Start wallet with public node
# View all options
make monero-full-stack # Shows complete setup instructions
Security notes:
- ``--disable-rpc-login`` is safe only when binding to localhost
- For remote access, use ``--rpc-login username:password``
- Running your own node ensures privacy and reliability
- The daemon automatically uses P2P to find peers and stay synchronized
**Account Structure**
Monero wallets contain multiple accounts, each with many subaddresses:
- **Account 0** (default): Main receiving account
- **Account 1+**: Can be used for organization (optional)
- **Subaddresses**: Unique addresses generated per payment
The ``MPS_MONERO_ACCOUNT_INDEX`` environment variable (default: 0) specifies which account to use.
Wallet Management
-----------------
**Checking Balance**
View wallet balance and incoming payments::
# Via CLI (stop RPC first)
monero-wallet-cli --wallet-file=/path/to/mps-wallet
[wallet]: balance
[wallet]: show_transfers
# Via RPC
curl -X POST http://127.0.0.1:18083/json_rpc -d '
{
"jsonrpc":"2.0",
"id":"0",
"method":"get_balance",
"params":{"account_index":0}
}'
**Sending Funds (Hot Wallet Management)**
The hot wallet runs as a service with mandatory auto-sweep:
1. **Automatic Post-Payment Sweep**:
Every confirmed payment triggers an immediate sweep to the shop's cold wallet.
Only 0.001 XMR remains for future transaction fees.
2. **Manual Sweep Commands** (for maintenance/recovery):
The crypto watcher includes automatic sweeping after each confirmed payment. For emergency situations or maintenance, administrators can use manual sweep tools that are integrated into the payment processing system and thoroughly tested.
**Cold Storage Best Practices**
1. **Minimize Hot Wallet Exposure**:
- Keep only enough XMR for daily operations
- Sweep excess funds to cold storage regularly
2. **Hardware Wallet Integration**:
- Use a hardware wallet (Ledger/Trezor) for cold storage
- Generate cold storage address offline
3. **Multi-signature Setup** (Advanced):
- Use 2-of-3 multisig for large amounts
- Requires multiple parties to authorize transfers
Security Considerations
-----------------------
**Hot Wallet Risks**
The wallet on the server is a "hot wallet" with inherent risks:
- Server compromise = potential fund loss
- No way to use external wallets (Cake Wallet, etc.) due to subaddress generation requirement
- Must trust the server environment
**Mitigation Strategies**
1. **Access Controls**:
- Restrict RPC to localhost only
- Use strong authentication if remote access needed
- Monitor access logs
2. **Operational Security**:
- Regular security updates
- Encrypted wallet file storage
- Secure backup procedures
- Audit trail for all transfers
3. **Monitoring**:
- Set up alerts for large incoming payments
- Monitor wallet balance changes
- Track unusual access patterns
Backup and Recovery
-------------------
**Backup Requirements**
1. **Mnemonic Seed** (Critical):
- 25-word recovery phrase
- Store offline in multiple secure locations
- Never store digitally on the server
2. **Wallet Files**:
- Regular backups of wallet file
- Include wallet.keys file
- Encrypt backups
**Recovery Procedures**
From mnemonic seed::
monero-wallet-cli --restore-deterministic-wallet
# Enter 25-word mnemonic
# Specify restore height to speed up sync
From wallet file backup::
# Copy wallet and wallet.keys files
cp backup/mps-wallet* /path/to/
# Start normally
Troubleshooting
---------------
**Common Issues**
1. **RPC Connection Failed**:
- Check monero-wallet-rpc is running
- Verify firewall allows localhost:18083
- Check RPC URL in configuration
2. **Payments Not Detected**:
- Ensure crypto_watcher is running
- Check wallet sync status
- Verify confirmations requirement
3. **Subaddress Generation Fails**:
- Check wallet is not locked
- Verify account index exists
- Ensure RPC has wallet access
**Debug Commands**
Check wallet sync status::
curl -X POST http://127.0.0.1:18083/json_rpc -d '
{"jsonrpc":"2.0","id":"0","method":"get_height"}'
List recent transfers::
curl -X POST http://127.0.0.1:18083/json_rpc -d '
{
"jsonrpc":"2.0","id":"0","method":"get_transfers",
"params":{"in":true,"out":true,"pending":true,"failed":true}
}'
References
----------
- Monero Documentation: https://www.getmonero.org/resources/
- Monero RPC Documentation: https://www.getmonero.org/resources/developer-guides/wallet-rpc.html
- Monero Security Best Practices: https://www.getmonero.org/resources/user-guides/securely_purchase.html