diff --git a/README.md b/README.md index 3d320d0..4d6ba5d 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,22 @@ To use this on Node.js you first must install `websocket-polyfill` and import it import 'websocket-polyfill' ``` +### Interacting with multiple relays + +```js +import {pool} from 'nostr-tools' + +const p = pool() + +["wss://relay.example.com", "wss://relay.example2.com"].forEach(async url => { + let relay = pool.ensureRelay(url) + await relay.connect() + + relay.sub(...) // same as above + relay.publish(...) // etc +}) +``` + ### Querying profile data from a NIP-05 address ```js @@ -195,7 +211,7 @@ let event = { sendEvent(event) // on the receiver side -sub.on('event', (event) => { +sub.on('event', event => { let sender = event.tags.find(([k, v]) => k === 'p' && v && v !== '')[1] pk1 === sender let plaintext = await nip04.decrypt(sk2, pk1, event.content) diff --git a/index.ts b/index.ts index 29f075f..6e4757c 100644 --- a/index.ts +++ b/index.ts @@ -2,6 +2,7 @@ export * from './keys' export * from './relay' export * from './event' export * from './filter' +export * from './pool' export * as nip04 from './nip04' export * as nip05 from './nip05' diff --git a/package.json b/package.json index 1669c9a..b5a763f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nostr-tools", - "version": "1.2.1", + "version": "1.2.3", "description": "Tools for making a Nostr client.", "repository": { "type": "git", diff --git a/pool.ts b/pool.ts new file mode 100644 index 0000000..2883254 --- /dev/null +++ b/pool.ts @@ -0,0 +1,27 @@ +import {Relay, relayInit} from './relay' +import {normalizeURL} from './utils' + +export function pool(defaultRelays: string[] = []) { + return new SimplePool(defaultRelays) +} + +class SimplePool { + private _conn: {[url: string]: Relay} + private _knownIds: Set = new Set() + + constructor(defaultRelays: string[]) { + this._conn = {} + defaultRelays.forEach(this.ensureRelay) + } + + ensureRelay(url: string): Relay { + const nm = normalizeURL(url) + const existing = this._conn[nm] + if (existing) return existing + + const hasEventId = (id: string): boolean => this._knownIds.has(id) + const relay = relayInit(nm, hasEventId) + this._conn[nm] = relay + return relay + } +} diff --git a/utils.ts b/utils.ts index 787afd5..28c26fa 100644 --- a/utils.ts +++ b/utils.ts @@ -3,6 +3,20 @@ import {Event} from './event' export const utf8Decoder = new TextDecoder('utf-8') export const utf8Encoder = new TextEncoder() +export function normalizeURL(url: string): string { + let p = new URL(url) + p.pathname = p.pathname.replace(/\/+/g, '/') + if (p.pathname.endsWith('/')) p.pathname = p.pathname.slice(0, -1) + if ( + (p.port === '80' && p.protocol === 'ws:') || + (p.port === '443' && p.protocol === 'wss:') + ) + p.port = '' + p.searchParams.sort() + p.hash = '' + return p.toString() +} + // // fast insert-into-sorted-array functions adapted from https://github.com/terrymorse58/fast-sorted-array //