story-research-zapwall/lib/paymentPolling.ts
Nicolas Cantu 3000872dbc refactoring
- **Motivations :** Assurer passage du lint strict et clarifier la logique paiements/publications.

- **Root causes :** Fonctions trop longues, promesses non gérées et typages WebLN/Nostr incomplets.

- **Correctifs :** Refactor PaymentModal (handlers void), extraction helpers articlePublisher, simplification polling sponsoring/zap, corrections curly et awaits.

- **Evolutions :** Nouveau module articlePublisherHelpers pour présentation/aiguillage contenu privé.

- **Page affectées :** components/PaymentModal.tsx, lib/articlePublisher.ts, lib/articlePublisherHelpers.ts, lib/paymentPolling.ts, lib/sponsoring.ts, lib/nostrZapVerification.ts et dépendances liées.
2025-12-22 17:56:00 +01:00

91 lines
2.5 KiB
TypeScript

import { nostrService } from './nostr'
import { articlePublisher } from './articlePublisher'
import { getStoredPrivateContent } from './articleStorage'
/**
* Poll for payment completion via zap receipt verification
* After payment is confirmed, sends private content to the user
*/
async function pollPaymentUntilDeadline(
articleId: string,
articlePubkey: string,
amount: number,
recipientPubkey: string,
interval: number,
deadline: number
): Promise<boolean> {
try {
const zapReceiptExists = await nostrService.checkZapReceipt(articlePubkey, articleId, amount, recipientPubkey)
if (zapReceiptExists) {
await sendPrivateContentAfterPayment(articleId, recipientPubkey)
return true
}
} catch (error) {
console.error('Error checking zap receipt:', error)
}
if (Date.now() > deadline) {
return false
}
return new Promise<boolean>((resolve) => {
setTimeout(() => {
void pollPaymentUntilDeadline(articleId, articlePubkey, amount, recipientPubkey, interval, deadline)
.then(resolve)
.catch(() => resolve(false))
}, interval)
})
}
export async function waitForArticlePayment(
_paymentHash: string,
articleId: string,
articlePubkey: string,
amount: number,
recipientPubkey: string,
timeout: number = 300000 // 5 minutes
): Promise<boolean> {
const interval = 2000
const deadline = Date.now() + timeout
try {
return await pollPaymentUntilDeadline(articleId, articlePubkey, amount, recipientPubkey, interval, deadline)
} catch (error) {
console.error('Wait for payment error:', error)
return false
}
}
/**
* Send private content to user after payment confirmation
*/
async function sendPrivateContentAfterPayment(
articleId: string,
recipientPubkey: string
): Promise<void> {
// Send private content to the user
const storedContent = await getStoredPrivateContent(articleId)
if (storedContent) {
const authorPrivateKey = nostrService.getPrivateKey()
if (authorPrivateKey) {
const sent = await articlePublisher.sendPrivateContent(
articleId,
recipientPubkey,
storedContent.authorPubkey,
authorPrivateKey
)
if (sent) {
// Private content sent successfully
} else {
console.warn('Failed to send private content, but payment was confirmed')
}
} else {
console.warn('Author private key not available, cannot send private content automatically')
}
} else {
console.warn('Stored private content not found for article:', articleId)
}
}