story-research-zapwall/lib/nostrZapVerification.ts
2025-12-22 09:48:57 +01:00

72 lines
1.6 KiB
TypeScript

import type { Event } from 'nostr-tools'
import { SimplePool } from 'nostr-tools'
const RELAY_URL = process.env.NEXT_PUBLIC_NOSTR_RELAY_URL || 'wss://relay.damus.io'
/**
* Check if user has paid for an article by looking for zap receipts
*/
export async function checkZapReceipt(
pool: SimplePool,
targetPubkey: string,
targetEventId: string,
amount: number,
userPubkey: string
): Promise<boolean> {
if (!pool) {
return false
}
return new Promise((resolve) => {
const filters = [
{
kinds: [9735], // Zap receipt
'#p': [targetPubkey],
'#e': [targetEventId],
authors: [userPubkey], // Filter by the payer's pubkey
},
]
let resolved = false
const sub = pool.sub([RELAY_URL], filters)
sub.on('event', async (event: Event) => {
if (resolved) return
// Import verification service dynamically to avoid circular dependencies
const { zapVerificationService } = await import('./zapVerification')
// Verify the zap receipt signature and details
const isValid = zapVerificationService.verifyZapReceiptForArticle(
event,
targetEventId,
targetPubkey,
userPubkey,
amount
)
if (isValid) {
resolved = true
sub.unsub()
resolve(true)
}
})
sub.on('eose', () => {
if (!resolved) {
resolved = true
sub.unsub()
resolve(false)
}
})
setTimeout(() => {
if (!resolved) {
resolved = true
sub.unsub()
resolve(false)
}
}, 3000)
})
}