@nostrify/nostrify 0.50.4 → 0.51.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/.turbo/turbo-build.log +36 -32
- package/.turbo/turbo-test.log +134 -114
- package/.turbo/turbo-typecheck.log +8 -6
- package/CHANGELOG.md +14 -0
- package/NIP05.ts +1 -1
- package/NPool.ts +1 -1
- package/NRelay1.test.ts +215 -3
- package/NRelay1.ts +81 -4
- package/dist/NIP05.js +1 -1
- package/dist/NPool.js +1 -1
- package/dist/NRelay1.d.ts +14 -0
- package/dist/NRelay1.d.ts.map +1 -1
- package/dist/NRelay1.js +65 -5
- package/dist/test/TestRelayServer.d.ts +2 -0
- package/dist/test/TestRelayServer.d.ts.map +1 -1
- package/dist/test/TestRelayServer.js +9 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/uploaders/BlossomUploader.d.ts.map +1 -1
- package/dist/uploaders/BlossomUploader.js +37 -24
- package/dist/utils/getFilterLimit.d.ts +15 -0
- package/dist/utils/getFilterLimit.d.ts.map +1 -0
- package/dist/utils/getFilterLimit.js +40 -0
- package/package.json +1 -1
- package/test/TestRelayServer.ts +10 -0
- package/uploaders/BlossomUploader.ts +45 -29
- package/utils/getFilterLimit.test.ts +74 -0
- package/utils/getFilterLimit.ts +69 -0
package/NRelay1.ts
CHANGED
|
@@ -13,7 +13,9 @@ import type {
|
|
|
13
13
|
NostrRelayInfo,
|
|
14
14
|
NRelay,
|
|
15
15
|
} from '@nostrify/types';
|
|
16
|
-
import {
|
|
16
|
+
import { matchFilters, verifyEvent as _verifyEvent } from 'nostr-tools';
|
|
17
|
+
|
|
18
|
+
import { getFilterLimit } from './utils/getFilterLimit.ts';
|
|
17
19
|
import { ArrayQueue, ExponentialBackoff, Websocket, WebsocketBuilder, WebsocketEvent } from 'websocket-ts';
|
|
18
20
|
import type { Backoff } from 'websocket-ts';
|
|
19
21
|
|
|
@@ -63,6 +65,15 @@ export class NRelay1 implements NRelay {
|
|
|
63
65
|
private opts: NRelay1Opts;
|
|
64
66
|
private relayInfoPromise?: Promise<NostrRelayInfo | undefined>;
|
|
65
67
|
|
|
68
|
+
/** Promise that resolves when the current AUTH flow completes. */
|
|
69
|
+
private authPromise?: Promise<void>;
|
|
70
|
+
/** Set of subscription IDs that have already been retried after auth, to prevent infinite loops. */
|
|
71
|
+
private authRetriedSubs = new Set<string>();
|
|
72
|
+
/** Set of event IDs that have already been retried after auth, to prevent infinite loops. */
|
|
73
|
+
private authRetriedEvents = new Set<string>();
|
|
74
|
+
/** Pending events waiting for AUTH, keyed by event ID. */
|
|
75
|
+
private pendingEvents = new Map<string, NostrEvent>();
|
|
76
|
+
|
|
66
77
|
private ee = new EventTarget();
|
|
67
78
|
|
|
68
79
|
get subscriptions(): readonly NostrClientREQ[] {
|
|
@@ -239,7 +250,12 @@ export class NRelay1 implements NRelay {
|
|
|
239
250
|
);
|
|
240
251
|
break;
|
|
241
252
|
case 'CLOSED':
|
|
253
|
+
if (auth && msg[2].startsWith('auth-required:') && !this.authRetriedSubs.has(msg[1])) {
|
|
254
|
+
this.retrySubAfterAuth(msg[1]);
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
242
257
|
this.subs.delete(msg[1]);
|
|
258
|
+
this.authRetriedSubs.delete(msg[1]);
|
|
243
259
|
this.maybeStartIdleTimer();
|
|
244
260
|
this.ee.dispatchEvent(
|
|
245
261
|
new CustomEvent(`sub:${msg[1]}`, { detail: msg }),
|
|
@@ -249,6 +265,12 @@ export class NRelay1 implements NRelay {
|
|
|
249
265
|
);
|
|
250
266
|
break;
|
|
251
267
|
case 'OK':
|
|
268
|
+
if (auth && !msg[2] && msg[3].startsWith('auth-required:') && !this.authRetriedEvents.has(msg[1])) {
|
|
269
|
+
this.retryEventAfterAuth(msg[1]);
|
|
270
|
+
break;
|
|
271
|
+
}
|
|
272
|
+
this.pendingEvents.delete(msg[1]);
|
|
273
|
+
this.authRetriedEvents.delete(msg[1]);
|
|
252
274
|
this.ee.dispatchEvent(new CustomEvent(`ok:${msg[1]}`, { detail: msg }));
|
|
253
275
|
break;
|
|
254
276
|
case 'NOTICE':
|
|
@@ -260,9 +282,62 @@ export class NRelay1 implements NRelay {
|
|
|
260
282
|
);
|
|
261
283
|
break;
|
|
262
284
|
case 'AUTH':
|
|
263
|
-
auth
|
|
264
|
-
|
|
265
|
-
|
|
285
|
+
if (auth) {
|
|
286
|
+
this.authPromise = this.doAuth(auth, msg[1]);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/** Perform NIP-42 authentication and wait for the relay's OK response. */
|
|
292
|
+
private async doAuth(auth: (challenge: string) => Promise<NostrEvent>, challenge: string): Promise<void> {
|
|
293
|
+
try {
|
|
294
|
+
const event = await auth(challenge);
|
|
295
|
+
const result = this.once(`ok:${event.id}`);
|
|
296
|
+
this.send(['AUTH', event]);
|
|
297
|
+
const [, , ok] = await result;
|
|
298
|
+
if (!ok) {
|
|
299
|
+
this.log({ level: 'warn', ns: 'relay.auth', message: 'AUTH failed' });
|
|
300
|
+
}
|
|
301
|
+
} catch {
|
|
302
|
+
// AUTH failed, nothing to do
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/** Re-send a subscription after AUTH completes. */
|
|
307
|
+
private async retrySubAfterAuth(subscriptionId: string): Promise<void> {
|
|
308
|
+
const req = this.subs.get(subscriptionId);
|
|
309
|
+
if (!req) return;
|
|
310
|
+
|
|
311
|
+
this.authRetriedSubs.add(subscriptionId);
|
|
312
|
+
|
|
313
|
+
try {
|
|
314
|
+
await this.authPromise;
|
|
315
|
+
} catch {
|
|
316
|
+
// AUTH failed — fall through to let the CLOSED propagate
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Re-send the original REQ if the subscription is still active.
|
|
320
|
+
if (this.subs.has(subscriptionId)) {
|
|
321
|
+
this.send(req);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/** Re-send an event after AUTH completes. */
|
|
326
|
+
private async retryEventAfterAuth(eventId: string): Promise<void> {
|
|
327
|
+
const event = this.pendingEvents.get(eventId);
|
|
328
|
+
if (!event) return;
|
|
329
|
+
|
|
330
|
+
this.authRetriedEvents.add(eventId);
|
|
331
|
+
|
|
332
|
+
try {
|
|
333
|
+
await this.authPromise;
|
|
334
|
+
} catch {
|
|
335
|
+
// AUTH failed — fall through to let the failed OK propagate
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Re-send the event if it's still pending.
|
|
339
|
+
if (this.pendingEvents.has(eventId)) {
|
|
340
|
+
this.send(['EVENT', event]);
|
|
266
341
|
}
|
|
267
342
|
}
|
|
268
343
|
|
|
@@ -280,6 +355,8 @@ export class NRelay1 implements NRelay {
|
|
|
280
355
|
this.maybeStartIdleTimer();
|
|
281
356
|
break;
|
|
282
357
|
case 'EVENT':
|
|
358
|
+
this.pendingEvents.set(msg[1].id, msg[1]);
|
|
359
|
+
return this.socket.send(JSON.stringify(msg));
|
|
283
360
|
case 'COUNT':
|
|
284
361
|
return this.socket.send(JSON.stringify(msg));
|
|
285
362
|
}
|
package/dist/NIP05.js
CHANGED
|
@@ -2,7 +2,7 @@ import { NSchema as n, z } from "./NSchema.js";
|
|
|
2
2
|
class NIP05 {
|
|
3
3
|
/** NIP-05 value regex. */
|
|
4
4
|
static regex() {
|
|
5
|
-
return /^(?:([\w.+-]+)@)?([\w
|
|
5
|
+
return /^(?:([\w.+-]+)@)?((?:[\w-]+\.)+[\w-]+)$/;
|
|
6
6
|
}
|
|
7
7
|
/** Nostr pubkey with relays object. */
|
|
8
8
|
static profilePointerSchema() {
|
package/dist/NPool.js
CHANGED
package/dist/NRelay1.d.ts
CHANGED
|
@@ -33,6 +33,14 @@ export declare class NRelay1 implements NRelay {
|
|
|
33
33
|
private url;
|
|
34
34
|
private opts;
|
|
35
35
|
private relayInfoPromise?;
|
|
36
|
+
/** Promise that resolves when the current AUTH flow completes. */
|
|
37
|
+
private authPromise?;
|
|
38
|
+
/** Set of subscription IDs that have already been retried after auth, to prevent infinite loops. */
|
|
39
|
+
private authRetriedSubs;
|
|
40
|
+
/** Set of event IDs that have already been retried after auth, to prevent infinite loops. */
|
|
41
|
+
private authRetriedEvents;
|
|
42
|
+
/** Pending events waiting for AUTH, keyed by event ID. */
|
|
43
|
+
private pendingEvents;
|
|
36
44
|
private ee;
|
|
37
45
|
get subscriptions(): readonly NostrClientREQ[];
|
|
38
46
|
private log;
|
|
@@ -47,6 +55,12 @@ export declare class NRelay1 implements NRelay {
|
|
|
47
55
|
private createSocket;
|
|
48
56
|
/** Handle a NIP-01 relay message. */
|
|
49
57
|
protected receive(msg: NostrRelayMsg): void;
|
|
58
|
+
/** Perform NIP-42 authentication and wait for the relay's OK response. */
|
|
59
|
+
private doAuth;
|
|
60
|
+
/** Re-send a subscription after AUTH completes. */
|
|
61
|
+
private retrySubAfterAuth;
|
|
62
|
+
/** Re-send an event after AUTH completes. */
|
|
63
|
+
private retryEventAfterAuth;
|
|
50
64
|
/** Send a NIP-01 client message to the relay. */
|
|
51
65
|
protected send(msg: NostrClientMsg): void;
|
|
52
66
|
req(filters: NostrFilter[], opts?: {
|
package/dist/NRelay1.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NRelay1.d.ts","sourceRoot":"","sources":["../NRelay1.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACd,UAAU,EACV,WAAW,EACX,gBAAgB,EAEhB,cAAc,EACd,eAAe,EACf,aAAa,EAGb,cAAc,EACd,MAAM,EACP,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"NRelay1.d.ts","sourceRoot":"","sources":["../NRelay1.ts"],"names":[],"mappings":"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"}
|
package/dist/NRelay1.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { matchFilters, verifyEvent as _verifyEvent } from "nostr-tools";
|
|
2
|
+
import { getFilterLimit } from "./utils/getFilterLimit.js";
|
|
2
3
|
import { ArrayQueue, ExponentialBackoff, WebsocketBuilder, WebsocketEvent } from "websocket-ts";
|
|
3
4
|
import { Machina } from "./utils/Machina.js";
|
|
4
5
|
import { NSchema as n } from "./NSchema.js";
|
|
@@ -12,6 +13,14 @@ class NRelay1 {
|
|
|
12
13
|
url;
|
|
13
14
|
opts;
|
|
14
15
|
relayInfoPromise;
|
|
16
|
+
/** Promise that resolves when the current AUTH flow completes. */
|
|
17
|
+
authPromise;
|
|
18
|
+
/** Set of subscription IDs that have already been retried after auth, to prevent infinite loops. */
|
|
19
|
+
authRetriedSubs = /* @__PURE__ */ new Set();
|
|
20
|
+
/** Set of event IDs that have already been retried after auth, to prevent infinite loops. */
|
|
21
|
+
authRetriedEvents = /* @__PURE__ */ new Set();
|
|
22
|
+
/** Pending events waiting for AUTH, keyed by event ID. */
|
|
23
|
+
pendingEvents = /* @__PURE__ */ new Map();
|
|
15
24
|
ee = new EventTarget();
|
|
16
25
|
get subscriptions() {
|
|
17
26
|
return [...this.subs.values()];
|
|
@@ -162,7 +171,12 @@ class NRelay1 {
|
|
|
162
171
|
);
|
|
163
172
|
break;
|
|
164
173
|
case "CLOSED":
|
|
174
|
+
if (auth && msg[2].startsWith("auth-required:") && !this.authRetriedSubs.has(msg[1])) {
|
|
175
|
+
this.retrySubAfterAuth(msg[1]);
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
165
178
|
this.subs.delete(msg[1]);
|
|
179
|
+
this.authRetriedSubs.delete(msg[1]);
|
|
166
180
|
this.maybeStartIdleTimer();
|
|
167
181
|
this.ee.dispatchEvent(
|
|
168
182
|
new CustomEvent(`sub:${msg[1]}`, { detail: msg })
|
|
@@ -172,6 +186,12 @@ class NRelay1 {
|
|
|
172
186
|
);
|
|
173
187
|
break;
|
|
174
188
|
case "OK":
|
|
189
|
+
if (auth && !msg[2] && msg[3].startsWith("auth-required:") && !this.authRetriedEvents.has(msg[1])) {
|
|
190
|
+
this.retryEventAfterAuth(msg[1]);
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
this.pendingEvents.delete(msg[1]);
|
|
194
|
+
this.authRetriedEvents.delete(msg[1]);
|
|
175
195
|
this.ee.dispatchEvent(new CustomEvent(`ok:${msg[1]}`, { detail: msg }));
|
|
176
196
|
break;
|
|
177
197
|
case "NOTICE":
|
|
@@ -183,10 +203,48 @@ class NRelay1 {
|
|
|
183
203
|
);
|
|
184
204
|
break;
|
|
185
205
|
case "AUTH":
|
|
186
|
-
auth
|
|
187
|
-
()
|
|
188
|
-
|
|
189
|
-
|
|
206
|
+
if (auth) {
|
|
207
|
+
this.authPromise = this.doAuth(auth, msg[1]);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/** Perform NIP-42 authentication and wait for the relay's OK response. */
|
|
212
|
+
async doAuth(auth, challenge) {
|
|
213
|
+
try {
|
|
214
|
+
const event = await auth(challenge);
|
|
215
|
+
const result = this.once(`ok:${event.id}`);
|
|
216
|
+
this.send(["AUTH", event]);
|
|
217
|
+
const [, , ok] = await result;
|
|
218
|
+
if (!ok) {
|
|
219
|
+
this.log({ level: "warn", ns: "relay.auth", message: "AUTH failed" });
|
|
220
|
+
}
|
|
221
|
+
} catch {
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/** Re-send a subscription after AUTH completes. */
|
|
225
|
+
async retrySubAfterAuth(subscriptionId) {
|
|
226
|
+
const req = this.subs.get(subscriptionId);
|
|
227
|
+
if (!req) return;
|
|
228
|
+
this.authRetriedSubs.add(subscriptionId);
|
|
229
|
+
try {
|
|
230
|
+
await this.authPromise;
|
|
231
|
+
} catch {
|
|
232
|
+
}
|
|
233
|
+
if (this.subs.has(subscriptionId)) {
|
|
234
|
+
this.send(req);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/** Re-send an event after AUTH completes. */
|
|
238
|
+
async retryEventAfterAuth(eventId) {
|
|
239
|
+
const event = this.pendingEvents.get(eventId);
|
|
240
|
+
if (!event) return;
|
|
241
|
+
this.authRetriedEvents.add(eventId);
|
|
242
|
+
try {
|
|
243
|
+
await this.authPromise;
|
|
244
|
+
} catch {
|
|
245
|
+
}
|
|
246
|
+
if (this.pendingEvents.has(eventId)) {
|
|
247
|
+
this.send(["EVENT", event]);
|
|
190
248
|
}
|
|
191
249
|
}
|
|
192
250
|
/** Send a NIP-01 client message to the relay. */
|
|
@@ -202,6 +260,8 @@ class NRelay1 {
|
|
|
202
260
|
this.maybeStartIdleTimer();
|
|
203
261
|
break;
|
|
204
262
|
case "EVENT":
|
|
263
|
+
this.pendingEvents.set(msg[1].id, msg[1]);
|
|
264
|
+
return this.socket.send(JSON.stringify(msg));
|
|
205
265
|
case "COUNT":
|
|
206
266
|
return this.socket.send(JSON.stringify(msg));
|
|
207
267
|
}
|
|
@@ -20,6 +20,8 @@ export declare class TestRelayServer {
|
|
|
20
20
|
get url(): string;
|
|
21
21
|
close(): Promise<void>;
|
|
22
22
|
open(): Promise<void>;
|
|
23
|
+
/** Close all active WebSocket connections without shutting down the server. */
|
|
24
|
+
dropConnections(): void;
|
|
23
25
|
event(event: NostrEvent): Promise<void>;
|
|
24
26
|
[Symbol.asyncDispose](): Promise<void>;
|
|
25
27
|
static create(opts?: TestRelayServerOpts): Promise<TestRelayServer>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TestRelayServer.d.ts","sourceRoot":"","sources":["../../test/TestRelayServer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEjF,OAAO,EAAE,SAAS,EAAmB,MAAM,IAAI,CAAC;AAKhD,UAAU,mBAAmB;IAC3B,aAAa,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC9E;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,IAAI,CAAsB;IAClC,OAAO,CAAC,WAAW,CAAwB;IAC3C,OAAO,CAAC,WAAW,CAAsC;IACzD,OAAO,CAAC,KAAK,CAAmB;gBAEpB,IAAI,CAAC,EAAE,mBAAmB;IAOtC,IAAI;IAWJ,OAAO,CAAC,oBAAoB;IAgC5B,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,GAAG,IAAI;YAOnC,aAAa;IA2C3B,IAAI,GAAG,IAAI,MAAM,CAIhB;IAGK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB5B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBrB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjC,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;WAM/B,MAAM,CAAC,IAAI,CAAC,EAAE,mBAAmB;CAK/C"}
|
|
1
|
+
{"version":3,"file":"TestRelayServer.d.ts","sourceRoot":"","sources":["../../test/TestRelayServer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEjF,OAAO,EAAE,SAAS,EAAmB,MAAM,IAAI,CAAC;AAKhD,UAAU,mBAAmB;IAC3B,aAAa,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC9E;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,IAAI,CAAsB;IAClC,OAAO,CAAC,WAAW,CAAwB;IAC3C,OAAO,CAAC,WAAW,CAAsC;IACzD,OAAO,CAAC,KAAK,CAAmB;gBAEpB,IAAI,CAAC,EAAE,mBAAmB;IAOtC,IAAI;IAWJ,OAAO,CAAC,oBAAoB;IAgC5B,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,GAAG,IAAI;YAOnC,aAAa;IA2C3B,IAAI,GAAG,IAAI,MAAM,CAIhB;IAGK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB5B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBrB,+EAA+E;IAC/E,eAAe,IAAI,IAAI;IASvB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjC,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;WAM/B,MAAM,CAAC,IAAI,CAAC,EAAE,mBAAmB;CAK/C"}
|
|
@@ -129,6 +129,15 @@ class TestRelayServer {
|
|
|
129
129
|
}
|
|
130
130
|
return Promise.resolve();
|
|
131
131
|
}
|
|
132
|
+
/** Close all active WebSocket connections without shutting down the server. */
|
|
133
|
+
dropConnections() {
|
|
134
|
+
if (!this.inited) throw new Error("TestRelayServer not initialized");
|
|
135
|
+
this.connections.forEach((conn) => {
|
|
136
|
+
if (conn.readyState === WebSocket.OPEN) {
|
|
137
|
+
conn.close();
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
132
141
|
event(event) {
|
|
133
142
|
if (!this.inited) throw new Error("TestRelayServer not initialized");
|
|
134
143
|
return this.store.event(event);
|