From 7706034b993acbd5712b7c5999bd3a713ea56871 Mon Sep 17 00:00:00 2001 From: Jon Staab Date: Thu, 20 Feb 2025 16:34:43 -0800 Subject: [PATCH] Work on new net --- packages/net2/.eslintignore | 3 ++ packages/net2/README.md | 61 +++++++++++++++++++++++++++++++++++++ packages/net2/package.json | 39 ++++++++++++++++++++++++ packages/net2/src/auth.ts | 38 +++++++++++++++++++++++ packages/net2/src/socket.ts | 10 ++++++ packages/net2/tsconfig.json | 14 +++++++++ packages/net2/typedoc.json | 3 ++ 7 files changed, 168 insertions(+) create mode 100644 packages/net2/.eslintignore create mode 100644 packages/net2/README.md create mode 100644 packages/net2/package.json create mode 100644 packages/net2/src/auth.ts create mode 100644 packages/net2/src/socket.ts create mode 100644 packages/net2/tsconfig.json create mode 100644 packages/net2/typedoc.json diff --git a/packages/net2/.eslintignore b/packages/net2/.eslintignore new file mode 100644 index 0000000..5d9959b --- /dev/null +++ b/packages/net2/.eslintignore @@ -0,0 +1,3 @@ +build +normalize-url +Negentropy.ts diff --git a/packages/net2/README.md b/packages/net2/README.md new file mode 100644 index 0000000..b543670 --- /dev/null +++ b/packages/net2/README.md @@ -0,0 +1,61 @@ +# @welshman/net [![version](https://badgen.net/npm/v/@welshman/net)](https://npmjs.com/package/@welshman/net) + +Utilities having to do with connection management and nostr messages. + +```typescript +import {ctx, setContext} from '@welshman/lib' +import {type TrustedEvent, createEvent, NOTE} from '@welshman/util' +import {subscribe, publish, getDefaultNetContext} from '@welshman/net' + +// Sets up customizable event valdation, handlers, etc +setContext(getDefaultNetContext()) + +// Send a subscription +const sub = subscribe({ + relays: ['wss://relay.example.com/'], + filters: [{kinds: [1], limit: 1}], + closeOnEose: true, + timeout: 10000, +}) + +sub.on(SubscriptionEvent.Event, (url: string, event: TrustedEvent) => { + console.log(url, event) + sub.close() +}) + +// Publish an event +const pub = publish({ + relays: ['wss://relay.example.com/'], + event: createEvent(NOTE, {content: 'hi'}), +}) + +pub.emitter.on('*', (status: PublishStatus, url: string) => { + console.log(status, url) +}) + +// The Tracker class can tell you which relays an event was read from or published to +console.log(ctx.net.tracker.getRelays(event.id)) +``` + +The main reason this module exists is to support different backends via Executor and different `target` classes. For example, to add a local relay that automatically gets used: + +```typescript +import {setContext} from '@welshman/lib' +import {LOCAL_RELAY_URL, Relay, Repository} from '@welshman/util' +import {getDefaultNetContext, Multi, Local, Relays, Executor} from '@welshman/net' + +const repository = new Repository() + +const relay = new Relay(repository) + +setContext(getDefaultNetContext({ + getExecutor: (relays: string[]) => { + return new Executor( + new Multi([ + new Local(relay), + new Relays(remoteUrls.map(url => ctx.net.pool.get(url))), + ]) + ) + }, +})) +``` diff --git a/packages/net2/package.json b/packages/net2/package.json new file mode 100644 index 0000000..c8fd468 --- /dev/null +++ b/packages/net2/package.json @@ -0,0 +1,39 @@ +{ + "name": "@welshman/net2", + "version": "0.0.48", + "author": "hodlbod", + "license": "MIT", + "description": "Utilities for connecting with nostr relays.", + "publishConfig": { + "access": "public" + }, + "type": "module", + "files": [ + "build" + ], + "types": "./build/src/index.d.ts", + "exports": { + ".": { + "types": "./build/src/index.d.ts", + "import": "./build/src/index.js", + "require": "./build/src/index.js" + } + }, + "scripts": { + "pub": "npm run lint && npm run build && npm publish", + "build": "gts clean && tsc", + "lint": "gts lint", + "fix": "gts fix", + "test": "mocha" + }, + "devDependencies": { + "mocha": "^10.7.3" + }, + "dependencies": { + "@welshman/lib": "~0.0.40", + "@welshman/util": "~0.0.59", + "isomorphic-ws": "^5.0.0", + "rxjs": "^7.8.1", + "ws": "^8.16.0" + } +} diff --git a/packages/net2/src/auth.ts b/packages/net2/src/auth.ts new file mode 100644 index 0000000..1775aad --- /dev/null +++ b/packages/net2/src/auth.ts @@ -0,0 +1,38 @@ +import type {WebSocketSubject} from "rxjs/websocket" +import {Subject} from "rxjs" +import type {SignedEvent} from "@welshman/util" +import {createEvent, CLIENT_AUTH} from "@welshman/util" +import type {SocketResponse} from "./socket.js" + +export const createAuthEvent = (url: string, challenge: string) => + createEvent(CLIENT_AUTH, { + tags: [ + ["relay", url], + ["challenge", challenge], + ], + }) + +export type AuthResult = { + ok: boolean + reason?: string +} + +export const authenticate = (socket: WebSocketSubject, event: SignedEvent) => { + const subject = new Subject() + + socket.next(["AUTH", event]) + + socket.subscribe(message => { + if (message[0] === "OK") { + const [id, ok = false, reason = ""] = message.slice(1) + + if (id === event.id) { + subject.next({ok, reason}) + } + } + }) + + return subject +} + +export const forceAuth = (socket: WebSocketSubject) => {} diff --git a/packages/net2/src/socket.ts b/packages/net2/src/socket.ts new file mode 100644 index 0000000..3df927f --- /dev/null +++ b/packages/net2/src/socket.ts @@ -0,0 +1,10 @@ +import {webSocket} from "rxjs/websocket" +import type {SignedEvent} from "@welshman/util" + +export type SocketResponse = + | ["AUTH", string] + | ["EVENT", string, SignedEvent] + | ["EOSE", string, SignedEvent] + | ["OK", string, boolean, string] + +export const connect = (url: string) => webSocket(url) diff --git a/packages/net2/tsconfig.json b/packages/net2/tsconfig.json new file mode 100644 index 0000000..97e6372 --- /dev/null +++ b/packages/net2/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../node_modules/gts/tsconfig-google.json", + "compilerOptions": { + "rootDir": ".", + "outDir": "build", + "module": "nodenext", + "moduleResolution": "nodenext", + "lib": ["esnext", "dom"] + }, + "include": [ + "src/**/*.ts", + "test/**/*.ts" + ] +} diff --git a/packages/net2/typedoc.json b/packages/net2/typedoc.json new file mode 100644 index 0000000..35fed2c --- /dev/null +++ b/packages/net2/typedoc.json @@ -0,0 +1,3 @@ +{ + "entryPoints": ["src/index.ts"] +}