- Correction toutes erreurs TypeScript : - Variables non utilisées supprimées - Types optionnels corrigés (exactOptionalPropertyTypes) - Imports corrigés (PLATFORM_BITCOIN_ADDRESS depuis platformConfig) - Gestion correcte des propriétés optionnelles - Suppression fichiers obsolètes : - code-cleanup-summary.md (redondant) - todo-implementation*.md (todos obsolètes) - corrections-completed.md, fallbacks-found.md (corrections faites) - implementation-summary.md (redondant) - documentation-plan.md (plan, pas documentation) - Suppression scripts temporaires : - add-ssh-key.sh - add-ssh-key-plink.sh - Réorganisation documentation dans docs/ : - architecture.md (nouveau) - commissions.md (nouveau) - implementation-summary.md - remaining-tasks.md - split-and-transfer.md - commission-system.md - commission-implementation.md - content-delivery-verification.md Toutes erreurs TypeScript corrigées, documentation centralisée.
127 lines
3.1 KiB
TypeScript
127 lines
3.1 KiB
TypeScript
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<ContentDeliveryStatus> {
|
|
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<boolean> {
|
|
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
|
|
}
|
|
}
|