- **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.
83 lines
2.3 KiB
TypeScript
83 lines
2.3 KiB
TypeScript
import { nostrService } from './nostr'
|
|
import { SimplePoolWithSub } from '@/types/nostr-tools-extended'
|
|
import type { Article } from '@/types/nostr'
|
|
|
|
const RELAY = process.env.NEXT_PUBLIC_NOSTR_RELAY_URL ?? 'wss://relay.damus.io'
|
|
|
|
function subscribeToPresentation(pool: SimplePoolWithSub, pubkey: string): Promise<number> {
|
|
const filters = [
|
|
{
|
|
kinds: [1],
|
|
authors: [pubkey],
|
|
'#category': ['author-presentation'],
|
|
limit: 1,
|
|
},
|
|
]
|
|
|
|
return new Promise((resolve) => {
|
|
let resolved = false
|
|
const sub = pool.sub([RELAY], filters)
|
|
|
|
const finalize = (value: number) => {
|
|
if (resolved) {
|
|
return
|
|
}
|
|
resolved = true
|
|
sub.unsub()
|
|
resolve(value)
|
|
}
|
|
|
|
sub.on('event', (event: import('nostr-tools').Event) => {
|
|
const isPresentation = event.tags.some((tag) => tag[0] === 'presentation' && tag[1] === 'true')
|
|
if (!isPresentation) {
|
|
return
|
|
}
|
|
const sponsoringTag = event.tags.find((tag) => tag[0] === 'total_sponsoring')
|
|
const total = sponsoringTag ? parseInt(sponsoringTag[1] ?? '0', 10) : 0
|
|
finalize(total)
|
|
})
|
|
|
|
sub.on('eose', () => finalize(0))
|
|
setTimeout(() => finalize(0), 5000)
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Get total sponsoring for an author by their pubkey
|
|
*/
|
|
export function getAuthorSponsoring(pubkey: string): Promise<number> {
|
|
const pool = nostrService.getPool()
|
|
if (!pool) {
|
|
return Promise.resolve(0)
|
|
}
|
|
|
|
return subscribeToPresentation(pool as SimplePoolWithSub, pubkey)
|
|
}
|
|
|
|
/**
|
|
* Get sponsoring for multiple authors (for sorting)
|
|
* Returns a map of pubkey -> total sponsoring
|
|
*/
|
|
export function getAuthorsSponsoring(pubkeys: string[]): Map<string, number> {
|
|
const sponsoringMap = new Map<string, number>()
|
|
|
|
// For now, we'll extract sponsoring from articles that are already loaded
|
|
// In a real implementation, we'd query all presentation articles
|
|
// For performance, we'll use the sponsoring from the article's totalSponsoring field
|
|
pubkeys.forEach((pubkey) => {
|
|
sponsoringMap.set(pubkey, 0)
|
|
})
|
|
|
|
return sponsoringMap
|
|
}
|
|
|
|
/**
|
|
* Get sponsoring from an article (if it's a presentation article)
|
|
*/
|
|
export function getSponsoringFromArticle(article: Article): number {
|
|
if (article.isPresentation && article.totalSponsoring !== undefined) {
|
|
return article.totalSponsoring
|
|
}
|
|
return 0
|
|
}
|