- **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.
66 lines
1.8 KiB
TypeScript
66 lines
1.8 KiB
TypeScript
import { Event, nip04 } from 'nostr-tools'
|
|
import { SimplePool } from 'nostr-tools'
|
|
|
|
const RELAY_URL = process.env.NEXT_PUBLIC_NOSTR_RELAY_URL ?? 'wss://relay.damus.io'
|
|
|
|
function createPrivateMessageFilters(eventId: string, publicKey: string, authorPubkey: string) {
|
|
return [
|
|
{
|
|
kinds: [4], // Encrypted direct messages
|
|
'#p': [publicKey],
|
|
'#e': [eventId], // Filter by event ID to find relevant private messages
|
|
authors: [authorPubkey], // Filter by author of the original article
|
|
limit: 10, // Limit to recent messages
|
|
},
|
|
]
|
|
}
|
|
|
|
function decryptContent(privateKey: string, event: Event): Promise<string | null> {
|
|
return Promise.resolve(nip04.decrypt(privateKey, event.pubkey, event.content)).then((decrypted) =>
|
|
decrypted ? decrypted : null
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Get private content for an article (encrypted message from author)
|
|
*/
|
|
export function getPrivateContent(
|
|
pool: SimplePool,
|
|
eventId: string,
|
|
authorPubkey: string,
|
|
privateKey: string,
|
|
publicKey: string
|
|
): Promise<string | null> {
|
|
if (!privateKey || !pool || !publicKey) {
|
|
throw new Error('Private key not set or pool not initialized')
|
|
}
|
|
|
|
return new Promise((resolve) => {
|
|
let resolved = false
|
|
const sub = pool.sub([RELAY_URL], createPrivateMessageFilters(eventId, publicKey, authorPubkey))
|
|
|
|
const finalize = (result: string | null) => {
|
|
if (resolved) {
|
|
return
|
|
}
|
|
resolved = true
|
|
sub.unsub()
|
|
resolve(result)
|
|
}
|
|
|
|
sub.on('event', (event: Event) => {
|
|
void decryptContent(privateKey, event)
|
|
.then((content) => {
|
|
if (content) {
|
|
finalize(content)
|
|
}
|
|
})
|
|
.catch((e) => {
|
|
console.error('Error decrypting content:', e)
|
|
})
|
|
})
|
|
sub.on('eose', () => finalize(null))
|
|
setTimeout(() => finalize(null), 5000)
|
|
})
|
|
}
|