UNPKG

@nostr-dev-kit/ndk

Version:

NDK - Nostr Development Kit. Includes AI Guardrails to catch common mistakes during development.

119 lines (100 loc) 3.82 kB
import type { NDK } from "../../ndk/index.js"; import { NDKRelaySet } from "../../relay/sets/index.js"; import { normalizeRelayUrl, tryNormalizeRelayUrl } from "../../utils/normalize-url.js"; import type { NostrEvent } from "../index.js"; import { NDKEvent } from "../index.js"; import { NDKKind } from "./index.js"; const READ_MARKER = "read"; const WRITE_MARKER = "write"; /** * Represents a relay list for a user, ideally coming from a NIP-65 kind:10002 or alternatively from a kind:3 event's content. * @group Kind Wrapper */ export class NDKRelayList extends NDKEvent { static kind = NDKKind.RelayList; static kinds = [NDKKind.RelayList]; constructor(ndk?: NDK, rawEvent?: NostrEvent) { super(ndk, rawEvent); this.kind ??= NDKKind.RelayList; } static from(ndkEvent: NDKEvent): NDKRelayList { return new NDKRelayList(ndkEvent.ndk, ndkEvent.rawEvent()); } get readRelayUrls(): WebSocket["url"][] { return this.tags .filter((tag) => tag[0] === "r" || tag[0] === "relay") .filter((tag) => !tag[2] || (tag[2] && tag[2] === READ_MARKER)) .map((tag) => tryNormalizeRelayUrl(tag[1])) .filter((url) => !!url) as WebSocket["url"][]; } set readRelayUrls(relays: WebSocket["url"][]) { for (const relay of relays) { this.tags.push(["r", relay, READ_MARKER]); } } get writeRelayUrls(): WebSocket["url"][] { return this.tags .filter((tag) => tag[0] === "r" || tag[0] === "relay") .filter((tag) => !tag[2] || (tag[2] && tag[2] === WRITE_MARKER)) .map((tag) => tryNormalizeRelayUrl(tag[1])) .filter((url) => !!url) as WebSocket["url"][]; } set writeRelayUrls(relays: WebSocket["url"][]) { for (const relay of relays) { this.tags.push(["r", relay, WRITE_MARKER]); } } get bothRelayUrls(): WebSocket["url"][] { return this.tags .filter((tag) => tag[0] === "r" || tag[0] === "relay") .filter((tag) => !tag[2]) .map((tag) => tag[1]); } set bothRelayUrls(relays: WebSocket["url"][]) { for (const relay of relays) { this.tags.push(["r", relay]); } } get relays(): WebSocket["url"][] { return this.tags.filter((tag) => tag[0] === "r" || tag[0] === "relay").map((tag) => tag[1]); } /** * Provides a relaySet for the relays in this list. */ get relaySet(): NDKRelaySet { if (!this.ndk) throw new Error("NDKRelayList has no NDK instance"); return new NDKRelaySet( new Set(this.relays.map((u) => this.ndk?.pool.getRelay(u)).filter((r) => !!r)), this.ndk, ); } } export function relayListFromKind3(ndk: NDK, contactList: NDKEvent): NDKRelayList | undefined { try { const content = JSON.parse(contactList.content); const relayList = new NDKRelayList(ndk); const readRelays = new Set<string>(); const writeRelays = new Set<string>(); for (let [key, config] of Object.entries(content)) { try { key = normalizeRelayUrl(key); } catch { continue; } if (!config) { readRelays.add(key); writeRelays.add(key); } else { const relayConfig: { read?: boolean; write?: boolean } = config; if (relayConfig.write) writeRelays.add(key); if (relayConfig.read) readRelays.add(key); } } relayList.readRelayUrls = Array.from(readRelays); relayList.writeRelayUrls = Array.from(writeRelays); return relayList; } catch { /* */ } return undefined; }