import { nostrService } from './nostr' import { waitForArticlePayment as waitForArticlePaymentHelper } from './paymentPolling' import { resolveArticleInvoice } from './invoiceResolver' import type { Article } from '@/types/nostr' import type { AlbyInvoice } from '@/types/alby' export interface PaymentRequest { article: Article userPubkey: string } export interface PaymentResult { success: boolean invoice?: AlbyInvoice paymentHash?: string error?: string } /** * Payment service integrating Alby/WebLN Lightning payments with Nostr articles */ export class PaymentService { /** * Create a Lightning invoice for an article payment * First checks if author has created an invoice in the event tags, otherwise creates a new one */ async createArticlePayment(request: PaymentRequest): Promise { try { const invoice = await resolveArticleInvoice(request.article) // Create zap request event on Nostr await nostrService.createZapRequest( request.article.pubkey, request.article.id, request.article.zapAmount ) return { success: true, invoice, paymentHash: invoice.paymentHash, } } catch (error) { console.error('Payment creation error:', error) return { success: false, error: error instanceof Error ? error.message : 'Failed to create payment', } } } /** * Check if payment for an article has been completed */ async checkArticlePayment( paymentHash: string, articleId: string, articlePubkey: string, amount: number, userPubkey?: string ): Promise { try { // With Alby/WebLN, we rely on zap receipts for payment verification // since WebLN doesn't provide payment status checking const zapReceiptExists = await nostrService.checkZapReceipt( articlePubkey, articleId, amount, userPubkey ) return zapReceiptExists } catch (error) { console.error('Payment check error:', error) return false } } /** * Wait for payment completion with polling * After payment is confirmed, sends private content to the user */ waitForArticlePayment( paymentHash: string, articleId: string, articlePubkey: string, amount: number, recipientPubkey: string, timeout: number = 300000 // 5 minutes ): Promise { return waitForArticlePaymentHelper( paymentHash, articleId, articlePubkey, amount, recipientPubkey, timeout ) } /** * Get payment URL for display/QR code generation */ async getPaymentUrl(request: PaymentRequest): Promise { try { const result = await this.createArticlePayment(request) if (result.success && result.invoice) { // Return Lightning URI format return `lightning:${result.invoice.invoice}` } return null } catch (error) { console.error('Get payment URL error:', error) return null } } } export const paymentService = new PaymentService()