TAO/client/src/utils/relays.ts

100 lines
2.3 KiB
TypeScript
Raw Normal View History

2023-09-15 15:56:25 +00:00
import {Event, Filter, relayInit, Relay, Sub} from 'nostr-tools';
2023-09-15 15:56:25 +00:00
type SubCallback = (
event: Readonly<Event>,
relay: Readonly<string>,
) => void;
2023-09-15 15:56:25 +00:00
type Subscribe = {
cb: SubCallback;
filter: Filter;
unsub?: boolean;
};
2023-09-15 15:56:25 +00:00
const subList: Array<Sub> = [];
const currentSubList: Array<Subscribe> = [];
const relayMap = new Map<string, Relay>();
export const addRelay = async (url: string) => {
const relay = relayInit(url);
relay.on('connect', () => {
console.info(`connected to ${relay.url}`);
});
relay.on('error', () => {
console.warn(`failed to connect to ${relay.url}`);
});
try {
await relay.connect();
currentSubList.forEach(({cb, filter}) => subscribe(cb, filter, relay));
relayMap.set(url, relay);
} catch {
console.warn(`could not connect to ${url}`);
}
};
export const unsubscribe = (sub: Sub) => {
sub.unsub();
subList.splice(subList.indexOf(sub), 1);
};
const subscribe = (
cb: SubCallback,
filter: Filter,
relay: Relay,
unsub?: boolean
) => {
2023-09-15 15:56:25 +00:00
const sub = relay.sub([filter]);
subList.push(sub);
sub.on('event', (event: Event) => {
cb(event, relay.url);
});
if (unsub) {
sub.on('eose', () => {
// console.log('eose', relay.url);
unsubscribe(sub);
});
}
return sub;
};
2023-09-15 15:56:25 +00:00
export const sub = (obj: Subscribe) => {
currentSubList.push(obj);
relayMap.forEach((relay) => subscribe(obj.cb, obj.filter, relay, obj.unsub));
};
export const subOnce = (
obj: Subscribe & {relay: string}
) => {
const relay = relayMap.get(obj.relay);
if (relay) {
const sub = subscribe(obj.cb, obj.filter, relay);
sub.on('eose', () => {
// console.log('eose', obj.relay);
unsubscribe(sub);
});
}
2023-09-15 15:56:25 +00:00
};
export const unsubAll = () => {
subList.forEach(unsubscribe);
currentSubList.length = 0;
};
2023-09-15 16:58:12 +00:00
export const publish = (event: Event) => {
2023-09-15 15:56:25 +00:00
relayMap.forEach(async (relay, url) => {
try {
await relay.publish(event);
2023-09-15 16:58:12 +00:00
console.info(`${relay.url} has accepted our event: ${event.id}`);
2023-09-15 15:56:25 +00:00
} catch (reason) {
console.error(`failed to publish to ${relay.url}: ${reason}`);
}
});
};
addRelay('wss://relay.snort.social');
2023-11-02 13:12:03 +00:00
addRelay('wss://nostr.bitcoiner.social');
2023-09-15 15:56:25 +00:00
addRelay('wss://nostr.mom');
addRelay('wss://relay.nostr.bg');
addRelay('wss://nos.lol');
2023-11-02 13:12:03 +00:00
addRelay('wss://powrelay.xyz');