/** * useRiderStats * * Fetches on-chain stats for a given pubkey to display on the Rider Card: * - spotsAdded: how many skate spots (kind 30818) this user has published * - eventsCreated: how many calendar events (kind 31923) they created * - zapsReceived: count of zap receipts (kind 9735) targeting their pubkey * - shopCards: kind 37097 shop rider cards issued TO this user * - parkCards: kind 35679 park access grants issued TO this user * * All queries hit the SkateSpots community relay so results are skate-specific. */ import { useQuery } from '@tanstack/react-query'; import { useNostr } from '@nostrify/react'; export interface RiderStats { spotsAdded: number; eventsCreated: number; zapsReceived: number; shopCards: number; parkCards: number; } export function useRiderStats(pubkey: string | undefined) { const { nostr } = useNostr(); return useQuery({ queryKey: ['rider-stats', pubkey], enabled: !!pubkey, staleTime: 60_000, queryFn: async (c) => { if (!pubkey) return null; const signal = AbortSignal.any([c.signal, AbortSignal.timeout(8000)]); // Single query — multiple filter objects, one round-trip const events = await nostr.query( [ // Spots the user added { kinds: [30818], authors: [pubkey], '#t': ['skatespot'], limit: 200 }, // Events they created { kinds: [31923], authors: [pubkey], limit: 100 }, // Zap receipts targeting their pubkey { kinds: [9735], '#p': [pubkey], limit: 200 }, // Shop rider cards issued TO this user (kind 37097) { kinds: [37097], '#p': [pubkey], limit: 50 }, // Park access cards issued TO this user (kind 35679) { kinds: [35679], '#p': [pubkey], limit: 50 }, ], { signal }, ); const stats: RiderStats = { spotsAdded: events.filter(e => e.kind === 30818).length, eventsCreated: events.filter(e => e.kind === 31923).length, zapsReceived: events.filter(e => e.kind === 9735).length, shopCards: events.filter(e => e.kind === 37097).length, parkCards: events.filter(e => e.kind === 35679).length, }; return stats; }, }); }