import { useQuery } from '@tanstack/react-query'; import { useNostr } from '@nostrify/react'; import { useAppContext } from '@/hooks/useAppContext'; /** Parse the `relay` tags of a kind-10050 event (NIP-17) into URLs. */ export function dmRelaysFromEvent(tags: string[][]): string[] { return tags .filter(([name]) => name === 'relay') .map(([, url]) => url) .filter((url): url is string => Boolean(url)); } /** The current user's own published DM relays (kind 10050), from config. */ export function useMyDmRelays(): string[] { const { config } = useAppContext(); return config.relayMetadata.dmRelays ?? []; } /** * Fetch the NIP-17 DM relay lists (kind 10050) for the given pubkeys. * Returns a `pubkey → relayUrls` map (newest event per author wins). */ export function useDmRelays(pubkeys: string[]) { const { nostr } = useNostr(); const unique = [...new Set(pubkeys.filter(Boolean))].sort(); return useQuery>({ queryKey: ['dm-relays', unique.join(',')], enabled: unique.length > 0, staleTime: 10 * 60 * 1000, queryFn: async (c) => { const signal = AbortSignal.any([c.signal, AbortSignal.timeout(8000)]); const events = await nostr.query( [{ kinds: [10050], authors: unique, limit: unique.length * 2 }], { signal }, ); const map: Record = {}; for (const ev of [...events].sort((a, b) => b.created_at - a.created_at)) { if (map[ev.pubkey]) continue; const urls = dmRelaysFromEvent(ev.tags); if (urls.length > 0) map[ev.pubkey] = urls; } return map; }, }); }