import { useMemo } from "react"; import { HexKey, FullRelaySettings, TaggedRawEvent, RelaySettings, EventKind, PubkeyReplaceableNoteStore, RequestBuilder, } from "@snort/system"; import debug from "debug"; import { sanitizeRelayUrl } from "SnortUtils"; import useRequestBuilder from "Hooks/useRequestBuilder"; import { UserRelays } from "Cache"; interface RelayList { pubkey: string; created_at: number; relays: FullRelaySettings[]; } export default function useRelaysFeedFollows(pubkeys: HexKey[]): Array { const sub = useMemo(() => { const b = new RequestBuilder(`relays:follows`); const since = UserRelays.newest(); debug("LoginFeed")("Loading relay lists since %s", new Date(since * 1000).toISOString()); b.withFilter().authors(pubkeys).kinds([EventKind.Relays, EventKind.ContactList]).since(since); return b; }, [pubkeys]); function mapFromRelays(notes: Array): Array { return notes.map(ev => { return { pubkey: ev.pubkey, created_at: ev.created_at, relays: ev.tags .map(a => { return { url: sanitizeRelayUrl(a[1]), settings: { read: a[2] === "read" || a[2] === undefined, write: a[2] === "write" || a[2] === undefined, }, } as FullRelaySettings; }) .filter(a => a.url !== undefined), }; }); } // instead of discarding the follow list we should also use it for follow graph function mapFromContactList(notes: Array): Array { return notes.map(ev => { if (ev.content !== "" && ev.content !== "{}" && ev.content.startsWith("{") && ev.content.endsWith("}")) { try { const relays: Record = JSON.parse(ev.content); return { pubkey: ev.pubkey, created_at: ev.created_at, relays: Object.entries(relays) .map(([k, v]) => { return { url: sanitizeRelayUrl(k), settings: v, } as FullRelaySettings; }) .filter(a => a.url !== undefined), }; } catch { // ignored } } return { pubkey: ev.pubkey, created_at: 0, relays: [], }; }); } const relays = useRequestBuilder(PubkeyReplaceableNoteStore, sub); const notesRelays = relays.data?.filter(a => a.kind === EventKind.Relays) ?? []; const notesContactLists = relays.data?.filter(a => a.kind === EventKind.ContactList) ?? []; return useMemo(() => { return [...mapFromContactList(notesContactLists), ...mapFromRelays(notesRelays)]; }, [relays]); }