@nostrify/nostrify 0.47.1 → 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.47.0 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 26 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 25ms
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,17 @@
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
+
3
15
  ## 0.47.1
4
16
 
5
17
  ### Patch Changes
@@ -71,7 +83,8 @@
71
83
  All notable changes to this project will be documented in this file.
72
84
 
73
85
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
74
- 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).
75
88
 
76
89
  ## 0.46.4 - 2025-07-15
77
90
 
@@ -83,7 +96,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
83
96
 
84
97
  ### Fixed
85
98
 
86
- - Fix fetch calls in browser by binding globalThis (NIP05, LNURL, BlossomUploader).
99
+ - Fix fetch calls in browser by binding globalThis (NIP05, LNURL,
100
+ BlossomUploader).
87
101
  - BlossomUploader: use a browser-supported file hashing method.
88
102
 
89
103
  ## 0.46.0 - 2025-05-10
@@ -108,7 +122,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
108
122
 
109
123
  ### Changed
110
124
 
111
- - 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`.
112
127
 
113
128
  ## 0.44.0 - 2025-04-23
114
129
 
@@ -120,7 +135,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
120
135
 
121
136
  ### Changed
122
137
 
123
- - Moved `NSeedSigner`, `NPhraseSigner`, and `NCustodial` into a separate `@nostrify/seed` package.
138
+ - Moved `NSeedSigner`, `NPhraseSigner`, and `NCustodial` into a separate
139
+ `@nostrify/seed` package.
124
140
 
125
141
  ## 0.42.1 - 2025-04-10
126
142
 
@@ -155,7 +171,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
155
171
 
156
172
  ### Added
157
173
 
158
- - 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.
159
176
 
160
177
  ## 0.40.0 - 2025-03-26
161
178
 
@@ -254,7 +271,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
254
271
 
255
272
  ### Added
256
273
 
257
- - NRelay1: added `idleTimeout` option to automatically close inactive connections.
274
+ - NRelay1: added `idleTimeout` option to automatically close inactive
275
+ connections.
258
276
  - NRelay1: support `await using` syntax.
259
277
 
260
278
  ## 0.31.0 - 2024-09-09
@@ -262,11 +280,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
262
280
  ### Added
263
281
 
264
282
  - Added ReplyBotPolicy to block replies from bots in the same second.
265
- - 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.
266
285
 
267
286
  ### Changed
268
287
 
269
- - 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.
270
291
 
271
292
  ### Fixed
272
293
 
@@ -306,7 +327,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
306
327
 
307
328
  ### Changed
308
329
 
309
- - 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.
310
333
 
311
334
  ## [0.26.3] - 2024-07-18
312
335
 
@@ -330,7 +353,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
330
353
 
331
354
  ### Changed
332
355
 
333
- - BREAKING: NPool: remove `reqRelays` option, add `reqRouter`. Rename `eventRelays` to `eventRouter`.
356
+ - BREAKING: NPool: remove `reqRelays` option, add `reqRouter`. Rename
357
+ `eventRelays` to `eventRouter`.
334
358
 
335
359
  ## [0.25.0] - 2024-06-29
336
360
 
@@ -348,7 +372,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
348
372
 
349
373
  ### Fixed
350
374
 
351
- - 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.
352
377
 
353
378
  ## [0.23.2] - 2024-06-13
354
379
 
@@ -391,7 +416,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
391
416
 
392
417
  ### Fixed
393
418
 
394
- - NostrMetadata: added `website` field so `NSchema.metadata()` returns the correct type.
419
+ - NostrMetadata: added `website` field so `NSchema.metadata()` returns the
420
+ correct type.
395
421
 
396
422
  ### Changed
397
423
 
@@ -416,7 +442,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
416
442
 
417
443
  ### Added
418
444
 
419
- - `NUploader` interface and two uploader classes under `@nostrify/nostrify/uploaders`.
445
+ - `NUploader` interface and two uploader classes under
446
+ `@nostrify/nostrify/uploaders`.
420
447
  - Blossom uploader (`BlossomUploader`) to upload files to Blossom servers.
421
448
  - nostr.build uploader (`NostrBuildUploader`) to upload files to nostr.build.
422
449
  - `NIP98` module to verify NIP-98 Requests.
@@ -431,11 +458,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
431
458
 
432
459
  ### Added
433
460
 
434
- - 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.
435
463
 
436
464
  ### Fixed
437
465
 
438
- - 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.
439
468
 
440
469
  ## [0.20.0] - 2024-05-16
441
470
 
@@ -445,7 +474,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
445
474
 
446
475
  ### Changed
447
476
 
448
- - 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'`.
449
479
 
450
480
  ## [0.19.2] - 2024-05-16
451
481
 
@@ -457,14 +487,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
457
487
 
458
488
  ### Fixed
459
489
 
460
- - 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.
461
492
 
462
493
  ## [0.19.0] - 2024-05-13
463
494
 
464
495
  ### Fixed
465
496
 
466
497
  - Improved performance of NDatabase when querying replaceable events by author.
467
- - 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.
468
500
 
469
501
  ## [0.18.0] - 2024-05-04
470
502
 
@@ -474,13 +506,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
474
506
 
475
507
  ## [0.17.1] - 2024-04-29
476
508
 
477
- 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)).
478
511
 
479
512
  ## [0.17.0] - 2024-04-28
480
513
 
481
514
  ### Changed
482
515
 
483
- - 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.
484
518
 
485
519
  ## [0.16.0] - 2024-04-25
486
520
 
@@ -504,7 +538,8 @@ Redeploy to JSR (to hopefully fix [npm compatibility](https://github.com/jsr-io/
504
538
 
505
539
  ### Fixed
506
540
 
507
- - `NConnectSigner` - fixed race condition between sending messages and receiving responses.
541
+ - `NConnectSigner` - fixed race condition between sending messages and receiving
542
+ responses.
508
543
 
509
544
  ## [0.14.1] - 2024-04-24
510
545
 
@@ -516,7 +551,8 @@ Redeploy to JSR (to hopefully fix [npm compatibility](https://github.com/jsr-io/
516
551
 
517
552
  ### Fixed
518
553
 
519
- - 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).
520
556
 
521
557
  ## [0.13.0] - 2024-04-24
522
558
 
@@ -534,7 +570,8 @@ Redeploy to JSR (to hopefully fix [npm compatibility](https://github.com/jsr-io/
534
570
 
535
571
  ### Added
536
572
 
537
- - 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.
538
575
 
539
576
  ### Changed
540
577
 
@@ -544,7 +581,8 @@ Redeploy to JSR (to hopefully fix [npm compatibility](https://github.com/jsr-io/
544
581
 
545
582
  ### Added
546
583
 
547
- - Added moderation policies. Including the `NPolicy` interface and several policies.
584
+ - Added moderation policies. Including the `NPolicy` interface and several
585
+ policies.
548
586
 
549
587
  ## [0.10.2] - 2024-04-21
550
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"}