import { useQuery } from '@tanstack/react-query'; import { useSkateRelays } from '@/hooks/useSkateRelays'; import { APP_DATA_KIND, NEWSLETTER_SUB_D } from '@/lib/types'; /** * A best-effort community tally of newsletter subscribers. * * Each subscriber owns a public NIP-78 marker (kind 30078, d=NEWSLETTER_SUB_D) * with a `subscribed` boolean tag. We query those markers and count the ones * currently set to "true", deduped by author (one vote per pubkey). * * This is intentionally approximate — relays only return what they hold — so we * present it as social proof ("N+ skaters"), not an exact figure. */ export function useNewsletterSubscriberCount() { const { querySkateContent, getQueryKeySuffix } = useSkateRelays(); return useQuery({ queryKey: ['newsletter-subscriber-count', getQueryKeySuffix()], staleTime: 5 * 60 * 1000, gcTime: 30 * 60 * 1000, queryFn: async (c): Promise => { const signal = AbortSignal.any([c.signal, AbortSignal.timeout(6000)]); const events = await querySkateContent( [{ kinds: [APP_DATA_KIND], '#d': [NEWSLETTER_SUB_D], limit: 1000 }], { signal }, ); // Keep the newest marker per author, then count the "true" ones. const latestByAuthor = new Map(); for (const ev of events) { const subscribed = ev.tags.find(([n]) => n === 'subscribed')?.[1] === 'true'; const existing = latestByAuthor.get(ev.pubkey); if (!existing || ev.created_at > existing.createdAt) { latestByAuthor.set(ev.pubkey, { subscribed, createdAt: ev.created_at }); } } let count = 0; for (const { subscribed } of latestByAuthor.values()) { if (subscribed) count++; } return count; }, }); }