@nostrify/nostrify 0.47.0 → 0.48.1

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,19 +1,32 @@
1
1
 
2
2
 
3
- > @nostrify/nostrify@0.46.9 build /home/sid/repos/nostrify/packages/nostrify
3
+ > @nostrify/nostrify@0.48.0 build /home/sid/repos/nostrify/packages/nostrify
4
4
  > npx tsc -p tsconfig.json && node ../../esbuild.config.js --package ./
5
5
 
6
6
  npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm.
7
7
  npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm.
8
- ⠙Building with esbuild...
8
+ ⠙⠙Building with esbuild...
9
9
 
10
- dist/NRelay1.js 8.9kb
11
- dist/NSchema.js 5.8kb
12
- dist/NPool.js 5.0kb
13
- dist/test/TestRelayServer.js 4.4kb
14
- dist/NSet.js 4.1kb
15
- ...and 25 more output files...
10
+ dist/NRelay1.js 8.9kb
11
+ dist/NSchema.js 5.8kb
12
+ dist/NPool.js 5.0kb
13
+ dist/test/TestRelayServer.js 4.4kb
14
+ dist/NSet.js 4.1kb
15
+ dist/NConnectSigner.js 3.9kb
16
+ dist/ln/LNURL.js 3.3kb
17
+ dist/NIP98.js 2.7kb
18
+ dist/NBrowserSigner.js 2.6kb
19
+ dist/uploaders/BlossomUploader.js 1.9kb
20
+ dist/uploaders/NostrBuildUploader.js 1.9kb
21
+ dist/test/MockRelay.js 1.4kb
22
+ dist/BunkerURI.js 1.4kb
23
+ dist/NKinds.js 1.1kb
24
+ dist/NIP05.js 1.1kb
25
+ dist/NSecSigner.js 1.1kb
26
+ dist/utils/Machina.js 925b 
27
+ dist/NCache.js 828b 
28
+ ...and 13 more output files...
16
29
 
17
- âšĦ Done in 24ms
30
+ âšĦ Done in 27ms
18
31
  Copying source files...
19
32
  Done!
@@ -1,91 +1,99 @@
1
1
 
2
2
 
3
- > @nostrify/nostrify@0.46.8 test /home/sid/repos/nostrify/packages/nostrify
3
+ > @nostrify/nostrify@0.48.0 test /home/sid/repos/nostrify/packages/nostrify
4
4
  > node --test "**/*.test.ts"
5
5
 
6
- ✔ BunkerURI (2.901722ms)
7
- ✔ BunkerURI.fromJSON (0.681727ms)
8
- ✔ NBrowserSigner - without extension (2.955361ms)
9
- ✔ NBrowserSigner - with extension polyfill (142.479686ms)
10
- ✔ NBrowserSigner.nip44 - with extension polyfill (63.176698ms)
11
- ✔ NBrowserSigner.nip04 - with extension polyfill (94.046199ms)
12
- ✔ NBrowserSigner.getRelays - with extension polyfill (1.225726ms)
13
- ✔ NBrowserSigner - missing nip44 support (0.470316ms)
14
- ✔ NBrowserSigner - missing nip04 support (0.596869ms)
15
- ✔ NBrowserSigner - feature detection (0.692134ms)
16
- ✔ NCache (4.463457ms)
17
- ✔ NConnectSigner.signEvent with nip04 encryption (264.497854ms)
18
- ✔ NConnectSigner.signEvent with nip44 encryption (151.108865ms)
19
- ✔ NIP05.lookup (82.449297ms)
20
- ✔ NIP05.lookup with invalid values but valid profile pointer (5.343535ms)
21
- ✔ NIP05.lookup with invalid document (5.910931ms)
22
- ✔ NIP50.parseInput (6.388441ms)
23
- ✔ NIP50.parseInput with negated token (0.443007ms)
24
- ✔ NIP98.template (3.769298ms)
25
- ✔ NIP98.template with payload (18.668676ms)
26
- ✔ NIP98.verify (102.562862ms)
27
- ✔ NIP98.verify fails with missing header (4.419038ms)
28
- ✔ NIP98.verify fails with missing token (2.752191ms)
29
- ✔ NIP98.verify fails with invalid token (4.587427ms)
30
- ✔ NIP98.verify fails with invalid event (16.989187ms)
31
- ✔ NIP98.verify fails with wrong event kind (40.621459ms)
32
- ✔ NIP98.verify fails with wrong request URL (41.071101ms)
33
- ✔ NIP98.verify fails with wrong request method (62.625645ms)
34
- ✔ NIP98.verify fails with expired event (20.760162ms)
35
- ✔ NIP98.verify fails with invalid payload (51.97091ms)
36
- ✔ NKinds (3.308412ms)
37
- ✔ NPool.query (368.093259ms)
38
- ✔ NPool.req (266.969001ms)
39
- ✔ NPool.event (232.161184ms)
40
- ✔ NRelay1.query (280.362725ms)
41
- ✔ NRelay1.query mismatched filter (245.542477ms)
42
- ✔ NRelay1.req (247.658198ms)
43
- ✔ NRelay1.event (216.357493ms)
44
- ïı£ NRelay1 backoff (0.334682ms) # SKIP
6
+ ✔ BunkerURI (8.032428ms)
7
+ ✔ BunkerURI.fromJSON (1.011522ms)
8
+ ✔ NBrowserSigner - without extension (10.371695ms)
9
+ ✔ NBrowserSigner - with extension polyfill (329.050343ms)
10
+ ✔ NBrowserSigner.nip44 - with extension polyfill (188.734388ms)
11
+ ✔ NBrowserSigner.nip04 - with extension polyfill (70.232955ms)
12
+ ✔ NBrowserSigner.getRelays - with extension polyfill (2.229952ms)
13
+ ✔ NBrowserSigner - missing nip44 support (5.683803ms)
14
+ ✔ NBrowserSigner - missing nip04 support (0.456198ms)
15
+ ✔ NBrowserSigner - feature detection (4.388092ms)
16
+ ✔ NCache (28.041794ms)
17
+ ✔ NConnectSigner.signEvent with nip04 encryption (357.348402ms)
18
+ ✔ NConnectSigner.signEvent with nip44 encryption (179.341911ms)
19
+ ✔ NIP05.lookup (110.840506ms)
20
+ ✔ NIP05.lookup with invalid values but valid profile pointer (6.688672ms)
21
+ ✔ NIP05.lookup with invalid document (6.384854ms)
22
+ ✔ NIP50.parseInput (5.363623ms)
23
+ ✔ NIP50.parseInput with negated token (0.425237ms)
24
+ ✔ NIP98.template (26.510529ms)
25
+ ✔ NIP98.template with payload (57.914746ms)
26
+ ✔ NIP98.verify (172.889905ms)
27
+ ✔ NIP98.verify fails with missing header (2.182248ms)
28
+ ✔ NIP98.verify fails with missing token (1.647725ms)
29
+ ✔ NIP98.verify fails with invalid token (1.945311ms)
30
+ ✔ NIP98.verify fails with invalid event (49.451318ms)
31
+ ✔ NIP98.verify fails with wrong event kind (70.598745ms)
32
+ ✔ NIP98.verify fails with wrong request URL (86.043572ms)
33
+ ✔ NIP98.verify fails with wrong request method (52.311711ms)
34
+ ✔ NIP98.verify fails with expired event (70.877534ms)
35
+ ✔ NIP98.verify fails with invalid payload (235.890385ms)
36
+ ✔ NIP98Client.fetch - basic GET request (204.607488ms)
37
+ ✔ NIP98Client.fetch - POST request with body (224.461879ms)
38
+ ✔ NIP98Client.fetch - with Request object input (110.155447ms)
39
+ ✔ NIP98Client.fetch - with URL object input (69.82442ms)
40
+ ✔ NIP98Client.fetch - uses default fetch when not provided (43.370412ms)
41
+ ✔ NIP98Client.fetch - preserves existing headers (75.087655ms)
42
+ ✔ NIP98Client.fetch - event can be verified with NIP98.verify (76.739559ms)
43
+ ✔ NIP98Client.fetch - handles different HTTP methods (226.588206ms)
44
+ ✔ NKinds (15.675591ms)
45
+ ✔ NPool.query (635.444667ms)
46
+ ✔ NPool.req (107.060121ms)
47
+ ✔ NPool.event (66.952535ms)
48
+ ✔ NRelay1.query (538.03435ms)
49
+ ✔ NRelay1.query mismatched filter (133.455243ms)
50
+ ✔ NRelay1.req (141.418776ms)
51
+ ✔ NRelay1.event (32.63963ms)
52
+ ïı£ NRelay1 backoff (1.106008ms) # SKIP
45
53
  â–ĥ NRelay1 idleTimeout
46
- ✔ websocket opens (40.531572ms)
47
- ✔ websocket closes after idleTimeout (150.405626ms)
48
- ✔ websocket wakes up during activity (14.544161ms)
49
- ✔ NRelay1 idleTimeout (209.795356ms)
50
- ✔ NRelay1.count rejects when the server sends CLOSED (6.440892ms)
51
- ✔ NRelay1 closes when it receives a binary message (5.03225ms)
52
- ✔ n.id (3.950608ms)
53
- ✔ n.bech32 (1.817636ms)
54
- ✔ n.filter (10.95275ms)
55
- ✔ n.event (2.561941ms)
56
- ✔ n.metadata (11.862022ms)
57
- ✔ NSecSigner (178.164717ms)
58
- ✔ NSecSigner.nip44 (31.935079ms)
59
- ✔ NSet (19.978352ms)
60
- ✔ NSet.add (replaceable) (0.615308ms)
61
- ✔ NSet.add (parameterized) (0.985888ms)
62
- ✔ NSet.add (deletion) (0.380918ms)
63
- ✔ Construct a RelayError from the reason message (1.717692ms)
64
- ✔ Throw a new RelayError if the OK message is false (0.750801ms)
65
- ✔ LNURL.fromString (7.817616ms)
66
- ✔ LNURL.fromLightningAddress (0.932529ms)
67
- ✔ LNURL.toString (1.933713ms)
68
- ✔ LNURL.getDetails (111.66131ms)
69
- ✔ LNURL.getInvoice (13.562812ms)
70
- ✔ ErrorRelay (112.209428ms)
71
- ✔ MockRelay (3.019126ms)
72
- ïı£ BlossomUploader.upload (1.127947ms) # SKIP
73
- ïı£ NostrBuildUploader.upload (2.842008ms) # SKIP
74
- ✔ CircularSet (2.247513ms)
75
- ✔ push, iterate, & close (103.751782ms)
76
- ✔ close & reopen (0.982257ms)
77
- ✔ aborts with signal (51.656203ms)
78
- ✔ already aborted signal in constructor (1.251916ms)
79
- ✔ push after abort (0.906129ms)
80
- ✔ multiple messages in queue (0.531637ms)
81
- ✔ N64 (8.171994ms)
82
- ✔ N64.encodeEvent (0.513338ms)
83
- ✔ N64.decodeEvent (1.449988ms)
84
- â„ı tests 77
54
+ ✔ websocket opens (13.835447ms)
55
+ ✔ websocket closes after idleTimeout (150.566912ms)
56
+ ✔ websocket wakes up during activity (27.121071ms)
57
+ ✔ NRelay1 idleTimeout (204.19181ms)
58
+ ✔ NRelay1.count rejects when the server sends CLOSED (16.828862ms)
59
+ ✔ NRelay1 closes when it receives a binary message (11.148585ms)
60
+ ✔ n.id (8.094721ms)
61
+ ✔ n.bech32 (5.484882ms)
62
+ ✔ n.filter (18.52384ms)
63
+ ✔ n.event (4.463901ms)
64
+ ✔ n.metadata (24.462155ms)
65
+ ✔ NSecSigner (219.082425ms)
66
+ ✔ NSecSigner.nip44 (37.591612ms)
67
+ ✔ NSet (24.542373ms)
68
+ ✔ NSet.add (replaceable) (0.656583ms)
69
+ ✔ NSet.add (parameterized) (1.209522ms)
70
+ ✔ NSet.add (deletion) (0.555925ms)
71
+ ✔ Construct a RelayError from the reason message (2.598397ms)
72
+ ✔ Throw a new RelayError if the OK message is false (0.892217ms)
73
+ ✔ LNURL.fromString (21.686509ms)
74
+ ✔ LNURL.fromLightningAddress (6.521633ms)
75
+ ✔ LNURL.toString (2.187929ms)
76
+ ✔ LNURL.getDetails (149.682932ms)
77
+ ✔ LNURL.getInvoice (7.231692ms)
78
+ ✔ ErrorRelay (189.467472ms)
79
+ ✔ MockRelay (4.420616ms)
80
+ ïı£ BlossomUploader.upload (1.337574ms) # SKIP
81
+ ïı£ NostrBuildUploader.upload (2.212377ms) # SKIP
82
+ ✔ CircularSet (14.732834ms)
83
+ ✔ push, iterate, & close (109.180767ms)
84
+ ✔ close & reopen (0.918119ms)
85
+ ✔ aborts with signal (53.398331ms)
86
+ ✔ already aborted signal in constructor (0.819754ms)
87
+ ✔ push after abort (1.01538ms)
88
+ ✔ multiple messages in queue (0.693816ms)
89
+ ✔ N64 (13.23745ms)
90
+ ✔ N64.encodeEvent (0.744977ms)
91
+ ✔ N64.decodeEvent (1.885313ms)
92
+ â„ı tests 85
85
93
  â„ı suites 0
86
- â„ı pass 74
94
+ â„ı pass 82
87
95
  â„ı fail 0
88
96
  â„ı cancelled 0
89
97
  â„ı skipped 3
90
98
  â„ı todo 0
91
- â„ı duration_ms 2192.909865
99
+ â„ı duration_ms 2367.358539
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.48.1
4
+
5
+ ### Patch Changes
6
+
7
+ - remove happy-dom dependency, fix improper test in NRelay1
8
+
9
+ ## 0.48.0
10
+
11
+ ### Minor Changes
12
+
13
+ - Remove all JSR imports
14
+
15
+ ## 0.47.1
16
+
17
+ ### Patch Changes
18
+
19
+ - rebuild package for NIP98Client member
20
+
3
21
  ## 0.47.0
4
22
 
5
23
  ### Minor Changes
@@ -65,7 +83,8 @@
65
83
  All notable changes to this project will be documented in this file.
66
84
 
67
85
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
68
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
86
+ and this project adheres to
87
+ [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
69
88
 
70
89
  ## 0.46.4 - 2025-07-15
71
90
 
@@ -77,7 +96,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77
96
 
78
97
  ### Fixed
79
98
 
80
- - Fix fetch calls in browser by binding globalThis (NIP05, LNURL, BlossomUploader).
99
+ - Fix fetch calls in browser by binding globalThis (NIP05, LNURL,
100
+ BlossomUploader).
81
101
  - BlossomUploader: use a browser-supported file hashing method.
82
102
 
83
103
  ## 0.46.0 - 2025-05-10
@@ -102,7 +122,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
102
122
 
103
123
  ### Changed
104
124
 
105
- - BREAKING: Redesign the `LNURL` module to be a stateful class, more similar to `URL`.
125
+ - BREAKING: Redesign the `LNURL` module to be a stateful class, more similar to
126
+ `URL`.
106
127
 
107
128
  ## 0.44.0 - 2025-04-23
108
129
 
@@ -114,7 +135,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
114
135
 
115
136
  ### Changed
116
137
 
117
- - Moved `NSeedSigner`, `NPhraseSigner`, and `NCustodial` into a separate `@nostrify/seed` package.
138
+ - Moved `NSeedSigner`, `NPhraseSigner`, and `NCustodial` into a separate
139
+ `@nostrify/seed` package.
118
140
 
119
141
  ## 0.42.1 - 2025-04-10
120
142
 
@@ -149,7 +171,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
149
171
 
150
172
  ### Added
151
173
 
152
- - NRelay1: batch ids-only filters and filters for replaceable events by author/kind within the same event loop.
174
+ - NRelay1: batch ids-only filters and filters for replaceable events by
175
+ author/kind within the same event loop.
153
176
 
154
177
  ## 0.40.0 - 2025-03-26
155
178
 
@@ -248,7 +271,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
248
271
 
249
272
  ### Added
250
273
 
251
- - NRelay1: added `idleTimeout` option to automatically close inactive connections.
274
+ - NRelay1: added `idleTimeout` option to automatically close inactive
275
+ connections.
252
276
  - NRelay1: support `await using` syntax.
253
277
 
254
278
  ## 0.31.0 - 2024-09-09
@@ -256,11 +280,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
256
280
  ### Added
257
281
 
258
282
  - Added ReplyBotPolicy to block replies from bots in the same second.
259
- - Added AuthorPolicy to reject events from authors without a kind 0, or with a particular kind 0.
283
+ - Added AuthorPolicy to reject events from authors without a kind 0, or with a
284
+ particular kind 0.
260
285
 
261
286
  ### Changed
262
287
 
263
- - BREAKING: Moved moderation policies to the `@nostrify/policies` package. Replace `@nostrify/nostrify/policies` with `@nostrify/policies` in your project.
288
+ - BREAKING: Moved moderation policies to the `@nostrify/policies` package.
289
+ Replace `@nostrify/nostrify/policies` with `@nostrify/policies` in your
290
+ project.
264
291
 
265
292
  ### Fixed
266
293
 
@@ -300,7 +327,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
300
327
 
301
328
  ### Changed
302
329
 
303
- - BREAKING: NDatabase: add kind, pubkey, and created_at columns to nostr_tags table. These columns are non-nullable, so the old database will need to be deleted or manually migrated.
330
+ - BREAKING: NDatabase: add kind, pubkey, and created_at columns to nostr_tags
331
+ table. These columns are non-nullable, so the old database will need to be
332
+ deleted or manually migrated.
304
333
 
305
334
  ## [0.26.3] - 2024-07-18
306
335
 
@@ -324,7 +353,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
324
353
 
325
354
  ### Changed
326
355
 
327
- - BREAKING: NPool: remove `reqRelays` option, add `reqRouter`. Rename `eventRelays` to `eventRouter`.
356
+ - BREAKING: NPool: remove `reqRelays` option, add `reqRouter`. Rename
357
+ `eventRelays` to `eventRouter`.
328
358
 
329
359
  ## [0.25.0] - 2024-06-29
330
360
 
@@ -342,7 +372,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
342
372
 
343
373
  ### Fixed
344
374
 
345
- - NDatabase: add intrinsic limits to filters when applicable, skip 0 limit filters.
375
+ - NDatabase: add intrinsic limits to filters when applicable, skip 0 limit
376
+ filters.
346
377
 
347
378
  ## [0.23.2] - 2024-06-13
348
379
 
@@ -385,7 +416,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
385
416
 
386
417
  ### Fixed
387
418
 
388
- - NostrMetadata: added `website` field so `NSchema.metadata()` returns the correct type.
419
+ - NostrMetadata: added `website` field so `NSchema.metadata()` returns the
420
+ correct type.
389
421
 
390
422
  ### Changed
391
423
 
@@ -410,7 +442,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
410
442
 
411
443
  ### Added
412
444
 
413
- - `NUploader` interface and two uploader classes under `@nostrify/nostrify/uploaders`.
445
+ - `NUploader` interface and two uploader classes under
446
+ `@nostrify/nostrify/uploaders`.
414
447
  - Blossom uploader (`BlossomUploader`) to upload files to Blossom servers.
415
448
  - nostr.build uploader (`NostrBuildUploader`) to upload files to nostr.build.
416
449
  - `NIP98` module to verify NIP-98 Requests.
@@ -425,11 +458,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
425
458
 
426
459
  ### Added
427
460
 
428
- - NConnectSigner: NIP-44 encryption support by setting `{ encryption: 'nip44' }` in the constructor.
461
+ - NConnectSigner: NIP-44 encryption support by setting `{ encryption: 'nip44' }`
462
+ in the constructor.
429
463
 
430
464
  ### Fixed
431
465
 
432
- - NDatabase: Postgres FTS now correctly uses the `searchText` option to create the search index.
466
+ - NDatabase: Postgres FTS now correctly uses the `searchText` option to create
467
+ the search index.
433
468
 
434
469
  ## [0.20.0] - 2024-05-16
435
470
 
@@ -439,7 +474,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
439
474
 
440
475
  ### Changed
441
476
 
442
- - BREAKING: NDatabase `fts5` option has been renamed to `fts`, and now accepts a string of either `'sqlite'` or `'postgres'`.
477
+ - BREAKING: NDatabase `fts5` option has been renamed to `fts`, and now accepts a
478
+ string of either `'sqlite'` or `'postgres'`.
443
479
 
444
480
  ## [0.19.2] - 2024-05-16
445
481
 
@@ -451,14 +487,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
451
487
 
452
488
  ### Fixed
453
489
 
454
- - NDatabase: fix deleting everything for the author when they delete a single event.
490
+ - NDatabase: fix deleting everything for the author when they delete a single
491
+ event.
455
492
 
456
493
  ## [0.19.0] - 2024-05-13
457
494
 
458
495
  ### Fixed
459
496
 
460
497
  - Improved performance of NDatabase when querying replaceable events by author.
461
- - NConnect.signEvent now throws if the connect message was rejected by the relay.
498
+ - NConnect.signEvent now throws if the connect message was rejected by the
499
+ relay.
462
500
 
463
501
  ## [0.18.0] - 2024-05-04
464
502
 
@@ -468,13 +506,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
468
506
 
469
507
  ## [0.17.1] - 2024-04-29
470
508
 
471
- Redeploy to JSR (to hopefully fix [npm compatibility](https://github.com/jsr-io/jsr/issues/446)).
509
+ Redeploy to JSR (to hopefully fix
510
+ [npm compatibility](https://github.com/jsr-io/jsr/issues/446)).
472
511
 
473
512
  ## [0.17.0] - 2024-04-28
474
513
 
475
514
  ### Changed
476
515
 
477
- - BREAKING: change `NRelay.req` return type from an AsyncGenerator to an AsyncIterable.
516
+ - BREAKING: change `NRelay.req` return type from an AsyncGenerator to an
517
+ AsyncIterable.
478
518
 
479
519
  ## [0.16.0] - 2024-04-25
480
520
 
@@ -498,7 +538,8 @@ Redeploy to JSR (to hopefully fix [npm compatibility](https://github.com/jsr-io/
498
538
 
499
539
  ### Fixed
500
540
 
501
- - `NConnectSigner` - fixed race condition between sending messages and receiving responses.
541
+ - `NConnectSigner` - fixed race condition between sending messages and receiving
542
+ responses.
502
543
 
503
544
  ## [0.14.1] - 2024-04-24
504
545
 
@@ -510,7 +551,8 @@ Redeploy to JSR (to hopefully fix [npm compatibility](https://github.com/jsr-io/
510
551
 
511
552
  ### Fixed
512
553
 
513
- - BREAKING: fixed `NConnectSigner.connect` method signature (it doesn't need to accept a pubkey).
554
+ - BREAKING: fixed `NConnectSigner.connect` method signature (it doesn't need to
555
+ accept a pubkey).
514
556
 
515
557
  ## [0.13.0] - 2024-04-24
516
558
 
@@ -528,7 +570,8 @@ Redeploy to JSR (to hopefully fix [npm compatibility](https://github.com/jsr-io/
528
570
 
529
571
  ### Added
530
572
 
531
- - Added `AnyPolicy` policy, a pipeline policy which rejects only if all policies reject.
573
+ - Added `AnyPolicy` policy, a pipeline policy which rejects only if all policies
574
+ reject.
532
575
 
533
576
  ### Changed
534
577
 
@@ -538,7 +581,8 @@ Redeploy to JSR (to hopefully fix [npm compatibility](https://github.com/jsr-io/
538
581
 
539
582
  ### Added
540
583
 
541
- - Added moderation policies. Including the `NPolicy` interface and several policies.
584
+ - Added moderation policies. Including the `NPolicy` interface and several
585
+ policies.
542
586
 
543
587
  ## [0.10.2] - 2024-04-21
544
588
 
package/NIP98.test.ts CHANGED
@@ -1,8 +1,6 @@
1
1
  import { test } from "node:test";
2
2
  import { deepStrictEqual, rejects } from "node:assert";
3
3
  import { generateSecretKey } from "nostr-tools";
4
- import { ZodError } from "zod";
5
-
6
4
  import { NIP98 } from "./NIP98.ts";
7
5
  import { NSecSigner } from "./NSecSigner.ts";
8
6
  import { N64 } from "./utils/mod.ts";
@@ -78,7 +76,7 @@ await test("NIP98.verify fails with invalid token", async () => {
78
76
 
79
77
  await rejects(
80
78
  () => NIP98.verify(request),
81
- ZodError,
79
+ (e) => e instanceof Error && e.message === "Invalid token",
82
80
  );
83
81
  });
84
82
 
package/NIP98.ts CHANGED
@@ -1,8 +1,8 @@
1
- import type { NostrEvent } from '@nostrify/types';
2
- import { encodeHex } from '@std/encoding/hex';
3
- import { verifyEvent as _verifyEvent } from 'nostr-tools';
1
+ import type { NostrEvent } from "@nostrify/types";
2
+ import { toHex } from "@smithy/util-hex-encoding";
3
+ import { verifyEvent as _verifyEvent } from "nostr-tools";
4
4
 
5
- import { N64 } from './utils/N64.ts';
5
+ import { N64 } from "./utils/N64.ts";
6
6
 
7
7
  /** [NIP-98](https://github.com/nostr-protocol/nips/blob/master/98.md) HTTP auth. */
8
8
  export class NIP98 {
@@ -10,27 +10,27 @@ export class NIP98 {
10
10
  static async template(
11
11
  request: Request,
12
12
  opts?: { validatePayload?: boolean },
13
- ): Promise<Omit<NostrEvent, 'id' | 'pubkey' | 'sig'>> {
13
+ ): Promise<Omit<NostrEvent, "id" | "pubkey" | "sig">> {
14
14
  const {
15
- validatePayload = ['POST', 'PUT', 'PATCH'].includes(request.method),
15
+ validatePayload = ["POST", "PUT", "PATCH"].includes(request.method),
16
16
  } = opts ?? {};
17
17
  const { method, url } = request;
18
18
 
19
19
  const tags = [
20
- ['method', method],
21
- ['u', url],
20
+ ["method", method],
21
+ ["u", url],
22
22
  ];
23
23
 
24
24
  if (validatePayload) {
25
25
  const buffer = await request.clone().arrayBuffer();
26
- const digest = await crypto.subtle.digest('SHA-256', buffer);
26
+ const digest = await crypto.subtle.digest("SHA-256", buffer);
27
27
 
28
- tags.push(['payload', encodeHex(digest)]);
28
+ tags.push(["payload", toHex(new Uint8Array(digest))]);
29
29
  }
30
30
 
31
31
  return {
32
32
  kind: 27235,
33
- content: '',
33
+ content: "",
34
34
  tags,
35
35
  created_at: Math.floor(Date.now() / 1000),
36
36
  };
@@ -47,48 +47,62 @@ export class NIP98 {
47
47
  ): Promise<NostrEvent> {
48
48
  const {
49
49
  maxAge = 60_000,
50
- validatePayload = ['POST', 'PUT', 'PATCH'].includes(request.method),
50
+ validatePayload = ["POST", "PUT", "PATCH"].includes(request.method),
51
51
  verifyEvent = _verifyEvent,
52
52
  } = opts ?? {};
53
53
 
54
- const header = request.headers.get('authorization');
54
+ const header = request.headers.get("authorization");
55
55
  if (!header) {
56
- throw new Error('Missing Nostr authorization header');
56
+ throw new Error("Missing Nostr authorization header");
57
57
  }
58
58
 
59
59
  const token = header.match(/^Nostr (.+)$/)?.[1];
60
60
  if (!token) {
61
- throw new Error('Missing Nostr authorization token');
61
+ throw new Error("Missing Nostr authorization token");
62
+ }
63
+
64
+ let event: NostrEvent;
65
+ try {
66
+ event = N64.decodeEvent(token);
67
+ } catch (e) {
68
+ if (
69
+ e instanceof TypeError &&
70
+ e.message.includes("Incorrect padding on base64")
71
+ ) {
72
+ throw new Error("Invalid token");
73
+ } else {
74
+ throw e;
75
+ }
62
76
  }
63
77
 
64
- const event = N64.decodeEvent(token);
65
78
  if (!verifyEvent(event)) {
66
- throw new Error('Event signature is invalid');
79
+ throw new Error("Event signature is invalid");
67
80
  }
68
81
 
69
82
  const age = Date.now() - (event.created_at * 1_000);
70
- const u = event.tags.find(([name]) => name === 'u')?.[1];
71
- const method = event.tags.find(([name]) => name === 'method')?.[1];
72
- const payload = event.tags.find(([name]) => name === 'payload')?.[1];
83
+ const u = event.tags.find(([name]) => name === "u")?.[1];
84
+ const method = event.tags.find(([name]) => name === "method")?.[1];
85
+ const payload = event.tags.find(([name]) => name === "payload")?.[1];
73
86
 
74
87
  if (event.kind !== 27235) {
75
- throw new Error('Event must be kind 27235');
88
+ throw new Error("Event must be kind 27235");
76
89
  }
77
90
  if (u !== request.url) {
78
- throw new Error('Event URL does not match request URL');
91
+ throw new Error("Event URL does not match request URL");
79
92
  }
80
93
  if (method !== request.method) {
81
- throw new Error('Event method does not match HTTP request method');
94
+ throw new Error("Event method does not match HTTP request method");
82
95
  }
83
96
  if (age >= maxAge) {
84
- throw new Error('Event expired');
97
+ throw new Error("Event expired");
85
98
  }
86
99
  if (validatePayload && payload !== undefined) {
87
100
  const buffer = await request.clone().arrayBuffer();
88
- const digest = await crypto.subtle.digest('SHA-256', buffer);
101
+ const digest = await crypto.subtle.digest("SHA-256", buffer);
102
+ const hexed = toHex(new Uint8Array(digest));
89
103
 
90
- if (encodeHex(digest) !== payload) {
91
- throw new Error('Event payload does not match request body');
104
+ if (hexed !== payload) {
105
+ throw new Error("Event payload does not match request body");
92
106
  }
93
107
  }
94
108
 
package/NRelay1.test.ts CHANGED
@@ -157,9 +157,12 @@ await test("NRelay1 idleTimeout", async () => {
157
157
  await using relay = new NRelay1(server.url, { idleTimeout: 100 });
158
158
 
159
159
  await it("websocket opens", async () => {
160
- await new Promise((resolve) => setTimeout(resolve, 20));
160
+ await new Promise((resolve) =>
161
+ relay.socket.addEventListener(WebsocketEvent.open, resolve, {
162
+ once: true,
163
+ })
164
+ );
161
165
  deepStrictEqual(relay.socket.readyState, WebSocket.OPEN);
162
- await new Promise((resolve) => setTimeout(resolve, 20));
163
166
  });
164
167
 
165
168
  await it("websocket closes after idleTimeout", async () => {
package/dist/NIP98.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import type { NostrEvent } from '@nostrify/types';
1
+ import type { NostrEvent } from "@nostrify/types";
2
2
  /** [NIP-98](https://github.com/nostr-protocol/nips/blob/master/98.md) HTTP auth. */
3
3
  export declare class NIP98 {
4
4
  /** Generate an auth event template from a Request. */
5
5
  static template(request: Request, opts?: {
6
6
  validatePayload?: boolean;
7
- }): Promise<Omit<NostrEvent, 'id' | 'pubkey' | 'sig'>>;
7
+ }): Promise<Omit<NostrEvent, "id" | "pubkey" | "sig">>;
8
8
  /** Compare the auth event with the request, throwing a human-readable error if validation fails. */
9
9
  static verify(request: Request, opts?: {
10
10
  maxAge?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"NIP98.d.ts","sourceRoot":"","sources":["../NIP98.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAMlD,oFAAoF;AACpF,qBAAa,KAAK;IAChB,sDAAsD;WACzC,QAAQ,CACnB,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACnC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,QAAQ,GAAG,KAAK,CAAC,CAAC;IA0BrD,oGAAoG;WACvF,MAAM,CACjB,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC,EAAE;QACL,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC;KAC9C,GACA,OAAO,CAAC,UAAU,CAAC;CAkDvB"}
1
+ {"version":3,"file":"NIP98.d.ts","sourceRoot":"","sources":["../NIP98.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAMlD,oFAAoF;AACpF,qBAAa,KAAK;IAChB,sDAAsD;WACzC,QAAQ,CACnB,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACnC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,QAAQ,GAAG,KAAK,CAAC,CAAC;IA0BrD,oGAAoG;WACvF,MAAM,CACjB,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC,EAAE;QACL,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC;KAC9C,GACA,OAAO,CAAC,UAAU,CAAC;CAgEvB"}