@qntx/nostr 0.6.0 → 0.8.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.
Files changed (183) hide show
  1. package/dist/{abort-Ba8tDrOI.mjs → abort-DBq2STPj.mjs} +13 -6
  2. package/dist/abort-DBq2STPj.mjs.map +1 -0
  3. package/dist/{builder-sSflu6nB.d.mts → builder-CTwkB2zM.d.mts} +14 -15
  4. package/dist/{builder-9tjI6WQ3.mjs → builder-aNU2gGFP.mjs} +11 -17
  5. package/dist/builder-aNU2gGFP.mjs.map +1 -0
  6. package/dist/{client-CadO5fAX.mjs → client-Cj2lUaVh.mjs} +141 -353
  7. package/dist/client-Cj2lUaVh.mjs.map +1 -0
  8. package/dist/client.d.mts +2 -2
  9. package/dist/client.mjs +2 -2
  10. package/dist/collections-DtwMc1NU.mjs +33 -0
  11. package/dist/collections-DtwMc1NU.mjs.map +1 -0
  12. package/dist/core.d.mts +9 -8
  13. package/dist/core.mjs +7 -7
  14. package/dist/emitter-DkCY6NkU.mjs +32 -0
  15. package/dist/emitter-DkCY6NkU.mjs.map +1 -0
  16. package/dist/{error-BW7re1UN.d.mts → error-BD_0QFKT.d.mts} +2 -2
  17. package/dist/{error-DrEIM7FO.mjs → error-BILMe3Gr.mjs} +2 -2
  18. package/dist/{error-DrEIM7FO.mjs.map → error-BILMe3Gr.mjs.map} +1 -1
  19. package/dist/{error-CR8Urc84.d.mts → error-BquXDmIN.d.mts} +4 -4
  20. package/dist/{error-B__OMBRY.mjs → error-DlhGW4mJ.mjs} +2 -2
  21. package/dist/{error-B__OMBRY.mjs.map → error-DlhGW4mJ.mjs.map} +1 -1
  22. package/dist/{event-D8Nfoh4K.mjs → event-CHf47dPM.mjs} +16 -10
  23. package/dist/event-CHf47dPM.mjs.map +1 -0
  24. package/dist/{event-fU3Y01PR.d.mts → event-DJeb_DIL.d.mts} +4 -2
  25. package/dist/{filter-C0IMByE3.d.mts → filter-jI_9htF7.d.mts} +2 -2
  26. package/dist/{gossip-oloDMWEj.mjs → gossip-DFxIBlsr.mjs} +23 -33
  27. package/dist/gossip-DFxIBlsr.mjs.map +1 -0
  28. package/dist/{gossip-DpIvkBuj.d.mts → gossip-OOeeFzG5.d.mts} +37 -28
  29. package/dist/gossip.d.mts +1 -1
  30. package/dist/gossip.mjs +1 -1
  31. package/dist/{index-D1bqFHKB.d.mts → index-BxCBX-8R.d.mts} +18 -18
  32. package/dist/{index-lvXeER5t.d.mts → index-CPVEyzNX.d.mts} +32 -50
  33. package/dist/{index-MxC28S4P.d.mts → index-C_w2WfVz.d.mts} +27 -29
  34. package/dist/{index-CNl2q67H.d.mts → index-Cl_1XdYP.d.mts} +111 -180
  35. package/dist/{index-CvkvqB16.d.mts → index-DU9tRFTZ.d.mts} +7 -20
  36. package/dist/{index-q4MDce_r.d.mts → index-DyKwQnbt.d.mts} +6 -8
  37. package/dist/index.d.mts +23 -21
  38. package/dist/index.mjs +21 -19
  39. package/dist/{instance-DQE8BoWt.mjs → instance-C62w3cEt.mjs} +26 -27
  40. package/dist/instance-C62w3cEt.mjs.map +1 -0
  41. package/dist/{instance-CIca-ynn.d.mts → instance-DjsL8h84.d.mts} +5 -5
  42. package/dist/{key-Cv4_pN3x.d.mts → key-D_5OgGT7.d.mts} +11 -7
  43. package/dist/{key-Bps-LqX7.mjs → key-DnVpchl6.mjs} +13 -9
  44. package/dist/key-DnVpchl6.mjs.map +1 -0
  45. package/dist/{loaders-o6YXB_Ri.mjs → loaders-BmPkQfzI.mjs} +73 -82
  46. package/dist/loaders-BmPkQfzI.mjs.map +1 -0
  47. package/dist/loaders.d.mts +3 -3
  48. package/dist/loaders.mjs +2 -2
  49. package/dist/{memory-C2EVx0_O.mjs → memory-CdJ07kub.mjs} +2 -2
  50. package/dist/memory-CdJ07kub.mjs.map +1 -0
  51. package/dist/{memory-index-Do1mz0WF.mjs → memory-index-Cbc83vOZ.mjs} +30 -247
  52. package/dist/memory-index-Cbc83vOZ.mjs.map +1 -0
  53. package/dist/message-oNr7t0SJ.mjs +194 -0
  54. package/dist/message-oNr7t0SJ.mjs.map +1 -0
  55. package/dist/{message-iGPIqnn0.d.mts → message-tclYCVNc.d.mts} +6 -6
  56. package/dist/{nip17-CKIufV98.d.mts → nip17-B5WgW4C4.d.mts} +6 -7
  57. package/dist/{nip19-BevCJZsp.d.mts → nip19-DpPN17bY.d.mts} +25 -31
  58. package/dist/{nip46-DDV4dC56.d.mts → nip46-BHaxC9TZ.d.mts} +19 -21
  59. package/dist/nip51-CR0Q8eym.d.mts +87 -0
  60. package/dist/{nip59-zQgdLcEr.d.mts → nip59-C-RWFQIv.d.mts} +11 -5
  61. package/dist/nip65-D1fbmhOg.d.mts +23 -0
  62. package/dist/{nip77-DH4RhS5r.d.mts → nip77-DzUwUxHq.d.mts} +8 -9
  63. package/dist/nips/blossom.d.mts +17 -13
  64. package/dist/nips/blossom.mjs +30 -9
  65. package/dist/nips/blossom.mjs.map +1 -1
  66. package/dist/nips/nip04.mjs +17 -7
  67. package/dist/nips/nip04.mjs.map +1 -1
  68. package/dist/nips/nip05.d.mts +9 -10
  69. package/dist/nips/nip05.mjs +1 -4
  70. package/dist/nips/nip05.mjs.map +1 -1
  71. package/dist/nips/nip10.d.mts +8 -8
  72. package/dist/nips/nip10.mjs +34 -32
  73. package/dist/nips/nip10.mjs.map +1 -1
  74. package/dist/nips/nip11.d.mts +28 -28
  75. package/dist/nips/nip11.mjs +4 -4
  76. package/dist/nips/nip11.mjs.map +1 -1
  77. package/dist/nips/nip13.d.mts +7 -7
  78. package/dist/nips/nip13.mjs +32 -10
  79. package/dist/nips/nip13.mjs.map +1 -1
  80. package/dist/nips/nip17.d.mts +1 -1
  81. package/dist/nips/nip17.mjs +16 -34
  82. package/dist/nips/nip17.mjs.map +1 -1
  83. package/dist/nips/nip19.d.mts +2 -2
  84. package/dist/nips/nip19.mjs +16 -28
  85. package/dist/nips/nip19.mjs.map +1 -1
  86. package/dist/nips/nip21.d.mts +9 -4
  87. package/dist/nips/nip21.mjs +15 -5
  88. package/dist/nips/nip21.mjs.map +1 -1
  89. package/dist/nips/nip27.d.mts +22 -22
  90. package/dist/nips/nip27.mjs +2 -2
  91. package/dist/nips/nip27.mjs.map +1 -1
  92. package/dist/nips/nip42.d.mts +1 -1
  93. package/dist/nips/nip42.mjs +2 -1
  94. package/dist/nips/nip42.mjs.map +1 -1
  95. package/dist/nips/nip44.mjs +2 -2
  96. package/dist/nips/nip44.mjs.map +1 -1
  97. package/dist/nips/nip46.d.mts +2 -2
  98. package/dist/nips/nip46.mjs +15 -19
  99. package/dist/nips/nip46.mjs.map +1 -1
  100. package/dist/nips/nip49.d.mts +9 -9
  101. package/dist/nips/nip49.mjs +4 -4
  102. package/dist/nips/nip49.mjs.map +1 -1
  103. package/dist/nips/nip51.d.mts +2 -86
  104. package/dist/nips/nip51.mjs +7 -23
  105. package/dist/nips/nip51.mjs.map +1 -1
  106. package/dist/nips/nip57.d.mts +25 -23
  107. package/dist/nips/nip57.mjs +12 -17
  108. package/dist/nips/nip57.mjs.map +1 -1
  109. package/dist/nips/nip59.d.mts +1 -1
  110. package/dist/nips/nip59.mjs +27 -19
  111. package/dist/nips/nip59.mjs.map +1 -1
  112. package/dist/nips/nip65.d.mts +2 -2
  113. package/dist/nips/nip65.mjs +14 -37
  114. package/dist/nips/nip65.mjs.map +1 -1
  115. package/dist/nips/nip77.d.mts +1 -1
  116. package/dist/nips/nip77.mjs +33 -32
  117. package/dist/nips/nip77.mjs.map +1 -1
  118. package/dist/nips/nip98.d.mts +5 -5
  119. package/dist/nips/nip98.mjs +8 -8
  120. package/dist/nips/nip98.mjs.map +1 -1
  121. package/dist/{pool-DBIYMtwy.d.mts → pool-CqQvUnsq.d.mts} +132 -108
  122. package/dist/pool-vlw74C4t.mjs +606 -0
  123. package/dist/pool-vlw74C4t.mjs.map +1 -0
  124. package/dist/put-w13ci3sC.mjs +187 -0
  125. package/dist/put-w13ci3sC.mjs.map +1 -0
  126. package/dist/{reactive-BfhPp9a3.mjs → reactive-Tz0otDIP.mjs} +125 -88
  127. package/dist/reactive-Tz0otDIP.mjs.map +1 -0
  128. package/dist/{reactive-7aqeip4A.d.mts → reactive-gGqUrzW8.d.mts} +20 -26
  129. package/dist/relay-quCs7MHD.mjs +1811 -0
  130. package/dist/relay-quCs7MHD.mjs.map +1 -0
  131. package/dist/relay.d.mts +4 -4
  132. package/dist/relay.mjs +3 -2
  133. package/dist/serial-Bzpw-xz3.mjs +21 -0
  134. package/dist/serial-Bzpw-xz3.mjs.map +1 -0
  135. package/dist/{signer-CYQutDzD.mjs → signer-poTGe6Er.mjs} +12 -14
  136. package/dist/signer-poTGe6Er.mjs.map +1 -0
  137. package/dist/signer.d.mts +2 -2
  138. package/dist/signer.mjs +2 -2
  139. package/dist/{storage-Dky3wuoH.mjs → storage-B5IXTVuS.mjs} +28 -51
  140. package/dist/storage-B5IXTVuS.mjs.map +1 -0
  141. package/dist/storage.d.mts +3 -3
  142. package/dist/storage.mjs +4 -4
  143. package/dist/store.d.mts +2 -2
  144. package/dist/store.mjs +1 -1
  145. package/dist/testing.d.mts +19 -19
  146. package/dist/testing.mjs +9 -9
  147. package/dist/testing.mjs.map +1 -1
  148. package/dist/{types-2pCUprRU.d.mts → types-BacwnDtU.d.mts} +10 -10
  149. package/dist/{types-CRQEk0Oi.d.mts → types-DNmiscfd.d.mts} +2 -2
  150. package/dist/{util-LfQirgDk.mjs → util-DMF9AIO0.mjs} +33 -7
  151. package/dist/util-DMF9AIO0.mjs.map +1 -0
  152. package/dist/{verifier-t5WoWbtY.mjs → verifier-B51Wkt5H.mjs} +3 -3
  153. package/dist/verifier-B51Wkt5H.mjs.map +1 -0
  154. package/dist/verifier-CgTFpgsC.d.mts +22 -0
  155. package/dist/wasm.browser.d.mts +3 -3
  156. package/dist/wasm.browser.mjs +3 -3
  157. package/dist/wasm.d.mts +3 -3
  158. package/dist/wasm.mjs +3 -3
  159. package/dist/wasm.mjs.map +1 -1
  160. package/package.json +5 -9
  161. package/dist/abort-Ba8tDrOI.mjs.map +0 -1
  162. package/dist/builder-9tjI6WQ3.mjs.map +0 -1
  163. package/dist/client-CadO5fAX.mjs.map +0 -1
  164. package/dist/event-D8Nfoh4K.mjs.map +0 -1
  165. package/dist/gossip-oloDMWEj.mjs.map +0 -1
  166. package/dist/instance-DQE8BoWt.mjs.map +0 -1
  167. package/dist/key-Bps-LqX7.mjs.map +0 -1
  168. package/dist/loaders-o6YXB_Ri.mjs.map +0 -1
  169. package/dist/memory-C2EVx0_O.mjs.map +0 -1
  170. package/dist/memory-index-Do1mz0WF.mjs.map +0 -1
  171. package/dist/message-DcY6Fi9o.mjs +0 -193
  172. package/dist/message-DcY6Fi9o.mjs.map +0 -1
  173. package/dist/nip65-CjgmdpPB.d.mts +0 -26
  174. package/dist/nips/nip96.d.mts +0 -40
  175. package/dist/nips/nip96.mjs +0 -118
  176. package/dist/nips/nip96.mjs.map +0 -1
  177. package/dist/pool-As20OGxB.mjs +0 -2166
  178. package/dist/pool-As20OGxB.mjs.map +0 -1
  179. package/dist/reactive-BfhPp9a3.mjs.map +0 -1
  180. package/dist/signer-CYQutDzD.mjs.map +0 -1
  181. package/dist/storage-Dky3wuoH.mjs.map +0 -1
  182. package/dist/util-LfQirgDk.mjs.map +0 -1
  183. package/dist/verifier-t5WoWbtY.mjs.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,25 +1,27 @@
1
- import { C as SUBSCRIPTION_ID_MAX_CHARS, S as SIGNATURE_BYTES, _ as UrlError, a as hexToBytes, b as PUBLIC_KEY_BYTES, f as CryptoError, g as NostrError, h as MessageError, i as bytesToHex, l as normalizeURL, m as HexError, o as isHex32, p as EventValidationError, s as isHex64, v as WasmVerifyPoisonedError, x as SECRET_KEY_BYTES, y as EVENT_ID_BYTES } from "./util-LfQirgDk.mjs";
1
+ import { C as EVENT_ID_BYTES, D as SUBSCRIPTION_ID_MAX_CHARS, E as SIGNATURE_BYTES, T as SECRET_KEY_BYTES, _ as MessageError, a as hexToBytes, b as WasmPoisonedError, g as HexError, h as EventValidationError, i as bytesToHex, m as CryptoError, o as isHex32, s as isHex64, u as normalizeURL, v as NostrError, w as PUBLIC_KEY_BYTES, y as UrlError } from "./util-DMF9AIO0.mjs";
2
2
  import { a as isRegularKind, i as isEphemeralKind, n as classifyKind, o as isReplaceableKind, r as isAddressableKind, t as Kind } from "./kind-Cxwhhkx8.mjs";
3
- import { S as tagValue, _ as formatEventAddress, a as isReplaceableWinner, b as parseEventAddress, d as sortEvents, f as sortedEvents, g as eventAddress, h as Tag, l as serializeEvent, m as validateSignedEvent, n as getEventHash, o as itemCompare, p as validateEvent, u as signedMatchesUnsigned, v as getDTag, x as tagName, y as isTag } from "./event-D8Nfoh4K.mjs";
4
- import { a as publicKeyFromHex, i as getPublicKey, n as SecretKey, o as signEvent, r as finalizeEvent, t as Keys } from "./key-Bps-LqX7.mjs";
5
- import { n as verifyEvent, t as createEventVerifier } from "./verifier-t5WoWbtY.mjs";
6
- import { t as EventBuilder } from "./builder-9tjI6WQ3.mjs";
3
+ import { C as tagValue, S as tagName, a as isReplaceableWinner, b as isTag, d as sortEvents, f as sortedEvents, g as eventAddress, h as Tag, l as serializeEvent, m as validateSignedEvent, n as getEventHash, o as itemCompare, p as validateEvent, u as signedMatchesUnsigned, v as formatEventAddress, x as parseEventAddress, y as getDTag } from "./event-CHf47dPM.mjs";
4
+ import { a as publicKeyFromHex, i as getPublicKey, n as SecretKey, o as signEvent, r as finalizeEvent, s as toSecretKey, t as Keys } from "./key-DnVpchl6.mjs";
5
+ import { n as verifyEvent, t as createEventVerifier } from "./verifier-B51Wkt5H.mjs";
6
+ import { t as EventBuilder } from "./builder-aNU2gGFP.mjs";
7
7
  import { a as matchFilter, i as getFilterLimit, n as canonicalizeFilters, o as matchFilters, r as filterFingerprint, s as mergeFilters, t as canonicalizeFilter } from "./filter-BQl3GlHt.mjs";
8
- import { a as mergeCountHll, i as encodeRelayMessage, n as createSubscriptionId, o as parseClientMessage, r as encodeClientMessage, s as parseRelayMessage, t as assertSubscriptionId } from "./message-DcY6Fi9o.mjs";
9
- import { t as NoSignerError } from "./error-B__OMBRY.mjs";
10
- import { a as KeysSigner, i as isNip07Available, n as Nip07Signer, r as getWindowNostr, t as Nip46Signer } from "./signer-CYQutDzD.mjs";
11
- import { Bech32MaxSize, Nip19Error, decode, decodeNostrURI, naddrEncode, neventEncode, noteEncode, nprofileEncode, npubEncode, nsecEncode } from "./nips/nip19.mjs";
8
+ import { a as mergeCountHll, i as encodeRelayMessage, n as createSubscriptionId, o as parseClientMessage, r as encodeClientMessage, s as parseRelayMessage, t as assertSubscriptionId } from "./message-oNr7t0SJ.mjs";
9
+ import { t as NoSignerError } from "./error-DlhGW4mJ.mjs";
10
+ import { a as KeysSigner, i as isNip07Available, n as Nip07Signer, r as getWindowNostr, t as Nip46Signer } from "./signer-poTGe6Er.mjs";
11
+ import { Bech32MaxSize, Nip19Error, decode, naddrEncode, neventEncode, noteEncode, nprofileEncode, npubEncode, nsecEncode } from "./nips/nip19.mjs";
12
+ import { Nip21Error, isNostrURI, parseNostrURI } from "./nips/nip21.mjs";
12
13
  import { buildReplyTags, parseThreadTags, replyTo } from "./nips/nip10.mjs";
13
14
  import { isAuthRequired, makeAuthEvent } from "./nips/nip42.mjs";
14
- import { markerOf, parseRelayList, readRelays, relayListEventBuilder, relayListToTags, writeRelays } from "./nips/nip65.mjs";
15
- import { a as RelayStatus, c as isInsecureRelayUrl, d as RelayClosedError, f as RelayConnectionError, g as RelayTimeoutError, h as RelaySuspendedError, i as Relay, m as RelayPublishError, p as RelayError, t as Pool, u as useWebSocketImplementation } from "./pool-As20OGxB.mjs";
15
+ import { parseRelayList, readRelays, relayListEventBuilder, relayListToTags, writeRelays } from "./nips/nip65.mjs";
16
+ import { c as RelayConnectionError, d as RelaySuspendedError, f as RelayTimeoutError, l as RelayError, n as Relay, o as useWebSocketImplementation, r as RelayStatus, s as RelayClosedError, u as RelayPublishError } from "./relay-quCs7MHD.mjs";
17
+ import { i as isInsecureRelayUrl, t as Pool } from "./pool-vlw74C4t.mjs";
16
18
  import "./relay.mjs";
17
- import { t as Gossip } from "./gossip-oloDMWEj.mjs";
18
- import { a as groupAuthorsByOutboxRelay, i as createOutboxFeed, n as OutboxError, o as bareNostrUser, r as OutboxFeed, t as createLoaders } from "./loaders-o6YXB_Ri.mjs";
19
- import { t as StorageError } from "./error-DrEIM7FO.mjs";
20
- import { t as MemoryEventStore } from "./memory-C2EVx0_O.mjs";
21
- import { t as ReactiveEventStore } from "./reactive-BfhPp9a3.mjs";
22
- import { i as ClientBuilder, n as ClientError, r as SyncDirection, t as Client } from "./client-CadO5fAX.mjs";
23
- import { n as IndexedDbEventStore, t as SqliteEventStore } from "./storage-Dky3wuoH.mjs";
19
+ import { t as Gossip } from "./gossip-DFxIBlsr.mjs";
20
+ import { a as bareNostrUser, i as groupAuthorsByOutboxRelay, n as OutboxError, r as OutboxFeed, t as createLoaders } from "./loaders-BmPkQfzI.mjs";
21
+ import { t as StorageError } from "./error-BILMe3Gr.mjs";
22
+ import { t as MemoryEventStore } from "./memory-CdJ07kub.mjs";
23
+ import { t as ReactiveEventStore } from "./reactive-Tz0otDIP.mjs";
24
+ import { n as ClientError, r as SyncDirection, t as Client } from "./client-Cj2lUaVh.mjs";
25
+ import { n as IndexedDbEventStore, t as SqliteEventStore } from "./storage-B5IXTVuS.mjs";
24
26
  import "./store.mjs";
25
- export { Bech32MaxSize, Client, ClientBuilder, ClientError, CryptoError, EVENT_ID_BYTES, EventBuilder, EventValidationError, Gossip, HexError, IndexedDbEventStore, Keys, KeysSigner, Kind, MemoryEventStore, MessageError, Nip07Signer, Nip19Error, Nip46Signer, NoSignerError, NostrError, OutboxError, OutboxFeed, PUBLIC_KEY_BYTES, Pool, ReactiveEventStore, Relay, RelayClosedError, RelayConnectionError, RelayError, RelayPublishError, RelayStatus, RelaySuspendedError, RelayTimeoutError, SECRET_KEY_BYTES, SIGNATURE_BYTES, SUBSCRIPTION_ID_MAX_CHARS, SecretKey, SqliteEventStore, StorageError, SyncDirection, Tag, UrlError, WasmVerifyPoisonedError, assertSubscriptionId, bareNostrUser, buildReplyTags, bytesToHex, canonicalizeFilter, canonicalizeFilters, classifyKind, createEventVerifier, createLoaders, createOutboxFeed, createSubscriptionId, decodeNostrURI, encodeClientMessage, encodeRelayMessage, eventAddress, filterFingerprint, finalizeEvent, formatEventAddress, getDTag, getEventHash, getFilterLimit, getPublicKey, getWindowNostr, groupAuthorsByOutboxRelay, hexToBytes, isAddressableKind, isAuthRequired, isEphemeralKind, isHex32, isHex64, isInsecureRelayUrl, isNip07Available, isRegularKind, isReplaceableKind, isReplaceableWinner, isTag, itemCompare, makeAuthEvent, markerOf, matchFilter, matchFilters, mergeCountHll, mergeFilters, naddrEncode, neventEncode, decode as nip19Decode, normalizeURL, noteEncode, nprofileEncode, npubEncode, nsecEncode, parseClientMessage, parseEventAddress, parseRelayList, parseRelayMessage, parseThreadTags, publicKeyFromHex, readRelays, relayListEventBuilder, relayListToTags, replyTo, serializeEvent, signEvent, signedMatchesUnsigned, sortEvents, sortedEvents, tagName, tagValue, useWebSocketImplementation, validateEvent, validateSignedEvent, verifyEvent, writeRelays };
27
+ export { Bech32MaxSize, Client, ClientError, CryptoError, EVENT_ID_BYTES, EventBuilder, EventValidationError, Gossip, HexError, IndexedDbEventStore, Keys, KeysSigner, Kind, MemoryEventStore, MessageError, Nip07Signer, Nip19Error, Nip21Error, Nip46Signer, NoSignerError, NostrError, OutboxError, OutboxFeed, PUBLIC_KEY_BYTES, Pool, ReactiveEventStore, Relay, RelayClosedError, RelayConnectionError, RelayError, RelayPublishError, RelayStatus, RelaySuspendedError, RelayTimeoutError, SECRET_KEY_BYTES, SIGNATURE_BYTES, SUBSCRIPTION_ID_MAX_CHARS, SecretKey, SqliteEventStore, StorageError, SyncDirection, Tag, UrlError, WasmPoisonedError, assertSubscriptionId, bareNostrUser, buildReplyTags, bytesToHex, canonicalizeFilter, canonicalizeFilters, classifyKind, createEventVerifier, createLoaders, createSubscriptionId, encodeClientMessage, encodeRelayMessage, eventAddress, filterFingerprint, finalizeEvent, formatEventAddress, getDTag, getEventHash, getFilterLimit, getPublicKey, getWindowNostr, groupAuthorsByOutboxRelay, hexToBytes, isAddressableKind, isAuthRequired, isEphemeralKind, isHex32, isHex64, isInsecureRelayUrl, isNip07Available, isNostrURI, isRegularKind, isReplaceableKind, isReplaceableWinner, isTag, itemCompare, makeAuthEvent, matchFilter, matchFilters, mergeCountHll, mergeFilters, naddrEncode, neventEncode, decode as nip19Decode, normalizeURL, noteEncode, nprofileEncode, npubEncode, nsecEncode, parseClientMessage, parseEventAddress, parseNostrURI, parseRelayList, parseRelayMessage, parseThreadTags, publicKeyFromHex, readRelays, relayListEventBuilder, relayListToTags, replyTo, serializeEvent, signEvent, signedMatchesUnsigned, sortEvents, sortedEvents, tagName, tagValue, toSecretKey, useWebSocketImplementation, validateEvent, validateSignedEvent, verifyEvent, writeRelays };
@@ -1,5 +1,5 @@
1
- import { f as CryptoError, v as WasmVerifyPoisonedError } from "./util-LfQirgDk.mjs";
2
- import { t as createEventVerifier } from "./verifier-t5WoWbtY.mjs";
1
+ import { b as WasmPoisonedError, m as CryptoError } from "./util-DMF9AIO0.mjs";
2
+ import { t as createEventVerifier } from "./verifier-B51Wkt5H.mjs";
3
3
  //#region src/wasm/abi.ts
4
4
  /** Imports 0.2.122 may request. Instantiation fails if anything else appears. */
5
5
  const ALLOWED_WASM_IMPORTS = [{
@@ -121,21 +121,32 @@ async function instantiateCryptoWasm(bytes) {
121
121
  //#endregion
122
122
  //#region src/wasm/adapter.ts
123
123
  /**
124
+ * Run `fn` unless the instance is already poisoned; a `WebAssembly.RuntimeError` aborts the
125
+ * instance, so it is converted to {@link WasmPoisonedError} and rethrown on every later call.
126
+ */
127
+ function runPoisoned(poison, fn) {
128
+ if (poison.error !== void 0) throw poison.error;
129
+ try {
130
+ return fn();
131
+ } catch (error) {
132
+ if (error instanceof WebAssembly.RuntimeError) {
133
+ poison.error = new WasmPoisonedError("wasm instance aborted", { cause: error });
134
+ throw poison.error;
135
+ }
136
+ throw error;
137
+ }
138
+ }
139
+ /**
124
140
  * Build the WASM event verifier on {@link createEventVerifier}. A `WebAssembly.RuntimeError` from
125
141
  * the module means the instance aborted — it poisons every later call with the same
126
- * `WasmVerifyPoisonedError`; any other backend error verifies `false` (the event is marked
127
- * failed).
142
+ * `WasmPoisonedError`; any other backend error verifies `false` (the event is marked failed).
128
143
  */
129
144
  function createWasmEventVerifier(verifySerialized, poison) {
130
145
  const backend = (serializedUtf8, id, pubkey, sig) => {
131
- if (poison.error !== void 0) throw poison.error;
132
146
  try {
133
- return verifySerialized(serializedUtf8, id, pubkey, sig);
147
+ return runPoisoned(poison, () => verifySerialized(serializedUtf8, id, pubkey, sig));
134
148
  } catch (error) {
135
- if (error instanceof WebAssembly.RuntimeError) {
136
- poison.error = new WasmVerifyPoisonedError("wasm verify aborted the instance", { cause: error });
137
- throw poison.error;
138
- }
149
+ if (error instanceof WasmPoisonedError) throw error;
139
150
  return false;
140
151
  }
141
152
  };
@@ -154,26 +165,14 @@ async function fetchWasmUrl(url) {
154
165
  function requireByteLength(bytes, expected, label) {
155
166
  if (bytes.length !== expected) throw new CryptoError(`invalid ${label} length: expected ${expected}, got ${bytes.length}`);
156
167
  }
157
- function wrapPoison(poison, fn) {
158
- if (poison.error) throw poison.error;
159
- try {
160
- return fn();
161
- } catch (error) {
162
- if (error instanceof WebAssembly.RuntimeError) {
163
- poison.error = new WasmVerifyPoisonedError("wasm verify aborted the instance", { cause: error });
164
- throw poison.error;
165
- }
166
- throw error;
167
- }
168
- }
169
168
  function bindExports(exports) {
170
169
  const poison = {};
171
170
  const rawSerialized = (serializedUtf8, id, pubkey, sig) => wasmVerifySerialized(exports, serializedUtf8, id, pubkey, sig);
172
171
  return {
173
- verify: (id, pubkey, sig) => wrapPoison(poison, () => wasmVerify(exports, id, pubkey, sig)),
174
- verifySerialized: (serializedUtf8, id, pubkey, sig) => wrapPoison(poison, () => rawSerialized(serializedUtf8, id, pubkey, sig)),
172
+ verify: (id, pubkey, sig) => runPoisoned(poison, () => wasmVerify(exports, id, pubkey, sig)),
173
+ verifySerialized: (serializedUtf8, id, pubkey, sig) => runPoisoned(poison, () => rawSerialized(serializedUtf8, id, pubkey, sig)),
175
174
  verifyEvent: createWasmEventVerifier(rawSerialized, poison),
176
- sign: (id, seckey, aux) => wrapPoison(poison, () => {
175
+ sign: (id, seckey, aux) => runPoisoned(poison, () => {
177
176
  requireByteLength(id, 32, "id");
178
177
  requireByteLength(seckey, 32, "secret key");
179
178
  requireByteLength(aux, 32, "aux");
@@ -181,7 +180,7 @@ function bindExports(exports) {
181
180
  if (sig.length !== 64) throw new CryptoError("wasm sign failed");
182
181
  return sig;
183
182
  }),
184
- publicKey: (seckey) => wrapPoison(poison, () => {
183
+ publicKey: (seckey) => runPoisoned(poison, () => {
185
184
  requireByteLength(seckey, 32, "secret key");
186
185
  const pk = wasmPublicKey(exports, seckey);
187
186
  if (pk.length !== 32) throw new CryptoError("wasm publicKey failed");
@@ -218,4 +217,4 @@ function createNostrWasmLoader(wasmBytes) {
218
217
  //#endregion
219
218
  export { fetchWasmUrl as n, isWasmBytes as r, createNostrWasmLoader as t };
220
219
 
221
- //# sourceMappingURL=instance-DQE8BoWt.mjs.map
220
+ //# sourceMappingURL=instance-C62w3cEt.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instance-C62w3cEt.mjs","names":[],"sources":["../src/wasm/abi.ts","../src/wasm/adapter.ts","../src/wasm/instance.ts"],"sourcesContent":["/** Wasm-bindgen 0.2.122 bundler-produced exports used by interned TS glue. */\nexport type CryptoWasmExports = {\n memory: WebAssembly.Memory;\n verify: (\n idPtr: number,\n idLen: number,\n pkPtr: number,\n pkLen: number,\n sigPtr: number,\n sigLen: number,\n ) => number;\n verify_serialized: (\n serPtr: number,\n serLen: number,\n idPtr: number,\n idLen: number,\n pkPtr: number,\n pkLen: number,\n sigPtr: number,\n sigLen: number,\n ) => number;\n sign: (\n retptr: number,\n idPtr: number,\n idLen: number,\n skPtr: number,\n skLen: number,\n auxPtr: number,\n auxLen: number,\n ) => void;\n public_key: (retptr: number, skPtr: number, skLen: number) => void;\n /** 0.2.122 name for `__wbindgen_malloc(size, align)`. */\n __wbindgen_export: (size: number, align: number) => number;\n /** 0.2.122 name for `__wbindgen_free(ptr, size, align)` after malloc claimed `__wbindgen_export`. */\n __wbindgen_export2: (ptr: number, size: number, align: number) => void;\n __wbindgen_add_to_stack_pointer: (delta: number) => number;\n __wbindgen_start?: () => void;\n};\n\n/** Imports 0.2.122 may request. Instantiation fails if anything else appears. */\nexport const ALLOWED_WASM_IMPORTS: ReadonlyArray<{ module: string; name: string }> = [\n { module: \"wbg\", name: \"__wbindgen_throw\" },\n { module: \"./nostr_crypto_wasm_bg.js\", name: \"__wbindgen_throw\" },\n];\n\nconst utf8 = new TextDecoder();\n\nfunction decodeUtf8(memory: WebAssembly.Memory, ptr: number, len: number): string {\n return utf8.decode(new Uint8Array(memory.buffer, ptr, len));\n}\n\nfunction makeWbgImports(holder: { exports?: CryptoWasmExports }): WebAssembly.Imports {\n const throwRuntime = (ptr: number, len: number): never => {\n const mem = holder.exports?.memory;\n const msg = mem ? decodeUtf8(mem, ptr, len) : \"wasm panic\";\n throw new WebAssembly.RuntimeError(msg);\n };\n const wbg = {\n __wbindgen_throw: throwRuntime,\n };\n return {\n wbg,\n \"./nostr_crypto_wasm_bg.js\": wbg,\n };\n}\n\n/** Fail if the module imports anything outside {@link ALLOWED_WASM_IMPORTS}. */\nexport function assertAllowedWasmImports(mod: WebAssembly.Module): void {\n const allowed = new Set(ALLOWED_WASM_IMPORTS.map((item) => `${item.module}\\0${item.name}`));\n for (const imp of WebAssembly.Module.imports(mod)) {\n if (imp.kind !== \"function\") {\n throw new TypeError(`unexpected wasm import kind ${imp.kind}: ${imp.module}.${imp.name}`);\n }\n if (!allowed.has(`${imp.module}\\0${imp.name}`)) {\n throw new TypeError(`unexpected wasm import ${imp.module}.${imp.name}`);\n }\n }\n}\n\nfunction requireMemory(value: WebAssembly.ExportValue | undefined): WebAssembly.Memory {\n if (!(value instanceof WebAssembly.Memory)) {\n throw new TypeError(\"wasm missing memory export\");\n }\n return value;\n}\n\n// oxlint-disable-next-line no-unnecessary-type-parameters -- T binds the declared ABI signature at each call site\nfunction requireFn<T extends (...args: number[]) => unknown>(\n value: WebAssembly.ExportValue | undefined,\n name: string,\n): T {\n if (typeof value !== \"function\") {\n throw new TypeError(`wasm missing ${name} export`);\n }\n // oxlint-disable-next-line no-unsafe-type-assertion -- wasm exports are opaque; each name is bound to the signature the ABI contract requires\n return value as T;\n}\n\nfunction asExports(raw: WebAssembly.Exports): CryptoWasmExports {\n const exports: CryptoWasmExports = {\n memory: requireMemory(raw[\"memory\"]),\n verify: requireFn(raw[\"verify\"], \"verify\"),\n verify_serialized: requireFn(raw[\"verify_serialized\"], \"verify_serialized\"),\n sign: requireFn(raw[\"sign\"], \"sign\"),\n public_key: requireFn(raw[\"public_key\"], \"public_key\"),\n __wbindgen_export: requireFn(raw[\"__wbindgen_export\"], \"__wbindgen_export\"),\n __wbindgen_export2: requireFn(raw[\"__wbindgen_export2\"], \"__wbindgen_export2\"),\n __wbindgen_add_to_stack_pointer: requireFn(\n raw[\"__wbindgen_add_to_stack_pointer\"],\n \"__wbindgen_add_to_stack_pointer\",\n ),\n };\n const start = raw[\"__wbindgen_start\"];\n if (typeof start === \"function\") {\n exports.__wbindgen_start = requireFn<() => void>(start, \"__wbindgen_start\");\n }\n return exports;\n}\n\nfunction passBytes(exports: CryptoWasmExports, bytes: Uint8Array): { ptr: number; len: number } {\n const len = bytes.length;\n const ptr = exports.__wbindgen_export(len, 1) >>> 0;\n new Uint8Array(exports.memory.buffer, ptr, len).set(bytes);\n return { ptr, len };\n}\n\nexport function wasmVerify(\n exports: CryptoWasmExports,\n id: Uint8Array,\n pubkey: Uint8Array,\n sig: Uint8Array,\n): boolean {\n const idP = passBytes(exports, id);\n const pkP = passBytes(exports, pubkey);\n const sigP = passBytes(exports, sig);\n return exports.verify(idP.ptr, idP.len, pkP.ptr, pkP.len, sigP.ptr, sigP.len) !== 0;\n}\n\nexport function wasmVerifySerialized(\n exports: CryptoWasmExports,\n serialized: Uint8Array,\n id: Uint8Array,\n pubkey: Uint8Array,\n sig: Uint8Array,\n): boolean {\n const serP = passBytes(exports, serialized);\n const idP = passBytes(exports, id);\n const pkP = passBytes(exports, pubkey);\n const sigP = passBytes(exports, sig);\n return (\n exports.verify_serialized(\n serP.ptr,\n serP.len,\n idP.ptr,\n idP.len,\n pkP.ptr,\n pkP.len,\n sigP.ptr,\n sigP.len,\n ) !== 0\n );\n}\n\nfunction takeBytes(exports: CryptoWasmExports, ptr: number, len: number): Uint8Array {\n const out = new Uint8Array(len);\n if (len > 0) {\n out.set(new Uint8Array(exports.memory.buffer, ptr, len));\n exports.__wbindgen_export2(ptr, len, 1);\n }\n return out;\n}\n\nfunction callReturningBytes(\n exports: CryptoWasmExports,\n invoke: (retptr: number) => void,\n): Uint8Array {\n const retptr = exports.__wbindgen_add_to_stack_pointer(-16);\n try {\n invoke(retptr);\n const view = new DataView(exports.memory.buffer);\n const ptr = view.getUint32(retptr, true);\n const len = view.getUint32(retptr + 4, true);\n return takeBytes(exports, ptr, len);\n } finally {\n exports.__wbindgen_add_to_stack_pointer(16);\n }\n}\n\nexport function wasmSign(\n exports: CryptoWasmExports,\n id: Uint8Array,\n seckey: Uint8Array,\n aux: Uint8Array,\n): Uint8Array {\n const idP = passBytes(exports, id);\n const skP = passBytes(exports, seckey);\n const auxP = passBytes(exports, aux);\n return callReturningBytes(exports, (retptr) => {\n exports.sign(retptr, idP.ptr, idP.len, skP.ptr, skP.len, auxP.ptr, auxP.len);\n });\n}\n\nexport function wasmPublicKey(exports: CryptoWasmExports, seckey: Uint8Array): Uint8Array {\n const skP = passBytes(exports, seckey);\n return callReturningBytes(exports, (retptr) => {\n exports.public_key(retptr, skP.ptr, skP.len);\n });\n}\n\nexport async function instantiateCryptoWasm(\n bytes: ArrayBuffer | ArrayBufferView,\n): Promise<CryptoWasmExports> {\n const holder: { exports?: CryptoWasmExports } = {};\n const { module, instance } = await WebAssembly.instantiate(bytes, makeWbgImports(holder));\n assertAllowedWasmImports(module);\n holder.exports = asExports(instance.exports);\n holder.exports.__wbindgen_start?.();\n return holder.exports;\n}\n","import { WasmPoisonedError } from \"../core/error.ts\";\nimport { createEventVerifier } from \"../core/verifier.ts\";\nimport type { EventVerifier, SerializedEventVerifier } from \"../core/verifier.ts\";\n\nexport { WasmPoisonedError } from \"../core/error.ts\";\n\n/**\n * Run `fn` unless the instance is already poisoned; a `WebAssembly.RuntimeError` aborts the\n * instance, so it is converted to {@link WasmPoisonedError} and rethrown on every later call.\n */\nexport function runPoisoned<T>(poison: { error?: Error }, fn: () => T): T {\n if (poison.error !== undefined) {\n throw poison.error;\n }\n try {\n return fn();\n } catch (error) {\n if (error instanceof WebAssembly.RuntimeError) {\n poison.error = new WasmPoisonedError(\"wasm instance aborted\", {\n cause: error,\n });\n throw poison.error;\n }\n throw error;\n }\n}\n\n/**\n * Build the WASM event verifier on {@link createEventVerifier}. A `WebAssembly.RuntimeError` from\n * the module means the instance aborted — it poisons every later call with the same\n * `WasmPoisonedError`; any other backend error verifies `false` (the event is marked failed).\n */\nexport function createWasmEventVerifier(\n verifySerialized: SerializedEventVerifier,\n poison: { error?: Error },\n): EventVerifier {\n const backend: SerializedEventVerifier = (serializedUtf8, id, pubkey, sig) => {\n try {\n return runPoisoned(poison, () => verifySerialized(serializedUtf8, id, pubkey, sig));\n } catch (error) {\n if (error instanceof WasmPoisonedError) {\n throw error;\n }\n return false;\n }\n };\n return createEventVerifier(backend);\n}\n","import { CryptoError } from \"../core/error.ts\";\nimport type { SigningBackend } from \"../core/key.ts\";\nimport type { EventVerifier } from \"../core/verifier.ts\";\nimport {\n instantiateCryptoWasm,\n wasmPublicKey,\n wasmSign,\n wasmVerify,\n wasmVerifySerialized,\n} from \"./abi.ts\";\nimport type { CryptoWasmExports } from \"./abi.ts\";\nimport { createWasmEventVerifier, runPoisoned } from \"./adapter.ts\";\n\nexport type LoadNostrWasmOptions = {\n /** Bytes, or a URL whose bytes will be read by the platform loader. */\n module?: ArrayBuffer | ArrayBufferView | URL | undefined;\n};\n\nexport type NostrWasm = SigningBackend & {\n verify: (id: Uint8Array, pubkey: Uint8Array, sig: Uint8Array) => boolean;\n verifySerialized: (\n serializedUtf8: Uint8Array,\n id: Uint8Array,\n pubkey: Uint8Array,\n sig: Uint8Array,\n ) => boolean;\n verifyEvent: EventVerifier;\n};\n\nexport function isWasmBytes(value: unknown): value is ArrayBuffer | ArrayBufferView {\n return value instanceof ArrayBuffer || ArrayBuffer.isView(value);\n}\n\nexport async function fetchWasmUrl(url: URL): Promise<Uint8Array> {\n const res = await fetch(url);\n if (!res.ok) {\n throw new CryptoError(`failed to fetch wasm: ${res.status} ${url.href}`);\n }\n return new Uint8Array(await res.arrayBuffer());\n}\n\nfunction requireByteLength(bytes: Uint8Array, expected: number, label: string): void {\n if (bytes.length !== expected) {\n throw new CryptoError(`invalid ${label} length: expected ${expected}, got ${bytes.length}`);\n }\n}\n\nfunction bindExports(exports: CryptoWasmExports): NostrWasm {\n const poison: { error?: Error } = {};\n const rawSerialized = (\n serializedUtf8: Uint8Array,\n id: Uint8Array,\n pubkey: Uint8Array,\n sig: Uint8Array,\n ): boolean => wasmVerifySerialized(exports, serializedUtf8, id, pubkey, sig);\n return {\n verify: (id, pubkey, sig) => runPoisoned(poison, () => wasmVerify(exports, id, pubkey, sig)),\n verifySerialized: (serializedUtf8, id, pubkey, sig) =>\n runPoisoned(poison, () => rawSerialized(serializedUtf8, id, pubkey, sig)),\n verifyEvent: createWasmEventVerifier(rawSerialized, poison),\n sign: (id, seckey, aux) =>\n runPoisoned(poison, () => {\n requireByteLength(id, 32, \"id\");\n requireByteLength(seckey, 32, \"secret key\");\n requireByteLength(aux, 32, \"aux\");\n const sig = wasmSign(exports, id, seckey, aux);\n if (sig.length !== 64) {\n throw new CryptoError(\"wasm sign failed\");\n }\n return sig;\n }),\n publicKey: (seckey) =>\n runPoisoned(poison, () => {\n requireByteLength(seckey, 32, \"secret key\");\n const pk = wasmPublicKey(exports, seckey);\n if (pk.length !== 32) {\n throw new CryptoError(\"wasm publicKey failed\");\n }\n return pk;\n }),\n };\n}\n\n/** Builds a loader that interns a single instance per module slot. */\nexport function createNostrWasmLoader(\n wasmBytes: (opts?: LoadNostrWasmOptions) => Promise<ArrayBuffer | ArrayBufferView>,\n): {\n loadNostrWasm: (opts?: LoadNostrWasmOptions) => Promise<NostrWasm>;\n resetNostrWasm: () => void;\n} {\n let interned: Promise<NostrWasm> | undefined;\n\n async function instantiate(opts?: LoadNostrWasmOptions): Promise<NostrWasm> {\n const bytes = await wasmBytes(opts);\n const exports = await instantiateCryptoWasm(bytes);\n return bindExports(exports);\n }\n\n /** Instantiate once. Repeats reuse the same module. Failure throws; no noble fallback. */\n async function loadNostrWasm(opts?: LoadNostrWasmOptions): Promise<NostrWasm> {\n if (interned) {\n return interned;\n }\n const pending = instantiate(opts);\n interned = pending;\n try {\n return await pending;\n } catch (error) {\n if (interned === pending) {\n interned = undefined;\n }\n throw error;\n }\n }\n\n function resetNostrWasm(): void {\n interned = undefined;\n }\n\n return { loadNostrWasm, resetNostrWasm };\n}\n"],"mappings":"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"}
@@ -1,15 +1,15 @@
1
- import { t as Event } from "./event-fU3Y01PR.mjs";
2
- import { i as SigningBackend } from "./key-Cv4_pN3x.mjs";
1
+ import { a as SigningBackend } from "./key-D_5OgGT7.mjs";
2
+ import { t as EventVerifier } from "./verifier-CgTFpgsC.mjs";
3
3
  //#region src/wasm/instance.d.ts
4
4
  type LoadNostrWasmOptions = {
5
5
  /** Bytes, or a URL whose bytes will be read by the platform loader. */
6
- module?: ArrayBuffer | ArrayBufferView | URL;
6
+ module?: ArrayBuffer | ArrayBufferView | URL | undefined;
7
7
  };
8
8
  type NostrWasm = SigningBackend & {
9
9
  verify: (id: Uint8Array, pubkey: Uint8Array, sig: Uint8Array) => boolean;
10
10
  verifySerialized: (serializedUtf8: Uint8Array, id: Uint8Array, pubkey: Uint8Array, sig: Uint8Array) => boolean;
11
- verifyEvent: (event: Event) => boolean;
11
+ verifyEvent: EventVerifier;
12
12
  };
13
13
  //#endregion
14
14
  export { NostrWasm as n, LoadNostrWasmOptions as t };
15
- //# sourceMappingURL=instance-CIca-ynn.d.mts.map
15
+ //# sourceMappingURL=instance-DjsL8h84.d.mts.map
@@ -1,4 +1,4 @@
1
- import { n as EventTemplate, r as UnsignedEvent, t as Event } from "./event-fU3Y01PR.mjs";
1
+ import { n as EventTemplate, r as UnsignedEvent, t as Event } from "./event-DJeb_DIL.mjs";
2
2
  //#region src/core/key.d.ts
3
3
  /** 32-byte secret key held as bytes; prefer zeroize when done. */
4
4
  declare class SecretKey {
@@ -12,6 +12,10 @@ declare class SecretKey {
12
12
  /** Best-effort wipe of the internal buffer. */
13
13
  zeroize(): void;
14
14
  }
15
+ /** Anything a secret key can be given as: instance, raw bytes, or hex. */
16
+ type SecretKeyInput = SecretKey | Uint8Array | string;
17
+ /** Coerce a {@link SecretKeyInput} to {@link SecretKey}. */
18
+ declare function toSecretKey(input: SecretKeyInput): SecretKey;
15
19
  /** Lowercase hex-encoded secp256k1 public key (x-only, 64 chars). */
16
20
  type PublicKey = string;
17
21
  /** Validate and normalize a hex public key; throws {@link HexError} on bad input. */
@@ -26,7 +30,7 @@ type SigningBackend = {
26
30
  sign: (id: Uint8Array, secretKey: Uint8Array, auxRand: Uint8Array) => Uint8Array;
27
31
  };
28
32
  /** Derive the public key for a secret key given as SecretKey, bytes, or hex. */
29
- declare function getPublicKey(secretKey: SecretKey | Uint8Array | string): PublicKey;
33
+ declare function getPublicKey(secretKey: SecretKeyInput): PublicKey;
30
34
  /** Keypair convenience wrapper. */
31
35
  declare class Keys {
32
36
  readonly secretKey: SecretKey;
@@ -39,15 +43,15 @@ declare class Keys {
39
43
  readonly backend: SigningBackend;
40
44
  private constructor();
41
45
  static generate(backend?: SigningBackend): Keys;
42
- static fromSecretKey(secretKey: SecretKey | Uint8Array | string, backend?: SigningBackend): Keys;
46
+ static fromSecretKey(secretKey: SecretKeyInput, backend?: SigningBackend): Keys;
43
47
  }
44
48
  /** Fill pubkey/id/sig on a template and return a signed event. */
45
- declare function finalizeEvent(template: EventTemplate, secretKey: SecretKey | Uint8Array | string | Keys): Event;
49
+ declare function finalizeEvent(template: EventTemplate, secretKey: SecretKeyInput | Keys): Event;
46
50
  /**
47
51
  * Sign an already-assembled unsigned event. Rejects when `unsigned.pubkey` does not match the
48
52
  * secret key.
49
53
  */
50
- declare function signEvent(unsigned: UnsignedEvent, secretKey: SecretKey | Uint8Array | string | Keys): Event;
54
+ declare function signEvent(unsigned: UnsignedEvent, secretKey: SecretKeyInput | Keys): Event;
51
55
  //#endregion
52
- export { finalizeEvent as a, signEvent as c, SigningBackend as i, PublicKey as n, getPublicKey as o, SecretKey as r, publicKeyFromHex as s, Keys as t };
53
- //# sourceMappingURL=key-Cv4_pN3x.d.mts.map
56
+ export { SigningBackend as a, publicKeyFromHex as c, SecretKeyInput as i, signEvent as l, PublicKey as n, finalizeEvent as o, SecretKey as r, getPublicKey as s, Keys as t, toSecretKey as u };
57
+ //# sourceMappingURL=key-D_5OgGT7.d.mts.map
@@ -1,5 +1,5 @@
1
- import { a as hexToBytes$1, f as CryptoError, i as bytesToHex$1, n as assertHex32, r as assertSecretKeyBytes } from "./util-LfQirgDk.mjs";
2
- import { c as markVerified, n as getEventHash, p as validateEvent } from "./event-D8Nfoh4K.mjs";
1
+ import { a as hexToBytes$1, h as EventValidationError, i as bytesToHex$1, m as CryptoError, n as assertHex32, r as assertSecretKeyBytes } from "./util-DMF9AIO0.mjs";
2
+ import { c as markVerified, n as getEventHash, p as validateEvent } from "./event-CHf47dPM.mjs";
3
3
  import { randomBytes } from "@noble/hashes/utils.js";
4
4
  import { schnorr } from "@noble/curves/secp256k1.js";
5
5
  //#region src/core/key.ts
@@ -34,6 +34,12 @@ var SecretKey = class SecretKey {
34
34
  }
35
35
  }
36
36
  };
37
+ /** Coerce a {@link SecretKeyInput} to {@link SecretKey}. */
38
+ function toSecretKey(input) {
39
+ if (input instanceof SecretKey) return input;
40
+ if (typeof input === "string") return SecretKey.fromHex(input);
41
+ return SecretKey.fromBytes(input);
42
+ }
37
43
  /** Validate and normalize a hex public key; throws {@link HexError} on bad input. */
38
44
  function publicKeyFromHex(hex) {
39
45
  return assertHex32(hex, "public key");
@@ -44,8 +50,7 @@ const nobleSigning = {
44
50
  };
45
51
  /** Derive the public key for a secret key given as SecretKey, bytes, or hex. */
46
52
  function getPublicKey(secretKey) {
47
- const bytes = secretKey instanceof SecretKey ? secretKey.bytes : typeof secretKey === "string" ? hexToBytes$1(assertHex32(secretKey, "secret key")) : (assertSecretKeyBytes(secretKey), secretKey);
48
- return bytesToHex$1(schnorr.getPublicKey(bytes));
53
+ return bytesToHex$1(schnorr.getPublicKey(toSecretKey(secretKey).bytes));
49
54
  }
50
55
  /** Keypair convenience wrapper. */
51
56
  var Keys = class Keys {
@@ -68,8 +73,7 @@ var Keys = class Keys {
68
73
  return new Keys(SecretKey.generate(), backend);
69
74
  }
70
75
  static fromSecretKey(secretKey, backend = nobleSigning) {
71
- const sk = secretKey instanceof SecretKey ? secretKey : typeof secretKey === "string" ? SecretKey.fromHex(secretKey) : SecretKey.fromBytes(secretKey);
72
- return new Keys(sk, backend);
76
+ return new Keys(toSecretKey(secretKey), backend);
73
77
  }
74
78
  };
75
79
  function resolveKeys(secretKey) {
@@ -92,7 +96,7 @@ function finalizeEvent(template, secretKey) {
92
96
  */
93
97
  function signEvent(unsigned, secretKey) {
94
98
  const keys = resolveKeys(secretKey);
95
- if (!validateEvent(unsigned)) throw new CryptoError("cannot sign invalid unsigned event");
99
+ if (!validateEvent(unsigned)) throw new EventValidationError("cannot sign invalid unsigned event");
96
100
  if (unsigned.pubkey !== keys.publicKey) throw new CryptoError("unsigned event pubkey does not match secret key");
97
101
  const normalized = {
98
102
  kind: unsigned.kind,
@@ -113,6 +117,6 @@ function signEvent(unsigned, secretKey) {
113
117
  return event;
114
118
  }
115
119
  //#endregion
116
- export { publicKeyFromHex as a, getPublicKey as i, SecretKey as n, signEvent as o, finalizeEvent as r, Keys as t };
120
+ export { publicKeyFromHex as a, getPublicKey as i, SecretKey as n, signEvent as o, finalizeEvent as r, toSecretKey as s, Keys as t };
117
121
 
118
- //# sourceMappingURL=key-Bps-LqX7.mjs.map
122
+ //# sourceMappingURL=key-DnVpchl6.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-DnVpchl6.mjs","names":["hexToBytes","bytesToHex"],"sources":["../src/core/key.ts"],"sourcesContent":["import { schnorr } from \"@noble/curves/secp256k1.js\";\nimport { randomBytes } from \"@noble/hashes/utils.js\";\n\nimport { CryptoError, EventValidationError } from \"./error.ts\";\nimport { getEventHash, markVerified, validateEvent } from \"./event.ts\";\nimport type { Event, EventTemplate, UnsignedEvent } from \"./event.ts\";\nimport { assertHex32, assertSecretKeyBytes, bytesToHex, hexToBytes } from \"./util.ts\";\n\n/** 32-byte secret key held as bytes; prefer zeroize when done. */\nexport class SecretKey {\n #bytes: Uint8Array | undefined;\n\n private constructor(bytes: Uint8Array) {\n assertSecretKeyBytes(bytes);\n this.#bytes = new Uint8Array(bytes);\n }\n\n static generate(): SecretKey {\n return new SecretKey(schnorr.utils.randomSecretKey());\n }\n\n static fromBytes(bytes: Uint8Array): SecretKey {\n return new SecretKey(bytes);\n }\n\n static fromHex(hex: string): SecretKey {\n return new SecretKey(hexToBytes(assertHex32(hex, \"secret key\")));\n }\n\n get bytes(): Uint8Array {\n if (!this.#bytes) {\n throw new CryptoError(\"secret key has been zeroized\");\n }\n return new Uint8Array(this.#bytes);\n }\n\n toHex(): string {\n return bytesToHex(this.bytes);\n }\n\n /** Best-effort wipe of the internal buffer. */\n zeroize(): void {\n if (this.#bytes) {\n this.#bytes.fill(0);\n this.#bytes = undefined;\n }\n }\n}\n\n/** Anything a secret key can be given as: instance, raw bytes, or hex. */\nexport type SecretKeyInput = SecretKey | Uint8Array | string;\n\n/** Coerce a {@link SecretKeyInput} to {@link SecretKey}. */\nexport function toSecretKey(input: SecretKeyInput): SecretKey {\n if (input instanceof SecretKey) {\n return input;\n }\n if (typeof input === \"string\") {\n return SecretKey.fromHex(input);\n }\n return SecretKey.fromBytes(input);\n}\n\n/** Lowercase hex-encoded secp256k1 public key (x-only, 64 chars). */\nexport type PublicKey = string;\n\n/** Validate and normalize a hex public key; throws {@link HexError} on bad input. */\nexport function publicKeyFromHex(hex: string): PublicKey {\n return assertHex32(hex, \"public key\");\n}\n\n/**\n * BIP-340 signing backend. `publicKey` returns the 32-byte x-only public key of a 32-byte secret\n * key; `sign` returns the 64-byte BIP-340 signature of a 32-byte `id` using 32 bytes of auxiliary\n * randomness. Both throw on invalid input (for example an out-of-range secret key).\n */\nexport type SigningBackend = {\n publicKey: (secretKey: Uint8Array) => Uint8Array;\n sign: (id: Uint8Array, secretKey: Uint8Array, auxRand: Uint8Array) => Uint8Array;\n};\n\nconst nobleSigning: SigningBackend = {\n publicKey: (secretKey) => schnorr.getPublicKey(secretKey),\n sign: (id, secretKey, auxRand) => schnorr.sign(id, secretKey, auxRand),\n};\n\n/** Derive the public key for a secret key given as SecretKey, bytes, or hex. */\nexport function getPublicKey(secretKey: SecretKeyInput): PublicKey {\n return bytesToHex(schnorr.getPublicKey(toSecretKey(secretKey).bytes));\n}\n\n/** Keypair convenience wrapper. */\nexport class Keys {\n readonly secretKey: SecretKey;\n readonly publicKey: PublicKey;\n /**\n * BIP-340 backend that derived {@link publicKey} and signs in {@link finalizeEvent}/\n * {@link signEvent}. Defaults to noble; pass a loaded `NostrWasm` module or a native backend to\n * delegate signing.\n */\n readonly backend: SigningBackend;\n\n private constructor(secretKey: SecretKey, backend: SigningBackend) {\n this.secretKey = secretKey;\n this.backend = backend;\n const pubkey = backend.publicKey(secretKey.bytes);\n if (pubkey.length !== 32) {\n throw new CryptoError(\"signing backend returned an invalid public key\");\n }\n this.publicKey = bytesToHex(pubkey);\n }\n\n static generate(backend: SigningBackend = nobleSigning): Keys {\n return new Keys(SecretKey.generate(), backend);\n }\n\n static fromSecretKey(secretKey: SecretKeyInput, backend: SigningBackend = nobleSigning): Keys {\n return new Keys(toSecretKey(secretKey), backend);\n }\n}\n\nfunction resolveKeys(secretKey: SecretKeyInput | Keys): Keys {\n return secretKey instanceof Keys ? secretKey : Keys.fromSecretKey(secretKey);\n}\n\n/** Fill pubkey/id/sig on a template and return a signed event. */\nexport function finalizeEvent(template: EventTemplate, secretKey: SecretKeyInput | Keys): Event {\n const keys = resolveKeys(secretKey);\n const unsigned: UnsignedEvent = {\n kind: template.kind,\n tags: template.tags,\n content: template.content,\n created_at: template.created_at,\n pubkey: keys.publicKey,\n };\n return signEvent(unsigned, keys);\n}\n\n/**\n * Sign an already-assembled unsigned event. Rejects when `unsigned.pubkey` does not match the\n * secret key.\n */\nexport function signEvent(unsigned: UnsignedEvent, secretKey: SecretKeyInput | Keys): Event {\n const keys = resolveKeys(secretKey);\n if (!validateEvent(unsigned)) {\n throw new EventValidationError(\"cannot sign invalid unsigned event\");\n }\n\n if (unsigned.pubkey !== keys.publicKey) {\n throw new CryptoError(\"unsigned event pubkey does not match secret key\");\n }\n\n const normalized: UnsignedEvent = {\n kind: unsigned.kind,\n tags: unsigned.tags,\n content: unsigned.content,\n created_at: unsigned.created_at,\n pubkey: keys.publicKey,\n };\n\n const id = getEventHash(normalized);\n const sig = keys.backend.sign(hexToBytes(id), keys.secretKey.bytes, randomBytes(32));\n if (sig.length !== 64) {\n throw new CryptoError(\"signing backend returned an invalid signature\");\n }\n const event: Event = { ...normalized, id, sig: bytesToHex(sig) };\n markVerified(event);\n return event;\n}\n"],"mappings":"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"}
@@ -1,12 +1,16 @@
1
- import { g as NostrError, l as normalizeURL, o as isHex32 } from "./util-LfQirgDk.mjs";
1
+ import { c as isRecord, d as nowSeconds, l as normalizeRelayUrls, o as isHex32, v as NostrError } from "./util-DMF9AIO0.mjs";
2
2
  import { r as isAddressableKind, t as Kind } from "./kind-Cxwhhkx8.mjs";
3
- import { _ as formatEventAddress, f as sortedEvents } from "./event-D8Nfoh4K.mjs";
3
+ import { f as sortedEvents, v as formatEventAddress } from "./event-CHf47dPM.mjs";
4
4
  import { t as invokeSafely } from "./report-CHld4uWj.mjs";
5
5
  import { Nip19Error, decode, npubEncode } from "./nips/nip19.mjs";
6
6
  import { parseRelayList } from "./nips/nip65.mjs";
7
- import { r as throwIfAborted } from "./abort-Ba8tDrOI.mjs";
7
+ import "./relay-quCs7MHD.mjs";
8
+ import { i as throwIfAborted } from "./abort-DBq2STPj.mjs";
9
+ import { i as trimOldest, r as touchKey } from "./collections-DtwMc1NU.mjs";
8
10
  import { parseDmRelayList } from "./nips/nip17.mjs";
9
- import { n as toStorageError } from "./error-DrEIM7FO.mjs";
11
+ import { parseMuteList } from "./nips/nip51.mjs";
12
+ import { n as toStorageError } from "./error-BILMe3Gr.mjs";
13
+ import { r as outboxBoundKey } from "./put-w13ci3sC.mjs";
10
14
  //#region src/loaders/context.ts
11
15
  /** Internal dependency bag for loaders — never a module-level singleton. */
12
16
  var LoaderContext = class {
@@ -37,7 +41,7 @@ var LoaderContext = class {
37
41
  setRelays(urls) {
38
42
  this.#relays = [...urls];
39
43
  }
40
- isFresh(fetchedAt, now = Math.floor(Date.now() / 1e3)) {
44
+ isFresh(fetchedAt, now = nowSeconds()) {
41
45
  return now - fetchedAt < this.staleAfterSec;
42
46
  }
43
47
  };
@@ -164,31 +168,16 @@ function createListLoaders(replaceable) {
164
168
  },
165
169
  async muteList(pubkey, opts) {
166
170
  const { event, fresh } = await muteLoader(pubkey, opts);
171
+ let items = [];
172
+ if (event) try {
173
+ items = parseMuteList(event);
174
+ } catch {
175
+ items = [];
176
+ }
167
177
  return {
168
178
  event,
169
179
  fresh,
170
- items: fromTags(event, (tag) => {
171
- if (tag[1] === void 0 || tag[1] === "") return;
172
- switch (tag[0]) {
173
- case "p": return isHex32(tag[1].toLowerCase()) ? {
174
- label: "pubkey",
175
- value: tag[1].toLowerCase()
176
- } : void 0;
177
- case "e": return isHex32(tag[1].toLowerCase()) ? {
178
- label: "thread",
179
- value: tag[1].toLowerCase()
180
- } : void 0;
181
- case "t": return {
182
- label: "hashtag",
183
- value: tag[1]
184
- };
185
- case "word": return {
186
- label: "word",
187
- value: tag[1]
188
- };
189
- default: return;
190
- }
191
- })
180
+ items
192
181
  };
193
182
  },
194
183
  async relayList(pubkey, opts) {
@@ -199,16 +188,6 @@ function createListLoaders(replaceable) {
199
188
  } catch {
200
189
  items = [];
201
190
  }
202
- items = items.map((i) => {
203
- try {
204
- return {
205
- ...i,
206
- url: normalizeURL(i.url)
207
- };
208
- } catch {
209
- return i;
210
- }
211
- });
212
191
  return {
213
192
  event,
214
193
  fresh,
@@ -255,11 +234,27 @@ function bareNostrUser(pubkey) {
255
234
  function nonEmpty(value) {
256
235
  return typeof value === "string" && value !== "" ? value : void 0;
257
236
  }
237
+ const PROFILE_METADATA_KEYS = [
238
+ "name",
239
+ "display_name",
240
+ "about",
241
+ "picture",
242
+ "banner",
243
+ "website",
244
+ "nip05",
245
+ "lud06",
246
+ "lud16"
247
+ ];
258
248
  function parseMetadata(content) {
259
249
  try {
260
250
  const obj = JSON.parse(content);
261
- if (typeof obj !== "object" || obj === null) return {};
262
- return obj;
251
+ if (!isRecord(obj)) return {};
252
+ const out = {};
253
+ for (const key of PROFILE_METADATA_KEYS) {
254
+ const value = obj[key];
255
+ if (typeof value === "string") out[key] = value;
256
+ }
257
+ return out;
263
258
  } catch {
264
259
  return {};
265
260
  }
@@ -390,16 +385,11 @@ const MAX_FETCHED_AT = 1e4;
390
385
  function createReplaceableLoader(ctx, kind) {
391
386
  const fetchedAt = /* @__PURE__ */ new Map();
392
387
  const markFetched = (addr, hit, now) => {
393
- fetchedAt.delete(addr);
394
- fetchedAt.set(addr, {
388
+ touchKey(fetchedAt, addr, {
395
389
  at: now,
396
390
  hit
397
391
  });
398
- while (fetchedAt.size > MAX_FETCHED_AT) {
399
- const oldest = fetchedAt.keys().next().value;
400
- if (oldest === void 0) break;
401
- fetchedAt.delete(oldest);
402
- }
392
+ trimOldest(fetchedAt, MAX_FETCHED_AT);
403
393
  };
404
394
  const loader = new DataLoader(async (keys) => {
405
395
  const authors = [...new Set(keys.map((k) => k.pubkey))];
@@ -414,7 +404,7 @@ function createReplaceableLoader(ctx, kind) {
414
404
  onevent: (event, relayUrl) => ctx.ingest(event, relayUrl)
415
405
  });
416
406
  }
417
- const now = Math.floor(Date.now() / 1e3);
407
+ const now = nowSeconds();
418
408
  return keys.map((k) => {
419
409
  const addr = formatEventAddress(kind, k.pubkey, "");
420
410
  const event = ctx.index.getByAddress(addr);
@@ -458,18 +448,8 @@ function createReplaceableLoader(ctx, kind) {
458
448
  var OutboxError = class extends NostrError {
459
449
  name = "OutboxError";
460
450
  };
461
- function boundKey(pubkey, kind) {
462
- return `${pubkey.toLowerCase()}:${kind}`;
463
- }
464
- /** Same skip/dedup as Gossip.setRoutes so prefer can match Client.relays. */
465
- function canonicalRelayUrls(urls) {
466
- const out = [];
467
- for (const raw of urls) try {
468
- const url = normalizeURL(raw);
469
- if (!out.includes(url)) out.push(url);
470
- } catch {}
471
- return out;
472
- }
451
+ /** Trailing-flush delay for live bound persistence: one write per dirty bound per window. */
452
+ const BOUND_FLUSH_MS = 1e3;
473
453
  /**
474
454
  * Group authors by outbox relay (discovery fallback). `prefer` reorders existing candidates only;
475
455
  * it never appends a URL that is not already in the author's outbox or discovery list. Returns
@@ -477,8 +457,8 @@ function canonicalRelayUrls(urls) {
477
457
  */
478
458
  function groupAuthorsByOutboxRelay(authors, gossip, discoveryRelays, maxRelaysPerAuthor = 3, prefer = []) {
479
459
  const leftover = new Set((gossip.route({ authors: authors.map((a) => a.toLowerCase()) }).remainder?.authors ?? []).map((a) => a.toLowerCase()));
480
- const preferSet = new Set(canonicalRelayUrls(prefer));
481
- const discovery = canonicalRelayUrls(discoveryRelays);
460
+ const preferSet = new Set(normalizeRelayUrls(prefer));
461
+ const discovery = normalizeRelayUrls(discoveryRelays);
482
462
  const map = /* @__PURE__ */ new Map();
483
463
  for (const author of authors) {
484
464
  const pk = author.toLowerCase();
@@ -513,6 +493,9 @@ var OutboxFeed = class {
513
493
  #applySync;
514
494
  #hydrate;
515
495
  #bounds = /* @__PURE__ */ new Map();
496
+ /** Bound keys dirtied by live events since the last flush. */
497
+ #dirtyBounds = /* @__PURE__ */ new Set();
498
+ #boundTimer;
516
499
  #authors;
517
500
  #liveCloser;
518
501
  #closed = false;
@@ -542,7 +525,7 @@ var OutboxFeed = class {
542
525
  this.#authors = [...new Set(authors.map((a) => a.toLowerCase()))];
543
526
  }
544
527
  getBound(pubkey, kind) {
545
- return this.#bounds.get(boundKey(pubkey, kind));
528
+ return this.#bounds.get(outboxBoundKey(pubkey, kind));
546
529
  }
547
530
  /** Load NIP-65 relay lists for authors that have no outbox routes yet. */
548
531
  async hydrate() {
@@ -585,7 +568,7 @@ var OutboxFeed = class {
585
568
  const dirty = /* @__PURE__ */ new Set();
586
569
  for (const event of applied) {
587
570
  this.#updateBounds(event);
588
- dirty.add(boundKey(event.pubkey, event.kind));
571
+ dirty.add(outboxBoundKey(event.pubkey, event.kind));
589
572
  invokeSafely(() => this.#onEvent?.(event));
590
573
  }
591
574
  await this.#persistBounds(dirty);
@@ -601,7 +584,7 @@ var OutboxFeed = class {
601
584
  const byRelay = groupAuthorsByOutboxRelay(this.#authors, this.#gossip, this.#discovery, this.#maxRelays, this.#pool.connectedUrls());
602
585
  const seen = /* @__PURE__ */ new Set();
603
586
  const closers = [];
604
- const since = opts?.since ?? Math.floor(Date.now() / 1e3) - 60;
587
+ const since = opts?.since ?? nowSeconds() - 60;
605
588
  for (const [url, authors] of byRelay) {
606
589
  const filter = {
607
590
  authors,
@@ -641,13 +624,18 @@ var OutboxFeed = class {
641
624
  this.#closed = true;
642
625
  this.#liveCloser?.close("feed closed");
643
626
  this.#liveCloser = void 0;
627
+ if (this.#boundTimer !== void 0) {
628
+ clearTimeout(this.#boundTimer);
629
+ this.#boundTimer = void 0;
630
+ }
631
+ this.#flushBounds();
644
632
  }
645
633
  #assertOpen() {
646
634
  if (this.#closed) throw new OutboxError("OutboxFeed is closed");
647
635
  }
648
636
  async #hydrateBoundsFromStore() {
649
637
  await Promise.all(this.#authors.flatMap((pk) => this.#kinds.map(async (kind) => {
650
- const key = boundKey(pk, kind);
638
+ const key = outboxBoundKey(pk, kind);
651
639
  if (this.#bounds.has(key)) return;
652
640
  const bound = await this.#storage.getOutboxBound(pk, kind);
653
641
  if (!bound) return;
@@ -676,7 +664,7 @@ var OutboxFeed = class {
676
664
  let newest;
677
665
  let complete = true;
678
666
  for (const kind of this.#kinds) {
679
- const b = this.#bounds.get(boundKey(pk, kind));
667
+ const b = this.#bounds.get(outboxBoundKey(pk, kind));
680
668
  if (!b) {
681
669
  complete = false;
682
670
  break;
@@ -708,18 +696,25 @@ var OutboxFeed = class {
708
696
  }
709
697
  #noteEvent(event, relayUrl) {
710
698
  this.#updateBounds(event);
711
- const bound = this.#bounds.get(boundKey(event.pubkey, event.kind));
712
- if (bound) (async () => {
713
- try {
714
- await this.#storage.setOutboxBound(event.pubkey, event.kind, {
715
- oldest: bound.oldest,
716
- newest: bound.newest
717
- });
718
- } catch {}
719
- })();
699
+ const key = outboxBoundKey(event.pubkey, event.kind);
700
+ if (this.#bounds.has(key)) {
701
+ this.#dirtyBounds.add(key);
702
+ this.#boundTimer ??= setTimeout(() => {
703
+ this.#boundTimer = void 0;
704
+ this.#flushBounds();
705
+ }, BOUND_FLUSH_MS);
706
+ }
720
707
  invokeSafely(() => this.#observe?.(event, relayUrl));
721
708
  invokeSafely(() => this.#onEvent?.(event));
722
709
  }
710
+ /** Persist all bounds dirtied since the last flush. Best-effort: errors are swallowed. */
711
+ async #flushBounds() {
712
+ const keys = [...this.#dirtyBounds];
713
+ this.#dirtyBounds.clear();
714
+ try {
715
+ await this.#persistBounds(keys);
716
+ } catch {}
717
+ }
723
718
  async #persistBounds(keys) {
724
719
  const writes = [];
725
720
  for (const key of keys) {
@@ -739,7 +734,7 @@ var OutboxFeed = class {
739
734
  }
740
735
  }
741
736
  #updateBounds(event) {
742
- const key = boundKey(event.pubkey, event.kind);
737
+ const key = outboxBoundKey(event.pubkey, event.kind);
743
738
  const prev = this.#bounds.get(key);
744
739
  if (!prev) {
745
740
  this.#bounds.set(key, {
@@ -752,10 +747,6 @@ var OutboxFeed = class {
752
747
  if (event.created_at > prev.newest) prev.newest = event.created_at;
753
748
  }
754
749
  };
755
- /** Factory matching other loaders helpers. */
756
- function createOutboxFeed(opts) {
757
- return new OutboxFeed(opts);
758
- }
759
750
  //#endregion
760
751
  //#region src/loaders/index.ts
761
752
  /** Build an instance-scoped loader suite (no module globals). */
@@ -786,6 +777,6 @@ function createLoaders(opts) {
786
777
  };
787
778
  }
788
779
  //#endregion
789
- export { groupAuthorsByOutboxRelay as a, createOutboxFeed as i, OutboxError as n, bareNostrUser as o, OutboxFeed as r, createLoaders as t };
780
+ export { bareNostrUser as a, groupAuthorsByOutboxRelay as i, OutboxError as n, OutboxFeed as r, createLoaders as t };
790
781
 
791
- //# sourceMappingURL=loaders-o6YXB_Ri.mjs.map
782
+ //# sourceMappingURL=loaders-BmPkQfzI.mjs.map