import { ref, computed } from 'vue' import { useAuth } from '@/composables/useAuth' import { useMarketStore } from '../stores/market' import { payInvoiceWithWallet } from '@/lib/api/events' import { toast } from 'vue-sonner' export function useLightningPayment() { const { isAuthenticated, currentUser } = useAuth() const marketStore = useMarketStore() // State const isPayingWithWallet = ref(false) const paymentError = ref(null) // Computed properties const userWallets = computed(() => currentUser.value?.wallets || []) const hasWalletWithBalance = computed(() => userWallets.value.some((wallet: any) => wallet.balance_msat > 0) ) // Get wallet with sufficient balance const getWalletWithBalance = (requiredAmount?: number) => { const wallets = userWallets.value if (!wallets.length) return null if (requiredAmount) { return wallets.find((wallet: any) => wallet.balance_msat >= requiredAmount * 1000) // Convert sats to msat } return wallets.find((wallet: any) => wallet.balance_msat > 0) } // Pay Lightning invoice with user's wallet async function payInvoice(paymentRequest: string, orderId?: string): Promise { if (!isAuthenticated.value || !currentUser.value) { throw new Error('User must be authenticated to pay with wallet') } const wallet = getWalletWithBalance() if (!wallet) { throw new Error('No wallet with sufficient balance found') } try { isPayingWithWallet.value = true paymentError.value = null console.log('💰 Paying invoice with wallet:', wallet.id.slice(0, 8)) // Use the same API function as events const paymentResult = await payInvoiceWithWallet(paymentRequest, wallet.id, wallet.adminkey) console.log('✅ Payment successful:', { paymentHash: paymentResult.payment_hash, feeMsat: paymentResult.fee_msat, orderId }) // Update order status to paid if orderId is provided if (orderId) { const order = marketStore.orders[orderId] if (order) { const updatedOrder = { ...order, paymentStatus: 'paid' as const, status: 'paid' as const, paidAt: Math.floor(Date.now() / 1000), paymentHash: paymentResult.payment_hash, feeMsat: paymentResult.fee_msat, items: [...order.items], // Convert readonly to mutable shippingZone: order.shippingZone ? { ...order.shippingZone, countries: order.shippingZone.countries ? [...order.shippingZone.countries] : undefined } : order.shippingZone } marketStore.updateOrder(orderId, updatedOrder) } } toast.success('Payment successful!', { description: orderId ? `Order ${orderId.slice(-8)} has been paid` : 'Lightning invoice paid successfully' }) return true } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Payment failed' paymentError.value = errorMessage console.error('💸 Payment failed:', error) toast.error('Payment failed', { description: errorMessage }) throw error } finally { isPayingWithWallet.value = false } } // Open external Lightning wallet (fallback) function openExternalLightningWallet(paymentRequest: string) { if (!paymentRequest) { toast.error('No payment request available') return } // Try lightning: protocol first const lightningUrl = `lightning:${paymentRequest}` try { window.open(lightningUrl, '_blank') toast.info('Opening Lightning wallet...', { description: 'If no wallet opens, copy the payment request manually' }) } catch (error) { console.warn('Failed to open lightning: URL, showing payment request for copy:', error) // Fallback: copy to clipboard or show for manual copy navigator.clipboard?.writeText(paymentRequest).then(() => { toast.success('Payment request copied to clipboard') }).catch(() => { toast.info('Please copy the payment request manually') }) } } // Main payment handler - tries wallet first, falls back to external async function handlePayment(paymentRequest: string, orderId?: string): Promise { if (!paymentRequest) { toast.error('No payment request available') return } // Try wallet payment first if user has balance if (hasWalletWithBalance.value) { try { await payInvoice(paymentRequest, orderId) return // Payment successful with wallet } catch (error) { console.log('Wallet payment failed, offering external wallet option:', error) // Don't throw here, continue to external wallet option } } // Fallback to external wallet openExternalLightningWallet(paymentRequest) } return { // State isPayingWithWallet, paymentError, // Computed hasWalletWithBalance, userWallets, // Methods payInvoice, openExternalLightningWallet, handlePayment, getWalletWithBalance } }