@qntx/nostr 0.1.0 → 0.2.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 (185) hide show
  1. package/dist/abort-Ba8tDrOI.mjs +38 -0
  2. package/dist/abort-Ba8tDrOI.mjs.map +1 -0
  3. package/dist/{builder-BphJa-Y-.d.mts → builder-BWn55Paf.d.mts} +20 -14
  4. package/dist/{builder-q0VsvnYE.mjs → builder-CyrGKRVP.mjs} +32 -16
  5. package/dist/builder-CyrGKRVP.mjs.map +1 -0
  6. package/dist/{client-Bd8B1mYm.mjs → client-BWsX9Cv1.mjs} +354 -195
  7. package/dist/client-BWsX9Cv1.mjs.map +1 -0
  8. package/dist/client.d.mts +1 -1
  9. package/dist/client.mjs +1 -1
  10. package/dist/core.d.mts +8 -8
  11. package/dist/core.mjs +8 -9
  12. package/dist/error-BW7re1UN.d.mts +9 -0
  13. package/dist/error-B__OMBRY.mjs +14 -0
  14. package/dist/error-B__OMBRY.mjs.map +1 -0
  15. package/dist/{error-WEFS-R-4.d.mts → error-CR8Urc84.d.mts} +20 -8
  16. package/dist/{error-CwBxle6N.mjs → error-DrEIM7FO.mjs} +5 -3
  17. package/dist/error-DrEIM7FO.mjs.map +1 -0
  18. package/dist/{event-CzoQEFMF.mjs → event-D8Nfoh4K.mjs} +40 -32
  19. package/dist/event-D8Nfoh4K.mjs.map +1 -0
  20. package/dist/{event-B5D2jxt_.d.mts → event-fU3Y01PR.d.mts} +23 -20
  21. package/dist/{filter-BxwjEkZp.mjs → filter-BQl3GlHt.mjs} +42 -35
  22. package/dist/filter-BQl3GlHt.mjs.map +1 -0
  23. package/dist/filter-C0IMByE3.d.mts +37 -0
  24. package/dist/{gossip-C5RVB1UB.d.mts → gossip-BRQwIM_q.d.mts} +25 -23
  25. package/dist/{gossip-3xkRRCm_.mjs → gossip-oloDMWEj.mjs} +52 -34
  26. package/dist/gossip-oloDMWEj.mjs.map +1 -0
  27. package/dist/gossip.d.mts +1 -1
  28. package/dist/gossip.mjs +1 -1
  29. package/dist/{http-6vevbBlu.d.mts → http-C4HwIu4B.d.mts} +7 -7
  30. package/dist/{http-D2rhokZo.mjs → http-CuazNRIP.mjs} +10 -6
  31. package/dist/http-CuazNRIP.mjs.map +1 -0
  32. package/dist/index-B425CAcQ.d.mts +328 -0
  33. package/dist/index-BVyfUBuG.d.mts +181 -0
  34. package/dist/{index-BYMnhRIC.d.mts → index-Ba7bJ7DD.d.mts} +68 -50
  35. package/dist/{index-DaRyjo7O.d.mts → index-Boe8FshM.d.mts} +13 -7
  36. package/dist/index-CUIvFQdE.d.mts +73 -0
  37. package/dist/index-JdaS_uce.d.mts +207 -0
  38. package/dist/index.d.mts +22 -20
  39. package/dist/index.mjs +19 -18
  40. package/dist/{key-Dn-aX4x4.mjs → key-Bbtys6o7.mjs} +22 -14
  41. package/dist/key-Bbtys6o7.mjs.map +1 -0
  42. package/dist/{key-BiGxGLhg.d.mts → key-BlsYhN1V.d.mts} +9 -6
  43. package/dist/{kind-BLl4cLOc.mjs → kind-Cxwhhkx8.mjs} +2 -1
  44. package/dist/kind-Cxwhhkx8.mjs.map +1 -0
  45. package/dist/{loaders-BNQszDAn.mjs → loaders-o6YXB_Ri.mjs} +329 -305
  46. package/dist/loaders-o6YXB_Ri.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 +46 -0
  50. package/dist/memory-C2EVx0_O.mjs.map +1 -0
  51. package/dist/{memory-BCmhZPek.mjs → memory-index-Do1mz0WF.mjs} +212 -82
  52. package/dist/memory-index-Do1mz0WF.mjs.map +1 -0
  53. package/dist/{message-C_Uj-Y-c.mjs → message-DcY6Fi9o.mjs} +38 -24
  54. package/dist/message-DcY6Fi9o.mjs.map +1 -0
  55. package/dist/{message-DJC-Jz6T.d.mts → message-iGPIqnn0.d.mts} +15 -8
  56. package/dist/{nip17-BWq-Kfq5.d.mts → nip17-DNEkz8rM.d.mts} +18 -17
  57. package/dist/{nip19-D7905oIv.d.mts → nip19-BevCJZsp.d.mts} +23 -3
  58. package/dist/{nip46-C_DoxiS_.d.mts → nip46-DDV4dC56.d.mts} +13 -12
  59. package/dist/{nip59-DljW_sYh.d.mts → nip59-zQgdLcEr.d.mts} +28 -25
  60. package/dist/{nip65-Di5hZRuV.d.mts → nip65-DBfh2smt.d.mts} +8 -3
  61. package/dist/{nip77-ByxlgoQO.d.mts → nip77-DH4RhS5r.d.mts} +9 -8
  62. package/dist/nips/blossom.d.mts +37 -37
  63. package/dist/nips/blossom.mjs +67 -52
  64. package/dist/nips/blossom.mjs.map +1 -1
  65. package/dist/nips/nip04.d.mts +2 -3
  66. package/dist/nips/nip04.mjs +6 -10
  67. package/dist/nips/nip04.mjs.map +1 -1
  68. package/dist/nips/nip05.d.mts +37 -43
  69. package/dist/nips/nip05.mjs +57 -57
  70. package/dist/nips/nip05.mjs.map +1 -1
  71. package/dist/nips/nip10.d.mts +18 -19
  72. package/dist/nips/nip10.mjs +76 -61
  73. package/dist/nips/nip10.mjs.map +1 -1
  74. package/dist/nips/nip11.d.mts +9 -8
  75. package/dist/nips/nip11.mjs +14 -11
  76. package/dist/nips/nip11.mjs.map +1 -1
  77. package/dist/nips/nip13.d.mts +9 -9
  78. package/dist/nips/nip13.mjs +15 -17
  79. package/dist/nips/nip13.mjs.map +1 -1
  80. package/dist/nips/nip17.d.mts +1 -1
  81. package/dist/nips/nip17.mjs +17 -12
  82. package/dist/nips/nip17.mjs.map +1 -1
  83. package/dist/nips/nip19.d.mts +1 -1
  84. package/dist/nips/nip19.mjs +52 -29
  85. package/dist/nips/nip19.mjs.map +1 -1
  86. package/dist/nips/nip21.d.mts +5 -6
  87. package/dist/nips/nip21.mjs +8 -7
  88. package/dist/nips/nip21.mjs.map +1 -1
  89. package/dist/nips/nip27.d.mts +7 -8
  90. package/dist/nips/nip27.mjs +26 -25
  91. package/dist/nips/nip27.mjs.map +1 -1
  92. package/dist/nips/nip42.d.mts +5 -6
  93. package/dist/nips/nip42.mjs +3 -3
  94. package/dist/nips/nip42.mjs.map +1 -1
  95. package/dist/nips/nip44.d.mts +24 -7
  96. package/dist/nips/nip44.mjs +25 -15
  97. package/dist/nips/nip44.mjs.map +1 -1
  98. package/dist/nips/nip46.d.mts +1 -1
  99. package/dist/nips/nip46.mjs +52 -49
  100. package/dist/nips/nip46.mjs.map +1 -1
  101. package/dist/nips/nip49.d.mts +8 -7
  102. package/dist/nips/nip49.mjs +16 -12
  103. package/dist/nips/nip49.mjs.map +1 -1
  104. package/dist/nips/nip51.d.mts +25 -27
  105. package/dist/nips/nip51.mjs +47 -36
  106. package/dist/nips/nip51.mjs.map +1 -1
  107. package/dist/nips/nip57.d.mts +12 -13
  108. package/dist/nips/nip57.mjs +35 -38
  109. package/dist/nips/nip57.mjs.map +1 -1
  110. package/dist/nips/nip59.d.mts +1 -1
  111. package/dist/nips/nip59.mjs +14 -18
  112. package/dist/nips/nip59.mjs.map +1 -1
  113. package/dist/nips/nip65.d.mts +1 -1
  114. package/dist/nips/nip65.mjs +11 -8
  115. package/dist/nips/nip65.mjs.map +1 -1
  116. package/dist/nips/nip77.d.mts +1 -1
  117. package/dist/nips/nip77.mjs +56 -34
  118. package/dist/nips/nip77.mjs.map +1 -1
  119. package/dist/nips/nip96.d.mts +21 -12
  120. package/dist/nips/nip96.mjs +59 -36
  121. package/dist/nips/nip96.mjs.map +1 -1
  122. package/dist/nips/nip98.d.mts +12 -12
  123. package/dist/nips/nip98.mjs +18 -19
  124. package/dist/nips/nip98.mjs.map +1 -1
  125. package/dist/{pool-C_j1OmBB.mjs → pool-XmAGaufS.mjs} +611 -487
  126. package/dist/pool-XmAGaufS.mjs.map +1 -0
  127. package/dist/pool-tEr7c5bG.d.mts +302 -0
  128. package/dist/reactive-DDlThDSZ.mjs +324 -0
  129. package/dist/reactive-DDlThDSZ.mjs.map +1 -0
  130. package/dist/reactive-DFpqtIf_.d.mts +66 -0
  131. package/dist/relay.d.mts +5 -4
  132. package/dist/relay.mjs +2 -2
  133. package/dist/report-CHld4uWj.mjs +32 -0
  134. package/dist/report-CHld4uWj.mjs.map +1 -0
  135. package/dist/{signer-CZ6K6FUc.mjs → signer-CKR9EHce.mjs} +107 -72
  136. package/dist/signer-CKR9EHce.mjs.map +1 -0
  137. package/dist/signer.d.mts +3 -3
  138. package/dist/signer.mjs +3 -2
  139. package/dist/storage-xXxLGCVb.mjs +1376 -0
  140. package/dist/storage-xXxLGCVb.mjs.map +1 -0
  141. package/dist/storage.d.mts +4 -4
  142. package/dist/storage.mjs +5 -4
  143. package/dist/store.d.mts +2 -0
  144. package/dist/store.mjs +2 -0
  145. package/dist/testing.d.mts +125 -0
  146. package/dist/testing.mjs +957 -0
  147. package/dist/testing.mjs.map +1 -0
  148. package/dist/types-2pCUprRU.d.mts +47 -0
  149. package/dist/types-CRQEk0Oi.d.mts +19 -0
  150. package/dist/util-LfQirgDk.mjs +113 -0
  151. package/dist/util-LfQirgDk.mjs.map +1 -0
  152. package/dist/wasm.d.mts +4 -4
  153. package/dist/wasm.mjs +54 -55
  154. package/dist/wasm.mjs.map +1 -1
  155. package/dist/websocket-CmeqvAkp.d.mts +27 -0
  156. package/package.json +31 -9
  157. package/dist/builder-q0VsvnYE.mjs.map +0 -1
  158. package/dist/client-Bd8B1mYm.mjs.map +0 -1
  159. package/dist/error-B49rbDzT.d.mts +0 -7
  160. package/dist/error-CwBxle6N.mjs.map +0 -1
  161. package/dist/error-DZEs5OuZ.mjs +0 -24
  162. package/dist/error-DZEs5OuZ.mjs.map +0 -1
  163. package/dist/event-CzoQEFMF.mjs.map +0 -1
  164. package/dist/filter-BxwjEkZp.mjs.map +0 -1
  165. package/dist/filter-DUEKP3q1.d.mts +0 -40
  166. package/dist/gossip-3xkRRCm_.mjs.map +0 -1
  167. package/dist/http-D2rhokZo.mjs.map +0 -1
  168. package/dist/index-C0C4e-Gn.d.mts +0 -55
  169. package/dist/index-DgOugrpF.d.mts +0 -275
  170. package/dist/index-EwL6fHLo.d.mts +0 -267
  171. package/dist/index-k2YhCgsh.d.mts +0 -57
  172. package/dist/key-Dn-aX4x4.mjs.map +0 -1
  173. package/dist/kind-BLl4cLOc.mjs.map +0 -1
  174. package/dist/loaders-BNQszDAn.mjs.map +0 -1
  175. package/dist/memory-BCmhZPek.mjs.map +0 -1
  176. package/dist/message-C_Uj-Y-c.mjs.map +0 -1
  177. package/dist/pool-C_j1OmBB.mjs.map +0 -1
  178. package/dist/pool-DhRi7l-b.d.mts +0 -297
  179. package/dist/signer-CZ6K6FUc.mjs.map +0 -1
  180. package/dist/storage-DOy0iLRE.mjs +0 -870
  181. package/dist/storage-DOy0iLRE.mjs.map +0 -1
  182. package/dist/types-BzyADqnw.d.mts +0 -19
  183. package/dist/types-Dn24TPFs.d.mts +0 -43
  184. package/dist/util-6tfLQ9JF.mjs +0 -73
  185. package/dist/util-6tfLQ9JF.mjs.map +0 -1
@@ -0,0 +1,38 @@
1
+ //#region src/core/abort.ts
2
+ function abortReason(signal) {
3
+ if (signal.reason !== void 0) return signal.reason;
4
+ const error = /* @__PURE__ */ new Error("This operation was aborted");
5
+ error.name = "AbortError";
6
+ return error;
7
+ }
8
+ function throwIfAborted(signal) {
9
+ if (signal?.aborted === true) throw abortReason(signal);
10
+ }
11
+ /**
12
+ * Race `promise` against the caller's `signal` without cancelling the shared work: on abort the
13
+ * returned promise rejects with `signal.reason` (or an `AbortError`-named Error) while `promise`
14
+ * itself keeps running. With no signal the original promise is returned.
15
+ */
16
+ async function raceSignal(promise, signal) {
17
+ if (!signal) return promise;
18
+ if (signal.aborted) throw abortReason(signal);
19
+ return new Promise((resolve, reject) => {
20
+ const onAbort = () => {
21
+ reject(abortReason(signal));
22
+ };
23
+ signal.addEventListener("abort", onAbort, { once: true });
24
+ (async () => {
25
+ try {
26
+ resolve(await promise);
27
+ } catch (error) {
28
+ reject(error);
29
+ } finally {
30
+ signal.removeEventListener("abort", onAbort);
31
+ }
32
+ })();
33
+ });
34
+ }
35
+ //#endregion
36
+ export { raceSignal as n, throwIfAborted as r, abortReason as t };
37
+
38
+ //# sourceMappingURL=abort-Ba8tDrOI.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abort-Ba8tDrOI.mjs","names":[],"sources":["../src/core/abort.ts"],"sourcesContent":["export function abortReason(signal: AbortSignal): unknown {\n if (signal.reason !== undefined) {\n return signal.reason;\n }\n const error = new Error(\"This operation was aborted\");\n error.name = \"AbortError\";\n return error;\n}\n\nexport function throwIfAborted(signal: AbortSignal | undefined): void {\n if (signal?.aborted === true) {\n throw abortReason(signal);\n }\n}\n\n/**\n * Race `promise` against the caller's `signal` without cancelling the shared work: on abort the\n * returned promise rejects with `signal.reason` (or an `AbortError`-named Error) while `promise`\n * itself keeps running. With no signal the original promise is returned.\n */\nexport async function raceSignal<T>(\n promise: Promise<T>,\n signal: AbortSignal | undefined,\n): Promise<T> {\n if (!signal) {\n return promise;\n }\n if (signal.aborted) {\n throw abortReason(signal);\n }\n return new Promise<T>((resolve, reject) => {\n const onAbort = (): void => {\n // oxlint-disable-next-line typescript/prefer-promise-reject-errors -- the rejection is the caller's signal.reason verbatim\n reject(abortReason(signal));\n };\n signal.addEventListener(\"abort\", onAbort, { once: true });\n void (async (): Promise<void> => {\n try {\n resolve(await promise);\n } catch (error) {\n // oxlint-disable-next-line typescript/prefer-promise-reject-errors -- forwards the raced promise's own rejection\n reject(error);\n } finally {\n signal.removeEventListener(\"abort\", onAbort);\n }\n })();\n });\n}\n"],"mappings":";AAAA,SAAgB,YAAY,QAA8B;CACxD,IAAI,OAAO,WAAW,KAAA,GACpB,OAAO,OAAO;CAEhB,MAAM,wBAAQ,IAAI,MAAM,4BAA4B;CACpD,MAAM,OAAO;CACb,OAAO;AACT;AAEA,SAAgB,eAAe,QAAuC;CACpE,IAAI,QAAQ,YAAY,MACtB,MAAM,YAAY,MAAM;AAE5B;;;;;;AAOA,eAAsB,WACpB,SACA,QACY;CACZ,IAAI,CAAC,QACH,OAAO;CAET,IAAI,OAAO,SACT,MAAM,YAAY,MAAM;CAE1B,OAAO,IAAI,SAAY,SAAS,WAAW;EACzC,MAAM,gBAAsB;GAE1B,OAAO,YAAY,MAAM,CAAC;EAC5B;EACA,OAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;EACxD,CAAM,YAA2B;GAC/B,IAAI;IACF,QAAQ,MAAM,OAAO;GACvB,SAAS,OAAO;IAEd,OAAO,KAAK;GACd,UAAU;IACR,OAAO,oBAAoB,SAAS,OAAO;GAC7C;EACF,EAAA,CAAG;CACL,CAAC;AACH"}
@@ -1,5 +1,5 @@
1
- import { n as EventTemplate, r as UnsignedEvent, t as Event, v as Tag } from "./event-B5D2jxt_.mjs";
2
- import { r as SecretKey, t as Keys } from "./key-BiGxGLhg.mjs";
1
+ import { _ as Tag, n as EventTemplate, r as UnsignedEvent, t as Event } from "./event-fU3Y01PR.mjs";
2
+ import { r as SecretKey, t as Keys } from "./key-BlsYhN1V.mjs";
3
3
  //#region src/core/builder.d.ts
4
4
  /** Profile metadata JSON (kind 0 content). NIP-05 is not verified here. */
5
5
  type ProfileMetadata = {
@@ -14,8 +14,8 @@ type ProfileMetadata = {
14
14
  lud16?: string;
15
15
  };
16
16
  /**
17
- * Fluent builder for event templates.
18
- * Decouples intent (kind/content/tags) from signing (Keys / NostrSigner).
17
+ * Fluent builder for event templates. Decouples intent (kind/content/tags) from signing (Keys /
18
+ * NostrSigner).
19
19
  */
20
20
  declare class EventBuilder {
21
21
  #private;
@@ -23,10 +23,16 @@ declare class EventBuilder {
23
23
  static textNote(content: string): EventBuilder;
24
24
  static metadata(meta: ProfileMetadata): EventBuilder;
25
25
  static contacts(pubkeys: string[]): EventBuilder;
26
- static deletion(ids: string[], reason?: string, opts?: {
27
- kinds?: readonly number[];
28
- addresses?: readonly string[];
29
- }): EventBuilder;
26
+ /**
27
+ * Kind-5 deletion. Each target is a bare event id string (or `{ id, kind }`), or `{ address }`
28
+ * for a `kind:pubkey:d` coordinate. Known kinds are emitted as deduped `k` tags (NIP-09 SHOULD).
29
+ */
30
+ static deletion(targets: ReadonlyArray<string | {
31
+ id: string;
32
+ kind?: number;
33
+ } | {
34
+ address: string;
35
+ }>, reason?: string): EventBuilder;
30
36
  static reaction(target: Event, content?: string, opts?: {
31
37
  relayHint?: string;
32
38
  }): EventBuilder;
@@ -44,7 +50,7 @@ declare class EventBuilder {
44
50
  createdAt(ts: number): this;
45
51
  get currentKind(): number;
46
52
  get currentContent(): string;
47
- get currentTags(): readonly Tag[];
53
+ get currentTags(): ReadonlyArray<Tag>;
48
54
  get currentCreatedAt(): number | undefined;
49
55
  /** Snapshot as EventTemplate (uses wall clock if created_at unset). */
50
56
  toTemplate(): EventTemplate;
@@ -53,15 +59,15 @@ declare class EventBuilder {
53
59
  /** Sign with local Keys (synchronous). */
54
60
  signWithKeys(keys: Keys | SecretKeyLike): Event;
55
61
  /**
56
- * Sign via any NostrSigner-shaped object.
57
- * Accepts a structural type so core does not depend on the signer module.
62
+ * Sign via any NostrSigner-shaped object. Accepts a structural type so core does not depend on
63
+ * the signer module.
58
64
  */
59
65
  sign(signer: {
60
- getPublicKey(): Promise<string>;
61
- signEvent(unsigned: UnsignedEvent): Promise<Event>;
66
+ getPublicKey: () => Promise<string>;
67
+ signEvent: (unsigned: UnsignedEvent) => Promise<Event>;
62
68
  }): Promise<Event>;
63
69
  }
64
70
  type SecretKeyLike = SecretKey | Uint8Array | string;
65
71
  //#endregion
66
72
  export { ProfileMetadata as n, EventBuilder as t };
67
- //# sourceMappingURL=builder-BphJa-Y-.d.mts.map
73
+ //# sourceMappingURL=builder-BWn55Paf.d.mts.map
@@ -1,8 +1,7 @@
1
- import { s as normalizeURL } from "./util-6tfLQ9JF.mjs";
2
- import { n as EventValidationError } from "./error-DZEs5OuZ.mjs";
3
- import { o as isReplaceableKind, r as isAddressableKind, t as Kind } from "./kind-BLl4cLOc.mjs";
4
- import { _ as getDTag, g as formatEventAddress, m as Tag } from "./event-CzoQEFMF.mjs";
5
- import { r as finalizeEvent, t as Keys } from "./key-Dn-aX4x4.mjs";
1
+ import { l as normalizeURL, p as EventValidationError } from "./util-LfQirgDk.mjs";
2
+ import { o as isReplaceableKind, r as isAddressableKind, t as Kind } from "./kind-Cxwhhkx8.mjs";
3
+ import { _ as formatEventAddress, b as parseEventAddress, h as Tag, v as getDTag } from "./event-D8Nfoh4K.mjs";
4
+ import { r as finalizeEvent, t as Keys } from "./key-Bbtys6o7.mjs";
6
5
  //#region src/core/builder.ts
7
6
  function hasProtectedTag(event) {
8
7
  for (const tag of event.tags) if (tag[0] === "-") return true;
@@ -10,12 +9,12 @@ function hasProtectedTag(event) {
10
9
  }
11
10
  /** NIP-18 e third entry MUST be a relay URL; empty string is not one. */
12
11
  function requireRelayUrl(relayHint) {
13
- if (!relayHint) throw new EventValidationError("relayHint must be a relay URL");
12
+ if (relayHint === void 0 || relayHint === "") throw new EventValidationError("relayHint must be a relay URL");
14
13
  return normalizeURL(relayHint);
15
14
  }
16
15
  /**
17
- * Fluent builder for event templates.
18
- * Decouples intent (kind/content/tags) from signing (Keys / NostrSigner).
16
+ * Fluent builder for event templates. Decouples intent (kind/content/tags) from signing (Keys /
17
+ * NostrSigner).
19
18
  */
20
19
  var EventBuilder = class EventBuilder {
21
20
  #kind;
@@ -39,11 +38,28 @@ var EventBuilder = class EventBuilder {
39
38
  for (const pk of pubkeys) b.#tags.push(Tag.p(pk));
40
39
  return b;
41
40
  }
42
- static deletion(ids, reason = "", opts) {
41
+ /**
42
+ * Kind-5 deletion. Each target is a bare event id string (or `{ id, kind }`), or `{ address }`
43
+ * for a `kind:pubkey:d` coordinate. Known kinds are emitted as deduped `k` tags (NIP-09 SHOULD).
44
+ */
45
+ static deletion(targets, reason = "") {
43
46
  const b = new EventBuilder(Kind.EventDeletion, reason);
44
- for (const id of ids) b.#tags.push(Tag.e(id));
45
- if (opts?.kinds) for (const kind of opts.kinds) b.#tags.push(Tag.k(kind));
46
- if (opts?.addresses) for (const address of opts.addresses) b.#tags.push(Tag.a(address));
47
+ const kinds = /* @__PURE__ */ new Set();
48
+ for (const target of targets) {
49
+ if (typeof target === "string") {
50
+ b.#tags.push(Tag.e(target));
51
+ continue;
52
+ }
53
+ if ("address" in target) {
54
+ const parsed = parseEventAddress(target.address);
55
+ if (parsed) kinds.add(parsed.kind);
56
+ b.#tags.push(Tag.a(target.address));
57
+ continue;
58
+ }
59
+ b.#tags.push(Tag.e(target.id));
60
+ if (target.kind !== void 0) kinds.add(target.kind);
61
+ }
62
+ for (const kind of kinds) b.#tags.push(Tag.k(kind));
47
63
  return b;
48
64
  }
49
65
  static reaction(target, content = "+", opts) {
@@ -127,7 +143,7 @@ var EventBuilder = class EventBuilder {
127
143
  return {
128
144
  kind: this.#kind,
129
145
  content: this.#content,
130
- tags: this.#tags.slice(),
146
+ tags: [...this.#tags],
131
147
  created_at: this.#createdAt ?? Math.floor(Date.now() / 1e3)
132
148
  };
133
149
  }
@@ -144,8 +160,8 @@ var EventBuilder = class EventBuilder {
144
160
  return finalizeEvent(this.toTemplate(), keys);
145
161
  }
146
162
  /**
147
- * Sign via any NostrSigner-shaped object.
148
- * Accepts a structural type so core does not depend on the signer module.
163
+ * Sign via any NostrSigner-shaped object. Accepts a structural type so core does not depend on
164
+ * the signer module.
149
165
  */
150
166
  async sign(signer) {
151
167
  const pubkey = await signer.getPublicKey();
@@ -155,4 +171,4 @@ var EventBuilder = class EventBuilder {
155
171
  //#endregion
156
172
  export { EventBuilder as t };
157
173
 
158
- //# sourceMappingURL=builder-q0VsvnYE.mjs.map
174
+ //# sourceMappingURL=builder-CyrGKRVP.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder-CyrGKRVP.mjs","names":[],"sources":["../src/core/builder.ts"],"sourcesContent":["import { EventValidationError } from \"./error.ts\";\nimport type { Event, EventTemplate, UnsignedEvent } from \"./event.ts\";\nimport { Keys, finalizeEvent } from \"./key.ts\";\nimport type { SecretKey } from \"./key.ts\";\nimport { Kind, isAddressableKind, isReplaceableKind } from \"./kind.ts\";\nimport { Tag, formatEventAddress, getDTag, parseEventAddress } from \"./tag.ts\";\nimport { normalizeURL } from \"./util.ts\";\n\nfunction hasProtectedTag(event: Event): boolean {\n for (const tag of event.tags) {\n if (tag[0] === \"-\") {\n return true;\n }\n }\n return false;\n}\n\n/** NIP-18 e third entry MUST be a relay URL; empty string is not one. */\nfunction requireRelayUrl(relayHint: string | undefined): string {\n if (relayHint === undefined || relayHint === \"\") {\n throw new EventValidationError(\"relayHint must be a relay URL\");\n }\n return normalizeURL(relayHint);\n}\n\n/** Profile metadata JSON (kind 0 content). NIP-05 is not verified here. */\nexport type ProfileMetadata = {\n name?: string;\n display_name?: string;\n about?: string;\n picture?: string;\n banner?: string;\n website?: string;\n nip05?: string;\n lud06?: string;\n lud16?: string;\n};\n\n/**\n * Fluent builder for event templates. Decouples intent (kind/content/tags) from signing (Keys /\n * NostrSigner).\n */\nexport class EventBuilder {\n #kind: number;\n #content: string;\n readonly #tags: Tag[];\n #createdAt: number | undefined;\n\n constructor(kind: number, content = \"\") {\n this.#kind = kind;\n this.#content = content;\n this.#tags = [];\n this.#createdAt = undefined;\n }\n\n static textNote(content: string): EventBuilder {\n return new EventBuilder(Kind.TextNote, content);\n }\n\n static metadata(meta: ProfileMetadata): EventBuilder {\n return new EventBuilder(Kind.Metadata, JSON.stringify(meta));\n }\n\n static contacts(pubkeys: string[]): EventBuilder {\n const b = new EventBuilder(Kind.Contacts, \"\");\n for (const pk of pubkeys) {\n b.#tags.push(Tag.p(pk));\n }\n return b;\n }\n\n /**\n * Kind-5 deletion. Each target is a bare event id string (or `{ id, kind }`), or `{ address }`\n * for a `kind:pubkey:d` coordinate. Known kinds are emitted as deduped `k` tags (NIP-09 SHOULD).\n */\n static deletion(\n targets: ReadonlyArray<string | { id: string; kind?: number } | { address: string }>,\n reason = \"\",\n ): EventBuilder {\n const b = new EventBuilder(Kind.EventDeletion, reason);\n const kinds = new Set<number>();\n for (const target of targets) {\n if (typeof target === \"string\") {\n b.#tags.push(Tag.e(target));\n continue;\n }\n if (\"address\" in target) {\n const parsed = parseEventAddress(target.address);\n if (parsed) {\n kinds.add(parsed.kind);\n }\n b.#tags.push(Tag.a(target.address));\n continue;\n }\n b.#tags.push(Tag.e(target.id));\n if (target.kind !== undefined) {\n kinds.add(target.kind);\n }\n }\n for (const kind of kinds) {\n b.#tags.push(Tag.k(kind));\n }\n return b;\n }\n\n static reaction(target: Event, content = \"+\", opts?: { relayHint?: string }): EventBuilder {\n const hint = opts?.relayHint === undefined ? undefined : requireRelayUrl(opts.relayHint);\n let coord: string | undefined;\n if (isAddressableKind(target.kind)) {\n const d = getDTag(target.tags);\n if (d === undefined) {\n throw new EventValidationError(\"addressable event is missing d tag\");\n }\n coord = formatEventAddress(target.kind, target.pubkey, d);\n }\n\n const b = new EventBuilder(Kind.Reaction, content);\n // NIP-25 e is [e, id, relay, pubkey]; Tag.e third arg is a NIP-10 marker.\n b.#tags.push([\"e\", target.id.toLowerCase(), hint ?? \"\", target.pubkey.toLowerCase()]);\n b.#tags.push(Tag.p(target.pubkey, hint));\n b.#tags.push([\"k\", String(target.kind)]);\n if (coord !== undefined) {\n b.#tags.push(Tag.a(coord, hint));\n }\n return b;\n }\n\n static repost(target: Event, opts: { relayHint: string }): EventBuilder {\n if (target.kind !== Kind.TextNote) {\n throw new EventValidationError(\"non-kind-1 uses EventBuilder.genericRepost\");\n }\n const hint = requireRelayUrl(opts?.relayHint);\n const content = hasProtectedTag(target) ? \"\" : JSON.stringify(target);\n const b = new EventBuilder(Kind.Repost, content);\n b.#tags.push(Tag.e(target.id, hint));\n b.#tags.push(Tag.p(target.pubkey));\n return b;\n }\n\n static genericRepost(target: Event, opts: { relayHint: string; pPubkey?: string }): EventBuilder {\n if (target.kind === Kind.TextNote) {\n throw new EventValidationError(\"kind 1 uses EventBuilder.repost\");\n }\n const hint = requireRelayUrl(opts?.relayHint);\n const replaceable = isReplaceableKind(target.kind);\n const addressable = isAddressableKind(target.kind);\n const d = getDTag(target.tags);\n if (addressable && d === undefined) {\n throw new EventValidationError(\"addressable event is missing d tag\");\n }\n\n const content =\n hasProtectedTag(target) || replaceable || addressable ? \"\" : JSON.stringify(target);\n const b = new EventBuilder(Kind.GenericRepost, content);\n b.#tags.push(Tag.e(target.id, hint));\n b.#tags.push(Tag.p(opts?.pPubkey ?? target.pubkey));\n b.#tags.push(Tag.k(target.kind));\n if (replaceable || addressable) {\n b.#tags.push(Tag.a(formatEventAddress(target.kind, target.pubkey, d ?? \"\")));\n }\n return b;\n }\n\n kind(kind: number): this {\n this.#kind = kind;\n return this;\n }\n\n content(content: string): this {\n this.#content = content;\n return this;\n }\n\n tag(tag: Tag): this {\n this.#tags.push(tag);\n return this;\n }\n\n tags(tags: Iterable<Tag>): this {\n for (const t of tags) {\n this.#tags.push(t);\n }\n return this;\n }\n\n createdAt(ts: number): this {\n this.#createdAt = ts;\n return this;\n }\n\n get currentKind(): number {\n return this.#kind;\n }\n\n get currentContent(): string {\n return this.#content;\n }\n\n get currentTags(): ReadonlyArray<Tag> {\n return this.#tags;\n }\n\n get currentCreatedAt(): number | undefined {\n return this.#createdAt;\n }\n\n /** Snapshot as EventTemplate (uses wall clock if created_at unset). */\n toTemplate(): EventTemplate {\n return {\n kind: this.#kind,\n content: this.#content,\n tags: [...this.#tags],\n created_at: this.#createdAt ?? Math.floor(Date.now() / 1000),\n };\n }\n\n /** Build unsigned event with the given pubkey. */\n buildUnsigned(pubkey: string): UnsignedEvent {\n const template = this.toTemplate();\n return {\n ...template,\n pubkey: pubkey.toLowerCase(),\n };\n }\n\n /** Sign with local Keys (synchronous). */\n signWithKeys(keys: Keys | SecretKeyLike): Event {\n if (keys instanceof Keys) {\n return finalizeEvent(this.toTemplate(), keys.secretKey);\n }\n return finalizeEvent(this.toTemplate(), keys);\n }\n\n /**\n * Sign via any NostrSigner-shaped object. Accepts a structural type so core does not depend on\n * the signer module.\n */\n async sign(signer: {\n getPublicKey: () => Promise<string>;\n signEvent: (unsigned: UnsignedEvent) => Promise<Event>;\n }): Promise<Event> {\n const pubkey = await signer.getPublicKey();\n return signer.signEvent(this.buildUnsigned(pubkey));\n }\n}\n\ntype SecretKeyLike = SecretKey | Uint8Array | string;\n"],"mappings":"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"}