# BTCPay Server Lethean Plugin — Testing Guide ## What is this? A BTCPay Server plugin that lets merchants accept Lethean (LTHN) payments. When a customer pays an invoice, the plugin: 1. Generates a unique **integrated address** (embeds a payment ID so each invoice gets its own address) 2. Shows a checkout page with QR code, address, and "Pay in wallet" button 3. Polls the Lethean wallet every 15 seconds via `get_bulk_payments` RPC to detect incoming payments 4. Tracks confirmations and settles the invoice based on the merchant's threshold setting Built by forking the Monero BTCPay plugin and adapting it for Lethean's RPC API. ## QA Instance - **URL**: https://btcpay.lethean.me - **Server**: obscura (157.180.1.140) - **Daemon**: Lethean testnet remote node (37.27.100.59:10505) - **Wallet**: freshly generated testnet wallet inside Docker --- ## Manual Testing (QA Engineer) ### Prerequisites - A Lethean testnet wallet with some balance (get testnet LTHN from https://faucet.testnet.lethean.io) - A browser ### Test 1: Setup & Enable Lethean 1. Go to https://btcpay.lethean.me 2. Register a new admin account (first user becomes admin) 3. Create a store (any name) 4. In the left sidebar under **Wallets**, click **Lethean** 5. **Verify**: The settings page shows: - Node available: True - Wallet RPC available: True - Synced: True (with current block height) 6. Check **Enabled** 7. Set "Consider the invoice settled when the payment transaction..." to **Zero Confirmation** 8. Click **Save** **Expected**: Green success message, Lethean stays enabled on page reload. ### Test 2: Create Invoice with Lethean 1. Go to **Invoices** in the sidebar 2. Click **Create Invoice** 3. Set Amount: `1`, Currency: `LTHN` (USD won't work without a rate source configured) 4. Click **Create** 5. Click the invoice link to open the checkout page **Expected**: - Shows amount: `1.010000000000 LTHN` (1 LTHN + 0.01 network fee) - Shows an integrated address starting with `iTHN` - QR code is displayed - "Pay in wallet" button is present (opens `lethean:` URI) - "View Details" shows the full address and amount breakdown ### Test 3: Pay an Invoice 1. Create an invoice as above 2. Copy the integrated address from the checkout page 3. From your testnet wallet, send the exact amount shown to that address: ``` transfer 10 ``` For 1.01 LTHN: amount = 1010000000000 atomic units 4. Wait up to 30 seconds on the checkout page **Expected**: - Checkout page updates to show "Processing" or "Paid" - With Zero Confirmation setting, invoice should settle almost immediately - Invoice details page shows payment with tx hash, confirmations count ### Test 4: Confirmation Tracking 1. Set confirmation threshold to **At Least One** in Lethean settings 2. Create and pay a new invoice 3. Watch the invoice status **Expected**: - Invoice shows "Processing" immediately after payment detected - After 1 block confirmation (~1 minute on testnet), status changes to "Settled" - Confirmation count updates on each poll (every 15 seconds) ### Test 5: Multiple Invoices 1. Create 3 invoices with different amounts 2. Pay one of them 3. Check that only the paid invoice changes status **Expected**: Each invoice has a unique integrated address. Payment to one doesn't affect the others. ### Test 6: Underpayment 1. Create an invoice for 2 LTHN 2. Send only 1 LTHN to the integrated address **Expected**: Invoice remains in "New" or shows partial payment, doesn't settle. ### Test 7: Settings Persistence 1. Enable Lethean, set Custom confirmation threshold to 5 2. Save, navigate away, come back to Lethean settings **Expected**: Settings are preserved (Enabled, Custom, value 5). --- ## Automated E2E Testing (Playwright CLI) ### Prerequisites - Node.js with `npx tsx` available - Playwright installed (`npm install playwright` in `~/.claude/scripts/`) - BTCPay Server running locally or accessible URL - Lethean wallet RPC accessible ### Running the test ```bash # Against local instance npx tsx ~/.claude/scripts/btcpay-lethean-e2e.ts # Against QA instance (edit BASE_URL in the script first) BASE_URL=https://btcpay.lethean.me npx tsx ~/.claude/scripts/btcpay-lethean-e2e.ts ``` ### What the script tests | Step | Action | Verification | |------|--------|-------------| | 1 | Register admin account | Redirects to dashboard | | 2 | Create store "Test Store" | Store appears in nav | | 3 | Navigate to Lethean settings | Shows Node/Wallet status | | 4 | Enable Lethean + Zero Confirmation | Settings saved successfully | | 5 | Create 1 LTHN invoice | Invoice created, ID assigned | | 6 | Open checkout page | Integrated address (iTHN...) displayed, QR code rendered | | 7 | Attempt payment via wallet RPC | Transfer call made (may fail if wallet has no funds) | | 8 | Check invoice status | Status page accessible | ### Screenshots Saved to `/tmp/btcpay-lethean-e2e/`: - `01-landing.png` — Initial page - `06-lethean-settings.png` — Lethean settings with node status - `07-lethean-settings-configured.png` — Enabled + threshold set - `12-checkout-page.png` — Checkout with QR code and address - `14-invoice-details.png` — Invoice admin view ### Adapting the script Key variables at the top of `btcpay-lethean-e2e.ts`: ```typescript const BASE_URL = 'http://127.0.0.1:23002'; // BTCPay Server URL const WALLET_RPC = 'http://127.0.0.1:36944/json_rpc'; // Lethean wallet RPC const EMAIL = 'admin@test.com'; const PASSWORD = 'Test1234!Test1234!'; ``` --- ## What to look for (common issues) | Symptom | Likely cause | |---------|-------------| | Lethean not in sidebar | Plugin not loaded — check BTCPay logs for "Plugins.Lethean" | | "Node available: False" | Daemon RPC unreachable — check BTCPAY_LTHN_DAEMON_URI | | "Wallet RPC available: False" | simplewallet not running or wrong port | | "Synced: False" | Daemon still syncing — wait or use a synced remote node | | Invoice shows no Lethean option | Lethean not enabled for this store | | Payment not detected | Check wallet is connected to same daemon, check get_bulk_payments response | | Wrong amount displayed | Divisibility issue (should be 12 decimal places) | | Address doesn't start with iTHN | Integrated address generation failed — check make_integrated_address RPC | ## Architecture ``` Customer → BTCPay checkout page → shows integrated address + QR ↓ Payment sent to address ↓ BTCPay plugin (every 15s) → get_bulk_payments(payment_ids) → wallet RPC ↓ Payment matched by payment_id ↓ Invoice status: Processing → Settled ``` ## RPC calls used | Method | Target | Purpose | |--------|--------|---------| | `getinfo` | Daemon | Sync status, block height | | `get_wallet_info` | Wallet | Wallet height, address | | `make_integrated_address` | Wallet | Generate unique address per invoice | | `get_bulk_payments` | Wallet | Detect payments by payment_id | | `getbalance` | Wallet | Balance check |