diff options
Diffstat (limited to 'shim')
-rw-r--r-- | shim/ws-shim/src/client.ts | 38 | ||||
-rw-r--r-- | shim/ws-shim/src/lib.ts | 38 | ||||
-rw-r--r-- | shim/ws-shim/src/nostr.ts | 8 | ||||
-rw-r--r-- | shim/ws-shim/src/server.ts | 176 | ||||
-rw-r--r-- | shim/ws-shim/src/test.ts | 188 | ||||
-rw-r--r-- | shim/ws-shim/src/types.ts | 30 |
6 files changed, 433 insertions, 45 deletions
diff --git a/shim/ws-shim/src/client.ts b/shim/ws-shim/src/client.ts index b7df3e9..c261f60 100644 --- a/shim/ws-shim/src/client.ts +++ b/shim/ws-shim/src/client.ts @@ -13,6 +13,8 @@ export class Relay { private messageQueue: ClientMessage[] = []; private reconnectTimer: Timer | null = null; private reconnectAttempts = 0; + private recentDisconnects = 0; + private disconnectTimer: Timer | null = null; private maxReconnectAttempts = 5; private reconnectDelay = 1000; @@ -21,14 +23,22 @@ export class Relay { public onconnect?: () => void; public ondisconnect?: () => void; + public onfailure?: () => void; public onerror?: (error: Error) => void; public onnotice?: (message: string) => void; + public onmsg: (message: RelayMessage) => void; - constructor(url: string) { + constructor(url: string, onmsg: (msg: RelayMessage) => void) { this.url = url; + this.onmsg = onmsg; } async connect(): Promise<void> { + // console.log("connecting to ws", { + // url: this.url, + // tries: this.reconnectAttempts, + // bad: this.recentDisconnects, + // }); return new Promise((resolve, reject) => { if (this.ws?.readyState === WebSocket.OPEN) { resolve(); @@ -82,11 +92,26 @@ export class Relay { } private attemptReconnect(): void { - if (this.reconnectAttempts >= this.maxReconnectAttempts) { + if ( + this.reconnectAttempts >= this.maxReconnectAttempts || + this.recentDisconnects >= this.maxReconnectAttempts + ) { this.status = "error"; + this.onfailure?.(); this.onerror?.(new Error("Max reconnection attempts reached")); return; } + if (this.disconnectTimer) { + clearTimeout(this.disconnectTimer); + this.disconnectTimer = null; + } + + this.recentDisconnects = this.recentDisconnects + 1; + const ddelay = 10_000; + this.disconnectTimer = setTimeout(() => { + console.log("resetting disconnect timer"); + this.recentDisconnects = 0; + }, ddelay); this.reconnectAttempts++; const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1); @@ -118,6 +143,7 @@ export class Relay { private handleMessage(data: string): void { try { const message = JSON.parse(data) as RelayMessage; + this.onmsg(message); switch (message[0]) { case "EVENT": { @@ -135,6 +161,7 @@ export class Relay { if (!success) { console.error(`Event ${eventId} rejected: ${messag}`); } + break; } @@ -147,6 +174,8 @@ export class Relay { case "CLOSED": { const [, subscriptionId, messag] = message; + const subscription = this.subscriptions.get(subscriptionId); + subscription?.onclose?.(messag); this.subscriptions.delete(subscriptionId); console.log(`Subscription ${subscriptionId} closed: ${messag}`); break; @@ -178,8 +207,13 @@ export class Relay { handlers: { onevent?: (event: NostrEvent) => void; oneose?: () => void; + onclose?: (message: string) => void; }, ): () => void { + // TODO mmm + const has = this.subscriptions.has(id); + if (has) return () => {}; + // const subscription: Subscription = { id, filters, diff --git a/shim/ws-shim/src/lib.ts b/shim/ws-shim/src/lib.ts new file mode 100644 index 0000000..ec61a90 --- /dev/null +++ b/shim/ws-shim/src/lib.ts @@ -0,0 +1,38 @@ +import type { RelayMessage, ShimRequest, ShimResponse } from "./types"; + +export function parseRelayMsg(message: RelayMessage): ShimResponse["msg"] { + switch (message[0]) { + case "EVENT": { + const [, subscription_id, event] = message; + return { event: { subscription_id, event } }; + } + + case "OK": { + const [, event_id, accepted, msg] = message; + return { ok: { event_id, accepted, message: msg } }; + } + + case "EOSE": { + const [, subscriptionId] = message; + return { eose: subscriptionId }; + } + + case "CLOSED": { + const [, subscription_id, msg] = message; + return { closed: { subscription_id, message: msg } }; + } + + case "NOTICE": { + const [, messag] = message; + return { notice: messag }; + } + + case "AUTH": { + const [, challenge] = message; + return { auth: challenge }; + } + } +} +export function wait(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} diff --git a/shim/ws-shim/src/nostr.ts b/shim/ws-shim/src/nostr.ts index 0b084b6..b123bc8 100644 --- a/shim/ws-shim/src/nostr.ts +++ b/shim/ws-shim/src/nostr.ts @@ -1,4 +1,4 @@ -import { finalizeEvent, validateEvent, verifyEvent } from "nostr-tools"; +import { finalizeEvent, nip19, validateEvent, verifyEvent } from "nostr-tools"; import type { NostrEvent } from "./types"; import { hexToBytes } from "nostr-tools/utils"; @@ -22,3 +22,9 @@ export function validate(event: NostrEvent) { console.log("is verified?", ok2); return ok && ok2; } + +export function checkPubkey(pubkey: string): boolean { + const npub = nip19.npubEncode(pubkey); + console.log({ npub, hex: pubkey }); + return false; +} diff --git a/shim/ws-shim/src/server.ts b/shim/ws-shim/src/server.ts index 0b807aa..f375fc7 100644 --- a/shim/ws-shim/src/server.ts +++ b/shim/ws-shim/src/server.ts @@ -32,9 +32,9 @@ let sub: number; // headers: { "Content-Type": "text/event-stream" }, // }); // } -function emit(channel: string, url: string, event?: any): void { +function emit(res: ShimResponse): void { // emitter.emit(channel, event, data); - const body = JSON.stringify({ event, relay: url }); + const body = JSON.stringify({ ws: res }); fetch(SHIP_URL + "/nostr-shim", { method: "PUT", headers: { "Content-type": "application/json" }, @@ -42,36 +42,24 @@ function emit(channel: string, url: string, event?: any): void { }); } const sockets: Map<string, Relay> = new Map(); +const unreliable: Set<string> = new Set(); const server = Bun.serve({ //http routes: { "/shim": async (req: Request) => { const data = (await req.json()) as ShimRequest; - console.log("request data", data); - if ("get" in data) { - for (const req of data.get) { - startWSClient(req.relay, req.filters); + console.log({ data }); + if ("ws" in data) { + console.log("request from urbit"); + console.dir(data, { depth: null }); + for (const relay of data.ws.relays) { + handleShimRequest(relay, data.ws.req); } + return new Response("OK"); + } else { + return oneOffClient(data.http); } - if ("post" in data) { - const ok = validate(data.post.event); - if (!ok) return; - for (const relay of data.post.relays) { - const socket = sockets.get(relay); - if (socket) socket.publishEvent(data.post.event); - else { - await startWSClient(relay, []); - - const socket = sockets.get(relay); - if (socket) socket.publishEvent(data.post.event); - else console.error("wtf man"); - } - } - } - // server.publish("shim", data); - // return sse(req, "all"); - return new Response("OK"); }, }, fetch(req, server) { @@ -136,22 +124,142 @@ const server = Bun.serve({ port: 8888, }); +export async function handleShimRequest(url: string, req: ClientMessage) { + switch (req[0]) { + case "REQ": { + const [, subscription_id, ...filters] = req; + await startWSSub(url, filters, subscription_id); + break; + } + case "EVENT": { + const [, event] = req; + const ok = validate(event); + if (!ok) break; + const socket = await getClient(url); + socket.publishEvent(event); + // socket.publishEvent(data.post.event); + // socket.disconnect(); + // sockets.delete(relay); + break; + } + case "AUTH": { + const [, event] = req; + const socket = await getClient(url); + socket.publishEvent(event); + break; + } + case "CLOSE": { + const [, subscriptionId] = req; + const socket = await getClient(url); + socket.unsubscribe(subscriptionId); + break; + } + } +} + import { Relay } from "./client"; -import type { Filter, ShimRequest } from "./types"; +import type { + ClientMessage, + Filter, + RelayMessage, + ShimHttpRequest, + ShimRequest, + ShimResponse, +} from "./types"; import { validate } from "./nostr"; -async function startWSClient(url: string, filters: Filter[]) { - console.log("connecting to relay..."); - const relay = new Relay(url); +import { parseRelayMsg, wait } from "./lib"; + +async function oneOffClient(req: ShimHttpRequest) { + const { relay: url, delay, subscription_id: subid, filters } = req; + const msgs: ShimResponse["msg"][] = []; + const relay = new Relay(url, (raw) => { + const msg = parseRelayMsg(raw); + msgs.push(msg); + }); + relay.onerror = (error) => { + console.log(url); + console.error("ws error", error); + }; + relay.ondisconnect = () => { + console.error(url, "relay disconnected"); + }; + relay.onfailure = () => { + console.error(url, "relay failed"); + unreliable.add(url); + }; + relay.onnotice = (notice) => { + console.error("on notice", notice); + // emit({ relay: url, msg: { notice } }); + }; + relay.onconnect = () => { + console.log("relay connected", url); + }; await relay.connect(); - const id = crypto.randomUUID(); - relay.subscribe(id, filters, { + for (const f of filters) { + console.dir(f, { depth: null }); + } + relay.subscribe(subid, filters, { oneose: () => { console.log("oneose"); }, - onevent(event) { - console.log("relay event", { url, event }); - emit("all", url, event); + // onevent(event) { + // console.log("relay event", { url, event }); + // }, + }); + await wait(delay); + relay.disconnect(); + return Response.json({ http: msgs }); +} + +async function getClient(url: string): Promise<Relay> { + const socket = sockets.get(url); + if (socket) { + console.log("socket present", socket.status); + if (socket.status !== "connected") await socket.connect(); + return socket; + } else { + const relay = new Relay(url, (raw) => { + const msg = parseRelayMsg(raw); + // console.log("emitting msg", msg); + emit({ relay: url, msg }); + }); + relay.onerror = (error) => { + console.log(url); + console.error("ws error", error); + emit({ relay: url, msg: { error: `${error}` } }); + }; + relay.ondisconnect = () => { + console.error(url, "relay disconnected"); + }; + relay.onfailure = () => { + console.error(url, "relay failed"); + unreliable.add(url); + emit({ relay: url, msg: { error: "failed to connect" } }); + }; + relay.onnotice = (notice) => { + console.error("on notice", notice); + emit({ relay: url, msg: { notice } }); + }; + relay.onconnect = () => { + console.log("relay connected", url); + }; + await relay.connect(); + sockets.set(url, relay); + return relay; + } +} +async function startWSSub(url: string, filters: Filter[], subId?: string) { + if (unreliable.has(url)) return; // just ignore it + + const relay = await getClient(url); + console.log("subscribing", filters); + const subid = subId ? subId : crypto.randomUUID(); + relay.subscribe(subid, filters, { + oneose: () => { + console.log("oneose"); }, + // onevent(event) { + // console.log("relay event", { url, event }); + // }, }); - sockets.set(url, relay); } diff --git a/shim/ws-shim/src/test.ts b/shim/ws-shim/src/test.ts index fb87555..e0f7784 100644 --- a/shim/ws-shim/src/test.ts +++ b/shim/ws-shim/src/test.ts @@ -1,18 +1,194 @@ import { Relay } from "./client"; const ids = [ - "1a4f2d987384a33753e777138586b1f9b3b62eb0f6e54ca1cdb42859de5625bc", + // "1a4f2d987384a33753e777138586b1f9b3b62eb0f6e54ca1cdb42859de5625bc", + "9ef9530b9601d798fcd4e29f151b16bbe4f659408a80618cdf9f2f12a8bc39c6", + "db2815575eddeed24f122de70023c861ec63d0473c40b899d8883194edf122b3", + "1ada56a84ffc94a3cd8ad68432c3cc0ed3e66ac8633226e92cc1a1686efa15a8", + "1a4e12c3c8d2c560c068ee71f51afb84eefda4ec2593ab160312265d626aaa72", + "f0907001d0349d8216c54106d7d3ae400466da204f08a29a69bd0a3d3d1f5cff", + "6a9265f37d944d64d3db918b3b5f06cd2151b428412e1d15672f4cfe16cb17ac", + "9844d8b23a5a5e51b922b25dec8e574a40a68e964fb116e1c283f045ddeb32c", + "fd0724d5238656a3a760c2b56f2eb9d9da7217936d7c51c865584e354485f664", + "1389f670203855c01f575c49f0830aabd7ed01c0fe7cab8f6ee9184393f1f067", + "ac668dc63d8aa38770ef79c2d5a98300d40e9e6daf91f3cd26b942587c70c790", + "f032c4871f82213419dc834db7c469813b1bc75b0f9256a47de90a0f7d28fac5", + "316141d2349969fe1b1d708c4045c455d2608950d7d6d32fb7f99ca622138c34", + "5e9c557df1e9e184e31ce1a8507497dbc79714aedaf4bb386981f8be4eb1dcb5", + "784e0a3af7b11279c612a94726db0056860aabb4e53c614e80fd7e02d409150f", + "4fcc1a0d933afaea7f4fe094cab42b433d0ae0748bcb55e685d5ac3da4191197", + "cf58063ffba4a0f25db862faa9f88e07177fb87c2e4c56b23303b561f7a34376", + "cd750bb5f99a89181f59234c1e5824da72dce4a0fbc87d0f29ef3e62e1de0040", + "ffcc0ed56c747a858224f3d2c122b1430a1df8648dba57544d5a50d976b504bb", + "d08be10b0338b3ab9dc49a31c8d5482289438f4dfbdb9dd844bc1b4990f1536f", + "576cbbddd18301191cca632b464092412362afbf31853d987cd461864b1328ec", + "a0ec2197b96c0e34ba04b89ee37d8fa2202bc02e77ea6a27322e7388afbc470e", + "4d4de8378e1f7238a5b00cbac70547e49a12db82121cb949459478124a799f03", + "d1ab588433fc684540d55e311f1ea4790dfcd793a66b83c5e05e34e319dd421d", + "564811aab801279ae7a473afe37557cfba61816480a5791079a1ca3bb166b038", + "fa5b72846f95271fc83966194f4e7bb63cec91d8412ea00a64f1d8ca304f9d56", + "b4e9c5d587ce36e87105e257eb9042070e415511ef58e29d40fc15e9de3a310d", + "c6c64bd7034cabb1f4d9efd47e76c7d18c631a033442b22d46c3a96614398f10", + "d0fcb5fed102c8779c23d57b4e159402ccc6297f5f8076f72865aa782713f05f", + "20d2505d8a74f0aaad2c1a7766897e717fcc016836cf0469ac54e5ea5458e0c2", + "f345c73a5e44837f88935151d9e34d0340b7a7cd40649f8d446a4445ef99ee7d", + "3b7ef95b5ed5b676b98cef84ab6e4ec9690068b8573a4f524fc6e07a4a88346a", + "735743bd4b332c8786b4592de2fa8fc2155f995e51a8977c8a784c5361d62bc0", + "816bd14613d9c01260a278db8b209b7031a9f91592daee205a74c8f8e475c3d", + "ac13a127f7c140ce29da2547f5262a311f4a6ceef09e1a9cd7ce291f2e6e62cb", + "b8388f25ad94e4c5ef09d424d6d24f7cfa156b863ee82cca4d28f74db476c81f", + "798d46bcde8ac14f5dd196ceab38b0cc806cfd97814dc30213b2fab37deeb41a", + "5864e73def8a4c697e79275ad545ba595fae0c3edb44b5639c9f971433eb4a7e", + "c834c49b93a56dee7800d299ce77f694aef72e3e9b536af360515a9d8226d411", + "307eede13672e33004de6e5d66c6a1a40408a34b6b095399d94a6028f4fdf498", + "6d26e33e9b1ac3e2924879ec39a8f565aebdd004b28ca0377e52a4ef9f86302d", + "5cc263a10f2b0c008b4f3074ffa0ee057c40f1490d2e0717715958e7307aa558", + "192f9b30a0e1d5d4ef16031eaa257d9d84f19c75431cdb3159ee5494c81eeaa8", + "e5e823f3b827c1951d870ef1c402947f1aa6466f313499daab18f60b1519c4a6", + "9895c3aafb063434b7507ae771e6ec4ea1faa5bcbbd5fcc2932a44031eac3547", + "b15411553c1e86f2e851e67e3de767bb9f017da7fd73542f9cb13ca85a2b9cc5", + "2971206110b600d0b0f2120dc98404c2fa0086ea8ece6ed68b4320f585026b30", + "6506597b23bbdb6d0949c16a7d432b8286566895dfe2b9d7e0dc9333ead0d645", + "a6c3c5ad654dcdc9515260426a476d69d8ce3b73151f660adad29ff444047f9a", + "7aa5492fe997029882a68f733c15cc09393b7f69c0608715fcbad813ad1c1fcf", + "6f5ccf726c09f097c4dd0279bb017a211caf9f1416520284f58314dea662d83a", + "f54a6019b86623e2afba6cf405a78a47dbc248fb12f11032e453cd1bb2c4cade", + "2380bdff9700736e12cb6038b7f7897bced9915e102a7e1715cbc2a93e85de08", + "5f12edfb089ec7da0e2d75003531f7dc19e52a5e0bb99fa448415a763a9d0466", + "968a97769cdc23893c407171b3d83b63cca25b88e838d6f489ba8874fc378642", + "e52552ffc80c4947dd1477fe06690ecee3544a24a2ec99b320de8386226cd57", + "30e39614bf11a831fe8e5abd4ff34e0d0f19337e505ea16e7b55770208f1a65b", + "ea2f2b92e8fe184a6eed5f15f042b1ef96a29ccf60b69be8585e84355e97d9b", + "606ce93b81816ceeb5d1582551c83edbb2324ddc3ea6c355502fb008e949b4c5", + "942e798d00041f0d923bfb7f438556f069500b17e4e37ea7a2c524c021913043", + "fade41bedfd5889dd7f1ee65c4c6daf8128a1cbfaebde0074b67d4650ce70af7", + "6be71a0b8facbd5c877f84173f1a251f4980be03395583e4c2fd20c52e2a4394", + "25323e64eaa402475e0b0c5b29c17bf38fa393cd2af469107f3b7a6d7a87d5bd", + "fd1ffe1c90265a9c5e8660bc5be8b9b547a27fffefa34f9d2d7c3bc4184864e2", + "8f849302b357d36535a9107bfe6cd0299c3e4f9e5cb6d9dd6da91e014529d7e0", + "c179af3a8482b96549dab5552f951f4eb9ccd4b17160941c16c3bf6be49b9fd1", + "db240bc1dcbdccbd39d48628ee2f849d8ab610f589015f9cc847ead13f0ed965", + "6b2c895da7ec15f58bd820dc8b2c71451e300b10119abfd74a2f56c0b34f9691", + "f62dc1addae6efbebb9270a38040ee36d8ddfd9faa06c0965d129311a3603049", + "ab18e7c0831991736f037ad9b4485888c9613e2632b8868bc4fd103d42f8ab95", + "e8ecef3ce401b129abbb90a691dd58cfe412b3cc91096ab938687d6a31790f5b", + "c5b72ee7a99992d6d69f1fa88448fd6114e02047563a17ff4b06b60cf95f1bc1", + "c03eede09d30f728c072b9a51d4196928b75ad97464a58123de63e2fb88ce6db", + "815a357554af46d2409b050bf5b8576ea4433f93be0022d60111f9666810fec1", + "5a12e5bf51e06e08ed407440c638db83f01e50a5e7ef60b2b6a5c4c97c638d72", + "9a63d5370d55feab709b5a89057cc958dcc27f8dc97fc31d756e254fca3ab95d", + "295f6bf83dd3786be112649b876bd7fc85092a26e371c32de1610e83aa0b52e2", + "2c49e4b7539af2c04106100b1ef9fb4e78256f579eab536795d6643de0995af6", + "9603af83c7a7f6d6bbb29e077d547daa108f82a88266f5ffa352dc32fc8fc2ad", + "ae351496525d73aa86f4bc75eff3838d416da3b7b8560631f1997bcee197df43", + "13c9788b5acb21a796c91ee98d4ec59212a3dd298dd679b63eceddd846fffc4e", + "ee1aa84638e8f0f1d569b41a7b086d115de8a60df51fd9be7bab5bbb9148452c", + "7eab180ce19c973aec552d8d3fd929f8c9887b70524d31afed455557bb128de9", + "48c8f8c17c54d18b5ba8030302ec6c69a24298ec802f059f594c27221209ae77", + "33b4f14d5941c4831217ed5f1133fe236379cf51e43d34e21cfa5f3b550b1e5b", + "ea052981db488cb53b880fa44904def82ca6817fce6750f4b67ae75471e768d6", + "5c3db160634a6dcd482ee6fde99ac1f3e3bfa98ea7362461ba020b86c2220f20", + "cf3ee418d7b53b25cf6e5114f5f57585d9597c9352af4d55835d5820f55d58c3", + "55d512494d2fe01303b724452d2ec80cba26cf431cea0c91117ec091204d46c1", + "17a23ffd90f53ec2ba760c418b8663f896fb307018fa8b71a3ee6d0f2dff0e0e", + "2b860e2a76738c8e3af1ba7be4df56b7ca49e817d9abc8367a74c42660b50109", + "dcb46a25511e3ec3ced2329d894ccc3da4840d66aab85c073d48d99d2d766030", + "79771a7db2d8c8a8a611a814328e2d2e4fc6d6f2c146d93181ffbe5a6226cc8c", + "8d73454d355f2835f8e97c53ef5da56e6f2e17ed66aae0670f06ad99e13beca6", + "2a97bd64fe3229c2fdc98039239246a02bb6d223d93f40657affd68a3bef58dd", + "abb8de517e96599bd18e849aa722a2ce1b59f87a1e7fe188fda734f07b4962fb", +]; + +const authors = [ + // "84659c5e4dbff288ac294b22e2cff54b5af8e2d2071985859298160de5211dd8", + // "8b6050822e1b51fbc70d4fa05e158f0067d24d86e9c831dd86909d22b77f67f6", + // "e9a2a5f535cce1f1447b4219d5f7f30cefea50be5e0017cfd877efe881f589c5", + // "efe5d120df0cc290fa748727fb45ac487caad346d4f2293ab069e8f01fc51981", + // "5afa711a2e4f45294c9ca8033861a0e15a879e6fc1a4a6903640f7faeae0d7b8", + // "8aa70f4433129dadb71330ac89f62b534caa200a9f3ee349a0f4a5593073d1a6", + // "c7e300eb1e297c5331cf57ae1304b48e5adeeb56c492d9f450494b39e94ebe38", + // "675b84fe75e216ab947c7438ee519ca7775376ddf05dadfba6278bd012e1d728", + + // "efe5d120df0cc290fa748727fb45ac487caad346d4f2293ab069e8f01fc51981", + // "5afa711a2e4f45294c9ca8033861a0e15a879e6fc1a4a6903640f7faeae0d7b8", + // "8aa70f4433129dadb71330ac89f62b534caa200a9f3ee349a0f4a5593073d1a6", + // "c7e300eb1e297c5331cf57ae1304b48e5adeeb56c492d9f450494b39e94ebe38", + // "675b84fe75e216ab947c7438ee519ca7775376ddf05dadfba6278bd012e1d728", + // "99cefa645b00817373239aebb96d2d1990244994e5e565566c82c04b8dc65b54", + // "b7c7f5d30652fbe57aa4ffd373c5fa3912760842c71d260b0f5c498f020f5f03", + // "d60397e8a390b41dd17551b04be27ad26831beb6d55a98a1f14d94ec2fe3fde0", + // "9279276bffb83cee33946e564c3600a32840269a8206d01ddf40c6432baa0bcb", + // "41e368dbaade3de1f0099f58d4e05f8956ad360a9eb7ea210c4272da9ffa04e8", + // "e05cb33ce37bfadfc26a5406e082f84550f63f992df5256dfd08ac62082a99e", + // "16afe0531a7cd932b9a7c6cdceb9b6c19a43b364af4cce7eb6064de2f9bf18d0", + // "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322", + // "e185c2ad0b87b3207ac2b96d6b8fb1ff10fbf25f93eef4d04fb6dbb9039f19fb", + // "99c31c5745565d627684dcf231378b77bb509606f550cfd77bc9ac8fe2bc26f6", + // "9ce71f1506ccf4b99f234af49bd6202be883a80f95a155c6e9a1c36fd7e780c7", + // "cbab7074a03bf89c7dd1623e42e65409e3918662af6c65fe2e38c92ff9f0bd61", + // "b6f856ffc06f6b1d3cc6fbee75adffaed247825b50b929f1bd3483a65b519e34", + // "18f54af1e10c5bb7a35468b0f62b295d12347903c9f95738d065c84bef1402ef", + // "7202985c7e34a7c1c48b93d882a953c5258cf226204ec95bececd8360c792969", + // "db333633799ef7f9dbb2967abcbed657b6c67578459f2bc2bd88d5842a60f954", + // + // + "6e1a6ad5b47e106d3f1be0f2d531580431533b2eb10fad59610594c5455cff7b", + "57dff5343897ca899797b0456d933b637f1051191fd2757889621d48e2f4d622", + "f40c016cf439fe9a1bd8deccf6e11bc3e00655147b5f69691a460972c5f5e7b3", + "9b01d92437819fd91c951ed09fd03036d1c036541f69e17ddfef2e7c7a3f31b7", + "30e39614bf11a831fe8e5abd4ff34e0d0f19337e505ea16e7b55770208f1a65b", + "d5f6d6db022fea369a2fec29541844567f12ad6991ed413c6b4be108a8468dcc", + // "41be274d7dd6cc2bf09bc9bc618cd4476ca1800bebd8888cabdc99f18ba", + "866285e35302b3f3688786bb5a118c8bffd98c255c8634f6a172e0abd63ddc73", + "7877d504a89e7464576d9c06ba2d06fb1de2b2e017ac107de2710216ef24df01", + "65eec5d230d6bb899db4d7d947f4fc82b0e8965b08fcd683a6478962337ebcdb", // ]; async function wsClient(url: string) { console.log("connecting to relae", url); - const relay = new Relay(url); + const relay = new Relay(url, (msg) => { + // console.log("msg", msg); + }); + + relay.onerror = (error) => { + console.log(url); + console.error("ws error", error); + }; + relay.ondisconnect = () => { + console.error(url, "relay disconnected"); + }; + relay.onfailure = () => { + console.error(url, "relay failed"); + }; + relay.onnotice = (notice) => { + console.error("on notice", notice); + }; + relay.onconnect = () => { + console.log("relay connected", url); + }; await relay.connect(); const id = crypto.randomUUID(); - relay.subscribe(id, [{ ids, limit: 50 }], { + const fids = ids.filter((i) => i.length === 64); + const filter = { ids: fids, limit: 500 }; + // const filter = { kinds: [1, 6], limit: 50 }; + // const filter = { + // kinds: [0], + // authors, + // }; + console.log("author count", authors.length); + let eventCount = 0; + const pubkeys: string[] = []; + relay.subscribe(id, [filter], { oneose: () => { console.log("oneose"); + console.log({ eventCount }); + console.log(pubkeys); }, onevent(event) { - console.log("relay event", { url, event }); + // console.log("relay event", { url, event }); + eventCount++; + pubkeys.push(event.pubkey); + }, + onclose: (msg) => { + console.log("sub closed wtf", msg); }, }); // const socket = new WebSocket(url); @@ -39,6 +215,8 @@ const relays = ["wss://nos.lol", "wss://relay.damus.io"]; async function run() { console.log("wth"); - await wsClient(relays[0]!); + for (const r of relays) { + await wsClient(r); + } } run(); diff --git a/shim/ws-shim/src/types.ts b/shim/ws-shim/src/types.ts index 4063772..feeb2f6 100644 --- a/shim/ws-shim/src/types.ts +++ b/shim/ws-shim/src/types.ts @@ -1,7 +1,29 @@ // Shim types -export type ShimRequest = { - get: Array<{ relay: string; filters: Filter[] }>; - post: { event: NostrEvent; relays: string[] }; +export type ShimRequest = + | { http: ShimHttpRequest } + | { + ws: { + relays: string[]; + req: ClientMessage; + }; + }; +export type ShimHttpRequest = { + relay: string; + delay: number; + subscription_id: string; + filters: Filter[]; +}; +export type ShimResponse = { + relay: string; + msg: + | { event: { subscription_id: string; event: NostrEvent } } + | { ok: { event_id: string; accepted: boolean; message: string } } + | { eose: string } + | { closed: { subscription_id: string; message: string } } + | { notice: string } + | { auth: string } + // this is ours + | { error: string }; }; // NOSTR official export interface NostrEvent { @@ -52,6 +74,7 @@ export interface Filter { export type ClientMessage = | ["EVENT", NostrEvent] + | ["AUTH", NostrEvent] | ["REQ", string, ...Filter[]] | ["CLOSE", string]; @@ -74,4 +97,5 @@ export interface Subscription { filters: Filter[]; oneose?: () => void; onevent?: (event: NostrEvent) => void; + onclose?: (message: string) => void; } |