@candypoets/nipworker 0.91.1 → 0.91.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,437 +1,452 @@
1
- import * as E from "flatbuffers";
2
- import { WebSocketServer as h, WebSocket as g } from "ws";
3
- import { C as v, W as M, M as A, G as I, R as F, N, S as k } from "./worker-message.js";
4
- function z(n = {}) {
5
- const r = n.host ?? "127.0.0.1", t = n.port ?? 7777, e = n.path ?? "/", o = n.logger ?? console;
6
- let s;
1
+ import * as A from "flatbuffers";
2
+ import { WebSocketServer as w, WebSocket as m } from "ws";
3
+ import { SocksProxyAgent as v } from "socks-proxy-agent";
4
+ import { C as T, W as E, M as k, G as M, R as F, N as C, S as N } from "./worker-message.js";
5
+ function q(t = {}) {
6
+ const r = t.host ?? "127.0.0.1", n = t.port ?? 7777, e = t.path ?? "/", s = t.logger ?? console, o = t.torSocksProxy;
7
+ let f;
7
8
  try {
8
- s = new h({
9
+ f = new w({
9
10
  host: r,
10
- port: t,
11
+ port: n,
11
12
  path: e
12
13
  });
13
- } catch (f) {
14
- throw o.error(`[relay-proxy] failed to create WebSocketServer: ${String(f)}`), f;
14
+ } catch (i) {
15
+ throw s.error(`[relay-proxy] failed to create WebSocketServer: ${String(i)}`), i;
15
16
  }
16
- let a = t;
17
- const i = s.address();
18
- return i && typeof i == "object" && (a = i.port), s.on("error", (f) => {
19
- o.error(`[relay-proxy] WebSocketServer error: ${String(f)}`);
20
- }), s.on("connection", (f) => {
21
- const c = {
17
+ let a = n;
18
+ const c = f.address();
19
+ return c && typeof c == "object" && (a = c.port), f.on("error", (i) => {
20
+ s.error(`[relay-proxy] WebSocketServer error: ${String(i)}`);
21
+ }), f.on("connection", (i) => {
22
+ const u = {
22
23
  relaySockets: /* @__PURE__ */ new Map(),
23
24
  pendingFrames: /* @__PURE__ */ new Map(),
24
25
  dedupBySubId: /* @__PURE__ */ new Map(),
25
- lastSubIdByRelay: /* @__PURE__ */ new Map()
26
+ lastSubIdByRelay: /* @__PURE__ */ new Map(),
27
+ torSocksProxy: o,
28
+ lastAuthChallenge: /* @__PURE__ */ new Map()
26
29
  };
27
- f.on("message", (u, y) => {
28
- if (y) {
29
- const l = x(u);
30
- if (!l) return;
31
- $(c, f, l, o);
30
+ i.on("message", (y, p) => {
31
+ if (p) {
32
+ const d = $(y);
33
+ if (!d) return;
34
+ x(u, i, d, s);
32
35
  return;
33
36
  }
34
- const d = w(u);
35
- d && b(c, d, o);
36
- }), f.on("close", () => {
37
- p(c, o);
38
- }), f.on("error", () => {
39
- p(c, o);
37
+ const l = h(y);
38
+ l && b(u, l, s);
39
+ }), i.on("close", () => {
40
+ g(u, s);
41
+ }), i.on("error", () => {
42
+ g(u, s);
40
43
  });
41
- }), o.info(`[relay-proxy] listening on ws://${r}:${a}${e}`), {
44
+ }), s.info(`[relay-proxy] listening on ws://${r}:${a}${e}`), {
42
45
  port: a,
43
- close: () => new Promise((f, c) => {
44
- s.close((u) => {
45
- if (u) {
46
- c(u);
46
+ close: () => new Promise((i, u) => {
47
+ f.close((y) => {
48
+ if (y) {
49
+ u(y);
47
50
  return;
48
51
  }
49
- f();
52
+ i();
50
53
  });
51
54
  })
52
55
  };
53
56
  }
54
- function Q(n) {
55
- const r = n.path ?? "/", t = n.logger ?? console, e = new h({
57
+ function X(t) {
58
+ const r = t.path ?? "/", n = t.logger ?? console, e = t.torSocksProxy, s = new w({
56
59
  noServer: true
57
60
  }), o = /* @__PURE__ */ new Map();
58
- return e.on("connection", (a) => {
59
- const i = {
61
+ return s.on("connection", (a) => {
62
+ const c = {
60
63
  relaySockets: /* @__PURE__ */ new Map(),
61
64
  pendingFrames: /* @__PURE__ */ new Map(),
62
65
  dedupBySubId: /* @__PURE__ */ new Map(),
63
- lastSubIdByRelay: /* @__PURE__ */ new Map()
66
+ lastSubIdByRelay: /* @__PURE__ */ new Map(),
67
+ torSocksProxy: e
64
68
  };
65
- o.set(a, i), a.on("message", (f, c) => {
66
- const u = o.get(a);
67
- if (!u) return;
68
- if (c) {
69
- const d = x(f);
70
- if (!d) return;
71
- $(u, a, d, t);
69
+ o.set(a, c), a.on("message", (i, u) => {
70
+ const y = o.get(a);
71
+ if (!y) return;
72
+ if (u) {
73
+ const l = $(i);
74
+ if (!l) return;
75
+ x(y, a, l, n);
72
76
  return;
73
77
  }
74
- const y = w(f);
75
- y && b(u, y, t);
78
+ const p = h(i);
79
+ p && b(y, p, n);
76
80
  }), a.on("close", () => {
77
- const f = o.get(a);
78
- f && (p(f, t), o.delete(a));
81
+ const i = o.get(a);
82
+ i && (g(i, n), o.delete(a));
79
83
  }), a.on("error", () => {
80
- const f = o.get(a);
81
- f && (p(f, t), o.delete(a));
84
+ const i = o.get(a);
85
+ i && (g(i, n), o.delete(a));
82
86
  });
83
87
  }), {
84
- wss: e,
85
- close: () => new Promise((a, i) => {
86
- o.forEach((f) => p(f, t)), o.clear(), e.close((f) => {
87
- if (f) {
88
- i(f);
88
+ wss: s,
89
+ close: () => new Promise((a, c) => {
90
+ o.forEach((i) => g(i, n)), o.clear(), s.close((i) => {
91
+ if (i) {
92
+ c(i);
89
93
  return;
90
94
  }
91
95
  a();
92
96
  });
93
97
  }),
94
- handleUpgrade: (a, i, f) => {
95
- (a.url ?? "").startsWith(r) && e.handleUpgrade(a, i, f, (u) => {
96
- e.emit("connection", u, a);
98
+ handleUpgrade: (a, c, i) => {
99
+ (a.url ?? "").startsWith(r) && s.handleUpgrade(a, c, i, (y) => {
100
+ s.emit("connection", y, a);
97
101
  });
98
102
  }
99
103
  };
100
104
  }
101
- function K(n) {
102
- const { server: r, path: t = "/", logger: e = console } = n, o = new h({
105
+ function Y(t) {
106
+ const { server: r, path: n = "/", logger: e = console, torSocksProxy: s } = t, o = new w({
103
107
  server: r,
104
- path: t
108
+ path: n
105
109
  });
106
- return o.on("connection", (s) => {
110
+ return o.on("connection", (f) => {
107
111
  const a = {
108
112
  relaySockets: /* @__PURE__ */ new Map(),
109
113
  pendingFrames: /* @__PURE__ */ new Map(),
110
114
  dedupBySubId: /* @__PURE__ */ new Map(),
111
- lastSubIdByRelay: /* @__PURE__ */ new Map()
115
+ lastSubIdByRelay: /* @__PURE__ */ new Map(),
116
+ torSocksProxy: s
112
117
  };
113
- s.on("message", (i, f) => {
114
- if (f) {
115
- const u = x(i);
116
- if (!u) return;
117
- $(a, s, u, e);
118
+ f.on("message", (c, i) => {
119
+ if (i) {
120
+ const y = $(c);
121
+ if (!y) return;
122
+ x(a, f, y, e);
118
123
  return;
119
124
  }
120
- const c = w(i);
121
- c && b(a, c, e);
122
- }), s.on("close", () => {
123
- p(a, e);
124
- }), s.on("error", () => {
125
- p(a, e);
125
+ const u = h(c);
126
+ u && b(a, u, e);
127
+ }), f.on("close", () => {
128
+ g(a, e);
129
+ }), f.on("error", () => {
130
+ g(a, e);
126
131
  });
127
- }), e.info(`[relay-proxy] attached to server at path: ${t}`), {
128
- close: () => new Promise((s, a) => {
129
- o.close((i) => {
130
- if (i) {
131
- a(i);
132
+ }), e.info(`[relay-proxy] attached to server at path: ${n}`), {
133
+ close: () => new Promise((f, a) => {
134
+ o.close((c) => {
135
+ if (c) {
136
+ a(c);
132
137
  return;
133
138
  }
134
- s();
139
+ f();
135
140
  });
136
141
  })
137
142
  };
138
143
  }
139
- function q(n, r) {
140
- const t = r.path ?? "/ws-proxy", e = r.logger ?? console;
144
+ function Z(t, r) {
145
+ const n = r.path ?? "/ws-proxy", e = r.logger ?? console, s = r.torSocksProxy;
141
146
  let o = null;
142
- const s = /* @__PURE__ */ new Map(), a = n.listen.bind(n);
143
- return n.listen = (...i) => {
144
- const f = a(...i);
145
- return o = new h({
146
- server: f,
147
- path: t
148
- }), o.on("connection", (c) => {
149
- const u = {
147
+ const f = /* @__PURE__ */ new Map(), a = t.listen.bind(t);
148
+ return t.listen = (...c) => {
149
+ const i = a(...c);
150
+ return o = new w({
151
+ server: i,
152
+ path: n
153
+ }), o.on("connection", (u) => {
154
+ const y = {
150
155
  relaySockets: /* @__PURE__ */ new Map(),
151
156
  pendingFrames: /* @__PURE__ */ new Map(),
152
157
  dedupBySubId: /* @__PURE__ */ new Map(),
153
- lastSubIdByRelay: /* @__PURE__ */ new Map()
158
+ lastSubIdByRelay: /* @__PURE__ */ new Map(),
159
+ torSocksProxy: s
154
160
  };
155
- s.set(c, u), c.on("message", (y, d) => {
156
- const l = s.get(c);
157
- if (!l) return;
158
- if (d) {
159
- const B = x(y);
161
+ f.set(u, y), u.on("message", (p, l) => {
162
+ const d = f.get(u);
163
+ if (!d) return;
164
+ if (l) {
165
+ const B = $(p);
160
166
  if (!B) return;
161
- $(l, c, B, e);
167
+ x(d, u, B, e);
162
168
  return;
163
169
  }
164
- const m = w(y);
165
- m && b(l, m, e);
166
- }), c.on("close", () => {
167
- const y = s.get(c);
168
- y && (p(y, e), s.delete(c));
169
- }), c.on("error", () => {
170
- const y = s.get(c);
171
- y && (p(y, e), s.delete(c));
170
+ const I = h(p);
171
+ I && b(d, I, e);
172
+ }), u.on("close", () => {
173
+ const p = f.get(u);
174
+ p && (g(p, e), f.delete(u));
175
+ }), u.on("error", () => {
176
+ const p = f.get(u);
177
+ p && (g(p, e), f.delete(u));
172
178
  });
173
- }), e.info(`[relay-proxy] attached to Express server at path: ${t}`), f;
179
+ }), e.info(`[relay-proxy] attached to Express server at path: ${n}`), i;
174
180
  }, {
175
- close: () => new Promise((i, f) => {
181
+ close: () => new Promise((c, i) => {
176
182
  if (!o) {
177
- i();
183
+ c();
178
184
  return;
179
185
  }
180
- s.forEach((c) => p(c, e)), s.clear(), o.close((c) => {
181
- if (c) {
182
- f(c);
186
+ f.forEach((u) => g(u, e)), f.clear(), o.close((u) => {
187
+ if (u) {
188
+ i(u);
183
189
  return;
184
190
  }
185
- i();
191
+ c();
186
192
  });
187
193
  })
188
194
  };
189
195
  }
190
- function b(n, r, t) {
191
- t.info(`[relay-proxy] handleClientCommand: ${r.slice(0, 200)}`);
196
+ function b(t, r, n) {
197
+ n.info(`[relay-proxy] handleClientCommand: ${r.slice(0, 200)}`);
192
198
  let e;
193
199
  try {
194
200
  e = JSON.parse(r);
195
- } catch (o) {
196
- t.warn(`[relay-proxy] failed to parse command JSON: ${o}`);
201
+ } catch (s) {
202
+ n.warn(`[relay-proxy] failed to parse command JSON: ${s}`);
197
203
  return;
198
204
  }
199
205
  if (j(e)) {
200
- t.info(`[relay-proxy] received auth_response for relay: ${e.relay}`);
201
- const o = JSON.stringify(["AUTH", e.event]);
202
- t.info(`[relay-proxy] sending AUTH frame to relay: ${e.relay}`), C(n, e.relay, o, t);
206
+ n.info(`[relay-proxy] received auth_response for relay: ${e.relay}`);
207
+ const s = JSON.stringify(["AUTH", e.event]);
208
+ n.info(`[relay-proxy] sending AUTH frame to relay: ${e.relay}`), P(t, e.relay, s, n);
203
209
  return;
204
210
  }
205
- if (D(e)) {
206
- n.dedupBySubId.delete(e.subscription_id);
207
- for (const [o, s] of n.relaySockets.entries())
208
- s.readyState === g.OPEN && s.send(JSON.stringify(["CLOSE", e.subscription_id])), n.lastSubIdByRelay.set(o, e.subscription_id);
211
+ if (G(e)) {
212
+ t.dedupBySubId.delete(e.subscription_id);
213
+ for (const [s, o] of t.relaySockets.entries())
214
+ o.readyState === m.OPEN && o.send(JSON.stringify(["CLOSE", e.subscription_id])), t.lastSubIdByRelay.set(s, e.subscription_id);
209
215
  }
210
216
  }
211
- function $(n, r, t, e) {
212
- e.info(`[relay-proxy] handleEnvelope: ${t.relays.length} relays, ${t.frames.length} frames`), e.info(`[relay-proxy] relays: ${t.relays.join(", ")}`);
213
- const o = t.frames.map((s) => ({
214
- frame: s,
215
- state: W(s)
217
+ function x(t, r, n, e) {
218
+ e.info(`[relay-proxy] handleEnvelope: ${n.relays.length} relays, ${n.frames.length} frames`), e.info(`[relay-proxy] relays: ${n.relays.join(", ")}`);
219
+ const s = n.frames.map((o) => ({
220
+ frame: o,
221
+ state: L(o)
216
222
  }));
217
- e.info(`[relay-proxy] tracked ${o.length} frames`);
218
- for (const s of t.relays) {
219
- e.info(`[relay-proxy] processing relay: ${s}`), T(n, r, s, e);
220
- for (const a of o) {
221
- P(n, s, a.state);
222
- const i = a.frame;
223
- e.info(`[relay-proxy] sending frame to ${s}: ${i.slice(0, 100)}`), C(n, s, i, e);
223
+ e.info(`[relay-proxy] tracked ${s.length} frames`);
224
+ for (const o of n.relays) {
225
+ e.info(`[relay-proxy] processing relay: ${o}`), W(t, r, o, e);
226
+ for (const f of s) {
227
+ _(t, o, f.state);
228
+ const a = f.frame;
229
+ e.info(`[relay-proxy] sending frame to ${o}: ${a.slice(0, 100)}`), P(t, o, a, e);
224
230
  }
225
231
  }
226
232
  }
227
- function T(n, r, t, e) {
228
- const o = n.relaySockets.get(t);
229
- if (o && o.readyState !== g.CLOSED) {
230
- e.info(`[relay-proxy] reusing existing connection to ${t}`);
233
+ function W(t, r, n, e) {
234
+ const s = t.relaySockets.get(n);
235
+ if (s && s.readyState !== m.CLOSED) {
236
+ e.info(`[relay-proxy] reusing existing connection to ${n}`);
231
237
  return;
232
238
  }
233
- e.info(`[relay-proxy] creating new WebSocket connection to ${t}`);
234
- const s = new URL(t), a = `${s.protocol}//${s.host}`, i = new g(t, {
239
+ e.info(`[relay-proxy] creating new WebSocket connection to ${n}`);
240
+ const o = new URL(n), f = `${o.protocol}//${o.host}`, a = o.hostname.endsWith(".onion"), c = {
235
241
  headers: {
236
- Origin: a,
242
+ Origin: f,
237
243
  "User-Agent": "nipworker/0.91.0"
238
244
  }
239
- });
240
- n.relaySockets.set(t, i), n.pendingFrames.set(t, []);
241
- const f = Date.now();
245
+ };
246
+ a && t.torSocksProxy && (e.info(`[relay-proxy] using Tor SOCKS proxy ${t.torSocksProxy} for ${n}`), c.agent = new v(t.torSocksProxy));
247
+ const i = new m(n, c);
248
+ t.relaySockets.set(n, i), t.pendingFrames.set(n, []);
249
+ const u = Date.now();
242
250
  i.on("open", () => {
243
- e.info(`[relay-proxy] connected to ${t}`);
244
- const c = n.pendingFrames.get(t);
245
- if (c) {
246
- e.info(`[relay-proxy] sending ${c.length} pending frames to ${t}`);
247
- for (const u of c)
248
- i.send(u);
249
- n.pendingFrames.set(t, []);
251
+ e.info(`[relay-proxy] connected to ${n}`);
252
+ const y = t.pendingFrames.get(n);
253
+ if (y) {
254
+ e.info(`[relay-proxy] sending ${y.length} pending frames to ${n}`);
255
+ for (const p of y)
256
+ i.send(p);
257
+ t.pendingFrames.set(n, []);
250
258
  }
251
- }), i.on("message", (c) => {
252
- const u = w(c);
253
- if (e.info(`[relay-proxy] received from ${t}: ${u == null ? void 0 : u.slice(0, 100)}`), !u || r.readyState !== g.OPEN) {
254
- e.warn(`[relay-proxy] cannot forward message: raw=${!!u}, clientOpen=${r.readyState === g.OPEN}`);
259
+ }), i.on("message", (y) => {
260
+ const p = h(y);
261
+ if (e.info(`[relay-proxy] received from ${n}: ${p == null ? void 0 : p.slice(0, 100)}`), !p || r.readyState !== m.OPEN) {
262
+ e.warn(`[relay-proxy] cannot forward message: raw=${!!p}, clientOpen=${r.readyState === m.OPEN}`);
255
263
  return;
256
264
  }
257
- const y = n.lastSubIdByRelay.get(t), d = _(n, t, u, y, e);
265
+ const l = t.lastSubIdByRelay.get(n), d = H(t, n, p, l, e);
258
266
  if (!d) {
259
267
  e.warn("[relay-proxy] failed to convert relay frame to worker message");
260
268
  return;
261
269
  }
262
270
  e.info(`[relay-proxy] forwarding ${d.length} bytes to client`), r.send(d, { binary: true });
263
- }), i.on("close", (c, u) => {
271
+ }), i.on("close", (y, p) => {
264
272
  var _a, _b;
265
- if (e.info(`[relay-proxy] connection closed to ${t} (code: ${c}, reason: ${u})`), n.pendingFrames.has(t) && ((_a = n.pendingFrames.get(t)) == null ? void 0 : _a.length) > 0) {
266
- const y = ((_b = n.pendingFrames.get(t)) == null ? void 0 : _b.length) ?? 0;
267
- if (e.warn(`[relay-proxy] connection to ${t} closed with ${y} pending frames - subscription may fail`), r.readyState === g.OPEN) {
273
+ if (e.info(`[relay-proxy] connection closed to ${n} (code: ${y}, reason: ${p})`), t.pendingFrames.has(n) && ((_a = t.pendingFrames.get(n)) == null ? void 0 : _a.length) > 0) {
274
+ const l = ((_b = t.pendingFrames.get(n)) == null ? void 0 : _b.length) ?? 0;
275
+ if (e.warn(`[relay-proxy] connection to ${n} closed with ${l} pending frames - subscription may fail`), r.readyState === m.OPEN) {
268
276
  const d = S(
269
- n.lastSubIdByRelay.get(t) ?? "",
270
- t,
277
+ t.lastSubIdByRelay.get(n) ?? "",
278
+ n,
271
279
  "failed",
272
- `Connection failed: ${c} ${u}`
280
+ `Connection failed: ${y} ${p}`
273
281
  );
274
282
  r.send(d, { binary: true });
275
283
  }
276
284
  }
277
- n.pendingFrames.delete(t);
278
- }), i.on("error", (c) => {
279
- if (!n.pendingFrames.has(t)) return;
280
- const u = String(c), y = Date.now() - f;
281
- e.warn(`[relay-proxy] relay socket error for ${t} after ${y}ms: ${u}`), u.includes("403") && e.warn(`[relay-proxy] 403 Forbidden from ${t} - relay may require NIP-42 auth or block this connection`), n.pendingFrames.delete(t);
285
+ t.pendingFrames.delete(n);
286
+ }), i.on("error", (y) => {
287
+ if (!t.pendingFrames.has(n)) return;
288
+ const p = String(y), l = Date.now() - u;
289
+ e.warn(`[relay-proxy] relay socket error for ${n} after ${l}ms: ${p}`), p.includes("403") && e.warn(`[relay-proxy] 403 Forbidden from ${n} - relay may require NIP-42 auth or block this connection`), t.pendingFrames.delete(n);
282
290
  });
283
291
  }
284
- function P(n, r, t) {
285
- if (t) {
286
- if (n.lastSubIdByRelay.set(r, t.subId), t.type === "REQ") {
287
- const e = t.subId;
288
- n.dedupBySubId.has(e) || n.dedupBySubId.set(e, /* @__PURE__ */ new Set());
292
+ function _(t, r, n) {
293
+ if (n) {
294
+ if (t.lastSubIdByRelay.set(r, n.subId), n.type === "REQ") {
295
+ const e = n.subId;
296
+ t.dedupBySubId.has(e) || t.dedupBySubId.set(e, /* @__PURE__ */ new Set());
289
297
  return;
290
298
  }
291
- n.dedupBySubId.delete(t.subId);
299
+ t.dedupBySubId.delete(n.subId);
292
300
  }
293
301
  }
294
- function W(n) {
295
- const r = R(n);
302
+ function L(t) {
303
+ const r = R(t);
296
304
  if (!r) return null;
297
- const t = r[0];
298
- if (t !== "REQ" && t !== "CLOSE") return null;
305
+ const n = r[0];
306
+ if (n !== "REQ" && n !== "CLOSE") return null;
299
307
  const e = typeof r[1] == "string" ? r[1] : null;
300
- return e ? { type: t, subId: e } : null;
308
+ return e ? { type: n, subId: e } : null;
301
309
  }
302
- function C(n, r, t, e) {
303
- const o = n.relaySockets.get(r);
304
- if (!o) {
310
+ function P(t, r, n, e) {
311
+ const s = t.relaySockets.get(r);
312
+ if (!s) {
305
313
  e.warn(`[relay-proxy] no relay socket for ${r}`);
306
314
  return;
307
315
  }
308
- if (o.readyState === g.OPEN) {
309
- e.info(`[relay-proxy] sending frame to ${r} (OPEN): ${t.slice(0, 100)}`), o.send(t);
316
+ if (s.readyState === m.OPEN) {
317
+ e.info(`[relay-proxy] sending frame to ${r} (OPEN): ${n.slice(0, 100)}`), s.send(n);
310
318
  return;
311
319
  }
312
- if (o.readyState === g.CONNECTING) {
320
+ if (s.readyState === m.CONNECTING) {
313
321
  e.info(`[relay-proxy] queueing frame for ${r} (CONNECTING)`);
314
- const s = n.pendingFrames.get(r) ?? [];
315
- s.push(t), n.pendingFrames.set(r, s);
322
+ const o = t.pendingFrames.get(r) ?? [];
323
+ o.push(n), t.pendingFrames.set(r, o);
316
324
  return;
317
325
  }
318
- e.warn(`[relay-proxy] dropping frame for closed relay socket ${r} (state: ${o.readyState})`);
326
+ e.warn(`[relay-proxy] dropping frame for closed relay socket ${r} (state: ${s.readyState})`);
319
327
  }
320
- function _(n, r, t, e, o) {
321
- const s = R(t);
322
- if (!s || s.length < 1 || typeof s[0] != "string")
323
- return O(e ?? "", r, t);
324
- const a = s[0];
325
- if (a === "EVENT") {
326
- const i = typeof s[1] == "string" ? s[1] : "", f = J(s[2]);
327
- if (!i || !f)
328
- return O(i, r, t);
329
- const c = n.dedupBySubId.get(i);
330
- return c && c.has(f.id) ? null : (c && c.add(f.id), L(i, r, f));
328
+ function H(t, r, n, e, s) {
329
+ const o = R(n);
330
+ if (!o || o.length < 1 || typeof o[0] != "string")
331
+ return O(e ?? "", r, n);
332
+ const f = o[0];
333
+ if (f === "EVENT") {
334
+ const a = typeof o[1] == "string" ? o[1] : "", c = J(o[2]);
335
+ if (!a || !c)
336
+ return O(a, r, n);
337
+ const i = t.dedupBySubId.get(a);
338
+ return i && i.has(c.id) ? null : (i && i.add(c.id), D(a, r, c));
331
339
  }
332
- if (a === "NOTICE") {
333
- const i = s[1] === void 0 ? null : String(s[1]);
334
- return S("", r, "NOTICE", i);
340
+ if (f === "NOTICE") {
341
+ const a = o[1] === void 0 ? null : String(o[1]);
342
+ return S("", r, "NOTICE", a);
335
343
  }
336
- if (a === "AUTH") {
337
- const i = s[1] === void 0 ? null : String(s[1]);
338
- o == null ? void 0 : o.info(`[relay-proxy] received AUTH challenge from ${r}: ${i}`);
339
- const f = S(e ?? "", r, "AUTH", i);
340
- return o == null ? void 0 : o.info(`[relay-proxy] built AUTH worker message (${f.length} bytes)`), f;
344
+ if (f === "AUTH") {
345
+ const a = o[1] === void 0 ? null : String(o[1]), c = Date.now(), i = t.lastAuthChallenge.get(r);
346
+ if (i) {
347
+ const y = c - i.timestamp;
348
+ if (i.challenge === a && y < 5e3)
349
+ return s == null ? void 0 : s.info(`[relay-proxy] dropping duplicate AUTH from ${r} (${y}ms ago)`), null;
350
+ if (y < 1e3)
351
+ return s == null ? void 0 : s.info(`[relay-proxy] rate limiting AUTH from ${r} (${y}ms since last)`), null;
352
+ }
353
+ t.lastAuthChallenge.set(r, { challenge: a, timestamp: c }), s == null ? void 0 : s.info(`[relay-proxy] received AUTH challenge from ${r}: ${a}`);
354
+ const u = S(e ?? "", r, "AUTH", a);
355
+ return s == null ? void 0 : s.info(`[relay-proxy] built AUTH worker message (${u.length} bytes)`), u;
341
356
  }
342
- if (a === "CLOSED") {
343
- const i = typeof s[1] == "string" ? s[1] : "", f = s[2] === void 0 ? null : String(s[2]);
344
- return S(i, r, "CLOSED", f);
357
+ if (f === "CLOSED") {
358
+ const a = typeof o[1] == "string" ? o[1] : "", c = o[2] === void 0 ? null : String(o[2]);
359
+ return S(a, r, "CLOSED", c);
345
360
  }
346
- if (a === "OK") {
347
- const i = typeof s[1] == "string" ? s[1] : "", f = s[2] === void 0 ? "false" : String(s[2]), c = s[3] === void 0 ? null : String(s[3]);
348
- return S(i, r, f, c);
361
+ if (f === "OK") {
362
+ const a = typeof o[1] == "string" ? o[1] : "", c = o[2] === void 0 ? "false" : String(o[2]), i = o[3] === void 0 ? null : String(o[3]);
363
+ return S(a, r, c, i);
349
364
  }
350
- if (a === "EOSE") {
351
- const i = typeof s[1] == "string" ? s[1] : "";
352
- return S(i, r, "EOSE", null);
365
+ if (f === "EOSE") {
366
+ const a = typeof o[1] == "string" ? o[1] : "";
367
+ return S(a, r, "EOSE", null);
353
368
  }
354
- return O(e ?? "", r, t);
369
+ return O(e ?? "", r, n);
355
370
  }
356
- function L(n, r, t) {
357
- const e = new E.Builder(1024), o = n ? e.createString(n) : 0, s = e.createString(r), a = e.createString(t.id), i = e.createString(t.pubkey), f = e.createString(t.content), c = e.createString(t.sig), u = new Array(t.tags.length);
358
- for (let m = 0; m < t.tags.length; m++)
359
- u[m] = V(e, t.tags[m]);
360
- const y = N.createTagsVector(e, u), d = N.createNostrEvent(
371
+ function D(t, r, n) {
372
+ const e = new A.Builder(1024), s = t ? e.createString(t) : 0, o = e.createString(r), f = e.createString(n.id), a = e.createString(n.pubkey), c = e.createString(n.content), i = e.createString(n.sig), u = new Array(n.tags.length);
373
+ for (let d = 0; d < n.tags.length; d++)
374
+ u[d] = V(e, n.tags[d]);
375
+ const y = C.createTagsVector(e, u), p = C.createNostrEvent(
361
376
  e,
362
- a,
363
- i,
364
- t.kind,
365
377
  f,
378
+ a,
379
+ n.kind,
380
+ c,
366
381
  y,
367
- t.created_at,
368
- c
369
- ), l = M.createWorkerMessage(
382
+ n.created_at,
383
+ i
384
+ ), l = E.createWorkerMessage(
370
385
  e,
371
- o,
372
386
  s,
373
- A.NostrEvent,
374
- I.NostrEvent,
375
- d
387
+ o,
388
+ k.NostrEvent,
389
+ M.NostrEvent,
390
+ p
376
391
  );
377
392
  return e.finish(l), e.asUint8Array();
378
393
  }
379
- function S(n, r, t, e) {
380
- const o = new E.Builder(256), s = n ? o.createString(n) : 0, a = o.createString(r), i = o.createString(t), f = e === null ? 0 : o.createString(e), c = v.createConnectionStatus(
381
- o,
382
- a,
383
- i,
384
- f
385
- ), u = M.createWorkerMessage(
386
- o,
394
+ function S(t, r, n, e) {
395
+ const s = new A.Builder(256), o = t ? s.createString(t) : 0, f = s.createString(r), a = s.createString(n), c = e === null ? 0 : s.createString(e), i = T.createConnectionStatus(
387
396
  s,
397
+ f,
388
398
  a,
389
- A.ConnectionStatus,
390
- I.ConnectionStatus,
391
399
  c
400
+ ), u = E.createWorkerMessage(
401
+ s,
402
+ o,
403
+ f,
404
+ k.ConnectionStatus,
405
+ M.ConnectionStatus,
406
+ i
392
407
  );
393
- return o.finish(u), o.asUint8Array();
408
+ return s.finish(u), s.asUint8Array();
394
409
  }
395
- function O(n, r, t) {
396
- const e = new E.Builder(256), o = n ? e.createString(n) : 0, s = e.createString(r), a = e.createString(t), i = F.createRaw(e, a), f = M.createWorkerMessage(
410
+ function O(t, r, n) {
411
+ const e = new A.Builder(256), s = t ? e.createString(t) : 0, o = e.createString(r), f = e.createString(n), a = F.createRaw(e, f), c = E.createWorkerMessage(
397
412
  e,
398
- o,
399
413
  s,
400
- A.Raw,
401
- I.Raw,
402
- i
414
+ o,
415
+ k.Raw,
416
+ M.Raw,
417
+ a
403
418
  );
404
- return e.finish(f), e.asUint8Array();
419
+ return e.finish(c), e.asUint8Array();
405
420
  }
406
- function J(n) {
407
- if (!n || typeof n != "object") return null;
408
- const r = n;
421
+ function J(t) {
422
+ if (!t || typeof t != "object") return null;
423
+ const r = t;
409
424
  if (typeof r.id != "string" || typeof r.pubkey != "string" || typeof r.kind != "number" || typeof r.content != "string" || typeof r.created_at != "number" || typeof r.sig != "string" || !Array.isArray(r.tags))
410
425
  return null;
411
- const t = r.tags;
426
+ const n = r.tags;
412
427
  let e = false;
413
- for (const s of t) {
414
- if (!Array.isArray(s) || s.length === 0) {
428
+ for (const o of n) {
429
+ if (!Array.isArray(o) || o.length === 0) {
415
430
  e = true;
416
431
  continue;
417
432
  }
418
- for (const a of s)
419
- if (typeof a != "string") {
433
+ for (const f of o)
434
+ if (typeof f != "string") {
420
435
  e = true;
421
436
  break;
422
437
  }
423
438
  }
424
- let o;
439
+ let s;
425
440
  if (!e)
426
- o = t;
441
+ s = n;
427
442
  else {
428
- o = [];
429
- for (const s of t) {
430
- if (!Array.isArray(s)) continue;
431
- const a = [];
432
- for (const i of s)
433
- typeof i == "string" && a.push(i);
434
- a.length > 0 && o.push(a);
443
+ s = [];
444
+ for (const o of n) {
445
+ if (!Array.isArray(o)) continue;
446
+ const f = [];
447
+ for (const a of o)
448
+ typeof a == "string" && f.push(a);
449
+ f.length > 0 && s.push(f);
435
450
  }
436
451
  }
437
452
  return {
@@ -441,63 +456,63 @@ function J(n) {
441
456
  content: r.content,
442
457
  created_at: r.created_at,
443
458
  sig: r.sig,
444
- tags: o
459
+ tags: s
445
460
  };
446
461
  }
447
- function V(n, r) {
448
- const t = new Array(r.length);
449
- for (let o = 0; o < r.length; o++)
450
- t[o] = n.createString(r[o]);
451
- const e = k.createItemsVector(n, t);
452
- return k.createStringVec(n, e);
462
+ function V(t, r) {
463
+ const n = new Array(r.length);
464
+ for (let s = 0; s < r.length; s++)
465
+ n[s] = t.createString(r[s]);
466
+ const e = N.createItemsVector(t, n);
467
+ return N.createStringVec(t, e);
453
468
  }
454
- function R(n) {
469
+ function R(t) {
455
470
  try {
456
- const r = JSON.parse(n);
471
+ const r = JSON.parse(t);
457
472
  return Array.isArray(r) ? r : null;
458
473
  } catch {
459
474
  return null;
460
475
  }
461
476
  }
462
- function x(n, r) {
463
- const t = w(n);
464
- if (!t)
477
+ function $(t, r) {
478
+ const n = h(t);
479
+ if (!n)
465
480
  return null;
466
481
  try {
467
- const e = JSON.parse(t);
482
+ const e = JSON.parse(n);
468
483
  if (!Array.isArray(e.relays) || !Array.isArray(e.frames))
469
484
  return r == null ? void 0 : r.warn(`[relay-proxy] parseEnvelope: invalid structure (relays: ${Array.isArray(e.relays)}, frames: ${Array.isArray(e.frames)})`), null;
470
- const o = e.relays.filter((a) => typeof a == "string"), s = e.frames.filter((a) => typeof a == "string");
471
- return r == null ? void 0 : r.info(`[relay-proxy] parseEnvelope: ${o.length} relays, ${s.length} frames`), o.length === 0 || s.length === 0 ? (r == null ? void 0 : r.warn("[relay-proxy] parseEnvelope: empty relays or frames after filter"), null) : { relays: o, frames: s };
485
+ const s = e.relays.filter((f) => typeof f == "string"), o = e.frames.filter((f) => typeof f == "string");
486
+ return r == null ? void 0 : r.info(`[relay-proxy] parseEnvelope: ${s.length} relays, ${o.length} frames`), s.length === 0 || o.length === 0 ? (r == null ? void 0 : r.warn("[relay-proxy] parseEnvelope: empty relays or frames after filter"), null) : { relays: s, frames: o };
472
487
  } catch {
473
488
  return null;
474
489
  }
475
490
  }
476
- function w(n) {
477
- return typeof n == "string" ? n : n instanceof ArrayBuffer ? Buffer.from(n).toString("utf8") : Buffer.isBuffer(n) ? n.toString("utf8") : n instanceof Uint8Array ? Buffer.from(n).toString("utf8") : Array.isArray(n) ? Buffer.concat(n.filter((r) => Buffer.isBuffer(r))).toString("utf8") : "";
491
+ function h(t) {
492
+ return typeof t == "string" ? t : t instanceof ArrayBuffer ? Buffer.from(t).toString("utf8") : Buffer.isBuffer(t) ? t.toString("utf8") : t instanceof Uint8Array ? Buffer.from(t).toString("utf8") : Array.isArray(t) ? Buffer.concat(t.filter((r) => Buffer.isBuffer(r))).toString("utf8") : "";
478
493
  }
479
- function j(n) {
480
- if (!n || typeof n != "object") return false;
481
- const r = n;
494
+ function j(t) {
495
+ if (!t || typeof t != "object") return false;
496
+ const r = t;
482
497
  return r.type === "auth_response" && typeof r.relay == "string" && r.event !== void 0;
483
498
  }
484
- function D(n) {
485
- if (!n || typeof n != "object") return false;
486
- const r = n;
499
+ function G(t) {
500
+ if (!t || typeof t != "object") return false;
501
+ const r = t;
487
502
  return r.type === "close_sub" && typeof r.subscription_id == "string";
488
503
  }
489
- function p(n, r) {
490
- r == null ? void 0 : r.info("[relay-proxy] closing session"), n.dedupBySubId.clear(), n.lastSubIdByRelay.clear();
491
- for (const [t, e] of n.relaySockets.entries())
504
+ function g(t, r) {
505
+ r == null ? void 0 : r.info("[relay-proxy] closing session"), t.dedupBySubId.clear(), t.lastSubIdByRelay.clear();
506
+ for (const [n, e] of t.relaySockets.entries())
492
507
  try {
493
- r == null ? void 0 : r.info(`[relay-proxy] closing socket to ${t}`), e.close();
508
+ r == null ? void 0 : r.info(`[relay-proxy] closing socket to ${n}`), e.close();
494
509
  } catch {
495
510
  }
496
- n.relaySockets.clear(), n.pendingFrames.clear();
511
+ t.relaySockets.clear(), t.pendingFrames.clear();
497
512
  }
498
513
  export {
499
- K as attachRelayProxyToServer,
500
- q as createExpressRelayProxyMiddleware,
501
- z as createRelayProxyServer,
502
- Q as createRelayProxyWebSocketServer
514
+ Y as attachRelayProxyToServer,
515
+ Z as createExpressRelayProxyMiddleware,
516
+ q as createRelayProxyServer,
517
+ X as createRelayProxyWebSocketServer
503
518
  };