import type { Event } from 'nostr-tools' import { SimplePool } from 'nostr-tools' import { createSubscription } from '@/types/nostr-tools-extended' import { getPrimaryRelaySync } from './config' function createZapFilters(targetPubkey: string, targetEventId: string, userPubkey: string) { return [ { kinds: [9735], // Zap receipt '#p': [targetPubkey], '#e': [targetEventId], authors: [userPubkey], // Filter by the payer's pubkey }, ] } async function isValidZapReceipt( event: Event, targetEventId: string, targetPubkey: string, userPubkey: string, amount: number ): Promise { // Import verification service dynamically to avoid circular dependencies const { zapVerificationService } = await import('./zapVerification') return zapVerificationService.verifyZapReceiptForArticle(event, targetEventId, targetPubkey, userPubkey, amount) } /** * Check if user has paid for an article by looking for zap receipts */ function handleZapReceiptEvent( event: Event, targetEventId: string, targetPubkey: string, userPubkey: string, amount: number, finalize: (value: boolean) => void, resolved: { current: boolean } ): void { if (resolved.current) { return } void isValidZapReceipt(event, targetEventId, targetPubkey, userPubkey, amount).then((isValid) => { if (isValid) { finalize(true) } }) } export function checkZapReceipt( pool: SimplePool, targetPubkey: string, targetEventId: string, amount: number, userPubkey: string ): Promise { if (!pool) { return Promise.resolve(false) } return new Promise((resolve) => { let resolved = false const relayUrl = getPrimaryRelaySync() const sub = createSubscription(pool, [relayUrl], createZapFilters(targetPubkey, targetEventId, userPubkey)) const finalize = (value: boolean) => { if (resolved) { return } resolved = true sub.unsub() resolve(value) } const resolvedRef = { current: resolved } sub.on('event', (event: Event) => { handleZapReceiptEvent(event, targetEventId, targetPubkey, userPubkey, amount, finalize, resolvedRef) }) const end = () => finalize(false) sub.on('eose', end) setTimeout(end, 3000) }) }