import { nostrService } from './nostr' import type { SimplePoolWithSub } from '@/types/nostr-tools-extended' const RELAY_URL = process.env.NEXT_PUBLIC_NOSTR_RELAY_URL ?? 'wss://relay.damus.io' export interface ContentDeliveryStatus { messageEventId: string | null published: boolean verifiedOnRelay: boolean retrievable: boolean error?: string } /** * Verify that private content was successfully delivered to recipient * Checks multiple aspects to ensure delivery certainty */ export async function verifyContentDelivery( articleId: string, authorPubkey: string, recipientPubkey: string, messageEventId: string ): Promise { const status: ContentDeliveryStatus = { messageEventId, published: false, verifiedOnRelay: false, retrievable: false, } try { const pool = nostrService.getPool() if (!pool) { status.error = 'Pool not initialized' return status } const poolWithSub = pool as SimplePoolWithSub const filters: Array<{ kinds: number[] ids?: string[] authors: string[] '#p': string[] '#e': string[] limit: number }> = [ { kinds: [4], authors: [authorPubkey], '#p': [recipientPubkey], '#e': [articleId], limit: 1, }, ] if (messageEventId && filters[0]) { filters[0].ids = [messageEventId] } return new Promise((resolve) => { let resolved = false const sub = poolWithSub.sub([RELAY_URL], filters) const finalize = (result: ContentDeliveryStatus) => { if (resolved) { return } resolved = true sub.unsub() resolve(result) } sub.on('event', (event) => { status.published = true status.verifiedOnRelay = true status.messageEventId = event.id status.retrievable = true finalize(status) }) sub.on('eose', () => { if (!status.published) { status.error = 'Message not found on relay' } finalize(status) }) setTimeout(() => { if (!resolved) { if (!status.published) { status.error = 'Timeout waiting for message verification' } finalize(status) } }, 5000) }) } catch (error) { status.error = error instanceof Error ? error.message : 'Unknown error' return status } } /** * Check if recipient can retrieve the private message * This verifies that the message is accessible with the recipient's key */ export async function verifyRecipientCanRetrieve( articleId: string, authorPubkey: string, recipientPubkey: string, messageEventId: string ): Promise { try { const status = await verifyContentDelivery(articleId, authorPubkey, recipientPubkey, messageEventId) return status.retrievable && status.verifiedOnRelay } catch (error) { console.error('Error verifying recipient can retrieve', { articleId, recipientPubkey, messageEventId, error: error instanceof Error ? error.message : 'Unknown error', }) return false } }