- Updated README.md to include new capabilities for Lightning invoice creation, smart payment scanning, universal payment support, and smart amount fields. - Enhanced wallet-module documentation to reflect comprehensive Lightning Network wallet functionality, including detailed descriptions of payment processing, QR code scanning, and invoice management features. - Added new sections for QR scanner component and payment flow architecture, improving clarity and usability for developers. These changes provide clearer guidance on the application's features and improve the overall documentation quality.
619 lines
No EOL
20 KiB
Markdown
619 lines
No EOL
20 KiB
Markdown
# 💰 Wallet Module
|
|
|
|
> **Lightning Network wallet management** with real-time balance updates, payment processing, and comprehensive transaction management integrated with LNbits.
|
|
|
|
## Table of Contents
|
|
|
|
- [[#Overview]]
|
|
- [[#Core Features]]
|
|
- [[#Architecture]]
|
|
- [[#Real-Time WebSocket Integration]]
|
|
- [[#Services]]
|
|
- [[#Components]]
|
|
- [[#Payment Processing]]
|
|
- [[#Configuration]]
|
|
- [[#Development Guide]]
|
|
|
|
## Overview
|
|
|
|
The Wallet Module provides comprehensive Lightning Network wallet functionality for the Ario application. It integrates with LNbits to handle payments, manage wallet balances, and provide real-time updates through WebSocket connections.
|
|
|
|
### **Key Capabilities**
|
|
- **Lightning invoice creation** (BOLT11) for receiving payments with QR codes
|
|
- **QR code scanning** for Lightning invoices, LNURL, and Lightning addresses
|
|
- **Smart payment processing** with automatic payment type detection
|
|
- **Universal payment support** for Lightning invoices, Lightning addresses, and LNURL
|
|
- **Real-time balance updates** via WebSocket connection to LNbits
|
|
- **Transaction management** with comprehensive history and status tracking
|
|
- **Multi-wallet support** with automatic wallet selection
|
|
- **Battery optimization** through VisibilityService integration
|
|
|
|
### **Dependencies**
|
|
- `['base']` - Requires base module for authentication and core services
|
|
- **LNbits Server** - External Lightning wallet backend
|
|
- **PaymentService** - Core payment processing service
|
|
|
|
## Core Features
|
|
|
|
### **🔄 Real-Time Balance Updates**
|
|
Automatic wallet balance synchronization without page refreshes:
|
|
|
|
- **WebSocket Connection** - Direct connection to LNbits WebSocket API
|
|
- **Instant Updates** - Balance changes reflect immediately in UI
|
|
- **Smart Unit Conversion** - Handles LNbits sats/millisats conversion differences
|
|
- **Payment Notifications** - Toast notifications for incoming payments
|
|
- **Connection Management** - Automatic reconnection with exponential backoff
|
|
|
|
### **💸 Payment Processing**
|
|
Comprehensive Lightning payment handling with smart detection:
|
|
|
|
- **Lightning Invoices** - Pay BOLT11 invoices directly with amount detection
|
|
- **Lightning Addresses** - Send to Lightning addresses (user@domain.com)
|
|
- **LNURL Pay** - Support for LNURL payment requests
|
|
- **QR Code Scanning** - Camera-based scanning for all payment types
|
|
- **Smart Amount Fields** - Amount input only appears when needed (LNURL, Lightning addresses, zero-amount invoices)
|
|
- **Lightning URI Support** - Handles "lightning:" prefixes and BIP-21 URIs
|
|
- **Payment Validation** - Pre-flight checks for sufficient balance
|
|
- **Error Handling** - User-friendly error messages and recovery
|
|
|
|
### **📊 Transaction Management**
|
|
Complete transaction history and tracking:
|
|
|
|
- **Transaction History** - Chronological list of all payments
|
|
- **Real-time Updates** - New transactions appear instantly
|
|
- **Transaction Details** - Amount, description, timestamp, fees, status
|
|
- **Transaction Types** - Sent, received, pending, confirmed, failed
|
|
- **Search and Filter** - Find specific transactions quickly
|
|
|
|
### **⚡ Lightning Invoice Creation**
|
|
Create BOLT11 invoices for receiving payments:
|
|
|
|
- **BOLT11 Invoice Generation** - Create Lightning invoices with specified amounts
|
|
- **QR Code Generation** - Automatic QR code creation for easy sharing
|
|
- **Expiry Management** - Configurable invoice expiration times
|
|
- **Description Support** - Add payment descriptions and memos
|
|
- **Real-time Status** - Live payment status updates (pending, paid, expired)
|
|
- **Mobile Optimization** - Responsive design for mobile devices
|
|
- **Copy Functionality** - Easy copying of invoice strings and payment hashes
|
|
|
|
## Architecture
|
|
|
|
### **Service Layer**
|
|
```
|
|
src/modules/wallet/services/
|
|
├── WalletService.ts # Core wallet operations
|
|
├── WalletWebSocketService.ts # Real-time balance updates
|
|
└── WalletAPI.ts # LNbits API integration
|
|
```
|
|
|
|
### **Component Layer**
|
|
```
|
|
src/modules/wallet/components/
|
|
├── SendDialog.vue # Payment sending interface with QR scanning
|
|
├── ReceiveDialog.vue # Lightning invoice creation interface
|
|
├── TransactionList.vue # Transaction history display
|
|
└── BalanceDisplay.vue # Wallet balance component
|
|
```
|
|
|
|
### **UI Components**
|
|
```
|
|
src/components/ui/
|
|
├── qr-scanner.vue # Camera-based QR code scanner
|
|
└── ... # Other Shadcn/UI components
|
|
```
|
|
|
|
### **Composables**
|
|
```
|
|
src/composables/
|
|
└── useQRScanner.ts # QR scanner functionality with camera access
|
|
```
|
|
|
|
### **Views Layer**
|
|
```
|
|
src/modules/wallet/views/
|
|
└── WalletPage.vue # Main wallet interface
|
|
```
|
|
|
|
## Real-Time WebSocket Integration
|
|
|
|
### **Connection Architecture**
|
|
The WebSocket service provides seamless real-time updates:
|
|
|
|
```typescript
|
|
// WebSocket URL format
|
|
wss://your-lnbits-server/api/v1/ws/{walletInkey}
|
|
|
|
// Connection lifecycle
|
|
┌─ Authentication Event ──→ Connect WebSocket
|
|
├─ Payment Received ─────→ Update Balance + Show Toast
|
|
├─ Payment Sent ─────────→ Update Balance
|
|
├─ Connection Lost ──────→ Automatic Reconnection
|
|
└─ App Hidden ───────────→ Pause (Battery Optimization)
|
|
```
|
|
|
|
### **Balance Update Logic**
|
|
Handles LNbits WebSocket behavior differences:
|
|
|
|
```typescript
|
|
// Incoming payments: LNbits sends post-payment balance
|
|
if (payment.amount > 0) {
|
|
// Use balance as-is (already includes received amount)
|
|
updateBalance(websocket_balance)
|
|
}
|
|
|
|
// Outgoing payments: LNbits sends pre-payment balance
|
|
if (payment.amount < 0) {
|
|
// Subtract payment amount from reported balance
|
|
final_balance = websocket_balance - payment_amount_sats
|
|
updateBalance(final_balance)
|
|
}
|
|
```
|
|
|
|
### **Connection Management**
|
|
- **Auto-reconnection** with exponential backoff (1s, 2s, 4s, 8s, 16s)
|
|
- **VisibilityService integration** for battery optimization
|
|
- **Connection health monitoring** with status indicators
|
|
- **Graceful disconnection** on logout
|
|
|
|
### **Error Handling**
|
|
- Connection failures with retry logic
|
|
- Invalid wallet credentials handling
|
|
- Network interruption recovery
|
|
- WebSocket protocol error handling
|
|
|
|
## Services
|
|
|
|
### **WalletService** 🏦
|
|
**Purpose:** Core wallet operations and transaction management
|
|
**Location:** `src/modules/wallet/services/WalletService.ts`
|
|
**Token:** `SERVICE_TOKENS.WALLET_SERVICE`
|
|
|
|
**Key Features:**
|
|
- Send Lightning payments (invoices, addresses, LNURL) with smart type detection
|
|
- Create Lightning invoices (BOLT11) for receiving payments
|
|
- Transaction history management with real-time updates
|
|
- QR code generation for payment sharing
|
|
|
|
**Reactive State:**
|
|
```typescript
|
|
interface WalletService {
|
|
transactions: ComputedRef<PaymentTransaction[]> // Transaction history
|
|
isCreatingInvoice: ComputedRef<boolean> // Invoice creation state
|
|
isSendingPayment: ComputedRef<boolean> // Payment sending state
|
|
error: ComputedRef<string | null> // Error state
|
|
}
|
|
```
|
|
|
|
**Key Methods:**
|
|
- `sendPayment(request: SendPaymentRequest)` - Send Lightning payment with type detection
|
|
- `createInvoice(params: CreateInvoiceRequest)` - Create BOLT11 Lightning invoice
|
|
- `refresh()` - Reload transactions and balance data
|
|
|
|
### **WalletWebSocketService** ⚡
|
|
**Purpose:** Real-time wallet balance updates via WebSocket
|
|
**Location:** `src/modules/wallet/services/WalletWebSocketService.ts`
|
|
**Token:** `SERVICE_TOKENS.WALLET_WEBSOCKET_SERVICE`
|
|
|
|
**Key Features:**
|
|
- WebSocket connection to LNbits
|
|
- Real-time balance updates
|
|
- Payment notification handling
|
|
- Connection health management
|
|
- Battery optimization via VisibilityService
|
|
|
|
**Reactive State:**
|
|
```typescript
|
|
interface WalletWebSocketService {
|
|
isConnected: Ref<boolean> // Connection status
|
|
connectionStatus: Ref<string> // Connection state
|
|
}
|
|
```
|
|
|
|
**Connection States:**
|
|
- `disconnected` - Not connected
|
|
- `connecting` - Connection in progress
|
|
- `connected` - Successfully connected
|
|
- `reconnecting` - Attempting to reconnect
|
|
- `error` - Connection failed
|
|
- `failed` - Max reconnection attempts reached
|
|
|
|
**Key Methods:**
|
|
- `reconnect()` - Manual reconnection trigger
|
|
- `disconnect()` - Graceful disconnection
|
|
- `cleanup()` - Service disposal
|
|
|
|
### **PaymentService Integration** 💳
|
|
The wallet module integrates with the core PaymentService:
|
|
|
|
**Shared Functionality:**
|
|
- Wallet balance management via `PaymentService.updateWalletBalance()`
|
|
- Preferred wallet selection with `PaymentService.getPreferredWallet()`
|
|
- Admin/invoice key access for API operations
|
|
- Multi-wallet support with consistent selection logic
|
|
|
|
## Components
|
|
|
|
### **SendDialog.vue** 📤
|
|
Payment sending interface with smart payment detection and QR scanning:
|
|
|
|
**Features:**
|
|
- QR code scanner for Lightning invoices, LNURL, and Lightning addresses
|
|
- Automatic payment type detection (BOLT11, LNURL, Lightning address)
|
|
- Smart amount field visibility (only shows when needed)
|
|
- Lightning URI prefix handling ("lightning:" prefixes, BIP-21 URIs)
|
|
- Payment request parsing and validation
|
|
- Amount validation against available balance
|
|
- Error handling with user-friendly messages
|
|
|
|
**Form Fields:**
|
|
- Destination (invoice, address, or LNURL) with QR scanner button
|
|
- Amount (conditionally visible based on payment type)
|
|
- Comment (for Lightning addresses and LNURL)
|
|
|
|
### **ReceiveDialog.vue** 📥
|
|
Lightning invoice creation interface for receiving payments:
|
|
|
|
**Features:**
|
|
- BOLT11 Lightning invoice generation
|
|
- QR code generation for easy sharing
|
|
- Real-time payment status tracking (pending, paid, expired)
|
|
- Mobile-responsive design with optimized layouts
|
|
- Copy functionality for invoice string and payment hash
|
|
- Payment success/failure indicators
|
|
- Configurable invoice expiry times
|
|
|
|
**Form Fields:**
|
|
- Amount (required, in satoshis)
|
|
- Description/Memo (optional payment description)
|
|
|
|
### **TransactionList.vue** 📋
|
|
Comprehensive transaction history display:
|
|
|
|
**Features:**
|
|
- Chronological transaction listing
|
|
- Real-time transaction updates
|
|
- Transaction status indicators
|
|
- Amount formatting with proper units
|
|
- Transaction type differentiation (sent/received)
|
|
- Fee information display
|
|
|
|
### **BalanceDisplay.vue** 💰
|
|
Wallet balance component with real-time updates:
|
|
|
|
**Features:**
|
|
- Real-time balance updates via WebSocket
|
|
- Multiple unit display (sats, millisats)
|
|
- Loading state indicators
|
|
- Connection status awareness
|
|
|
|
### **QRScanner Component** 📷
|
|
Camera-based QR code scanning for payments:
|
|
|
|
**Features:**
|
|
- WebRTC camera access with permission handling
|
|
- Real-time QR code detection using qr-scanner library
|
|
- Support for all Lightning payment types (BOLT11, LNURL, Lightning addresses)
|
|
- Lightning URI prefix cleaning ("lightning:" removal)
|
|
- Professional camera interface with scanning overlays
|
|
- Flash/torch support for low-light conditions
|
|
- Error handling for camera access issues
|
|
- Mobile-optimized scanning experience
|
|
|
|
**Technical Details:**
|
|
- Uses `qr-scanner` library for robust QR detection
|
|
- Handles camera permissions with user-friendly error messages
|
|
- Automatic cleanup on component unmount
|
|
- Configurable scan rate and highlighting options
|
|
|
|
## Payment Processing
|
|
|
|
### **Payment Flow Architecture**
|
|
```
|
|
User Action ──→ Type Detection ──→ Validation ──→ Payment ──→ Confirmation ──→ UI Update
|
|
│ │ │ │ │ │
|
|
│ │ │ │ │ └─ Real-time via WebSocket
|
|
│ │ │ │ └─ Transaction recorded
|
|
│ │ │ └─ LNbits API call
|
|
│ │ └─ Balance check, format validation
|
|
│ └─ BOLT11/LNURL/Lightning address detection
|
|
└─ Send/Receive dialog or QR scan
|
|
```
|
|
|
|
### **QR Code Scanning Flow**
|
|
```
|
|
Camera Access ──→ QR Detection ──→ URI Cleaning ──→ Type Detection ──→ Form Population
|
|
│ │ │ │ │
|
|
│ │ │ │ └─ Auto-fill destination field
|
|
│ │ │ └─ BOLT11/LNURL/Lightning address
|
|
│ │ └─ Remove "lightning:" prefixes
|
|
│ └─ Real-time scanning with qr-scanner
|
|
└─ Permission handling with user-friendly errors
|
|
```
|
|
|
|
### **Payment Types Supported**
|
|
|
|
#### **Lightning Invoices (BOLT11)**
|
|
```typescript
|
|
// Direct invoice payment
|
|
await walletService.sendPayment({
|
|
destination: "lnbc1000n1p3xh4v...",
|
|
amount: 1000 // Optional if invoice has amount
|
|
})
|
|
```
|
|
|
|
#### **Lightning Addresses**
|
|
```typescript
|
|
// Lightning address payment
|
|
await walletService.sendPayment({
|
|
destination: "user@stacker.news",
|
|
amount: 1000,
|
|
comment: "Great post!"
|
|
})
|
|
```
|
|
|
|
#### **LNURL Pay**
|
|
```typescript
|
|
// LNURL payment
|
|
await walletService.sendPayment({
|
|
destination: "LNURL1DP68GURN8GHJ7UM9WFMXJCM99E3K7MF0V9CXJ0M385EKVCENXC6R2C35XVUKXEFCV5MKVV34X5EKZD3EV56NYD3HXQURZEPEXEJXXEPNXSCRVWFNV9NXZCN9XQ6XYEFHVGCXXCMYXYMNSERXFQ5FNS",
|
|
amount: 1000
|
|
})
|
|
```
|
|
|
|
### **Lightning Invoice Creation**
|
|
Create BOLT11 invoices for receiving payments:
|
|
|
|
#### **Invoice Creation**
|
|
```typescript
|
|
// Create Lightning invoice
|
|
const invoice = await walletService.createInvoice({
|
|
amount: 1000, // Amount in satoshis
|
|
memo: "Payment for services", // Optional description
|
|
expiry: 3600 // Optional expiry in seconds (default: 1 hour)
|
|
})
|
|
|
|
// Returns invoice object with:
|
|
// - payment_request: BOLT11 invoice string
|
|
// - payment_hash: Payment hash for tracking
|
|
// - amount: Invoice amount in sats
|
|
// - memo: Invoice description
|
|
// - expiry: Expiration time
|
|
```
|
|
|
|
#### **QR Code Generation**
|
|
```typescript
|
|
// QR code is automatically generated for created invoices
|
|
// Available in the UI for easy sharing
|
|
const qrCodeDataUrl = await paymentService.generateQRCode(invoice.payment_request)
|
|
```
|
|
|
|
### **Error Handling**
|
|
Comprehensive error handling for payment failures:
|
|
|
|
- **Insufficient balance** - Clear messaging with current balance
|
|
- **Invalid payment request** - Format validation errors
|
|
- **Network failures** - Retry options and offline handling
|
|
- **Payment routing failures** - Lightning network routing errors
|
|
- **Timeout handling** - Payment timeout with status updates
|
|
|
|
## Configuration
|
|
|
|
### **Module Configuration**
|
|
Configure the wallet module in `src/app.config.ts`:
|
|
|
|
```typescript
|
|
modules: {
|
|
wallet: {
|
|
enabled: true,
|
|
config: {
|
|
// WebSocket configuration
|
|
websocket: {
|
|
enabled: true, // Enable real-time updates
|
|
reconnectDelay: 1000, // Initial reconnection delay (ms)
|
|
maxReconnectAttempts: 5 // Maximum reconnection attempts
|
|
},
|
|
|
|
// Payment configuration
|
|
payments: {
|
|
defaultUnit: 'sats', // Default amount unit
|
|
showFees: true, // Display fee information
|
|
confirmLarge: 10000 // Confirm payments above this amount
|
|
},
|
|
|
|
// UI configuration
|
|
ui: {
|
|
showBalance: true, // Display balance in UI
|
|
showTransactions: true, // Show transaction history
|
|
transactionLimit: 100 // Max transactions to display
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### **Environment Variables**
|
|
Required environment setup:
|
|
|
|
```bash
|
|
# LNbits server URL
|
|
VITE_LNBITS_BASE_URL=https://your-lnbits-server.com
|
|
|
|
# Optional: Default wallet configuration
|
|
VITE_DEFAULT_CURRENCY=sats
|
|
VITE_PAYMENT_TIMEOUT=30000
|
|
```
|
|
|
|
## Development Guide
|
|
|
|
### **Adding New Payment Types**
|
|
To add support for new payment methods:
|
|
|
|
1. **Extend SendPaymentRequest interface:**
|
|
```typescript
|
|
interface SendPaymentRequest {
|
|
destination: string
|
|
amount: number
|
|
comment?: string
|
|
newPaymentType?: NewPaymentParams // Add new type
|
|
}
|
|
```
|
|
|
|
2. **Update WalletService.sendPayment():**
|
|
```typescript
|
|
async sendPayment(request: SendPaymentRequest): Promise<boolean> {
|
|
// Add detection logic
|
|
if (this.isNewPaymentType(request.destination)) {
|
|
return this.handleNewPaymentType(request)
|
|
}
|
|
// ... existing logic
|
|
}
|
|
```
|
|
|
|
3. **Add validation and processing:**
|
|
```typescript
|
|
private isNewPaymentType(destination: string): boolean {
|
|
// Detection logic
|
|
}
|
|
|
|
private async handleNewPaymentType(request: SendPaymentRequest): Promise<boolean> {
|
|
// Processing logic
|
|
}
|
|
```
|
|
|
|
### **Extending Transaction Types**
|
|
To add new transaction types:
|
|
|
|
1. **Update PaymentTransaction interface:**
|
|
```typescript
|
|
interface PaymentTransaction {
|
|
// ... existing fields
|
|
type: 'sent' | 'received' | 'new_type'
|
|
metadata?: NewTypeMetadata
|
|
}
|
|
```
|
|
|
|
2. **Update transaction mapping:**
|
|
```typescript
|
|
private mapPaymentToTransaction(payment: any): PaymentTransaction {
|
|
// Add new type detection and mapping
|
|
}
|
|
```
|
|
|
|
### **Custom WebSocket Handlers**
|
|
To add custom WebSocket message handling:
|
|
|
|
```typescript
|
|
class WalletWebSocketService extends BaseService {
|
|
private handleMessage(event: MessageEvent): void {
|
|
const data = JSON.parse(event.data)
|
|
|
|
// Handle existing message types
|
|
if (data.payment) {
|
|
this.handlePaymentNotification(data.payment)
|
|
}
|
|
|
|
// Add custom message handling
|
|
if (data.custom_event) {
|
|
this.handleCustomEvent(data.custom_event)
|
|
}
|
|
}
|
|
|
|
private handleCustomEvent(event: CustomEvent): void {
|
|
// Custom event processing
|
|
}
|
|
}
|
|
```
|
|
|
|
### **Testing Wallet Functionality**
|
|
|
|
#### **Unit Tests**
|
|
```typescript
|
|
describe('WalletService', () => {
|
|
let service: WalletService
|
|
|
|
beforeEach(() => {
|
|
service = new WalletService()
|
|
})
|
|
|
|
it('should send Lightning payment', async () => {
|
|
const request = {
|
|
destination: 'lnbc1000n...',
|
|
amount: 1000
|
|
}
|
|
|
|
const result = await service.sendPayment(request)
|
|
expect(result).toBe(true)
|
|
})
|
|
|
|
it('should create Lightning invoice', async () => {
|
|
const invoiceData = {
|
|
amount: 1000,
|
|
memo: 'Test payment'
|
|
}
|
|
|
|
const invoice = await service.createInvoice(invoiceData)
|
|
expect(invoice.payment_request).toMatch(/^lnbc/)
|
|
expect(invoice.amount).toBe(1000)
|
|
})
|
|
})
|
|
```
|
|
|
|
#### **QR Scanner Tests**
|
|
```typescript
|
|
describe('QRScanner', () => {
|
|
it('should detect BOLT11 invoices', async () => {
|
|
const invoice = 'lnbc1000n1p3xh4v...'
|
|
const result = parsePaymentDestination(invoice)
|
|
|
|
expect(result.type).toBe('bolt11')
|
|
expect(result.amount).toBe(100)
|
|
})
|
|
|
|
it('should clean Lightning URIs', () => {
|
|
const uri = 'lightning:lnbc1000n1p3xh4v...'
|
|
const cleaned = normalizePaymentRequest(uri)
|
|
|
|
expect(cleaned).toBe('lnbc1000n1p3xh4v...')
|
|
})
|
|
})
|
|
```
|
|
|
|
#### **Integration Tests**
|
|
```typescript
|
|
describe('Wallet Integration', () => {
|
|
it('should update balance after payment', async () => {
|
|
const websocketService = new WalletWebSocketService()
|
|
const paymentService = new PaymentService()
|
|
|
|
// Mock payment notification
|
|
await websocketService.handlePaymentNotification({
|
|
amount: 1000,
|
|
wallet_balance: 5000
|
|
})
|
|
|
|
expect(paymentService.totalBalance).toBe(5000000) // millisats
|
|
})
|
|
})
|
|
```
|
|
|
|
## See Also
|
|
|
|
### Related Documentation
|
|
- **[[../base-module/index|🏗️ Base Module]]** - Authentication and core services
|
|
- **[[../../03-core-services/payment-service|💳 Payment Service]]** - Core payment processing
|
|
- **[[websocket-integration|⚡ WebSocket Integration]]** - Real-time update details
|
|
- **[[payment-processing|💸 Payment Processing]]** - Payment flow documentation
|
|
|
|
### API References
|
|
- **[[../../05-api-reference/lnbits-api|⚡ LNbits API]]** - Backend API integration
|
|
- **[[../../05-api-reference/lightning-payments|💰 Lightning Payments]]** - Payment protocol details
|
|
|
|
### Development Guides
|
|
- **[[../../04-development/testing|🧪 Testing Guide]]** - Testing strategies
|
|
- **[[../../04-development/debugging|🐛 Debugging]]** - Troubleshooting guide
|
|
|
|
---
|
|
|
|
**Tags:** #wallet #lightning #payments #websocket #real-time #module
|
|
**Last Updated:** 2025-09-18
|
|
**Author:** Development Team |