import { getStoredPrivateContent } from './articleStorage' import { nostrService } from './nostr' import { articlePublisher } from './articlePublisher' import { validatePaymentData, verifyPaymentAmount } from './paymentPollingValidation' import { createTrackingData, triggerAutomaticTransfer, logPaymentResult } from './paymentPollingTracking' import { platformTracking } from './platformTracking' import { publishPurchaseNote } from './paymentNotes' /** * Send private content to user after payment confirmation * Returns true if content was successfully sent and verified */ export async function sendPrivateContentAfterPayment( articleId: string, recipientPubkey: string, amount: number, zapReceiptId?: string ): Promise { const storedContent = await getStoredPrivateContent(articleId) const authorPrivateKey = nostrService.getPrivateKey() const validation = validatePaymentData(storedContent, authorPrivateKey, articleId, recipientPubkey) if (!validation.valid || !validation.storedContent || !validation.authorPrivateKey) { return false } const result = await articlePublisher.sendPrivateContent(articleId, recipientPubkey, validation.authorPrivateKey) if (result.success && result.messageEventId) { verifyPaymentAmount(amount, articleId) const trackingData = createTrackingData({ articleId, authorPubkey: validation.storedContent.authorPubkey, recipientPubkey, messageEventId: result.messageEventId, amount, verified: result.verified ?? false, ...(zapReceiptId ? { zapReceiptId } : {}), }) await platformTracking.trackContentDelivery(trackingData, validation.authorPrivateKey) await triggerAutomaticTransfer(validation.storedContent.authorPubkey, articleId, amount) // Publish explicit payment note (kind 1) with project tags try { const article = await nostrService.getArticleById(articleId) if (!article) { return logPaymentResult(result, articleId, recipientPubkey, amount) } const payerPrivateKey = nostrService.getPrivateKey() if (!payerPrivateKey) { return logPaymentResult(result, articleId, recipientPubkey, amount) } const paymentHash = await resolvePaymentHashForPurchaseNote({ articlePaymentHash: article.paymentHash, articleId, ...(zapReceiptId ? { zapReceiptId } : {}), }) const category = normalizePurchaseNoteCategory(article.category) await publishPurchaseNote({ articleId: article.id, authorPubkey: article.pubkey, payerPubkey: recipientPubkey, amount, paymentHash, ...(zapReceiptId ? { zapReceiptId } : {}), ...(category ? { category } : {}), ...(article.seriesId ? { seriesId: article.seriesId } : {}), payerPrivateKey, }) } catch (error) { console.error('Error publishing purchase note:', error) // Don't fail the payment if note publication fails } return logPaymentResult(result, articleId, recipientPubkey, amount) } return logPaymentResult(result, articleId, recipientPubkey, amount) } function normalizePurchaseNoteCategory(category: string | undefined): 'science-fiction' | 'scientific-research' | undefined { if (category === 'science-fiction' || category === 'scientific-research') { return category } return undefined } async function resolvePaymentHashForPurchaseNote(params: { articlePaymentHash: string | undefined articleId: string zapReceiptId?: string }): Promise { let paymentHash = params.articlePaymentHash ?? params.articleId if (!params.zapReceiptId) { return paymentHash } const { getZapReceiptById } = await import('./zapReceiptQueries') const zapReceipt = await getZapReceiptById(params.zapReceiptId) const paymentHashTag = zapReceipt?.tags.find((tag) => tag[0] === 'payment_hash')?.[1] if (paymentHashTag) { paymentHash = paymentHashTag } return paymentHash }