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