Add Wallet Module documentation and WebSocket integration
- Introduced comprehensive documentation for the new Wallet Module, detailing its purpose, features, and key components. - Added WebSocket integration documentation, outlining real-time balance updates, connection management, and error handling. - Updated README and module index files to include references to the Wallet Module, enhancing overall module visibility and accessibility. These changes improve the clarity and usability of the Wallet Module, providing developers with essential information for implementation and integration.
This commit is contained in:
parent
832bf4d4ca
commit
71cec00bfc
6 changed files with 1748 additions and 1 deletions
|
|
@ -80,6 +80,43 @@ interface AuthService {
|
|||
|
||||
**See:** [[authentication|📖 Authentication Service Documentation]]
|
||||
|
||||
### **PaymentService** 💳
|
||||
**Purpose:** Centralized Lightning payment processing and wallet management
|
||||
**Location:** `src/core/services/PaymentService.ts`
|
||||
**Token:** `SERVICE_TOKENS.PAYMENT_SERVICE`
|
||||
|
||||
**Key Features:**
|
||||
- **Wallet Management** - Multi-wallet support with preferred wallet selection
|
||||
- **Payment Processing** - Lightning invoices, QR code generation, and external wallet handling
|
||||
- **Balance Management** - Real-time wallet balance updates and tracking
|
||||
- **Payment Validation** - Balance checking and payment amount validation
|
||||
- **Error Handling** - Consistent payment error handling and user feedback
|
||||
|
||||
**Reactive State:**
|
||||
```typescript
|
||||
interface PaymentService {
|
||||
isProcessingPayment: ComputedRef<boolean> // Payment in progress
|
||||
paymentError: ComputedRef<string | null> // Payment error state
|
||||
totalBalance: number // Total balance across wallets (getter)
|
||||
hasWalletWithBalance: boolean // Wallet availability check (getter)
|
||||
}
|
||||
```
|
||||
|
||||
**Key Methods:**
|
||||
- `payWithWallet(paymentRequest, amount?, options?)` - Process Lightning payment
|
||||
- `generateQRCode(paymentRequest, options?)` - Generate payment QR codes
|
||||
- `openExternalWallet(paymentRequest)` - Launch external Lightning wallet
|
||||
- `updateWalletBalance(balanceMsat, walletId?)` - Update wallet balance from WebSocket
|
||||
- `getPreferredWallet()` - Get the primary wallet for operations
|
||||
- `getWalletWithBalance(requiredAmount?)` - Find wallet with sufficient balance
|
||||
|
||||
**Wallet Selection Logic:**
|
||||
- Always uses first wallet (`wallets[0]`) for consistency across modules
|
||||
- Provides helper methods for wallet selection and balance checking
|
||||
- Integrates with AuthService for wallet credentials and management
|
||||
|
||||
**See:** [[payment-service|📖 Payment Service Documentation]]
|
||||
|
||||
### **RelayHub** 🌐
|
||||
**Purpose:** Centralized Nostr relay connection management
|
||||
**Location:** `src/modules/base/nostr/relay-hub.ts`
|
||||
|
|
@ -222,6 +259,74 @@ interface EventBusEvents {
|
|||
|
||||
**See:** [[../01-architecture/event-bus|📖 Event Bus Communication Documentation]]
|
||||
|
||||
### **WalletService** 🏦
|
||||
**Purpose:** Wallet operations and transaction management
|
||||
**Location:** `src/modules/wallet/services/WalletService.ts`
|
||||
**Token:** `SERVICE_TOKENS.WALLET_SERVICE`
|
||||
|
||||
**Key Features:**
|
||||
- **Payment Operations** - Send Lightning payments to invoices, addresses, and LNURL
|
||||
- **Payment Link Management** - Create and manage LNURL payment links and Lightning addresses
|
||||
- **Transaction History** - Load and manage comprehensive transaction history
|
||||
- **Real-time Updates** - Add new transactions from WebSocket notifications
|
||||
|
||||
**Reactive State:**
|
||||
```typescript
|
||||
interface WalletService {
|
||||
transactions: ComputedRef<PaymentTransaction[]> // Transaction history
|
||||
payLinks: ComputedRef<PayLink[]> // Created payment links
|
||||
isCreatingPayLink: ComputedRef<boolean> // Pay link creation state
|
||||
isSendingPayment: ComputedRef<boolean> // Payment sending state
|
||||
error: ComputedRef<string | null> // Error state
|
||||
}
|
||||
```
|
||||
|
||||
**Key Methods:**
|
||||
- `sendPayment(request: SendPaymentRequest)` - Send Lightning payment
|
||||
- `createReceiveAddress(params)` - Create LNURL payment link with Lightning address
|
||||
- `deletePayLink(linkId: string)` - Remove payment link
|
||||
- `addTransaction(payment)` - Add transaction from WebSocket notification
|
||||
- `refresh()` - Reload transactions and payment links
|
||||
|
||||
### **WalletWebSocketService** ⚡
|
||||
**Purpose:** Real-time wallet balance updates via WebSocket
|
||||
**Location:** `src/modules/wallet/services/WalletWebSocketService.ts`
|
||||
**Token:** `SERVICE_TOKENS.WALLET_WEBSOCKET_SERVICE`
|
||||
|
||||
**Key Features:**
|
||||
- **Real-time Connection** - WebSocket connection to LNbits for instant updates
|
||||
- **Balance Synchronization** - Smart balance updates with unit conversion handling
|
||||
- **Payment Notifications** - Toast notifications for incoming payments
|
||||
- **Connection Management** - Automatic reconnection with exponential backoff
|
||||
- **Battery Optimization** - VisibilityService integration for mobile efficiency
|
||||
|
||||
**Reactive State:**
|
||||
```typescript
|
||||
interface WalletWebSocketService {
|
||||
isConnected: Ref<boolean> // WebSocket connection status
|
||||
connectionStatus: Ref<string> // Connection state details
|
||||
}
|
||||
```
|
||||
|
||||
**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
|
||||
|
||||
**WebSocket Integration:**
|
||||
- Connects to `wss://lnbits-server/api/v1/ws/{walletInkey}`
|
||||
- Handles incoming/outgoing payment balance differences
|
||||
- Updates PaymentService with converted balance (sats → millisats)
|
||||
- Integrates with WalletService for transaction updates
|
||||
|
||||
## Service Lifecycle
|
||||
|
||||
### **Initialization Phase**
|
||||
|
|
@ -479,9 +584,11 @@ describe('Service Integration', () => {
|
|||
|
||||
### Service Documentation
|
||||
- **[[authentication|🔐 Authentication Service]]** - User identity and session management
|
||||
- **[[payment-service|💳 Payment Service]]** - Lightning payment processing and wallet management
|
||||
- **[[storage-service|💾 Storage Service]]** - User-scoped data persistence
|
||||
- **[[toast-service|📢 Toast Service]]** - User notifications and feedback
|
||||
- **[[visibility-service|👁️ Visibility Service]]** - Dynamic UI component control
|
||||
- **[[../02-modules/wallet-module/index|💰 Wallet Services]]** - WalletService and WebSocket integration
|
||||
|
||||
### Architecture References
|
||||
- **[[../01-architecture/dependency-injection|⚙️ Dependency Injection]]** - DI container system
|
||||
|
|
|
|||
507
docs/03-core-services/payment-service.md
Normal file
507
docs/03-core-services/payment-service.md
Normal file
|
|
@ -0,0 +1,507 @@
|
|||
# 💳 Payment Service
|
||||
|
||||
> **Centralized Lightning payment processing** with wallet management, QR code generation, and real-time balance tracking integrated with LNbits.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [[#Overview]]
|
||||
- [[#Architecture]]
|
||||
- [[#Payment Processing]]
|
||||
- [[#Wallet Management]]
|
||||
- [[#Balance Management]]
|
||||
- [[#QR Code Generation]]
|
||||
- [[#Error Handling]]
|
||||
- [[#Integration with WebSocket]]
|
||||
- [[#API Reference]]
|
||||
|
||||
## Overview
|
||||
|
||||
The PaymentService is a core infrastructure service that centralizes all Lightning Network payment operations in the Ario application. It provides a clean abstraction layer over LNbits operations and manages wallet state across all modules.
|
||||
|
||||
### **Key Responsibilities**
|
||||
- **Payment Processing** - Handle Lightning invoices, external wallets, and payment validation
|
||||
- **Wallet Management** - Multi-wallet support with consistent wallet selection
|
||||
- **Balance Tracking** - Real-time balance updates from WebSocket integration
|
||||
- **QR Code Generation** - Payment request and custom data QR codes
|
||||
- **Error Handling** - Consistent payment error handling and user feedback
|
||||
|
||||
### **Service Integration**
|
||||
```
|
||||
┌─ UI Components ─┐ ┌─ PaymentService ─┐ ┌─ External Services ─┐
|
||||
│ │ │ │ │ │
|
||||
│ • Send Dialog │───▶│ • Payment Logic │───▶│ • LNbits API │
|
||||
│ • Balance Display│ │ • Wallet Mgmt │ │ • External Wallets │
|
||||
│ • QR Generator │ │ • Balance State │ │ • QR Library │
|
||||
│ │ │ • Error Handling │ │ │
|
||||
└─────────────────┘ └──────────────────┘ └─────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─ AuthService ─────┐
|
||||
│ │
|
||||
│ • User Wallets │
|
||||
│ • Authentication │
|
||||
│ • Wallet Keys │
|
||||
└───────────────────┘
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
### **Service Structure**
|
||||
```typescript
|
||||
export class PaymentService extends BaseService {
|
||||
// Service metadata
|
||||
protected readonly metadata = {
|
||||
name: 'PaymentService',
|
||||
version: '1.0.0',
|
||||
dependencies: ['AuthService']
|
||||
}
|
||||
|
||||
// Reactive state
|
||||
private _isProcessingPayment = ref(false)
|
||||
private _paymentError = ref<string | null>(null)
|
||||
|
||||
// Public computed state
|
||||
public readonly isProcessingPayment = computed(() => this._isProcessingPayment.value)
|
||||
public readonly paymentError = computed(() => this._paymentError.value)
|
||||
}
|
||||
```
|
||||
|
||||
### **Dependencies**
|
||||
- **AuthService** - User authentication and wallet access
|
||||
- **BaseService** - Service lifecycle and error handling
|
||||
- **Vue Reactivity** - Reactive state management
|
||||
|
||||
### **External Integrations**
|
||||
- **LNbits API** - Lightning wallet backend
|
||||
- **QRCode Library** - QR code generation
|
||||
- **External Wallets** - Lightning wallet applications
|
||||
- **Browser APIs** - Clipboard, window.open for external wallets
|
||||
|
||||
## Payment Processing
|
||||
|
||||
### **Payment Types Supported**
|
||||
|
||||
#### **Lightning Invoices (BOLT11)**
|
||||
Process Lightning payment requests directly:
|
||||
```typescript
|
||||
await paymentService.payWithWallet(
|
||||
'lnbc1000n1p3xh4v...', // Lightning invoice
|
||||
undefined, // Amount already in invoice
|
||||
{
|
||||
successMessage: 'Payment sent successfully!',
|
||||
showToast: true
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
#### **External Wallet Fallback**
|
||||
Automatically fall back to external wallets when user wallet lacks balance:
|
||||
```typescript
|
||||
// Automatic payment handling with fallback
|
||||
const result = await paymentService.handlePayment(
|
||||
paymentRequest,
|
||||
requiredAmount,
|
||||
{ successMessage: 'Payment completed!' }
|
||||
)
|
||||
|
||||
// Returns PaymentResult for wallet payments, null for external wallet
|
||||
if (result) {
|
||||
console.log('Paid with user wallet:', result.payment_hash)
|
||||
} else {
|
||||
console.log('Opened external wallet')
|
||||
}
|
||||
```
|
||||
|
||||
### **Payment Flow**
|
||||
```
|
||||
1. Payment Request Validation
|
||||
├── Check payment request format
|
||||
├── Extract amount if present
|
||||
└── Validate against available balance
|
||||
|
||||
2. Wallet Selection
|
||||
├── Get preferred wallet
|
||||
├── Check sufficient balance
|
||||
└── Retrieve wallet credentials
|
||||
|
||||
3. Payment Execution
|
||||
├── Call LNbits payment API
|
||||
├── Handle response/errors
|
||||
└── Update UI state
|
||||
|
||||
4. Completion Handling
|
||||
├── Show success/error notifications
|
||||
├── Reset payment state
|
||||
└── Emit completion events
|
||||
```
|
||||
|
||||
### **Payment Options**
|
||||
```typescript
|
||||
interface PaymentOptions {
|
||||
successMessage?: string // Custom success message
|
||||
errorMessage?: string // Custom error message
|
||||
showToast?: boolean // Show toast notifications (default: true)
|
||||
}
|
||||
```
|
||||
|
||||
## Wallet Management
|
||||
|
||||
### **Multi-Wallet Support**
|
||||
PaymentService provides consistent wallet selection across all modules:
|
||||
|
||||
```typescript
|
||||
// Preferred wallet selection (always first wallet)
|
||||
const wallet = paymentService.getPreferredWallet()
|
||||
// Returns: wallets[0] or null if no wallets
|
||||
|
||||
// Wallet with sufficient balance
|
||||
const wallet = paymentService.getWalletWithBalance(1000) // 1000 sats
|
||||
// Returns: first wallet with >= 1000 sats or null
|
||||
|
||||
// Wallet credentials access
|
||||
const adminKey = paymentService.getPreferredWalletAdminKey()
|
||||
const invoiceKey = paymentService.getPreferredWalletInvoiceKey()
|
||||
```
|
||||
|
||||
### **Wallet Selection Logic**
|
||||
The service follows a consistent wallet selection strategy:
|
||||
|
||||
1. **Preferred Wallet**: Always use `wallets[0]` for consistency
|
||||
2. **Balance Checking**: Check if preferred wallet has sufficient balance
|
||||
3. **Fallback Strategy**: No automatic fallback - use external wallet instead
|
||||
4. **Credential Access**: Provide admin/invoice keys for API operations
|
||||
|
||||
### **Balance Access**
|
||||
```typescript
|
||||
// Total balance across all wallets (in millisats)
|
||||
const totalBalance = paymentService.totalBalance
|
||||
|
||||
// Check if any wallet has balance
|
||||
const hasBalance = paymentService.hasWalletWithBalance
|
||||
|
||||
// Balance formatted for display
|
||||
const balanceSats = Math.round(totalBalance / 1000)
|
||||
```
|
||||
|
||||
## Balance Management
|
||||
|
||||
### **Real-Time Balance Updates**
|
||||
PaymentService receives balance updates from WalletWebSocketService:
|
||||
|
||||
```typescript
|
||||
// Called by WebSocket service when balance changes
|
||||
paymentService.updateWalletBalance(balanceMsat, walletId)
|
||||
```
|
||||
|
||||
### **Balance Update Logic**
|
||||
```typescript
|
||||
updateWalletBalance(balanceMsat: number, walletId?: string): void {
|
||||
// Determine target wallet
|
||||
let walletToUpdate
|
||||
if (walletId) {
|
||||
walletToUpdate = this.authService.user.value.wallets.find(w => w.id === walletId)
|
||||
} else {
|
||||
walletToUpdate = this.getPreferredWallet() // Default to first wallet
|
||||
}
|
||||
|
||||
if (walletToUpdate) {
|
||||
const oldBalance = walletToUpdate.balance_msat
|
||||
walletToUpdate.balance_msat = balanceMsat
|
||||
|
||||
// Trigger Vue reactivity
|
||||
this.authService.user.value = { ...this.authService.user.value }
|
||||
|
||||
console.log(`Wallet ${walletToUpdate.id} balance: ${oldBalance} → ${balanceMsat} msat`)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### **Balance State Management**
|
||||
- **Storage**: Balances stored in AuthService user object
|
||||
- **Reactivity**: Vue reactivity ensures UI updates automatically
|
||||
- **Consistency**: Single source of truth for wallet balances
|
||||
- **Persistence**: Balances persist across app sessions via AuthService
|
||||
|
||||
## QR Code Generation
|
||||
|
||||
### **Payment Request QR Codes**
|
||||
Generate QR codes for Lightning payment requests:
|
||||
```typescript
|
||||
// Standard payment QR code
|
||||
const qrDataUrl = await paymentService.generateQRCode(
|
||||
'lnbc1000n1p3xh4v...', // Payment request
|
||||
{
|
||||
width: 256, // QR code size
|
||||
margin: 2, // Border margin
|
||||
darkColor: '#000000', // QR code color
|
||||
lightColor: '#FFFFFF' // Background color
|
||||
}
|
||||
)
|
||||
|
||||
// Use in components
|
||||
<img :src="qrDataUrl" alt="Payment QR Code" />
|
||||
```
|
||||
|
||||
### **Custom Data QR Codes**
|
||||
Generate QR codes for tickets, links, or other data:
|
||||
```typescript
|
||||
// Ticket QR code
|
||||
const ticketQR = await paymentService.generateCustomQRCode(
|
||||
JSON.stringify({
|
||||
eventId: 'event123',
|
||||
ticketId: 'ticket456',
|
||||
timestamp: Date.now()
|
||||
}),
|
||||
{ width: 128 } // Smaller size for tickets
|
||||
)
|
||||
```
|
||||
|
||||
### **QR Code Options**
|
||||
```typescript
|
||||
interface QRCodeOptions {
|
||||
width?: number // QR code width in pixels (default: 256)
|
||||
margin?: number // Border margin (default: 2)
|
||||
darkColor?: string // QR code color (default: #000000)
|
||||
lightColor?: string // Background color (default: #FFFFFF)
|
||||
}
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
### **Payment Error Types**
|
||||
```typescript
|
||||
// Common payment errors
|
||||
enum PaymentErrorType {
|
||||
INSUFFICIENT_BALANCE = 'Insufficient wallet balance',
|
||||
INVALID_INVOICE = 'Invalid payment request',
|
||||
NETWORK_ERROR = 'Network connection failed',
|
||||
TIMEOUT = 'Payment timeout',
|
||||
ROUTING_FAILED = 'Lightning routing failed',
|
||||
WALLET_LOCKED = 'Wallet is locked',
|
||||
UNKNOWN = 'Unknown payment error'
|
||||
}
|
||||
```
|
||||
|
||||
### **Error Handling Pattern**
|
||||
```typescript
|
||||
async payWithWallet(paymentRequest: string): Promise<PaymentResult> {
|
||||
try {
|
||||
this._isProcessingPayment.value = true
|
||||
this._paymentError.value = null
|
||||
|
||||
// Payment processing logic
|
||||
const result = await this.processPayment(paymentRequest)
|
||||
|
||||
// Success notification
|
||||
toast.success('Payment successful!')
|
||||
return result
|
||||
|
||||
} catch (error) {
|
||||
// Error handling
|
||||
const errorMessage = this.parsePaymentError(error)
|
||||
this._paymentError.value = errorMessage
|
||||
|
||||
// User notification
|
||||
toast.error('Payment failed', {
|
||||
description: errorMessage
|
||||
})
|
||||
|
||||
throw error
|
||||
} finally {
|
||||
this._isProcessingPayment.value = false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### **Error Recovery**
|
||||
```typescript
|
||||
// Clear error state
|
||||
paymentService.clearPaymentError()
|
||||
|
||||
// Force reset payment state (for debugging)
|
||||
paymentService.forceResetPaymentState()
|
||||
|
||||
// Retry payment after error
|
||||
await paymentService.payWithWallet(paymentRequest, amount, {
|
||||
errorMessage: 'Retry failed - please try again'
|
||||
})
|
||||
```
|
||||
|
||||
## Integration with WebSocket
|
||||
|
||||
### **WebSocket Collaboration**
|
||||
PaymentService works closely with WalletWebSocketService:
|
||||
|
||||
```
|
||||
┌─ WalletWebSocketService ─┐ ┌─ PaymentService ─┐
|
||||
│ │ │ │
|
||||
│ 1. Receive WS Message │ │ │
|
||||
│ 2. Parse Balance Update │───▶│ 4. Update Balance│
|
||||
│ 3. Convert Sats→MSats │ │ 5. Trigger UI │
|
||||
│ │ │ │
|
||||
└──────────────────────────┘ └──────────────────┘
|
||||
```
|
||||
|
||||
### **Balance Update Flow**
|
||||
1. **WebSocket Message**: WalletWebSocketService receives balance update
|
||||
2. **Unit Conversion**: Convert sats to millisats for internal consistency
|
||||
3. **Balance Update**: Call `PaymentService.updateWalletBalance()`
|
||||
4. **State Update**: PaymentService updates wallet balance in AuthService
|
||||
5. **UI Reactivity**: Vue reactivity updates all UI components
|
||||
|
||||
### **Payment Notifications**
|
||||
```typescript
|
||||
// WebSocket triggers payment notification
|
||||
eventBus.on('payment:received', (data) => {
|
||||
// PaymentService can listen and handle accordingly
|
||||
paymentService.handlePaymentNotification(data)
|
||||
})
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### **Public Methods**
|
||||
|
||||
#### **Payment Operations**
|
||||
```typescript
|
||||
// Process Lightning payment with user wallet
|
||||
payWithWallet(
|
||||
paymentRequest: string,
|
||||
requiredAmountSats?: number,
|
||||
options?: PaymentOptions
|
||||
): Promise<PaymentResult>
|
||||
|
||||
// Handle payment with automatic fallback
|
||||
handlePayment(
|
||||
paymentRequest: string,
|
||||
requiredAmountSats?: number,
|
||||
options?: PaymentOptions
|
||||
): Promise<PaymentResult | null>
|
||||
|
||||
// Open external Lightning wallet
|
||||
openExternalWallet(paymentRequest: string): void
|
||||
```
|
||||
|
||||
#### **Wallet Management**
|
||||
```typescript
|
||||
// Get preferred wallet (first wallet)
|
||||
getPreferredWallet(): Wallet | null
|
||||
|
||||
// Get wallet with sufficient balance
|
||||
getWalletWithBalance(requiredAmountSats?: number): Wallet | null
|
||||
|
||||
// Get wallet credentials
|
||||
getPreferredWalletAdminKey(): string | null
|
||||
getPreferredWalletInvoiceKey(): string | null
|
||||
|
||||
// Update wallet balance (called by WebSocket)
|
||||
updateWalletBalance(balanceMsat: number, walletId?: string): void
|
||||
```
|
||||
|
||||
#### **QR Code Generation**
|
||||
```typescript
|
||||
// Generate payment QR code
|
||||
generateQRCode(
|
||||
paymentRequest: string,
|
||||
options?: QRCodeOptions
|
||||
): Promise<string>
|
||||
|
||||
// Generate custom data QR code
|
||||
generateCustomQRCode(
|
||||
data: string,
|
||||
options?: QRCodeOptions
|
||||
): Promise<string>
|
||||
```
|
||||
|
||||
#### **State Management**
|
||||
```typescript
|
||||
// Clear payment error
|
||||
clearPaymentError(): void
|
||||
|
||||
// Reset payment state
|
||||
resetPaymentState(): void
|
||||
|
||||
// Force reset (for debugging)
|
||||
forceResetPaymentState(): void
|
||||
```
|
||||
|
||||
### **Reactive State**
|
||||
```typescript
|
||||
// Access reactive state
|
||||
const paymentService = injectService(SERVICE_TOKENS.PAYMENT_SERVICE)
|
||||
|
||||
// Payment processing state
|
||||
const isProcessing = paymentService.isProcessingPayment
|
||||
const error = paymentService.paymentError
|
||||
|
||||
// Wallet information
|
||||
const totalBalance = paymentService.totalBalance
|
||||
const hasBalance = paymentService.hasWalletWithBalance
|
||||
```
|
||||
|
||||
### **Integration Example**
|
||||
```vue
|
||||
<script setup>
|
||||
import { injectService, SERVICE_TOKENS } from '@/core/di-container'
|
||||
|
||||
const paymentService = injectService(SERVICE_TOKENS.PAYMENT_SERVICE)
|
||||
|
||||
// Reactive state
|
||||
const { isProcessingPayment, paymentError, totalBalance } = paymentService
|
||||
|
||||
// Payment method
|
||||
const sendPayment = async (invoice: string) => {
|
||||
try {
|
||||
const result = await paymentService.payWithWallet(invoice, undefined, {
|
||||
successMessage: 'Payment sent successfully!'
|
||||
})
|
||||
console.log('Payment completed:', result.payment_hash)
|
||||
} catch (error) {
|
||||
console.error('Payment failed:', error.message)
|
||||
}
|
||||
}
|
||||
|
||||
// Formatted balance for display
|
||||
const balanceDisplay = computed(() => {
|
||||
return `${Math.round(totalBalance / 1000)} sats`
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="payment-interface">
|
||||
<div class="balance">Balance: {{ balanceDisplay }}</div>
|
||||
|
||||
<button
|
||||
@click="sendPayment(invoice)"
|
||||
:disabled="isProcessingPayment || !hasBalance"
|
||||
>
|
||||
{{ isProcessingPayment ? 'Processing...' : 'Send Payment' }}
|
||||
</button>
|
||||
|
||||
<div v-if="paymentError" class="error">
|
||||
{{ paymentError }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
## See Also
|
||||
|
||||
### Related Documentation
|
||||
- **[[../02-modules/wallet-module/index|💰 Wallet Module]]** - Wallet UI and WebSocket integration
|
||||
- **[[../02-modules/wallet-module/websocket-integration|⚡ WebSocket Integration]]** - Real-time balance updates
|
||||
- **[[authentication|🔐 Authentication Service]]** - User wallets and credentials
|
||||
|
||||
### API References
|
||||
- **[[../05-api-reference/lnbits-api|⚡ LNbits API]]** - Backend Lightning wallet API
|
||||
- **[[../05-api-reference/lightning-payments|💰 Lightning Payments]]** - Payment protocol details
|
||||
|
||||
### Development Guides
|
||||
- **[[../04-development/testing|🧪 Testing Guide]]** - Testing payment functionality
|
||||
- **[[../04-development/debugging|🐛 Debugging]]** - Payment troubleshooting
|
||||
|
||||
---
|
||||
|
||||
**Tags:** #payment #lightning #service #wallet #qr-code #lnbits
|
||||
**Last Updated:** 2025-09-18
|
||||
**Author:** Development Team
|
||||
Loading…
Add table
Add a link
Reference in a new issue