You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

94 lines
2.2 KiB

/**
* Relay list fetcher (kind 10002 and 10432)
*/
import { nostrClient } from '../nostr/nostr-client.js';
import { config } from '../nostr/config.js';
import type { NostrEvent } from '../../types/nostr.js';
export interface RelayInfo {
url: string;
read: boolean;
write: boolean;
}
/**
* Parse relay list from event
*/
export function parseRelayList(event: NostrEvent): RelayInfo[] {
const relays: RelayInfo[] = [];
for (const tag of event.tags) {
if (tag[0] === 'r' && tag[1]) {
const url = tag[1];
const markers = tag.slice(2);
// If no markers, relay is both read and write
if (markers.length === 0) {
relays.push({ url, read: true, write: true });
continue;
}
// Check for explicit markers
const hasRead = markers.includes('read');
const hasWrite = markers.includes('write');
// If only 'read' marker: read=true, write=false
// If only 'write' marker: read=false, write=true
// If both or neither explicitly: both true (default behavior)
const read = hasRead || (!hasRead && !hasWrite);
const write = hasWrite || (!hasRead && !hasWrite);
relays.push({ url, read, write });
}
}
return relays;
}
/**
* Fetch relay lists for a pubkey (kind 10002 and 10432)
*/
export async function fetchRelayLists(
pubkey: string,
relays?: string[]
): Promise<{
inbox: string[];
outbox: string[];
}> {
const relayList = relays || [
...config.defaultRelays,
...config.profileRelays
];
// Fetch both kind 10002 and 10432
const events = await nostrClient.fetchEvents(
[
{ kinds: [10002], authors: [pubkey], limit: 1 },
{ kinds: [10432], authors: [pubkey], limit: 1 }
],
relayList,
{ useCache: true, cacheResults: true }
);
const inbox: string[] = [];
const outbox: string[] = [];
for (const event of events) {
const relayInfos = parseRelayList(event);
for (const info of relayInfos) {
if (info.read && !inbox.includes(info.url)) {
inbox.push(info.url);
}
if (info.write && !outbox.includes(info.url)) {
outbox.push(info.url);
}
}
}
// Deduplicate
return {
inbox: [...new Set(inbox)],
outbox: [...new Set(outbox)]
};
}