@qntx/nostr 0.10.1 → 0.11.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 (99) hide show
  1. package/dist/{builder-CVRmUeNm.mjs → builder-BQbFDO6S.mjs} +22 -5
  2. package/dist/builder-BQbFDO6S.mjs.map +1 -0
  3. package/dist/{client-CeyDLoyO.mjs → client-CTmp5w84.mjs} +14 -14
  4. package/dist/{client-CeyDLoyO.mjs.map → client-CTmp5w84.mjs.map} +1 -1
  5. package/dist/client.d.mts +1 -1
  6. package/dist/client.mjs +1 -1
  7. package/dist/core.d.mts +2 -2
  8. package/dist/core.mjs +7 -7
  9. package/dist/{error-BILMe3Gr.mjs → error-DH4guike.mjs} +2 -2
  10. package/dist/{error-BILMe3Gr.mjs.map → error-DH4guike.mjs.map} +1 -1
  11. package/dist/{error-DlhGW4mJ.mjs → error-UHkqzWL7.mjs} +2 -2
  12. package/dist/{error-DlhGW4mJ.mjs.map → error-UHkqzWL7.mjs.map} +1 -1
  13. package/dist/{event-C2eLiPpV.mjs → event-B3ua2_oL.mjs} +24 -11
  14. package/dist/event-B3ua2_oL.mjs.map +1 -0
  15. package/dist/{filter-TrF2LEoy.mjs → filter-B16P33dz.mjs} +31 -10
  16. package/dist/filter-B16P33dz.mjs.map +1 -0
  17. package/dist/{filter-CfEgQBXt.d.mts → filter-PG7r79rt.d.mts} +6 -2
  18. package/dist/{gossip-BWb9HmfK.d.mts → gossip-BTMdlUI7.d.mts} +2 -2
  19. package/dist/{gossip-5ezg0Quo.mjs → gossip-K_JIexQs.mjs} +3 -3
  20. package/dist/{gossip-5ezg0Quo.mjs.map → gossip-K_JIexQs.mjs.map} +1 -1
  21. package/dist/gossip.d.mts +1 -1
  22. package/dist/gossip.mjs +1 -1
  23. package/dist/{index-B1fLejg4.d.mts → index-BP94lABY.d.mts} +5 -5
  24. package/dist/{index-uCYwXaaP.d.mts → index-CSsnE32i.d.mts} +7 -7
  25. package/dist/{index-CLJEKFGd.d.mts → index-DD0Ywpay.d.mts} +3 -3
  26. package/dist/{index-C0mFpelb.d.mts → index-N7HUGgwo.d.mts} +2 -2
  27. package/dist/{index-CoX7SnO7.d.mts → index-rKcmI6ex.d.mts} +3 -3
  28. package/dist/index.d.mts +11 -11
  29. package/dist/index.mjs +18 -18
  30. package/dist/{key-DY_HEIpY.mjs → key-k8LDEPZh.mjs} +3 -3
  31. package/dist/{key-DY_HEIpY.mjs.map → key-k8LDEPZh.mjs.map} +1 -1
  32. package/dist/{loaders-DifimjJ7.mjs → loaders-Dp2nXEFk.mjs} +6 -6
  33. package/dist/{loaders-DifimjJ7.mjs.map → loaders-Dp2nXEFk.mjs.map} +1 -1
  34. package/dist/loaders.d.mts +2 -2
  35. package/dist/loaders.mjs +1 -1
  36. package/dist/{memory-DENGQ_f6.mjs → memory-VyPnOBU3.mjs} +2 -2
  37. package/dist/{memory-DENGQ_f6.mjs.map → memory-VyPnOBU3.mjs.map} +1 -1
  38. package/dist/{memory-index-D_lvlYAy.mjs → memory-index-Bhwe0ZdG.mjs} +4 -4
  39. package/dist/{memory-index-D_lvlYAy.mjs.map → memory-index-Bhwe0ZdG.mjs.map} +1 -1
  40. package/dist/{message-Rd5Z_17h.mjs → message-pYfVKxPn.mjs} +74 -29
  41. package/dist/message-pYfVKxPn.mjs.map +1 -0
  42. package/dist/nips/blossom.mjs +2 -2
  43. package/dist/nips/nip04.mjs +1 -1
  44. package/dist/nips/nip05.mjs +1 -1
  45. package/dist/nips/nip10.mjs +3 -3
  46. package/dist/nips/nip11.mjs +1 -1
  47. package/dist/nips/nip13.mjs +1 -1
  48. package/dist/nips/nip17.mjs +3 -3
  49. package/dist/nips/nip19.mjs +11 -4
  50. package/dist/nips/nip19.mjs.map +1 -1
  51. package/dist/nips/nip21.mjs +1 -1
  52. package/dist/nips/nip42.mjs +1 -1
  53. package/dist/nips/nip44.mjs +1 -1
  54. package/dist/nips/nip46.mjs +1 -1
  55. package/dist/nips/nip49.mjs +1 -1
  56. package/dist/nips/nip51.mjs +3 -3
  57. package/dist/nips/nip57.mjs +3 -3
  58. package/dist/nips/nip59.mjs +4 -4
  59. package/dist/nips/nip65.mjs +2 -2
  60. package/dist/nips/nip77.mjs +1 -1
  61. package/dist/nips/nip98.mjs +3 -3
  62. package/dist/{pool-jok2-iBJ.mjs → pool-BMUsw2un.mjs} +5 -5
  63. package/dist/{pool-jok2-iBJ.mjs.map → pool-BMUsw2un.mjs.map} +1 -1
  64. package/dist/{pool-Bfe3Tu40.d.mts → pool-DUuYJ0x4.d.mts} +3 -3
  65. package/dist/{put-JsiCKMyZ.mjs → put-DRmV1wHD.mjs} +3 -3
  66. package/dist/{put-JsiCKMyZ.mjs.map → put-DRmV1wHD.mjs.map} +1 -1
  67. package/dist/{reactive-6Wn9qf_d.mjs → reactive--pDpLt2H.mjs} +5 -5
  68. package/dist/{reactive-6Wn9qf_d.mjs.map → reactive--pDpLt2H.mjs.map} +1 -1
  69. package/dist/{reactive-X4p6nABy.d.mts → reactive-jyKrA9ej.d.mts} +3 -3
  70. package/dist/{relay-__QtO33h.mjs → relay-DXtwUEdX.mjs} +6 -6
  71. package/dist/{relay-__QtO33h.mjs.map → relay-DXtwUEdX.mjs.map} +1 -1
  72. package/dist/relay.d.mts +3 -3
  73. package/dist/relay.mjs +2 -2
  74. package/dist/{signer-D7PtVvQn.mjs → signer-CWtxpOxc.mjs} +5 -5
  75. package/dist/{signer-D7PtVvQn.mjs.map → signer-CWtxpOxc.mjs.map} +1 -1
  76. package/dist/signer.d.mts +1 -1
  77. package/dist/signer.mjs +2 -2
  78. package/dist/{storage-oihjE0_x.mjs → storage-B5Wdt_Mn.mjs} +12 -29
  79. package/dist/storage-B5Wdt_Mn.mjs.map +1 -0
  80. package/dist/storage.d.mts +2 -2
  81. package/dist/storage.mjs +4 -4
  82. package/dist/store.d.mts +1 -1
  83. package/dist/store.mjs +1 -1
  84. package/dist/testing.d.mts +1 -1
  85. package/dist/testing.mjs +18 -7
  86. package/dist/testing.mjs.map +1 -1
  87. package/dist/{types-Ccox7-5v.d.mts → types-CqhnT-Mx.d.mts} +2 -2
  88. package/dist/{util-DMF9AIO0.mjs → util-DDpPkiED.mjs} +14 -2
  89. package/dist/util-DDpPkiED.mjs.map +1 -0
  90. package/dist/{verifier-uC_jd-Nw.mjs → verifier-CjH1vnP2.mjs} +3 -3
  91. package/dist/{verifier-uC_jd-Nw.mjs.map → verifier-CjH1vnP2.mjs.map} +1 -1
  92. package/dist/{verifier-9c-bINrv.d.mts → verifier-Cl24c9ph.d.mts} +3 -3
  93. package/package.json +1 -1
  94. package/dist/builder-CVRmUeNm.mjs.map +0 -1
  95. package/dist/event-C2eLiPpV.mjs.map +0 -1
  96. package/dist/filter-TrF2LEoy.mjs.map +0 -1
  97. package/dist/message-Rd5Z_17h.mjs.map +0 -1
  98. package/dist/storage-oihjE0_x.mjs.map +0 -1
  99. package/dist/util-DMF9AIO0.mjs.map +0 -1
@@ -1,9 +1,12 @@
1
- import { _ as MessageError, a as hexToBytes, c as isRecord, i as bytesToHex } from "./util-DMF9AIO0.mjs";
2
- import { h as validateSignedEvent } from "./event-C2eLiPpV.mjs";
1
+ import { i as bytesToHex, l as isRecord, o as hexToBytes, v as MessageError } from "./util-DDpPkiED.mjs";
2
+ import { h as validateSignedEvent } from "./event-B3ua2_oL.mjs";
3
+ import { n as canonicalizeFilters, t as canonicalizeFilter } from "./filter-B16P33dz.mjs";
3
4
  //#region src/core/message.ts
4
- /** Validate a subscription id; throws {@link MessageError} unless 1..64 chars. */
5
+ /** Validate a subscription id; throws {@link MessageError} unless 1..64 Unicode scalar values. */
5
6
  function assertSubscriptionId(id) {
6
- if (id.length === 0 || id.length > 64) throw new MessageError(`subscription id length must be 1..64`);
7
+ let length = 0;
8
+ for (const _ of id) length += 1;
9
+ if (length === 0 || length > 64) throw new MessageError(`subscription id length must be 1..64`);
7
10
  return id;
8
11
  }
9
12
  /** Validate the given id, or mint a random 16-hex-char subscription id. */
@@ -34,7 +37,24 @@ function mergeCountHll(hexes) {
34
37
  }
35
38
  /** Serialize a client->relay message to its NIP-01 JSON wire form. */
36
39
  function encodeClientMessage(message) {
37
- return JSON.stringify(message);
40
+ switch (message[0]) {
41
+ case "REQ":
42
+ case "COUNT": {
43
+ const [type, id, ...filters] = message;
44
+ return JSON.stringify([
45
+ type,
46
+ id,
47
+ ...canonicalizeFilters(filters)
48
+ ]);
49
+ }
50
+ case "NEG-OPEN": return JSON.stringify([
51
+ "NEG-OPEN",
52
+ message[1],
53
+ canonicalizeFilter(message[2]),
54
+ message[3]
55
+ ]);
56
+ default: return JSON.stringify(message);
57
+ }
38
58
  }
39
59
  /** Serialize a relay->client message to its NIP-01 JSON wire form. */
40
60
  function encodeRelayMessage(message) {
@@ -59,12 +79,12 @@ function parseClientMessage(raw) {
59
79
  if (items.length < 3 || typeof items[1] !== "string") throw new MessageError("invalid REQ client message");
60
80
  return [
61
81
  "REQ",
62
- items[1],
82
+ assertSubscriptionId(items[1]),
63
83
  ...parseWireFilters(items.slice(2), "REQ")
64
84
  ];
65
85
  case "CLOSE":
66
86
  if (items.length !== 2 || typeof items[1] !== "string") throw new MessageError("invalid CLOSE client message");
67
- return ["CLOSE", items[1]];
87
+ return ["CLOSE", assertSubscriptionId(items[1])];
68
88
  case "AUTH":
69
89
  if (items.length !== 2 || !validateSignedEvent(items[1])) throw new MessageError("invalid AUTH client message");
70
90
  return ["AUTH", items[1]];
@@ -72,28 +92,28 @@ function parseClientMessage(raw) {
72
92
  if (items.length < 3 || typeof items[1] !== "string") throw new MessageError("invalid COUNT client message");
73
93
  return [
74
94
  "COUNT",
75
- items[1],
95
+ assertSubscriptionId(items[1]),
76
96
  ...parseWireFilters(items.slice(2), "COUNT")
77
97
  ];
78
98
  case "NEG-OPEN":
79
99
  if (items.length === 5) throw new MessageError("obsolete 5-element NEG-OPEN; expected [NEG-OPEN, id, filter, hex]");
80
- if (items.length !== 4 || typeof items[1] !== "string" || !isWireFilter(items[2]) || !isNegHex(items[3])) throw new MessageError("invalid NEG-OPEN client message");
100
+ if (items.length !== 4 || typeof items[1] !== "string" || !isRecord(items[2]) || !isNegHex(items[3])) throw new MessageError("invalid NEG-OPEN client message");
81
101
  return [
82
102
  "NEG-OPEN",
83
- items[1],
84
- items[2],
103
+ assertSubscriptionId(items[1]),
104
+ parseWireFilter(items[2], "NEG-OPEN"),
85
105
  items[3].toLowerCase()
86
106
  ];
87
107
  case "NEG-MSG":
88
108
  if (items.length !== 3 || typeof items[1] !== "string" || !isNegHex(items[2])) throw new MessageError("invalid NEG-MSG client message");
89
109
  return [
90
110
  "NEG-MSG",
91
- items[1],
111
+ assertSubscriptionId(items[1]),
92
112
  items[2].toLowerCase()
93
113
  ];
94
114
  case "NEG-CLOSE":
95
115
  if (items.length !== 2 || typeof items[1] !== "string") throw new MessageError("invalid NEG-CLOSE client message");
96
- return ["NEG-CLOSE", items[1]];
116
+ return ["NEG-CLOSE", assertSubscriptionId(items[1])];
97
117
  default: throw new MessageError(`unknown client message type: ${String(type)}`);
98
118
  }
99
119
  }
@@ -113,11 +133,11 @@ function parseRelayMessage(raw) {
113
133
  if (items.length !== 3 || typeof items[1] !== "string" || !validateSignedEvent(items[2])) throw new MessageError("invalid EVENT relay message");
114
134
  return [
115
135
  "EVENT",
116
- items[1],
136
+ assertSubscriptionId(items[1]),
117
137
  items[2]
118
138
  ];
119
139
  case "OK":
120
- if (items.length !== 4 || typeof items[1] !== "string" || typeof items[2] !== "boolean" || typeof items[3] !== "string") throw new MessageError("invalid OK relay message");
140
+ if (items.length !== 4 || typeof items[1] !== "string" || !HEX64_LOWER_RE.test(items[1]) || typeof items[2] !== "boolean" || typeof items[3] !== "string") throw new MessageError("invalid OK relay message");
121
141
  return [
122
142
  "OK",
123
143
  items[1],
@@ -126,12 +146,12 @@ function parseRelayMessage(raw) {
126
146
  ];
127
147
  case "EOSE":
128
148
  if (items.length !== 2 || typeof items[1] !== "string") throw new MessageError("invalid EOSE relay message");
129
- return ["EOSE", items[1]];
149
+ return ["EOSE", assertSubscriptionId(items[1])];
130
150
  case "CLOSED":
131
151
  if (items.length !== 3 || typeof items[1] !== "string" || typeof items[2] !== "string") throw new MessageError("invalid CLOSED relay message");
132
152
  return [
133
153
  "CLOSED",
134
- items[1],
154
+ assertSubscriptionId(items[1]),
135
155
  items[2]
136
156
  ];
137
157
  case "NOTICE":
@@ -150,7 +170,7 @@ function parseRelayMessage(raw) {
150
170
  if (hll !== void 0) result.hll = hll;
151
171
  return [
152
172
  "COUNT",
153
- items[1],
173
+ assertSubscriptionId(items[1]),
154
174
  result
155
175
  ];
156
176
  }
@@ -158,14 +178,14 @@ function parseRelayMessage(raw) {
158
178
  if (items.length !== 3 || typeof items[1] !== "string" || !isNegHex(items[2])) throw new MessageError("invalid NEG-MSG relay message");
159
179
  return [
160
180
  "NEG-MSG",
161
- items[1],
181
+ assertSubscriptionId(items[1]),
162
182
  items[2].toLowerCase()
163
183
  ];
164
184
  case "NEG-ERR":
165
185
  if (items.length !== 3 && items.length !== 4 || typeof items[1] !== "string" || typeof items[2] !== "string") throw new MessageError("invalid NEG-ERR relay message");
166
186
  return [
167
187
  "NEG-ERR",
168
- items[1],
188
+ assertSubscriptionId(items[1]),
169
189
  items[2]
170
190
  ];
171
191
  default: throw new MessageError(`unknown relay message type: ${String(type)}`);
@@ -175,16 +195,41 @@ function parseCountHll(value) {
175
195
  if (typeof value !== "string" || value.length !== HLL_HEX_LEN || !HEX_RE.test(value)) return;
176
196
  return value.toLowerCase();
177
197
  }
178
- function isWireFilter(value) {
179
- return isRecord(value);
198
+ const HEX64_RE = /^[0-9a-fA-F]{64}$/;
199
+ const HEX64_LOWER_RE = /^[0-9a-f]{64}$/;
200
+ /**
201
+ * Validates a wire filter per NIP-01: `ids`/`authors` are 64-hex arrays (normalized lowercase),
202
+ * `kinds` are integers in 0..=65535, `since`/`until`/`limit` non-negative integers, `search` a
203
+ * string, and `#<single letter>` arrays of strings (`#e`/`#p` lowercased). Multi-letter `#` keys
204
+ * and unknown non-`#` keys are dropped; wrong types throw {@link MessageError}. Duplicate keys and
205
+ * integer spellings (`1e3`, `1.0`, `-0`) need no handling: `JSON.parse` already applied last-wins
206
+ * and normalized the numbers before this runs (nk-core's map visitors mirror that, NK-ADR-012).
207
+ */
208
+ function parseWireFilter(value, kind) {
209
+ if (!isRecord(value)) throw new MessageError(`invalid ${kind} filter`);
210
+ const fail = () => new MessageError(`invalid ${kind} filter`);
211
+ const out = {};
212
+ for (const [key, v] of Object.entries(value)) if (key.startsWith("#")) {
213
+ if (!/^#[a-zA-Z]$/.test(key)) continue;
214
+ if (!Array.isArray(v) || !v.every((x) => typeof x === "string")) throw fail();
215
+ out[`#${key.slice(1)}`] = key === "#e" || key === "#p" ? v.map((x) => x.toLowerCase()) : v;
216
+ } else if (key === "ids" || key === "authors") {
217
+ if (!Array.isArray(v) || !v.every((x) => typeof x === "string" && HEX64_RE.test(x))) throw fail();
218
+ out[key] = v.map((x) => x.toLowerCase());
219
+ } else if (key === "kinds") {
220
+ if (!Array.isArray(v) || !v.every((x) => typeof x === "number" && Number.isSafeInteger(x) && x >= 0 && x <= 65535)) throw fail();
221
+ out.kinds = v;
222
+ } else if (key === "since" || key === "until" || key === "limit") {
223
+ if (typeof v !== "number" || !Number.isSafeInteger(v) || v < 0) throw fail();
224
+ out[key] = v;
225
+ } else if (key === "search") {
226
+ if (typeof v !== "string") throw fail();
227
+ out.search = v;
228
+ }
229
+ return out;
180
230
  }
181
231
  function parseWireFilters(items, kind) {
182
- const filters = [];
183
- for (const item of items) {
184
- if (!isWireFilter(item)) throw new MessageError(`invalid ${kind} filter`);
185
- filters.push(item);
186
- }
187
- return filters;
232
+ return items.map((item) => parseWireFilter(item, kind));
188
233
  }
189
234
  function isNegHex(value) {
190
235
  return typeof value === "string" && value.length > 0 && value.length % 2 === 0 && HEX_RE.test(value);
@@ -192,4 +237,4 @@ function isNegHex(value) {
192
237
  //#endregion
193
238
  export { mergeCountHll as a, encodeRelayMessage as i, createSubscriptionId as n, parseClientMessage as o, encodeClientMessage as r, parseRelayMessage as s, assertSubscriptionId as t };
194
239
 
195
- //# sourceMappingURL=message-Rd5Z_17h.mjs.map
240
+ //# sourceMappingURL=message-pYfVKxPn.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-pYfVKxPn.mjs","names":[],"sources":["../src/core/message.ts"],"sourcesContent":["import { MessageError } from \"./error.ts\";\nimport type { Event } from \"./event.ts\";\nimport { validateSignedEvent } from \"./event.ts\";\nimport { canonicalizeFilter, canonicalizeFilters } from \"./filter.ts\";\nimport type { Filter } from \"./filter.ts\";\nimport { SUBSCRIPTION_ID_MAX_CHARS } from \"./limits.ts\";\nimport type { Mutable } from \"./util.ts\";\nimport { bytesToHex, hexToBytes, isRecord } from \"./util.ts\";\n\n/** NIP-01 subscription id: 1..64 chars. */\nexport type SubscriptionId = string;\n\n/** Validate a subscription id; throws {@link MessageError} unless 1..64 Unicode scalar values. */\nexport function assertSubscriptionId(id: string): SubscriptionId {\n // Iterating a string yields code points, so astral chars count once (NIP-01's \"chars\").\n let length = 0;\n for (const _ of id) {\n length += 1;\n }\n if (length === 0 || length > SUBSCRIPTION_ID_MAX_CHARS) {\n throw new MessageError(`subscription id length must be 1..${SUBSCRIPTION_ID_MAX_CHARS}`);\n }\n return id;\n}\n\n/** Validate the given id, or mint a random 16-hex-char subscription id. */\nexport function createSubscriptionId(id?: string): SubscriptionId {\n if (id !== undefined) {\n return assertSubscriptionId(id);\n }\n const bytes = new Uint8Array(8);\n crypto.getRandomValues(bytes);\n return bytesToHex(bytes);\n}\n\n/** Client → relay messages (NIP-01 + NIP-42 AUTH + NIP-45 COUNT + NIP-77). */\nexport type ClientMessage =\n | [\"EVENT\", Event]\n | [\"REQ\", SubscriptionId, ...Filter[]]\n | [\"CLOSE\", SubscriptionId]\n | [\"AUTH\", Event]\n | [\"COUNT\", SubscriptionId, ...Filter[]]\n | [\"NEG-OPEN\", SubscriptionId, Filter, string]\n | [\"NEG-MSG\", SubscriptionId, string]\n | [\"NEG-CLOSE\", SubscriptionId];\n\n/** Relay → client messages. */\nexport type RelayMessage =\n | [\"EVENT\", SubscriptionId, Event]\n | [\"OK\", string, boolean, string]\n | [\"EOSE\", SubscriptionId]\n | [\"CLOSED\", SubscriptionId, string]\n | [\"NOTICE\", string]\n | [\"AUTH\", string]\n | [\"COUNT\", SubscriptionId, CountResult]\n | [\"NEG-MSG\", SubscriptionId, string]\n | [\"NEG-ERR\", SubscriptionId, string];\n\n/** NIP-45 COUNT reply payload. */\nexport type CountResult = {\n readonly count: number;\n readonly approximate?: boolean | undefined;\n /**\n * Optional 512-char hex HyperLogLog sketch (256 registers). Merge sketches with `mergeCountHll`.\n * Estimation is unspecified by NIP-45 and not provided.\n */\n readonly hll?: string | undefined;\n};\n\nconst HLL_BYTES = 256; // 512 hex chars (NIP-45; hex only, not base64)\nconst HLL_HEX_LEN = HLL_BYTES * 2;\nconst HEX_RE = /^[0-9a-fA-F]+$/;\n\n/**\n * Register-wise max of NIP-45 HyperLogLog sketches. Output is always lowercase 512 hex. Empty input\n * is the zero sketch (identity).\n */\nexport function mergeCountHll(hexes: ReadonlyArray<string>): string {\n const merged = new Uint8Array(HLL_BYTES);\n for (const hex of hexes) {\n if (hex.length !== HLL_HEX_LEN || !HEX_RE.test(hex)) {\n throw new MessageError(\"invalid NIP-45 HLL sketch: expected 512-char hex\");\n }\n const bytes = hexToBytes(hex);\n for (const [i, b] of bytes.entries()) {\n const m = merged[i];\n if (m !== undefined && b > m) {\n merged[i] = b;\n }\n }\n }\n return bytesToHex(merged);\n}\n\n/** Serialize a client->relay message to its NIP-01 JSON wire form. */\nexport function encodeClientMessage(message: ClientMessage): string {\n // REQ/COUNT/NEG-OPEN filters are canonicalized so the wire form matches nk-core.\n switch (message[0]) {\n case \"REQ\":\n case \"COUNT\": {\n const [type, id, ...filters] = message;\n return JSON.stringify([type, id, ...canonicalizeFilters(filters)]);\n }\n case \"NEG-OPEN\":\n return JSON.stringify([\"NEG-OPEN\", message[1], canonicalizeFilter(message[2]), message[3]]);\n default:\n return JSON.stringify(message);\n }\n}\n\n/** Serialize a relay->client message to its NIP-01 JSON wire form. */\nexport function encodeRelayMessage(message: RelayMessage): string {\n return JSON.stringify(message);\n}\n\n/** Parse a client->relay JSON message; throws {@link MessageError} on malformed input. */\nexport function parseClientMessage(raw: string): ClientMessage {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new MessageError(\"client message is not valid JSON\");\n }\n if (!Array.isArray(parsed) || parsed.length === 0 || typeof parsed[0] !== \"string\") {\n throw new MessageError(\"client message must be a non-empty JSON array\");\n }\n const items: unknown[] = parsed;\n const [type] = items;\n switch (type) {\n case \"EVENT\":\n if (items.length !== 2 || !validateSignedEvent(items[1])) {\n throw new MessageError(\"invalid EVENT client message\");\n }\n return [\"EVENT\", items[1]];\n\n case \"REQ\":\n if (items.length < 3 || typeof items[1] !== \"string\") {\n throw new MessageError(\"invalid REQ client message\");\n }\n return [\"REQ\", assertSubscriptionId(items[1]), ...parseWireFilters(items.slice(2), \"REQ\")];\n\n case \"CLOSE\":\n if (items.length !== 2 || typeof items[1] !== \"string\") {\n throw new MessageError(\"invalid CLOSE client message\");\n }\n return [\"CLOSE\", assertSubscriptionId(items[1])];\n\n case \"AUTH\":\n if (items.length !== 2 || !validateSignedEvent(items[1])) {\n throw new MessageError(\"invalid AUTH client message\");\n }\n return [\"AUTH\", items[1]];\n\n case \"COUNT\":\n if (items.length < 3 || typeof items[1] !== \"string\") {\n throw new MessageError(\"invalid COUNT client message\");\n }\n return [\n \"COUNT\",\n assertSubscriptionId(items[1]),\n ...parseWireFilters(items.slice(2), \"COUNT\"),\n ];\n\n case \"NEG-OPEN\":\n if (items.length === 5) {\n throw new MessageError(\"obsolete 5-element NEG-OPEN; expected [NEG-OPEN, id, filter, hex]\");\n }\n if (\n items.length !== 4 ||\n typeof items[1] !== \"string\" ||\n !isRecord(items[2]) ||\n !isNegHex(items[3])\n ) {\n throw new MessageError(\"invalid NEG-OPEN client message\");\n }\n return [\n \"NEG-OPEN\",\n assertSubscriptionId(items[1]),\n parseWireFilter(items[2], \"NEG-OPEN\"),\n items[3].toLowerCase(),\n ];\n\n case \"NEG-MSG\":\n if (items.length !== 3 || typeof items[1] !== \"string\" || !isNegHex(items[2])) {\n throw new MessageError(\"invalid NEG-MSG client message\");\n }\n return [\"NEG-MSG\", assertSubscriptionId(items[1]), items[2].toLowerCase()];\n\n case \"NEG-CLOSE\":\n if (items.length !== 2 || typeof items[1] !== \"string\") {\n throw new MessageError(\"invalid NEG-CLOSE client message\");\n }\n return [\"NEG-CLOSE\", assertSubscriptionId(items[1])];\n\n default:\n throw new MessageError(`unknown client message type: ${String(type)}`);\n }\n}\n\n/** Parse a relay->client JSON message; throws {@link MessageError} on malformed input. */\nexport function parseRelayMessage(raw: string): RelayMessage {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new MessageError(\"relay message is not valid JSON\");\n }\n if (!Array.isArray(parsed) || parsed.length === 0 || typeof parsed[0] !== \"string\") {\n throw new MessageError(\"relay message must be a non-empty JSON array\");\n }\n const items: unknown[] = parsed;\n const [type] = items;\n switch (type) {\n case \"EVENT\":\n if (items.length !== 3 || typeof items[1] !== \"string\" || !validateSignedEvent(items[2])) {\n throw new MessageError(\"invalid EVENT relay message\");\n }\n return [\"EVENT\", assertSubscriptionId(items[1]), items[2]];\n\n case \"OK\":\n if (\n items.length !== 4 ||\n typeof items[1] !== \"string\" ||\n !HEX64_LOWER_RE.test(items[1]) ||\n typeof items[2] !== \"boolean\" ||\n typeof items[3] !== \"string\"\n ) {\n throw new MessageError(\"invalid OK relay message\");\n }\n return [\"OK\", items[1], items[2], items[3]];\n\n case \"EOSE\":\n if (items.length !== 2 || typeof items[1] !== \"string\") {\n throw new MessageError(\"invalid EOSE relay message\");\n }\n return [\"EOSE\", assertSubscriptionId(items[1])];\n\n case \"CLOSED\":\n if (items.length !== 3 || typeof items[1] !== \"string\" || typeof items[2] !== \"string\") {\n throw new MessageError(\"invalid CLOSED relay message\");\n }\n return [\"CLOSED\", assertSubscriptionId(items[1]), items[2]];\n\n case \"NOTICE\":\n if (items.length !== 2 || typeof items[1] !== \"string\") {\n throw new MessageError(\"invalid NOTICE relay message\");\n }\n return [\"NOTICE\", items[1]];\n\n case \"AUTH\":\n if (items.length !== 2 || typeof items[1] !== \"string\") {\n throw new MessageError(\"invalid AUTH relay message\");\n }\n return [\"AUTH\", items[1]];\n\n case \"COUNT\": {\n const payload = items.at(2);\n const count = isRecord(payload) ? payload[\"count\"] : undefined;\n if (\n items.length !== 3 ||\n typeof items[1] !== \"string\" ||\n !isRecord(payload) ||\n typeof count !== \"number\" ||\n !Number.isSafeInteger(count) ||\n count < 0\n ) {\n throw new MessageError(\"invalid COUNT relay message\");\n }\n const result: Mutable<CountResult> = { count };\n if (typeof payload[\"approximate\"] === \"boolean\") {\n result.approximate = payload[\"approximate\"];\n }\n const hll = parseCountHll(payload[\"hll\"]);\n if (hll !== undefined) {\n result.hll = hll;\n }\n return [\"COUNT\", assertSubscriptionId(items[1]), result];\n }\n case \"NEG-MSG\":\n if (items.length !== 3 || typeof items[1] !== \"string\" || !isNegHex(items[2])) {\n throw new MessageError(\"invalid NEG-MSG relay message\");\n }\n return [\"NEG-MSG\", assertSubscriptionId(items[1]), items[2].toLowerCase()];\n\n case \"NEG-ERR\":\n if (\n (items.length !== 3 && items.length !== 4) ||\n typeof items[1] !== \"string\" ||\n typeof items[2] !== \"string\"\n ) {\n throw new MessageError(\"invalid NEG-ERR relay message\");\n }\n return [\"NEG-ERR\", assertSubscriptionId(items[1]), items[2]];\n\n default:\n throw new MessageError(`unknown relay message type: ${String(type)}`);\n }\n}\n\nfunction parseCountHll(value: unknown): string | undefined {\n if (typeof value !== \"string\" || value.length !== HLL_HEX_LEN || !HEX_RE.test(value)) {\n return undefined;\n }\n return value.toLowerCase();\n}\n\nconst HEX64_RE = /^[0-9a-fA-F]{64}$/;\nconst HEX64_LOWER_RE = /^[0-9a-f]{64}$/;\n\n/**\n * Validates a wire filter per NIP-01: `ids`/`authors` are 64-hex arrays (normalized lowercase),\n * `kinds` are integers in 0..=65535, `since`/`until`/`limit` non-negative integers, `search` a\n * string, and `#<single letter>` arrays of strings (`#e`/`#p` lowercased). Multi-letter `#` keys\n * and unknown non-`#` keys are dropped; wrong types throw {@link MessageError}. Duplicate keys and\n * integer spellings (`1e3`, `1.0`, `-0`) need no handling: `JSON.parse` already applied last-wins\n * and normalized the numbers before this runs (nk-core's map visitors mirror that, NK-ADR-012).\n */\nfunction parseWireFilter(value: unknown, kind: string): Filter {\n if (!isRecord(value)) {\n throw new MessageError(`invalid ${kind} filter`);\n }\n const fail = (): MessageError => new MessageError(`invalid ${kind} filter`);\n const out: Mutable<Filter> = {};\n for (const [key, v] of Object.entries(value)) {\n if (key.startsWith(\"#\")) {\n if (!/^#[a-zA-Z]$/.test(key)) {\n continue;\n }\n if (!Array.isArray(v) || !v.every((x): x is string => typeof x === \"string\")) {\n throw fail();\n }\n out[`#${key.slice(1)}`] = key === \"#e\" || key === \"#p\" ? v.map((x) => x.toLowerCase()) : v;\n } else if (key === \"ids\" || key === \"authors\") {\n if (\n !Array.isArray(v) ||\n !v.every((x): x is string => typeof x === \"string\" && HEX64_RE.test(x))\n ) {\n throw fail();\n }\n out[key] = v.map((x) => x.toLowerCase());\n } else if (key === \"kinds\") {\n if (\n !Array.isArray(v) ||\n !v.every(\n (x): x is number =>\n typeof x === \"number\" && Number.isSafeInteger(x) && x >= 0 && x <= 65535,\n )\n ) {\n throw fail();\n }\n out.kinds = v;\n } else if (key === \"since\" || key === \"until\" || key === \"limit\") {\n if (typeof v !== \"number\" || !Number.isSafeInteger(v) || v < 0) {\n throw fail();\n }\n out[key] = v;\n } else if (key === \"search\") {\n if (typeof v !== \"string\") {\n throw fail();\n }\n out.search = v;\n }\n }\n return out;\n}\n\nfunction parseWireFilters(items: unknown[], kind: string): Filter[] {\n return items.map((item) => parseWireFilter(item, kind));\n}\n\nfunction isNegHex(value: unknown): value is string {\n return (\n typeof value === \"string\" && value.length > 0 && value.length % 2 === 0 && HEX_RE.test(value)\n );\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import { c as isRecord, d as nowSeconds, h as EventValidationError, i as bytesToHex, n as assertHex32, p as utf8Encoder, v as NostrError } from "../util-DMF9AIO0.mjs";
1
+ import { f as nowSeconds, g as EventValidationError, i as bytesToHex, l as isRecord, m as utf8Encoder, n as assertHex32, y as NostrError } from "../util-DDpPkiED.mjs";
2
2
  import { t as Kind } from "../kind-D8fENiiL.mjs";
3
- import { t as EventBuilder } from "../builder-CVRmUeNm.mjs";
3
+ import { t as EventBuilder } from "../builder-BQbFDO6S.mjs";
4
4
  import { n as requireGlobalFetch, r as sendManual, t as fetchManual } from "../http-CuazNRIP.mjs";
5
5
  import { sha256 } from "@noble/hashes/sha2.js";
6
6
  import { base64urlnopad } from "@scure/base";
@@ -1,4 +1,4 @@
1
- import { a as hexToBytes$1, f as utf8Decoder, m as CryptoError, n as assertHex32, p as utf8Encoder, r as assertSecretKeyBytes } from "../util-DMF9AIO0.mjs";
1
+ import { h as CryptoError, m as utf8Encoder, n as assertHex32, o as hexToBytes$1, p as utf8Decoder, r as assertSecretKeyBytes } from "../util-DDpPkiED.mjs";
2
2
  import { randomBytes } from "@noble/hashes/utils.js";
3
3
  import { secp256k1 } from "@noble/curves/secp256k1.js";
4
4
  import { cbc } from "@noble/ciphers/aes.js";
@@ -1,4 +1,4 @@
1
- import { c as isRecord, o as isHex32, v as NostrError } from "../util-DMF9AIO0.mjs";
1
+ import { l as isRecord, s as isHex32, y as NostrError } from "../util-DDpPkiED.mjs";
2
2
  import { n as requireGlobalFetch, t as fetchManual } from "../http-CuazNRIP.mjs";
3
3
  //#region src/nips/nip05.ts
4
4
  /**
@@ -1,7 +1,7 @@
1
- import { h as EventValidationError, o as isHex32 } from "../util-DMF9AIO0.mjs";
1
+ import { g as EventValidationError, s as isHex32 } from "../util-DDpPkiED.mjs";
2
2
  import { t as Kind } from "../kind-D8fENiiL.mjs";
3
- import { S as parseEventAddress, g as Tag, y as formatEventAddress } from "../event-C2eLiPpV.mjs";
4
- import { t as EventBuilder } from "../builder-CVRmUeNm.mjs";
3
+ import { S as parseEventAddress, g as Tag, y as formatEventAddress } from "../event-B3ua2_oL.mjs";
4
+ import { t as EventBuilder } from "../builder-BQbFDO6S.mjs";
5
5
  //#region src/nips/nip10.ts
6
6
  /**
7
7
  * NIP-10: Text Notes and Threads
@@ -1,4 +1,4 @@
1
- import { c as isRecord, v as NostrError } from "../util-DMF9AIO0.mjs";
1
+ import { l as isRecord, y as NostrError } from "../util-DDpPkiED.mjs";
2
2
  import { n as requireGlobalFetch, t as fetchManual } from "../http-CuazNRIP.mjs";
3
3
  //#region src/nips/nip11.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { d as nowSeconds, i as bytesToHex, o as isHex32, p as utf8Encoder, v as NostrError } from "../util-DMF9AIO0.mjs";
1
+ import { f as nowSeconds, i as bytesToHex, m as utf8Encoder, s as isHex32, y as NostrError } from "../util-DDpPkiED.mjs";
2
2
  import { t as abortReason } from "../abort-DBq2STPj.mjs";
3
3
  import { sha256 } from "@noble/hashes/sha2.js";
4
4
  //#region src/nips/nip13.ts
@@ -1,7 +1,7 @@
1
- import { h as EventValidationError, l as normalizeRelayUrls, n as assertHex32, v as NostrError } from "../util-DMF9AIO0.mjs";
1
+ import { g as EventValidationError, n as assertHex32, u as normalizeRelayUrls, y as NostrError } from "../util-DDpPkiED.mjs";
2
2
  import { t as Kind } from "../kind-D8fENiiL.mjs";
3
- import { g as Tag } from "../event-C2eLiPpV.mjs";
4
- import { t as EventBuilder } from "../builder-CVRmUeNm.mjs";
3
+ import { g as Tag } from "../event-B3ua2_oL.mjs";
4
+ import { t as EventBuilder } from "../builder-BQbFDO6S.mjs";
5
5
  import { createGiftWrap, createRumor, createSeal } from "./nip59.mjs";
6
6
  //#region src/nips/nip17.ts
7
7
  /**
@@ -1,4 +1,5 @@
1
- import { a as hexToBytes, f as utf8Decoder, i as bytesToHex, n as assertHex32, p as utf8Encoder, t as assertByteLength, v as NostrError, x as errorMessage } from "../util-DMF9AIO0.mjs";
1
+ import { S as errorMessage, i as bytesToHex, m as utf8Encoder, n as assertHex32, o as hexToBytes, p as utf8Decoder, t as assertByteLength, y as NostrError } from "../util-DDpPkiED.mjs";
2
+ import { secp256k1 } from "@noble/curves/secp256k1.js";
2
3
  import { bech32 } from "@scure/base";
3
4
  //#region src/nips/nip19.ts
4
5
  /** Maximum bech32 string length accepted by {@link decode} (NIP-19). */
@@ -29,7 +30,7 @@ function parseTLV(data) {
29
30
  return result;
30
31
  }
31
32
  function assertNip19Kind(kind) {
32
- if (!Number.isInteger(kind) || kind < 0 || kind > 4294967295) throw new Nip19Error(`invalid kind: ${kind}`);
33
+ if (!Number.isInteger(kind) || kind < 0 || kind > 65535) throw new Nip19Error(`invalid kind: ${kind}`);
33
34
  }
34
35
  function encodeTLV(tlv) {
35
36
  const entries = [];
@@ -140,7 +141,10 @@ function decode(code) {
140
141
  const author = tlv[2]?.[0];
141
142
  if (author !== void 0) pointer.author = bytesToHex(author);
142
143
  const kind = tlv[3]?.[0];
143
- if (kind !== void 0) pointer.kind = readUint32(kind);
144
+ if (kind !== void 0) {
145
+ pointer.kind = readUint32(kind);
146
+ assertNip19Kind(pointer.kind);
147
+ }
144
148
  return {
145
149
  type: "nevent",
146
150
  data: pointer
@@ -153,18 +157,21 @@ function decode(code) {
153
157
  if (tlv[2][0].length !== 32) throw new Nip19Error("TLV 2 should be 32 bytes");
154
158
  if (!tlv[3]?.[0]) throw new Nip19Error("missing TLV 3 for naddr");
155
159
  if (tlv[3][0].length !== 4) throw new Nip19Error("TLV 3 should be 4 bytes");
160
+ const naddrKind = readUint32(tlv[3][0]);
161
+ assertNip19Kind(naddrKind);
156
162
  return {
157
163
  type: "naddr",
158
164
  data: {
159
165
  identifier: utf8Decoder.decode(tlv[0][0]),
160
166
  pubkey: bytesToHex(tlv[2][0]),
161
- kind: readUint32(tlv[3][0]),
167
+ kind: naddrKind,
162
168
  relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : []
163
169
  }
164
170
  };
165
171
  }
166
172
  case "nsec":
167
173
  if (data.length !== 32) throw new Nip19Error("nsec must be 32 bytes");
174
+ if (!secp256k1.utils.isValidSecretKey(data)) throw new Nip19Error("invalid nsec secret key");
168
175
  return {
169
176
  type: "nsec",
170
177
  data
@@ -1 +1 @@
1
- {"version":3,"file":"nip19.mjs","names":[],"sources":["../../src/nips/nip19.ts"],"sourcesContent":["import { bech32 } from \"@scure/base\";\n\nimport { NostrError, errorMessage } from \"../core/error.ts\";\nimport type { Mutable } from \"../core/util.ts\";\nimport {\n assertByteLength,\n assertHex32,\n bytesToHex,\n hexToBytes,\n utf8Decoder,\n utf8Encoder,\n} from \"../core/util.ts\";\n\n/** Bech32 `nprofile1…` string (TLV profile pointer). */\nexport type NProfile = `nprofile1${string}`;\n/** Bech32 `nevent1…` string (TLV event pointer). */\nexport type NEvent = `nevent1${string}`;\n/** Bech32 `naddr1…` string (TLV address pointer). */\nexport type NAddr = `naddr1${string}`;\n/** Bech32 `nsec1…` string (32-byte secret key). */\nexport type NSec = `nsec1${string}`;\n/** Bech32 `npub1…` string (32-byte public key). */\nexport type NPub = `npub1${string}`;\n/** Bech32 `note1…` string (32-byte event id). */\nexport type Note = `note1${string}`;\n\n/** Maximum bech32 string length accepted by {@link decode} (NIP-19). */\nexport const Bech32MaxSize = 5000;\n\n/** Decoded `nprofile` payload: a pubkey plus optional relay hints. */\nexport type ProfilePointer = {\n readonly pubkey: string;\n readonly relays?: ReadonlyArray<string> | undefined;\n};\n\n/** Decoded `nevent` payload: an event id plus optional relay/author/kind hints. */\nexport type EventPointer = {\n readonly id: string;\n readonly relays?: ReadonlyArray<string> | undefined;\n readonly author?: string | undefined;\n readonly kind?: number | undefined;\n};\n\n/** Decoded `naddr` payload: a replaceable-event coordinate plus optional relay hints. */\nexport type AddressPointer = {\n readonly identifier: string;\n readonly pubkey: string;\n readonly kind: number;\n readonly relays?: ReadonlyArray<string> | undefined;\n};\n\n/** Result of {@link decode}: the bech32 prefix and its decoded payload. */\nexport type DecodedResult =\n | { readonly type: \"nprofile\"; readonly data: ProfilePointer }\n | { readonly type: \"nevent\"; readonly data: EventPointer }\n | { readonly type: \"naddr\"; readonly data: AddressPointer }\n | { readonly type: \"nsec\"; readonly data: Uint8Array }\n | { readonly type: \"npub\"; readonly data: string }\n | { readonly type: \"note\"; readonly data: string };\n\n/** Error thrown by NIP-19 encoding/decoding failures. */\nexport class Nip19Error extends NostrError {\n override name = \"Nip19Error\";\n}\n\ntype TLV = Record<number, Uint8Array[]>;\n\nfunction integerToUint8Array(number: number): Uint8Array {\n const out = new Uint8Array(4);\n new DataView(out.buffer).setUint32(0, number);\n return out;\n}\n\nfunction parseTLV(data: Uint8Array): TLV {\n const result: TLV = {};\n let rest = data;\n while (rest.length > 0) {\n if (rest.length < 2) {\n throw new Nip19Error(\"not enough data to read TLV\");\n }\n const t = rest.at(0);\n const l = rest.at(1);\n if (t === undefined || l === undefined) {\n throw new Nip19Error(\"not enough data to read TLV\");\n }\n const v = rest.slice(2, 2 + l);\n rest = rest.slice(2 + l);\n if (v.length < l) {\n throw new Nip19Error(`not enough data to read on TLV ${t}`);\n }\n result[t] = result[t] ?? [];\n result[t].push(v);\n }\n return result;\n}\n\nfunction assertNip19Kind(kind: number): void {\n if (!Number.isInteger(kind) || kind < 0 || kind > 0xffffffff) {\n throw new Nip19Error(`invalid kind: ${kind}`);\n }\n}\n\nfunction encodeTLV(tlv: TLV): Uint8Array {\n const entries: Uint8Array[] = [];\n for (const [t, vs] of Object.entries(tlv).reverse()) {\n for (const v of vs) {\n if (v.length > 255) {\n throw new Nip19Error(\"TLV value exceeds 255 bytes\");\n }\n const entry = new Uint8Array(v.length + 2);\n entry[0] = Math.trunc(Number(t));\n entry[1] = v.length;\n entry.set(v, 2);\n entries.push(entry);\n }\n }\n let total = 0;\n for (const e of entries) {\n total += e.length;\n }\n const out = new Uint8Array(total);\n let offset = 0;\n for (const e of entries) {\n out.set(e, offset);\n offset += e.length;\n }\n return out;\n}\n\nfunction encodeBech32<Prefix extends string>(\n prefix: Prefix,\n data: Uint8Array,\n): `${Prefix}1${string}` {\n const words = bech32.toWords(data);\n // oxlint-disable-next-line no-unsafe-type-assertion -- bech32 output is `${prefix}1…` by construction\n return bech32.encode(prefix, words, Bech32MaxSize) as `${Prefix}1${string}`;\n}\n\nexport function encodeBytes<Prefix extends string>(\n prefix: Prefix,\n bytes: Uint8Array,\n): `${Prefix}1${string}` {\n return encodeBech32(prefix, bytes);\n}\n\n/** Encode a 32-byte secret key as `nsec1…`; throws {@link Nip19Error} on wrong length. */\nexport function nsecEncode(key: Uint8Array): NSec {\n assertByteLength(key, 32, \"secret key\");\n return encodeBytes(\"nsec\", key);\n}\n\n/** Encode a hex public key as `npub1…`; throws {@link HexError} on bad hex. */\nexport function npubEncode(hex: string): NPub {\n return encodeBytes(\"npub\", hexToBytes(assertHex32(hex, \"pubkey\")));\n}\n\n/** Encode a hex event id as `note1…`; throws {@link HexError} on bad hex. */\nexport function noteEncode(hex: string): Note {\n return encodeBytes(\"note\", hexToBytes(assertHex32(hex, \"event id\")));\n}\n\n/** Encode a profile pointer as `nprofile1…`. */\nexport function nprofileEncode(profile: ProfilePointer): NProfile {\n const data = encodeTLV({\n 0: [hexToBytes(assertHex32(profile.pubkey, \"pubkey\"))],\n 1: (profile.relays ?? []).map((url) => utf8Encoder.encode(url)),\n });\n return encodeBech32(\"nprofile\", data);\n}\n\n/** Encode an event pointer as `nevent1…`. */\nexport function neventEncode(event: EventPointer): NEvent {\n if (event.kind !== undefined) {\n assertNip19Kind(event.kind);\n }\n const kindArray = event.kind === undefined ? undefined : integerToUint8Array(event.kind);\n const data = encodeTLV({\n 0: [hexToBytes(assertHex32(event.id, \"event id\"))],\n 1: (event.relays ?? []).map((url) => utf8Encoder.encode(url)),\n 2:\n event.author !== undefined && event.author !== \"\"\n ? [hexToBytes(assertHex32(event.author, \"author\"))]\n : [],\n 3: kindArray ? [kindArray] : [],\n });\n return encodeBech32(\"nevent\", data);\n}\n\n/** Encode an address pointer as `naddr1…`. */\nexport function naddrEncode(addr: AddressPointer): NAddr {\n assertNip19Kind(addr.kind);\n const kind = integerToUint8Array(addr.kind);\n const data = encodeTLV({\n 0: [utf8Encoder.encode(addr.identifier)],\n 1: (addr.relays ?? []).map((url) => utf8Encoder.encode(url)),\n 2: [hexToBytes(assertHex32(addr.pubkey, \"pubkey\"))],\n 3: [kind],\n });\n return encodeBech32(\"naddr\", data);\n}\n\nfunction readUint32(bytes: Uint8Array): number {\n return new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(0);\n}\n\n/** Decode a NIP-19 bech32 entity; throws {@link Nip19Error} on bad input or unknown prefix. */\nexport function decode(code: string): DecodedResult {\n let prefix: string;\n let data: Uint8Array;\n try {\n const { prefix: hrp, words } = bech32.decode(code, Bech32MaxSize);\n prefix = hrp;\n data = new Uint8Array(bech32.fromWords(words));\n } catch (error) {\n throw new Nip19Error(`invalid bech32: ${errorMessage(error)}`, { cause: error });\n }\n\n switch (prefix) {\n case \"nprofile\": {\n const tlv = parseTLV(data);\n if (!tlv[0]?.[0]) {\n throw new Nip19Error(\"missing TLV 0 for nprofile\");\n }\n if (tlv[0][0].length !== 32) {\n throw new Nip19Error(\"TLV 0 should be 32 bytes\");\n }\n return {\n type: \"nprofile\",\n data: {\n pubkey: bytesToHex(tlv[0][0]),\n relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [],\n },\n };\n }\n case \"nevent\": {\n const tlv = parseTLV(data);\n if (!tlv[0]?.[0]) {\n throw new Nip19Error(\"missing TLV 0 for nevent\");\n }\n if (tlv[0][0].length !== 32) {\n throw new Nip19Error(\"TLV 0 should be 32 bytes\");\n }\n if (tlv[2]?.[0] && tlv[2][0].length !== 32) {\n throw new Nip19Error(\"TLV 2 should be 32 bytes\");\n }\n if (tlv[3]?.[0] && tlv[3][0].length !== 4) {\n throw new Nip19Error(\"TLV 3 should be 4 bytes\");\n }\n const pointer: Mutable<EventPointer> = {\n id: bytesToHex(tlv[0][0]),\n relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [],\n };\n const author = tlv[2]?.[0];\n if (author !== undefined) {\n pointer.author = bytesToHex(author);\n }\n const kind = tlv[3]?.[0];\n if (kind !== undefined) {\n pointer.kind = readUint32(kind);\n }\n return { type: \"nevent\", data: pointer };\n }\n case \"naddr\": {\n const tlv = parseTLV(data);\n if (!tlv[0]?.[0]) {\n throw new Nip19Error(\"missing TLV 0 for naddr\");\n }\n if (!tlv[2]?.[0]) {\n throw new Nip19Error(\"missing TLV 2 for naddr\");\n }\n if (tlv[2][0].length !== 32) {\n throw new Nip19Error(\"TLV 2 should be 32 bytes\");\n }\n if (!tlv[3]?.[0]) {\n throw new Nip19Error(\"missing TLV 3 for naddr\");\n }\n if (tlv[3][0].length !== 4) {\n throw new Nip19Error(\"TLV 3 should be 4 bytes\");\n }\n return {\n type: \"naddr\",\n data: {\n identifier: utf8Decoder.decode(tlv[0][0]),\n pubkey: bytesToHex(tlv[2][0]),\n kind: readUint32(tlv[3][0]),\n relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [],\n },\n };\n }\n case \"nsec\":\n if (data.length !== 32) {\n throw new Nip19Error(\"nsec must be 32 bytes\");\n }\n return { type: \"nsec\", data };\n case \"npub\":\n case \"note\":\n if (data.length !== 32) {\n throw new Nip19Error(`${prefix} must be 32 bytes`);\n }\n return { type: prefix, data: bytesToHex(data) };\n default:\n throw new Nip19Error(`unknown prefix ${prefix}`);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"nip19.mjs","names":[],"sources":["../../src/nips/nip19.ts"],"sourcesContent":["import { secp256k1 } from \"@noble/curves/secp256k1.js\";\nimport { bech32 } from \"@scure/base\";\n\nimport { NostrError, errorMessage } from \"../core/error.ts\";\nimport type { Mutable } from \"../core/util.ts\";\nimport {\n assertByteLength,\n assertHex32,\n bytesToHex,\n hexToBytes,\n utf8Decoder,\n utf8Encoder,\n} from \"../core/util.ts\";\n\n/** Bech32 `nprofile1…` string (TLV profile pointer). */\nexport type NProfile = `nprofile1${string}`;\n/** Bech32 `nevent1…` string (TLV event pointer). */\nexport type NEvent = `nevent1${string}`;\n/** Bech32 `naddr1…` string (TLV address pointer). */\nexport type NAddr = `naddr1${string}`;\n/** Bech32 `nsec1…` string (32-byte secret key). */\nexport type NSec = `nsec1${string}`;\n/** Bech32 `npub1…` string (32-byte public key). */\nexport type NPub = `npub1${string}`;\n/** Bech32 `note1…` string (32-byte event id). */\nexport type Note = `note1${string}`;\n\n/** Maximum bech32 string length accepted by {@link decode} (NIP-19). */\nexport const Bech32MaxSize = 5000;\n\n/** Decoded `nprofile` payload: a pubkey plus optional relay hints. */\nexport type ProfilePointer = {\n readonly pubkey: string;\n readonly relays?: ReadonlyArray<string> | undefined;\n};\n\n/** Decoded `nevent` payload: an event id plus optional relay/author/kind hints. */\nexport type EventPointer = {\n readonly id: string;\n readonly relays?: ReadonlyArray<string> | undefined;\n readonly author?: string | undefined;\n readonly kind?: number | undefined;\n};\n\n/** Decoded `naddr` payload: a replaceable-event coordinate plus optional relay hints. */\nexport type AddressPointer = {\n readonly identifier: string;\n readonly pubkey: string;\n readonly kind: number;\n readonly relays?: ReadonlyArray<string> | undefined;\n};\n\n/** Result of {@link decode}: the bech32 prefix and its decoded payload. */\nexport type DecodedResult =\n | { readonly type: \"nprofile\"; readonly data: ProfilePointer }\n | { readonly type: \"nevent\"; readonly data: EventPointer }\n | { readonly type: \"naddr\"; readonly data: AddressPointer }\n | { readonly type: \"nsec\"; readonly data: Uint8Array }\n | { readonly type: \"npub\"; readonly data: string }\n | { readonly type: \"note\"; readonly data: string };\n\n/** Error thrown by NIP-19 encoding/decoding failures. */\nexport class Nip19Error extends NostrError {\n override name = \"Nip19Error\";\n}\n\ntype TLV = Record<number, Uint8Array[]>;\n\nfunction integerToUint8Array(number: number): Uint8Array {\n const out = new Uint8Array(4);\n new DataView(out.buffer).setUint32(0, number);\n return out;\n}\n\nfunction parseTLV(data: Uint8Array): TLV {\n const result: TLV = {};\n let rest = data;\n while (rest.length > 0) {\n if (rest.length < 2) {\n throw new Nip19Error(\"not enough data to read TLV\");\n }\n const t = rest.at(0);\n const l = rest.at(1);\n if (t === undefined || l === undefined) {\n throw new Nip19Error(\"not enough data to read TLV\");\n }\n const v = rest.slice(2, 2 + l);\n rest = rest.slice(2 + l);\n if (v.length < l) {\n throw new Nip19Error(`not enough data to read on TLV ${t}`);\n }\n result[t] = result[t] ?? [];\n result[t].push(v);\n }\n return result;\n}\n\n// NIP-01 kinds are u16, so the 4-byte wire TLV is limited to 0..=65535 on\n// both encode and decode.\nfunction assertNip19Kind(kind: number): void {\n if (!Number.isInteger(kind) || kind < 0 || kind > 0xffff) {\n throw new Nip19Error(`invalid kind: ${kind}`);\n }\n}\n\nfunction encodeTLV(tlv: TLV): Uint8Array {\n const entries: Uint8Array[] = [];\n for (const [t, vs] of Object.entries(tlv).reverse()) {\n for (const v of vs) {\n if (v.length > 255) {\n throw new Nip19Error(\"TLV value exceeds 255 bytes\");\n }\n const entry = new Uint8Array(v.length + 2);\n entry[0] = Math.trunc(Number(t));\n entry[1] = v.length;\n entry.set(v, 2);\n entries.push(entry);\n }\n }\n let total = 0;\n for (const e of entries) {\n total += e.length;\n }\n const out = new Uint8Array(total);\n let offset = 0;\n for (const e of entries) {\n out.set(e, offset);\n offset += e.length;\n }\n return out;\n}\n\nfunction encodeBech32<Prefix extends string>(\n prefix: Prefix,\n data: Uint8Array,\n): `${Prefix}1${string}` {\n const words = bech32.toWords(data);\n // oxlint-disable-next-line no-unsafe-type-assertion -- bech32 output is `${prefix}1…` by construction\n return bech32.encode(prefix, words, Bech32MaxSize) as `${Prefix}1${string}`;\n}\n\nexport function encodeBytes<Prefix extends string>(\n prefix: Prefix,\n bytes: Uint8Array,\n): `${Prefix}1${string}` {\n return encodeBech32(prefix, bytes);\n}\n\n/** Encode a 32-byte secret key as `nsec1…`; throws {@link Nip19Error} on wrong length. */\nexport function nsecEncode(key: Uint8Array): NSec {\n assertByteLength(key, 32, \"secret key\");\n return encodeBytes(\"nsec\", key);\n}\n\n/** Encode a hex public key as `npub1…`; throws {@link HexError} on bad hex. */\nexport function npubEncode(hex: string): NPub {\n return encodeBytes(\"npub\", hexToBytes(assertHex32(hex, \"pubkey\")));\n}\n\n/** Encode a hex event id as `note1…`; throws {@link HexError} on bad hex. */\nexport function noteEncode(hex: string): Note {\n return encodeBytes(\"note\", hexToBytes(assertHex32(hex, \"event id\")));\n}\n\n/** Encode a profile pointer as `nprofile1…`. */\nexport function nprofileEncode(profile: ProfilePointer): NProfile {\n const data = encodeTLV({\n 0: [hexToBytes(assertHex32(profile.pubkey, \"pubkey\"))],\n 1: (profile.relays ?? []).map((url) => utf8Encoder.encode(url)),\n });\n return encodeBech32(\"nprofile\", data);\n}\n\n/** Encode an event pointer as `nevent1…`. */\nexport function neventEncode(event: EventPointer): NEvent {\n if (event.kind !== undefined) {\n assertNip19Kind(event.kind);\n }\n const kindArray = event.kind === undefined ? undefined : integerToUint8Array(event.kind);\n const data = encodeTLV({\n 0: [hexToBytes(assertHex32(event.id, \"event id\"))],\n 1: (event.relays ?? []).map((url) => utf8Encoder.encode(url)),\n 2:\n event.author !== undefined && event.author !== \"\"\n ? [hexToBytes(assertHex32(event.author, \"author\"))]\n : [],\n 3: kindArray ? [kindArray] : [],\n });\n return encodeBech32(\"nevent\", data);\n}\n\n/** Encode an address pointer as `naddr1…`. */\nexport function naddrEncode(addr: AddressPointer): NAddr {\n assertNip19Kind(addr.kind);\n const kind = integerToUint8Array(addr.kind);\n const data = encodeTLV({\n 0: [utf8Encoder.encode(addr.identifier)],\n 1: (addr.relays ?? []).map((url) => utf8Encoder.encode(url)),\n 2: [hexToBytes(assertHex32(addr.pubkey, \"pubkey\"))],\n 3: [kind],\n });\n return encodeBech32(\"naddr\", data);\n}\n\nfunction readUint32(bytes: Uint8Array): number {\n return new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(0);\n}\n\n/** Decode a NIP-19 bech32 entity; throws {@link Nip19Error} on bad input or unknown prefix. */\nexport function decode(code: string): DecodedResult {\n let prefix: string;\n let data: Uint8Array;\n try {\n const { prefix: hrp, words } = bech32.decode(code, Bech32MaxSize);\n prefix = hrp;\n data = new Uint8Array(bech32.fromWords(words));\n } catch (error) {\n throw new Nip19Error(`invalid bech32: ${errorMessage(error)}`, { cause: error });\n }\n\n switch (prefix) {\n case \"nprofile\": {\n const tlv = parseTLV(data);\n if (!tlv[0]?.[0]) {\n throw new Nip19Error(\"missing TLV 0 for nprofile\");\n }\n if (tlv[0][0].length !== 32) {\n throw new Nip19Error(\"TLV 0 should be 32 bytes\");\n }\n return {\n type: \"nprofile\",\n data: {\n pubkey: bytesToHex(tlv[0][0]),\n relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [],\n },\n };\n }\n case \"nevent\": {\n const tlv = parseTLV(data);\n if (!tlv[0]?.[0]) {\n throw new Nip19Error(\"missing TLV 0 for nevent\");\n }\n if (tlv[0][0].length !== 32) {\n throw new Nip19Error(\"TLV 0 should be 32 bytes\");\n }\n if (tlv[2]?.[0] && tlv[2][0].length !== 32) {\n throw new Nip19Error(\"TLV 2 should be 32 bytes\");\n }\n if (tlv[3]?.[0] && tlv[3][0].length !== 4) {\n throw new Nip19Error(\"TLV 3 should be 4 bytes\");\n }\n const pointer: Mutable<EventPointer> = {\n id: bytesToHex(tlv[0][0]),\n relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [],\n };\n const author = tlv[2]?.[0];\n if (author !== undefined) {\n pointer.author = bytesToHex(author);\n }\n const kind = tlv[3]?.[0];\n if (kind !== undefined) {\n pointer.kind = readUint32(kind);\n assertNip19Kind(pointer.kind);\n }\n return { type: \"nevent\", data: pointer };\n }\n case \"naddr\": {\n const tlv = parseTLV(data);\n if (!tlv[0]?.[0]) {\n throw new Nip19Error(\"missing TLV 0 for naddr\");\n }\n if (!tlv[2]?.[0]) {\n throw new Nip19Error(\"missing TLV 2 for naddr\");\n }\n if (tlv[2][0].length !== 32) {\n throw new Nip19Error(\"TLV 2 should be 32 bytes\");\n }\n if (!tlv[3]?.[0]) {\n throw new Nip19Error(\"missing TLV 3 for naddr\");\n }\n if (tlv[3][0].length !== 4) {\n throw new Nip19Error(\"TLV 3 should be 4 bytes\");\n }\n const naddrKind = readUint32(tlv[3][0]);\n assertNip19Kind(naddrKind);\n return {\n type: \"naddr\",\n data: {\n identifier: utf8Decoder.decode(tlv[0][0]),\n pubkey: bytesToHex(tlv[2][0]),\n kind: naddrKind,\n relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [],\n },\n };\n }\n case \"nsec\":\n if (data.length !== 32) {\n throw new Nip19Error(\"nsec must be 32 bytes\");\n }\n if (!secp256k1.utils.isValidSecretKey(data)) {\n throw new Nip19Error(\"invalid nsec secret key\");\n }\n return { type: \"nsec\", data };\n case \"npub\":\n case \"note\":\n if (data.length !== 32) {\n throw new Nip19Error(`${prefix} must be 32 bytes`);\n }\n return { type: prefix, data: bytesToHex(data) };\n default:\n throw new Nip19Error(`unknown prefix ${prefix}`);\n }\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { v as NostrError } from "../util-DMF9AIO0.mjs";
1
+ import { y as NostrError } from "../util-DDpPkiED.mjs";
2
2
  import { decode } from "./nip19.mjs";
3
3
  //#region src/nips/nip21.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { d as nowSeconds } from "../util-DMF9AIO0.mjs";
1
+ import { f as nowSeconds } from "../util-DDpPkiED.mjs";
2
2
  import { t as Kind } from "../kind-D8fENiiL.mjs";
3
3
  //#region src/nips/nip42.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { a as hexToBytes$1, f as utf8Decoder, m as CryptoError, n as assertHex32, p as utf8Encoder, r as assertSecretKeyBytes } from "../util-DMF9AIO0.mjs";
1
+ import { h as CryptoError, m as utf8Encoder, n as assertHex32, o as hexToBytes$1, p as utf8Decoder, r as assertSecretKeyBytes } from "../util-DDpPkiED.mjs";
2
2
  import { concatBytes, randomBytes } from "@noble/hashes/utils.js";
3
3
  import { sha256 } from "@noble/hashes/sha2.js";
4
4
  import { secp256k1 } from "@noble/curves/secp256k1.js";
@@ -1,4 +1,4 @@
1
- import { c as isRecord, o as isHex32, v as NostrError } from "../util-DMF9AIO0.mjs";
1
+ import { l as isRecord, s as isHex32, y as NostrError } from "../util-DDpPkiED.mjs";
2
2
  //#region src/nips/nip46.ts
3
3
  /**
4
4
  * NIP-46 (Nostr Connect) protocol helpers: bunker URI, nostrconnect URI, RPC JSON.
@@ -1,4 +1,4 @@
1
- import { p as utf8Encoder, r as assertSecretKeyBytes, v as NostrError } from "../util-DMF9AIO0.mjs";
1
+ import { m as utf8Encoder, r as assertSecretKeyBytes, y as NostrError } from "../util-DDpPkiED.mjs";
2
2
  import { Bech32MaxSize, encodeBytes } from "./nip19.mjs";
3
3
  import { concatBytes, randomBytes } from "@noble/hashes/utils.js";
4
4
  import { bech32 } from "@scure/base";
@@ -1,7 +1,7 @@
1
- import { h as EventValidationError, l as normalizeRelayUrls, n as assertHex32, o as isHex32 } from "../util-DMF9AIO0.mjs";
1
+ import { g as EventValidationError, n as assertHex32, s as isHex32, u as normalizeRelayUrls } from "../util-DDpPkiED.mjs";
2
2
  import { t as Kind } from "../kind-D8fENiiL.mjs";
3
- import { b as getDTag, g as Tag, v as firstTagValue, x as isTag } from "../event-C2eLiPpV.mjs";
4
- import { t as EventBuilder } from "../builder-CVRmUeNm.mjs";
3
+ import { b as getDTag, g as Tag, v as firstTagValue, x as isTag } from "../event-B3ua2_oL.mjs";
4
+ import { t as EventBuilder } from "../builder-BQbFDO6S.mjs";
5
5
  //#region src/nips/nip51.ts
6
6
  /**
7
7
  * NIP-51: Lists Public tags plus NIP-44 private `.content` (author encrypts to self). Crypto is
@@ -1,7 +1,7 @@
1
- import { a as hexToBytes, d as nowSeconds, h as EventValidationError, p as utf8Encoder } from "../util-DMF9AIO0.mjs";
1
+ import { f as nowSeconds, g as EventValidationError, m as utf8Encoder, o as hexToBytes } from "../util-DDpPkiED.mjs";
2
2
  import { r as isAddressableKind, t as Kind } from "../kind-D8fENiiL.mjs";
3
- import { S as parseEventAddress, _ as eventAddress, b as getDTag, g as Tag, h as validateSignedEvent, v as firstTagValue } from "../event-C2eLiPpV.mjs";
4
- import { n as verifyEvent } from "../verifier-uC_jd-Nw.mjs";
3
+ import { S as parseEventAddress, _ as eventAddress, b as getDTag, g as Tag, h as validateSignedEvent, v as firstTagValue } from "../event-B3ua2_oL.mjs";
4
+ import { n as verifyEvent } from "../verifier-CjH1vnP2.mjs";
5
5
  import { sha256 } from "@noble/hashes/sha2.js";
6
6
  import { bech32 } from "@scure/base";
7
7
  import { equalBytes } from "@noble/ciphers/utils.js";
@@ -1,8 +1,8 @@
1
- import { c as isRecord, d as nowSeconds, n as assertHex32, v as NostrError } from "../util-DMF9AIO0.mjs";
1
+ import { f as nowSeconds, l as isRecord, n as assertHex32, y as NostrError } from "../util-DDpPkiED.mjs";
2
2
  import { t as Kind } from "../kind-D8fENiiL.mjs";
3
- import { g as Tag, h as validateSignedEvent, m as validateEvent, n as getEventHash } from "../event-C2eLiPpV.mjs";
4
- import { r as finalizeEvent, t as Keys } from "../key-DY_HEIpY.mjs";
5
- import { n as verifyEvent } from "../verifier-uC_jd-Nw.mjs";
3
+ import { g as Tag, h as validateSignedEvent, m as validateEvent, n as getEventHash } from "../event-B3ua2_oL.mjs";
4
+ import { r as finalizeEvent, t as Keys } from "../key-k8LDEPZh.mjs";
5
+ import { n as verifyEvent } from "../verifier-CjH1vnP2.mjs";
6
6
  import { encryptToPubkey } from "./nip44.mjs";
7
7
  import { randomBytes } from "@noble/hashes/utils.js";
8
8
  //#region src/nips/nip59.ts
@@ -1,6 +1,6 @@
1
- import { h as EventValidationError, u as normalizeURL } from "../util-DMF9AIO0.mjs";
1
+ import { d as normalizeURL, g as EventValidationError } from "../util-DDpPkiED.mjs";
2
2
  import { t as Kind } from "../kind-D8fENiiL.mjs";
3
- import { t as EventBuilder } from "../builder-CVRmUeNm.mjs";
3
+ import { t as EventBuilder } from "../builder-BQbFDO6S.mjs";
4
4
  //#region src/nips/nip65.ts
5
5
  /** Parse a kind:10002 NIP-65 event into relay list entries. */
6
6
  function parseRelayList(event) {
@@ -1,4 +1,4 @@
1
- import { a as hexToBytes, i as bytesToHex, n as assertHex32, v as NostrError } from "../util-DMF9AIO0.mjs";
1
+ import { i as bytesToHex, n as assertHex32, o as hexToBytes, y as NostrError } from "../util-DDpPkiED.mjs";
2
2
  import { sha256 } from "@noble/hashes/sha2.js";
3
3
  //#region src/nips/nip77.ts
4
4
  /**
@@ -1,7 +1,7 @@
1
- import { d as nowSeconds, f as utf8Decoder, i as bytesToHex, p as utf8Encoder, v as NostrError } from "../util-DMF9AIO0.mjs";
1
+ import { f as nowSeconds, i as bytesToHex, m as utf8Encoder, p as utf8Decoder, y as NostrError } from "../util-DDpPkiED.mjs";
2
2
  import { t as Kind } from "../kind-D8fENiiL.mjs";
3
- import { h as validateSignedEvent, v as firstTagValue } from "../event-C2eLiPpV.mjs";
4
- import { n as verifyEvent } from "../verifier-uC_jd-Nw.mjs";
3
+ import { h as validateSignedEvent, v as firstTagValue } from "../event-B3ua2_oL.mjs";
4
+ import { n as verifyEvent } from "../verifier-CjH1vnP2.mjs";
5
5
  import { sha256 } from "@noble/hashes/sha2.js";
6
6
  import { base64 } from "@scure/base";
7
7
  //#region src/nips/nip98.ts
@@ -1,9 +1,9 @@
1
- import { S as toError, _ as MessageError, u as normalizeURL } from "./util-DMF9AIO0.mjs";
2
- import { n as canonicalizeFilters } from "./filter-TrF2LEoy.mjs";
3
- import { t as assertSubscriptionId } from "./message-Rd5Z_17h.mjs";
1
+ import { C as toError, d as normalizeURL, v as MessageError } from "./util-DDpPkiED.mjs";
2
+ import { n as canonicalizeFilters } from "./filter-B16P33dz.mjs";
3
+ import { t as assertSubscriptionId } from "./message-pYfVKxPn.mjs";
4
4
  import { i as throwIfAborted, n as onAbort, t as abortReason } from "./abort-DBq2STPj.mjs";
5
5
  import { t as invokeSafely } from "./report-CHld4uWj.mjs";
6
- import { c as RelayConnectionError, d as RelaySuspendedError, n as Relay, r as RelayStatus, u as RelayPublishError } from "./relay-__QtO33h.mjs";
6
+ import { c as RelayConnectionError, d as RelaySuspendedError, n as Relay, r as RelayStatus, u as RelayPublishError } from "./relay-DXtwUEdX.mjs";
7
7
  import { t as Emitter } from "./emitter-DkCY6NkU.mjs";
8
8
  //#region src/relay/url.ts
9
9
  /**
@@ -610,4 +610,4 @@ var Pool = class {
610
610
  //#endregion
611
611
  export { isInsecureRelayUrl as i, fanIn as n, fetchRouted as r, Pool as t };
612
612
 
613
- //# sourceMappingURL=pool-jok2-iBJ.mjs.map
613
+ //# sourceMappingURL=pool-BMUsw2un.mjs.map