@qntx/nostr 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +25 -0
  3. package/dist/builder-BphJa-Y-.d.mts +67 -0
  4. package/dist/builder-q0VsvnYE.mjs +158 -0
  5. package/dist/builder-q0VsvnYE.mjs.map +1 -0
  6. package/dist/client-Bd8B1mYm.mjs +835 -0
  7. package/dist/client-Bd8B1mYm.mjs.map +1 -0
  8. package/dist/client.d.mts +2 -0
  9. package/dist/client.mjs +2 -0
  10. package/dist/core.d.mts +8 -0
  11. package/dist/core.mjs +9 -0
  12. package/dist/error-B49rbDzT.d.mts +7 -0
  13. package/dist/error-CwBxle6N.mjs +13 -0
  14. package/dist/error-CwBxle6N.mjs.map +1 -0
  15. package/dist/error-DZEs5OuZ.mjs +24 -0
  16. package/dist/error-DZEs5OuZ.mjs.map +1 -0
  17. package/dist/error-WEFS-R-4.d.mts +20 -0
  18. package/dist/event-B5D2jxt_.d.mts +108 -0
  19. package/dist/event-CzoQEFMF.mjs +188 -0
  20. package/dist/event-CzoQEFMF.mjs.map +1 -0
  21. package/dist/filter-BxwjEkZp.mjs +113 -0
  22. package/dist/filter-BxwjEkZp.mjs.map +1 -0
  23. package/dist/filter-DUEKP3q1.d.mts +40 -0
  24. package/dist/gossip-3xkRRCm_.mjs +220 -0
  25. package/dist/gossip-3xkRRCm_.mjs.map +1 -0
  26. package/dist/gossip-C5RVB1UB.d.mts +71 -0
  27. package/dist/gossip.d.mts +3 -0
  28. package/dist/gossip.mjs +2 -0
  29. package/dist/http-6vevbBlu.d.mts +22 -0
  30. package/dist/http-D2rhokZo.mjs +24 -0
  31. package/dist/http-D2rhokZo.mjs.map +1 -0
  32. package/dist/index-BYMnhRIC.d.mts +161 -0
  33. package/dist/index-C0C4e-Gn.d.mts +55 -0
  34. package/dist/index-CaxrMD1A.d.mts +1 -0
  35. package/dist/index-DaRyjo7O.d.mts +77 -0
  36. package/dist/index-DgOugrpF.d.mts +275 -0
  37. package/dist/index-EwL6fHLo.d.mts +267 -0
  38. package/dist/index-k2YhCgsh.d.mts +57 -0
  39. package/dist/index.d.mts +22 -0
  40. package/dist/index.mjs +23 -0
  41. package/dist/key-BiGxGLhg.d.mts +37 -0
  42. package/dist/key-Dn-aX4x4.mjs +130 -0
  43. package/dist/key-Dn-aX4x4.mjs.map +1 -0
  44. package/dist/kind-BLl4cLOc.mjs +59 -0
  45. package/dist/kind-BLl4cLOc.mjs.map +1 -0
  46. package/dist/loaders-BNQszDAn.mjs +767 -0
  47. package/dist/loaders-BNQszDAn.mjs.map +1 -0
  48. package/dist/loaders.d.mts +3 -0
  49. package/dist/loaders.mjs +2 -0
  50. package/dist/memory-BCmhZPek.mjs +461 -0
  51. package/dist/memory-BCmhZPek.mjs.map +1 -0
  52. package/dist/message-C_Uj-Y-c.mjs +179 -0
  53. package/dist/message-C_Uj-Y-c.mjs.map +1 -0
  54. package/dist/message-DJC-Jz6T.d.mts +32 -0
  55. package/dist/nip17-BWq-Kfq5.d.mts +38 -0
  56. package/dist/nip19-D7905oIv.d.mts +63 -0
  57. package/dist/nip46-C_DoxiS_.d.mts +51 -0
  58. package/dist/nip59-DljW_sYh.d.mts +76 -0
  59. package/dist/nip65-Di5hZRuV.d.mts +21 -0
  60. package/dist/nip77-ByxlgoQO.d.mts +55 -0
  61. package/dist/nips/blossom.d.mts +93 -0
  62. package/dist/nips/blossom.mjs +325 -0
  63. package/dist/nips/blossom.mjs.map +1 -0
  64. package/dist/nips/nip04.d.mts +8 -0
  65. package/dist/nips/nip04.mjs +41 -0
  66. package/dist/nips/nip04.mjs.map +1 -0
  67. package/dist/nips/nip05.d.mts +89 -0
  68. package/dist/nips/nip05.mjs +147 -0
  69. package/dist/nips/nip05.mjs.map +1 -0
  70. package/dist/nips/nip10.d.mts +43 -0
  71. package/dist/nips/nip10.mjs +194 -0
  72. package/dist/nips/nip10.mjs.map +1 -0
  73. package/dist/nips/nip11.d.mts +43 -0
  74. package/dist/nips/nip11.mjs +99 -0
  75. package/dist/nips/nip11.mjs.map +1 -0
  76. package/dist/nips/nip13.d.mts +23 -0
  77. package/dist/nips/nip13.mjs +88 -0
  78. package/dist/nips/nip13.mjs.map +1 -0
  79. package/dist/nips/nip17.d.mts +2 -0
  80. package/dist/nips/nip17.mjs +138 -0
  81. package/dist/nips/nip17.mjs.map +1 -0
  82. package/dist/nips/nip19.d.mts +2 -0
  83. package/dist/nips/nip19.mjs +174 -0
  84. package/dist/nips/nip19.mjs.map +1 -0
  85. package/dist/nips/nip21.d.mts +17 -0
  86. package/dist/nips/nip21.mjs +29 -0
  87. package/dist/nips/nip21.mjs.map +1 -0
  88. package/dist/nips/nip27.d.mts +42 -0
  89. package/dist/nips/nip27.mjs +175 -0
  90. package/dist/nips/nip27.mjs.map +1 -0
  91. package/dist/nips/nip42.d.mts +12 -0
  92. package/dist/nips/nip42.mjs +22 -0
  93. package/dist/nips/nip42.mjs.map +1 -0
  94. package/dist/nips/nip44.d.mts +12 -0
  95. package/dist/nips/nip44.mjs +125 -0
  96. package/dist/nips/nip44.mjs.map +1 -0
  97. package/dist/nips/nip46.d.mts +2 -0
  98. package/dist/nips/nip46.mjs +132 -0
  99. package/dist/nips/nip46.mjs.map +1 -0
  100. package/dist/nips/nip49.d.mts +12 -0
  101. package/dist/nips/nip49.mjs +80 -0
  102. package/dist/nips/nip49.mjs.map +1 -0
  103. package/dist/nips/nip51.d.mts +88 -0
  104. package/dist/nips/nip51.mjs +246 -0
  105. package/dist/nips/nip51.mjs.map +1 -0
  106. package/dist/nips/nip57.d.mts +43 -0
  107. package/dist/nips/nip57.mjs +230 -0
  108. package/dist/nips/nip57.mjs.map +1 -0
  109. package/dist/nips/nip59.d.mts +2 -0
  110. package/dist/nips/nip59.mjs +171 -0
  111. package/dist/nips/nip59.mjs.map +1 -0
  112. package/dist/nips/nip65.d.mts +2 -0
  113. package/dist/nips/nip65.mjs +76 -0
  114. package/dist/nips/nip65.mjs.map +1 -0
  115. package/dist/nips/nip77.d.mts +2 -0
  116. package/dist/nips/nip77.mjs +421 -0
  117. package/dist/nips/nip77.mjs.map +1 -0
  118. package/dist/nips/nip96.d.mts +31 -0
  119. package/dist/nips/nip96.mjs +95 -0
  120. package/dist/nips/nip96.mjs.map +1 -0
  121. package/dist/nips/nip98.d.mts +28 -0
  122. package/dist/nips/nip98.mjs +91 -0
  123. package/dist/nips/nip98.mjs.map +1 -0
  124. package/dist/nostr_crypto_wasm_bg-hi5aXi5P.mjs +4 -0
  125. package/dist/nostr_crypto_wasm_bg.wasm +0 -0
  126. package/dist/pool-C_j1OmBB.mjs +1881 -0
  127. package/dist/pool-C_j1OmBB.mjs.map +1 -0
  128. package/dist/pool-DhRi7l-b.d.mts +297 -0
  129. package/dist/relay.d.mts +4 -0
  130. package/dist/relay.mjs +2 -0
  131. package/dist/signer-CZ6K6FUc.mjs +473 -0
  132. package/dist/signer-CZ6K6FUc.mjs.map +1 -0
  133. package/dist/signer.d.mts +3 -0
  134. package/dist/signer.mjs +2 -0
  135. package/dist/storage-DOy0iLRE.mjs +870 -0
  136. package/dist/storage-DOy0iLRE.mjs.map +1 -0
  137. package/dist/storage.d.mts +4 -0
  138. package/dist/storage.mjs +4 -0
  139. package/dist/types-BzyADqnw.d.mts +19 -0
  140. package/dist/types-Dn24TPFs.d.mts +43 -0
  141. package/dist/util-6tfLQ9JF.mjs +73 -0
  142. package/dist/util-6tfLQ9JF.mjs.map +1 -0
  143. package/dist/wasm.d.mts +19 -0
  144. package/dist/wasm.mjs +237 -0
  145. package/dist/wasm.mjs.map +1 -0
  146. package/package.json +204 -0
@@ -0,0 +1,267 @@
1
+ import { t as Event } from "./event-B5D2jxt_.mjs";
2
+ import { n as ProfileMetadata } from "./builder-BphJa-Y-.mjs";
3
+ import { t as RelayListItem } from "./nip65-Di5hZRuV.mjs";
4
+ import { t as Gossip } from "./gossip-C5RVB1UB.mjs";
5
+ import { a as NostrError } from "./error-WEFS-R-4.mjs";
6
+ import { t as Pool } from "./pool-DhRi7l-b.mjs";
7
+ import { i as EventPointer, t as AddressPointer } from "./nip19-D7905oIv.mjs";
8
+ import { r as OutboxBound, t as EventStore } from "./types-Dn24TPFs.mjs";
9
+ //#region src/loaders/cache.d.ts
10
+ type ReplaceableKey = {
11
+ kind: number;
12
+ pubkey: string;
13
+ dTag?: string;
14
+ };
15
+ /** In-memory replaceable-event cache used by loaders (no DOM / localStorage). */
16
+ declare class ReplaceableCache {
17
+ #private;
18
+ get(spec: ReplaceableKey): {
19
+ event: Event | null;
20
+ fetchedAt: number;
21
+ } | undefined;
22
+ set(spec: ReplaceableKey, event: Event | null, fetchedAt?: number): void;
23
+ /** Keep newer event by created_at. */
24
+ putIfNewer(event: Event, dTag?: string): void;
25
+ clear(spec?: ReplaceableKey): void;
26
+ get size(): number;
27
+ }
28
+ //#endregion
29
+ //#region src/loaders/context.d.ts
30
+ type LoaderContextOptions = {
31
+ pool: Pool;
32
+ /** Fallback / discovery relays when no per-user routing is known. */
33
+ relays: readonly string[];
34
+ cache?: ReplaceableCache;
35
+ /** Max age (seconds) before a cached replaceable is considered stale. Default 2 days. */
36
+ staleAfterSec?: number;
37
+ fetchTimeoutMs?: number;
38
+ };
39
+ /**
40
+ * Explicit dependency bag for loaders — never a module-level singleton.
41
+ */
42
+ declare class LoaderContext {
43
+ #private;
44
+ readonly pool: Pool;
45
+ readonly cache: ReplaceableCache;
46
+ readonly staleAfterSec: number;
47
+ readonly fetchTimeoutMs: number;
48
+ constructor(opts: LoaderContextOptions);
49
+ /** Snapshot of discovery/fallback relays. */
50
+ get relays(): readonly string[];
51
+ addRelay(url: string): void;
52
+ removeRelay(url: string): void;
53
+ setRelays(urls: readonly string[]): void;
54
+ isFresh(fetchedAt: number, now?: number): boolean;
55
+ }
56
+ //#endregion
57
+ //#region src/loaders/dataloader.d.ts
58
+ declare class LoaderError extends NostrError {}
59
+ /** Minimal request coalescer. Batches keys within a microtask; no global state. */
60
+ type BatchLoadFn<K, V> = (keys: readonly K[]) => Promise<readonly (V | Error)[]>;
61
+ type DataLoaderOptions<K, C = K> = {
62
+ cacheKeyFn?: (key: K) => C;
63
+ maxBatchSize?: number;
64
+ /** When false, only coalesces in-flight requests (no durable memoization). Default true. */
65
+ cache?: boolean;
66
+ };
67
+ declare class DataLoader<K, V, C = K> {
68
+ #private;
69
+ constructor(batchLoadFn: BatchLoadFn<K, V>, options?: DataLoaderOptions<K, C>);
70
+ load(key: K): Promise<V>;
71
+ clear(key: K): void;
72
+ clearAll(): void;
73
+ }
74
+ //#endregion
75
+ //#region src/loaders/replaceable.d.ts
76
+ type ReplaceableLoadResult = {
77
+ event: Event | null;
78
+ fresh: boolean;
79
+ };
80
+ type LoadStyle = "default" | "force" | "cache-only";
81
+ /**
82
+ * Batch-fetch replaceable events (kind + authors) via the pool, with cache.
83
+ * Durable cache is ReplaceableCache; DataLoader only coalesces in-flight requests.
84
+ */
85
+ declare function createReplaceableLoader(ctx: LoaderContext, kind: number): {
86
+ load(pubkey: string, opts?: {
87
+ hints?: string[];
88
+ style?: LoadStyle;
89
+ }): Promise<ReplaceableLoadResult>;
90
+ clear(pubkey?: string): void;
91
+ };
92
+ //#endregion
93
+ //#region src/loaders/lists.d.ts
94
+ type ListResult<T> = {
95
+ event: Event | null;
96
+ items: T[];
97
+ fresh: boolean;
98
+ };
99
+ type MutedEntity = {
100
+ label: "pubkey";
101
+ value: string;
102
+ } | {
103
+ label: "thread";
104
+ value: string;
105
+ } | {
106
+ label: "hashtag";
107
+ value: string;
108
+ } | {
109
+ label: "word";
110
+ value: string;
111
+ };
112
+ declare function createListLoaders(ctx: LoaderContext): {
113
+ follows(pubkey: string, opts?: {
114
+ hints?: string[];
115
+ style?: LoadStyle;
116
+ }): Promise<ListResult<string>>;
117
+ muteList(pubkey: string, opts?: {
118
+ hints?: string[];
119
+ style?: LoadStyle;
120
+ }): Promise<ListResult<MutedEntity>>;
121
+ relayList(pubkey: string, opts?: {
122
+ hints?: string[];
123
+ style?: LoadStyle;
124
+ }): Promise<ListResult<RelayListItem>>;
125
+ dmRelayList(pubkey: string, opts?: {
126
+ hints?: string[];
127
+ style?: LoadStyle;
128
+ }): Promise<ListResult<string>>;
129
+ };
130
+ type ListLoaders = ReturnType<typeof createListLoaders>;
131
+ //#endregion
132
+ //#region src/loaders/profile.d.ts
133
+ type NostrUser = {
134
+ pubkey: string;
135
+ npub: string;
136
+ shortName: string;
137
+ image?: string;
138
+ metadata: ProfileMetadata;
139
+ lastUpdated: number;
140
+ event: Event | null;
141
+ fresh: boolean;
142
+ };
143
+ declare function bareNostrUser(pubkey: string): NostrUser;
144
+ declare function createProfileLoader(ctx: LoaderContext): {
145
+ load(pubkey: string, opts?: {
146
+ hints?: string[];
147
+ style?: LoadStyle;
148
+ }): Promise<NostrUser>;
149
+ };
150
+ type ProfileLoader = ReturnType<typeof createProfileLoader>;
151
+ //#endregion
152
+ //#region src/loaders/event.d.ts
153
+ type EventRef = string | EventPointer | AddressPointer;
154
+ declare function createEventLoader(ctx: LoaderContext): {
155
+ load(ref: EventRef): Promise<Event | undefined>;
156
+ clearAll(): void;
157
+ };
158
+ type EventLoader = ReturnType<typeof createEventLoader>;
159
+ //#endregion
160
+ //#region src/loaders/outbox.d.ts
161
+ declare class OutboxError extends NostrError {}
162
+ type OutboxFeedOptions = {
163
+ pool: Pool;
164
+ gossip: Gossip;
165
+ storage: EventStore;
166
+ /** Fallback relays when an author has no known outbox routes. */
167
+ discoveryRelays: readonly string[];
168
+ authors: readonly string[];
169
+ /** Event kinds to fetch. Default `[Kind.TextNote]`. */
170
+ kinds?: readonly number[];
171
+ /** Max write-relays to use per author. Default 3. */
172
+ maxRelaysPerAuthor?: number;
173
+ fetchTimeoutMs?: number;
174
+ /** Called for live events after observe, and for sync events returned by applySync. */
175
+ onEvent?: (event: Event) => void;
176
+ /** Live ingest (e.g. `client.observe`). StartLive never putManys. */
177
+ observe?: (event: Event) => void;
178
+ /**
179
+ * Sync path only. Awaited. Return events that should advance bounds.
180
+ * Throw → sync throws, bounds unchanged.
181
+ */
182
+ applySync?: (events: readonly Event[]) => Promise<readonly Event[]>;
183
+ /**
184
+ * Load kind:10002 for authors before sync when routes are missing.
185
+ * Requires a relay-list loader.
186
+ */
187
+ hydrate?: (pubkeys: readonly string[]) => Promise<void>;
188
+ };
189
+ /**
190
+ * Group authors by outbox relay (discovery fallback).
191
+ * `prefer` reorders existing candidates only; it never appends a URL
192
+ * that is not already in the author's outbox or discovery list.
193
+ * Returns Map<relayUrl, authors[]>.
194
+ */
195
+ declare function groupAuthorsByOutboxRelay(authors: readonly string[], gossip: Gossip, discoveryRelays: readonly string[], maxRelaysPerAuthor?: number, prefer?: readonly string[]): Map<string, string[]>;
196
+ /**
197
+ * Outbox-model feed: history sync + live subscription for a set of authors,
198
+ * routed via NIP-65 write relays (with discovery fallback).
199
+ */
200
+ declare class OutboxFeed {
201
+ #private;
202
+ constructor(opts: OutboxFeedOptions);
203
+ get authors(): readonly string[];
204
+ get kinds(): readonly number[];
205
+ /** Replace the author set (does not auto-restart live). */
206
+ setAuthors(authors: readonly string[]): void;
207
+ getBound(pubkey: string, kind: number): OutboxBound | undefined;
208
+ /**
209
+ * Load NIP-65 relay lists for authors that have no outbox routes yet.
210
+ */
211
+ hydrate(): Promise<void>;
212
+ /**
213
+ * One-shot history pull. Persistence is `applySync`; bounds move only for events it returns.
214
+ */
215
+ sync(opts?: {
216
+ limit?: number;
217
+ since?: number;
218
+ until?: number;
219
+ signal?: AbortSignal;
220
+ /** Skip hydrate() even if provided. */
221
+ skipHydrate?: boolean;
222
+ }): Promise<Event[]>;
223
+ /**
224
+ * Start a live subscription across outbox relays for the current authors.
225
+ * Closes any previous live subscription.
226
+ */
227
+ startLive(opts?: {
228
+ signal?: AbortSignal;
229
+ since?: number;
230
+ }): {
231
+ close: (reason?: string) => void;
232
+ };
233
+ /** Convenience: hydrate + sync + startLive. */
234
+ start(opts?: {
235
+ limit?: number;
236
+ signal?: AbortSignal;
237
+ }): Promise<{
238
+ close: (reason?: string) => void;
239
+ events: Event[];
240
+ }>;
241
+ close(): void;
242
+ }
243
+ /** Factory matching other loaders helpers. */
244
+ declare function createOutboxFeed(opts: OutboxFeedOptions): OutboxFeed;
245
+ //#endregion
246
+ //#region src/loaders/index.d.ts
247
+ type Loaders = {
248
+ context: LoaderContext;
249
+ follows: ListLoaders["follows"];
250
+ muteList: ListLoaders["muteList"];
251
+ relayList: ListLoaders["relayList"];
252
+ dmRelayList: ListLoaders["dmRelayList"];
253
+ profile: ProfileLoader["load"];
254
+ event: EventLoader["load"];
255
+ };
256
+ type CreateLoadersOptions = {
257
+ pool: Pool;
258
+ relays: readonly string[];
259
+ cache?: ReplaceableCache;
260
+ staleAfterSec?: number;
261
+ fetchTimeoutMs?: number;
262
+ };
263
+ /** Build an instance-scoped loader suite (no module globals). */
264
+ declare function createLoaders(opts: CreateLoadersOptions): Loaders;
265
+ //#endregion
266
+ export { DataLoader as C, ReplaceableCache as D, LoaderContextOptions as E, createReplaceableLoader as S, LoaderContext as T, ListResult as _, OutboxFeed as a, LoadStyle as b, groupAuthorsByOutboxRelay as c, createEventLoader as d, NostrUser as f, ListLoaders as g, createProfileLoader as h, OutboxError as i, EventLoader as l, bareNostrUser as m, Loaders as n, OutboxFeedOptions as o, ProfileLoader as p, createLoaders as r, createOutboxFeed as s, CreateLoadersOptions as t, EventRef as u, MutedEntity as v, LoaderError as w, ReplaceableLoadResult as x, createListLoaders as y };
267
+ //# sourceMappingURL=index-EwL6fHLo.d.mts.map
@@ -0,0 +1,57 @@
1
+ import { t as Event } from "./event-B5D2jxt_.mjs";
2
+ import { t as Filter } from "./filter-DUEKP3q1.mjs";
3
+ import { i as PutResult, n as NegentropyItem, r as OutboxBound, t as EventStore } from "./types-Dn24TPFs.mjs";
4
+ //#region src/storage/memory.d.ts
5
+ /**
6
+ * In-memory event store with NIP-01 replaceable / addressable / ephemeral
7
+ * handling and NIP-09 deletion (kind 5) application.
8
+ */
9
+ declare class MemoryEventStore implements EventStore {
10
+ #private;
11
+ put(raw: Event): Promise<PutResult>;
12
+ /** Sequential `put` in input order. No transaction: a throw leaves earlier events applied. */
13
+ putMany(events: readonly Event[]): Promise<PutResult[]>;
14
+ get(id: string): Promise<Event | undefined>;
15
+ query(filters: Filter[]): Promise<Event[]>;
16
+ count(filters: Filter[]): Promise<number>;
17
+ negentropyItems(filter: Filter): Promise<NegentropyItem[]>;
18
+ remove(ids: string[]): Promise<number>;
19
+ getOutboxBound(pubkey: string, kind: number): Promise<OutboxBound | undefined>;
20
+ setOutboxBound(pubkey: string, kind: number, bound: OutboxBound): Promise<void>;
21
+ clear(): Promise<void>;
22
+ get size(): number;
23
+ }
24
+ //#endregion
25
+ //#region src/storage/indexeddb.d.ts
26
+ type IndexedDbEventStoreOptions = {
27
+ /** IndexedDB database name. */
28
+ dbName?: string;
29
+ };
30
+ /**
31
+ * Browser IndexedDB event store with the same replaceable / deletion semantics
32
+ * as {@link MemoryEventStore}. Requires a DOM IndexedDB implementation.
33
+ *
34
+ * `open` loads every tombstone and address row into memory. Fine at 10^4 events;
35
+ * tens of MB at 10^5 addressables.
36
+ */
37
+ declare class IndexedDbEventStore implements EventStore {
38
+ #private;
39
+ constructor(opts?: IndexedDbEventStoreOptions);
40
+ static isAvailable(): boolean;
41
+ open(): Promise<void>;
42
+ put(event: Event): Promise<PutResult>;
43
+ /** One readwrite transaction; abort rejects the whole batch with no partial persist. */
44
+ putMany(events: readonly Event[]): Promise<PutResult[]>;
45
+ get(id: string): Promise<Event | undefined>;
46
+ query(filters: Filter[]): Promise<Event[]>;
47
+ count(filters: Filter[]): Promise<number>;
48
+ negentropyItems(filter: Filter): Promise<NegentropyItem[]>;
49
+ getOutboxBound(pubkey: string, kind: number): Promise<OutboxBound | undefined>;
50
+ setOutboxBound(pubkey: string, kind: number, bound: OutboxBound): Promise<void>;
51
+ remove(ids: string[]): Promise<number>;
52
+ clear(): Promise<void>;
53
+ close(): void;
54
+ }
55
+ //#endregion
56
+ export { IndexedDbEventStoreOptions as n, MemoryEventStore as r, IndexedDbEventStore as t };
57
+ //# sourceMappingURL=index-k2YhCgsh.d.mts.map
@@ -0,0 +1,22 @@
1
+ import { C as isTag, E as tagValue, S as getDTag, T as tagName, _ as EventAddress, b as eventAddress, c as itemCompare, d as serializeEvent, f as signedMatchesUnsigned, g as validateSignedEvent, h as validateEvent, i as getEventHash, m as sortedEvents, n as EventTemplate, o as isMarkedVerified, p as sortEvents, r as UnsignedEvent, s as isReplaceableWinner, t as Event, v as Tag, w as parseEventAddress, x as formatEventAddress, y as TagInput } from "./event-B5D2jxt_.mjs";
2
+ import { a as getPublicKey, c as verifyEvent, i as finalizeEvent, n as PublicKey, o as publicKeyFromHex, r as SecretKey, s as signEvent, t as Keys } from "./key-BiGxGLhg.mjs";
3
+ import { n as ProfileMetadata, t as EventBuilder } from "./builder-BphJa-Y-.mjs";
4
+ import { a as filterFingerprint, c as matchFilters, i as cloneFilter, l as mergeFilters, n as canonicalizeFilter, o as getFilterLimit, r as canonicalizeFilters, s as matchFilter, t as Filter } from "./filter-DUEKP3q1.mjs";
5
+ import { a as readRelays, c as writeRelays, i as parseRelayList, n as RelayMarker, o as relayListEventBuilder, r as markerOf, s as relayListToTags, t as RelayListItem } from "./nip65-Di5hZRuV.mjs";
6
+ import { i as RoutedFilter, r as PubkeyRoutes, t as Gossip } from "./gossip-C5RVB1UB.mjs";
7
+ import { a as assertSubscriptionId, c as encodeRelayMessage, d as parseRelayMessage, i as SubscriptionId, l as mergeCountHll, n as CountResult, o as createSubscriptionId, r as RelayMessage, s as encodeClientMessage, t as ClientMessage, u as parseClientMessage } from "./message-DJC-Jz6T.mjs";
8
+ import { a as NostrError, i as MessageError, n as EventValidationError, o as UrlError, r as HexError, s as WasmVerifyPoisonedError, t as CryptoError } from "./error-WEFS-R-4.mjs";
9
+ import { a as PublishResult, c as RelayStatus, i as PoolPublishResult, l as RelayStatusName, m as SubscribeOptions, n as PoolCountResult, o as Relay, p as useWebSocketImplementation, r as PoolOptions, s as RelayOptions, t as Pool } from "./pool-DhRi7l-b.mjs";
10
+ import { C as DataLoader, D as ReplaceableCache, T as LoaderContext, _ as ListResult, a as OutboxFeed, b as LoadStyle, c as groupAuthorsByOutboxRelay, f as NostrUser, i as OutboxError, m as bareNostrUser, n as Loaders, o as OutboxFeedOptions, r as createLoaders, s as createOutboxFeed, v as MutedEntity, w as LoaderError } from "./index-EwL6fHLo.mjs";
11
+ import { _ as neventEncode, a as NAddr, b as npubEncode, c as NPub, d as Note, f as ProfilePointer, g as naddrEncode, i as EventPointer, l as NSec, m as decodeNostrURI, n as Bech32MaxSize, o as NEvent, p as decode, r as DecodedResult, s as NProfile, t as AddressPointer, u as Nip19Error, v as noteEncode, x as nsecEncode, y as nprofileEncode } from "./nip19-D7905oIv.mjs";
12
+ import { i as PutResult, n as NegentropyItem, r as OutboxBound, t as EventStore } from "./types-Dn24TPFs.mjs";
13
+ import { t as NostrSigner } from "./types-BzyADqnw.mjs";
14
+ import { t as StorageError } from "./error-B49rbDzT.mjs";
15
+ import { a as FetchPrivateMessagesOptions, c as ReceivedPrivateMessage, d as SubscribePrivateMessagesOptions, f as SyncDirection, g as ClientBuilder, h as SyncSummary, l as SendPrivateMessageOptions, m as SyncOptions, n as ClientError, o as PrivateMessageSendResult, p as SyncDirectionName, r as ClientOptions, t as Client } from "./index-DgOugrpF.mjs";
16
+ import { C as SUBSCRIPTION_ID_MAX_CHARS, S as SIGNATURE_BYTES, _ as utf8Decoder, a as classifyKind, b as PUBLIC_KEY_BYTES, c as isRegularKind, f as bytesToHex, g as normalizeURL, h as isHex64, i as KnownKind, l as isReplaceableKind, m as isHex32, n as KindClassification, o as isAddressableKind, p as hexToBytes, r as KindName, s as isEphemeralKind, t as Kind, v as utf8Encoder, x as SECRET_KEY_BYTES, y as EVENT_ID_BYTES } from "./index-DaRyjo7O.mjs";
17
+ import { a as Nip07Signer, c as isNip07Available, i as Nip46Transport, l as KeysSigner, n as Nip46SignerOptions, o as WindowNostr, r as Nip46SubscribeOptions, s as getWindowNostr, t as Nip46Signer } from "./index-BYMnhRIC.mjs";
18
+ import { ReplyTagsOptions, ThreadReferences, buildReplyTags, parseThreadTags, replyTo } from "./nips/nip10.mjs";
19
+ import { isAuthRequired, makeAuthEvent } from "./nips/nip42.mjs";
20
+ import { a as isInsecureRelayUrl, c as RelayError, l as RelayPublishError, o as RelayClosedError, s as RelayConnectionError } from "./index-C0C4e-Gn.mjs";
21
+ import { n as IndexedDbEventStoreOptions, r as MemoryEventStore, t as IndexedDbEventStore } from "./index-k2YhCgsh.mjs";
22
+ export { type AddressPointer, Bech32MaxSize, Client, ClientBuilder, ClientError, type ClientMessage, type ClientOptions, type CountResult, CryptoError, DataLoader, type DecodedResult, EVENT_ID_BYTES, type Event, type EventAddress, EventBuilder, type EventPointer, type EventStore, type EventTemplate, EventValidationError, type FetchPrivateMessagesOptions, type Filter, Gossip, HexError, IndexedDbEventStore, type IndexedDbEventStoreOptions, Keys, KeysSigner, Kind, type KindClassification, type KindName, type KnownKind, type ListResult, type LoadStyle, LoaderContext, LoaderError, type Loaders, MemoryEventStore, MessageError, type MutedEntity, type NAddr, type NEvent, type NProfile, type NPub, type NSec, type NegentropyItem, Nip07Signer, Nip19Error, Nip46Signer, type Nip46SignerOptions, type Nip46SubscribeOptions, type Nip46Transport, NostrError, type NostrSigner, type NostrUser, type Note, type OutboxBound, OutboxError, OutboxFeed, type OutboxFeedOptions, PUBLIC_KEY_BYTES, Pool, type PoolCountResult, type PoolOptions, type PoolPublishResult, type PrivateMessageSendResult, type ProfileMetadata, type ProfilePointer, type PubkeyRoutes, type PublicKey, type PublishResult, type PutResult, type ReceivedPrivateMessage, Relay, RelayClosedError, RelayConnectionError, RelayError, type RelayListItem, type RelayMarker, type RelayMessage, type RelayOptions, RelayPublishError, RelayStatus, type RelayStatusName, ReplaceableCache, type ReplyTagsOptions, type RoutedFilter, SECRET_KEY_BYTES, SIGNATURE_BYTES, SUBSCRIPTION_ID_MAX_CHARS, SecretKey, type SendPrivateMessageOptions, StorageError, type SubscribeOptions, type SubscribePrivateMessagesOptions, type SubscriptionId, SyncDirection, type SyncDirectionName, type SyncOptions, type SyncSummary, Tag, type TagInput, type ThreadReferences, type UnsignedEvent, UrlError, WasmVerifyPoisonedError, type WindowNostr, assertSubscriptionId, bareNostrUser, buildReplyTags, bytesToHex, canonicalizeFilter, canonicalizeFilters, classifyKind, cloneFilter, createLoaders, createOutboxFeed, createSubscriptionId, decodeNostrURI, encodeClientMessage, encodeRelayMessage, eventAddress, filterFingerprint, finalizeEvent, formatEventAddress, getDTag, getEventHash, getFilterLimit, getPublicKey, getWindowNostr, groupAuthorsByOutboxRelay, hexToBytes, isAddressableKind, isAuthRequired, isEphemeralKind, isHex32, isHex64, isInsecureRelayUrl, isMarkedVerified, 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, utf8Decoder, utf8Encoder, validateEvent, validateSignedEvent, verifyEvent, writeRelays };
package/dist/index.mjs ADDED
@@ -0,0 +1,23 @@
1
+ import { a as isHex32, c as utf8Decoder, d as PUBLIC_KEY_BYTES, f as SECRET_KEY_BYTES, i as hexToBytes, l as utf8Encoder, m as SUBSCRIPTION_ID_MAX_CHARS, o as isHex64, p as SIGNATURE_BYTES, r as bytesToHex, s as normalizeURL, u as EVENT_ID_BYTES } from "./util-6tfLQ9JF.mjs";
2
+ import { a as NostrError, i as MessageError, n as EventValidationError, o as UrlError, r as HexError, s as WasmVerifyPoisonedError, t as CryptoError } from "./error-DZEs5OuZ.mjs";
3
+ import { a as isRegularKind, i as isEphemeralKind, n as classifyKind, o as isReplaceableKind, r as isAddressableKind, t as Kind } from "./kind-BLl4cLOc.mjs";
4
+ import { _ as getDTag, a as itemCompare, b as tagName, c as serializeEvent, d as sortedEvents, f as validateEvent, g as formatEventAddress, h as eventAddress, i as isReplaceableWinner, l as signedMatchesUnsigned, m as Tag, p as validateSignedEvent, r as isMarkedVerified, t as getEventHash, u as sortEvents, v as isTag, x as tagValue, y as parseEventAddress } from "./event-CzoQEFMF.mjs";
5
+ import { a as publicKeyFromHex, i as getPublicKey, n as SecretKey, o as signEvent, r as finalizeEvent, s as verifyEvent, t as Keys } from "./key-Dn-aX4x4.mjs";
6
+ import { t as EventBuilder } from "./builder-q0VsvnYE.mjs";
7
+ import { a as getFilterLimit, c as mergeFilters, i as filterFingerprint, n as canonicalizeFilters, o as matchFilter, r as cloneFilter, s as matchFilters, t as canonicalizeFilter } from "./filter-BxwjEkZp.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-C_Uj-Y-c.mjs";
9
+ import "./core.mjs";
10
+ import { a as KeysSigner, i as isNip07Available, n as Nip07Signer, r as getWindowNostr, t as Nip46Signer } from "./signer-CZ6K6FUc.mjs";
11
+ import { Bech32MaxSize, Nip19Error, decode, decodeNostrURI, naddrEncode, neventEncode, noteEncode, nprofileEncode, npubEncode, nsecEncode } from "./nips/nip19.mjs";
12
+ import { buildReplyTags, parseThreadTags, replyTo } from "./nips/nip10.mjs";
13
+ 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, i as Relay, m as RelayPublishError, p as RelayError, t as Pool, u as useWebSocketImplementation } from "./pool-C_j1OmBB.mjs";
16
+ import "./relay.mjs";
17
+ import { t as Gossip } from "./gossip-3xkRRCm_.mjs";
18
+ import { a as groupAuthorsByOutboxRelay, d as LoaderError, i as createOutboxFeed, m as ReplaceableCache, n as OutboxError, o as bareNostrUser, p as LoaderContext, r as OutboxFeed, t as createLoaders, u as DataLoader } from "./loaders-BNQszDAn.mjs";
19
+ import { t as StorageError } from "./error-CwBxle6N.mjs";
20
+ import { t as MemoryEventStore } from "./memory-BCmhZPek.mjs";
21
+ import { i as ClientBuilder, n as ClientError, r as SyncDirection, t as Client } from "./client-Bd8B1mYm.mjs";
22
+ import { t as IndexedDbEventStore } from "./storage-DOy0iLRE.mjs";
23
+ export { Bech32MaxSize, Client, ClientBuilder, ClientError, CryptoError, DataLoader, EVENT_ID_BYTES, EventBuilder, EventValidationError, Gossip, HexError, IndexedDbEventStore, Keys, KeysSigner, Kind, LoaderContext, LoaderError, MemoryEventStore, MessageError, Nip07Signer, Nip19Error, Nip46Signer, NostrError, OutboxError, OutboxFeed, PUBLIC_KEY_BYTES, Pool, Relay, RelayClosedError, RelayConnectionError, RelayError, RelayPublishError, RelayStatus, ReplaceableCache, SECRET_KEY_BYTES, SIGNATURE_BYTES, SUBSCRIPTION_ID_MAX_CHARS, SecretKey, StorageError, SyncDirection, Tag, UrlError, WasmVerifyPoisonedError, assertSubscriptionId, bareNostrUser, buildReplyTags, bytesToHex, canonicalizeFilter, canonicalizeFilters, classifyKind, cloneFilter, createLoaders, createOutboxFeed, createSubscriptionId, decodeNostrURI, encodeClientMessage, encodeRelayMessage, eventAddress, filterFingerprint, finalizeEvent, formatEventAddress, getDTag, getEventHash, getFilterLimit, getPublicKey, getWindowNostr, groupAuthorsByOutboxRelay, hexToBytes, isAddressableKind, isAuthRequired, isEphemeralKind, isHex32, isHex64, isInsecureRelayUrl, isMarkedVerified, 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, utf8Decoder, utf8Encoder, validateEvent, validateSignedEvent, verifyEvent, writeRelays };
@@ -0,0 +1,37 @@
1
+ import { n as EventTemplate, r as UnsignedEvent, t as Event } from "./event-B5D2jxt_.mjs";
2
+ //#region src/core/key.d.ts
3
+ /** 32-byte secret key held as bytes; prefer zeroize when done. */
4
+ declare class SecretKey {
5
+ #private;
6
+ private constructor();
7
+ static generate(): SecretKey;
8
+ static fromBytes(bytes: Uint8Array): SecretKey;
9
+ static fromHex(hex: string): SecretKey;
10
+ get bytes(): Uint8Array;
11
+ toHex(): string;
12
+ /** Best-effort wipe of the internal buffer. */
13
+ zeroize(): void;
14
+ }
15
+ type PublicKey = string;
16
+ declare function publicKeyFromHex(hex: string): PublicKey;
17
+ declare function getPublicKey(secretKey: SecretKey | Uint8Array | string): PublicKey;
18
+ /** Keypair convenience wrapper. */
19
+ declare class Keys {
20
+ readonly secretKey: SecretKey;
21
+ readonly publicKey: PublicKey;
22
+ private constructor();
23
+ static generate(): Keys;
24
+ static fromSecretKey(secretKey: SecretKey | Uint8Array | string): Keys;
25
+ }
26
+ /** Fill pubkey/id/sig on a template and return a signed event. */
27
+ declare function finalizeEvent(template: EventTemplate, secretKey: SecretKey | Uint8Array | string): Event;
28
+ /**
29
+ * Sign an already-assembled unsigned event.
30
+ * Rejects when `unsigned.pubkey` does not match the secret key.
31
+ */
32
+ declare function signEvent(unsigned: UnsignedEvent, secretKey: SecretKey | Uint8Array | string): Event;
33
+ /** Verify event id and BIP-340 signature. Uses WeakSet cache (does not mutate the event). */
34
+ declare function verifyEvent(event: Event): boolean;
35
+ //#endregion
36
+ export { getPublicKey as a, verifyEvent as c, finalizeEvent as i, PublicKey as n, publicKeyFromHex as o, SecretKey as r, signEvent as s, Keys as t };
37
+ //# sourceMappingURL=key-BiGxGLhg.d.mts.map
@@ -0,0 +1,130 @@
1
+ import { i as hexToBytes, n as assertSecretKeyBytes, r as bytesToHex, t as assertHex32 } from "./util-6tfLQ9JF.mjs";
2
+ import { t as CryptoError } from "./error-DZEs5OuZ.mjs";
3
+ import { f as validateEvent, n as isMarkedFailed, o as markUnverified, p as validateSignedEvent, r as isMarkedVerified, s as markVerified, t as getEventHash } from "./event-CzoQEFMF.mjs";
4
+ import { schnorr } from "@noble/curves/secp256k1.js";
5
+ //#region src/core/key.ts
6
+ /** 32-byte secret key held as bytes; prefer zeroize when done. */
7
+ var SecretKey = class SecretKey {
8
+ #bytes;
9
+ constructor(bytes) {
10
+ assertSecretKeyBytes(bytes);
11
+ this.#bytes = new Uint8Array(bytes);
12
+ }
13
+ static generate() {
14
+ return new SecretKey(schnorr.utils.randomSecretKey());
15
+ }
16
+ static fromBytes(bytes) {
17
+ return new SecretKey(bytes);
18
+ }
19
+ static fromHex(hex) {
20
+ return new SecretKey(hexToBytes(assertHex32(hex, "secret key")));
21
+ }
22
+ get bytes() {
23
+ if (!this.#bytes) throw new CryptoError("secret key has been zeroized");
24
+ return new Uint8Array(this.#bytes);
25
+ }
26
+ toHex() {
27
+ return bytesToHex(this.bytes);
28
+ }
29
+ /** Best-effort wipe of the internal buffer. */
30
+ zeroize() {
31
+ if (this.#bytes) {
32
+ this.#bytes.fill(0);
33
+ this.#bytes = null;
34
+ }
35
+ }
36
+ };
37
+ function publicKeyFromHex(hex) {
38
+ return assertHex32(hex, "public key");
39
+ }
40
+ function getPublicKey(secretKey) {
41
+ const bytes = secretKey instanceof SecretKey ? secretKey.bytes : typeof secretKey === "string" ? hexToBytes(assertHex32(secretKey, "secret key")) : (assertSecretKeyBytes(secretKey), secretKey);
42
+ return bytesToHex(schnorr.getPublicKey(bytes));
43
+ }
44
+ /** Keypair convenience wrapper. */
45
+ var Keys = class Keys {
46
+ secretKey;
47
+ publicKey;
48
+ constructor(secretKey) {
49
+ this.secretKey = secretKey;
50
+ this.publicKey = getPublicKey(secretKey);
51
+ }
52
+ static generate() {
53
+ return new Keys(SecretKey.generate());
54
+ }
55
+ static fromSecretKey(secretKey) {
56
+ const sk = secretKey instanceof SecretKey ? secretKey : typeof secretKey === "string" ? SecretKey.fromHex(secretKey) : SecretKey.fromBytes(secretKey);
57
+ return new Keys(sk);
58
+ }
59
+ };
60
+ function resolveSecretKeyBytes(secretKey) {
61
+ if (secretKey instanceof SecretKey) return secretKey.bytes;
62
+ if (typeof secretKey === "string") return hexToBytes(assertHex32(secretKey, "secret key"));
63
+ assertSecretKeyBytes(secretKey);
64
+ return secretKey;
65
+ }
66
+ /** Fill pubkey/id/sig on a template and return a signed event. */
67
+ function finalizeEvent(template, secretKey) {
68
+ const sk = resolveSecretKeyBytes(secretKey);
69
+ const pubkey = bytesToHex(schnorr.getPublicKey(sk));
70
+ return signEvent({
71
+ kind: template.kind,
72
+ tags: template.tags,
73
+ content: template.content,
74
+ created_at: template.created_at,
75
+ pubkey
76
+ }, sk);
77
+ }
78
+ /**
79
+ * Sign an already-assembled unsigned event.
80
+ * Rejects when `unsigned.pubkey` does not match the secret key.
81
+ */
82
+ function signEvent(unsigned, secretKey) {
83
+ const sk = resolveSecretKeyBytes(secretKey);
84
+ if (!validateEvent(unsigned)) throw new CryptoError("cannot sign invalid unsigned event");
85
+ const expected = bytesToHex(schnorr.getPublicKey(sk));
86
+ if (unsigned.pubkey.toLowerCase() !== expected) throw new CryptoError("unsigned event pubkey does not match secret key");
87
+ const normalized = {
88
+ kind: unsigned.kind,
89
+ tags: unsigned.tags,
90
+ content: unsigned.content,
91
+ created_at: unsigned.created_at,
92
+ pubkey: expected
93
+ };
94
+ const id = getEventHash(normalized);
95
+ const sig = bytesToHex(schnorr.sign(hexToBytes(id), sk));
96
+ const event = {
97
+ ...normalized,
98
+ id,
99
+ sig
100
+ };
101
+ markVerified(event);
102
+ return event;
103
+ }
104
+ /** Verify event id and BIP-340 signature. Uses WeakSet cache (does not mutate the event). */
105
+ function verifyEvent(event) {
106
+ if (isMarkedVerified(event)) return true;
107
+ if (isMarkedFailed(event)) return false;
108
+ if (!validateSignedEvent(event)) {
109
+ markUnverified(event);
110
+ return false;
111
+ }
112
+ try {
113
+ const hash = getEventHash(event);
114
+ if (hash !== event.id.toLowerCase()) {
115
+ markUnverified(event);
116
+ return false;
117
+ }
118
+ const ok = schnorr.verify(hexToBytes(event.sig.toLowerCase()), hexToBytes(hash), hexToBytes(event.pubkey.toLowerCase()));
119
+ if (ok) markVerified(event);
120
+ else markUnverified(event);
121
+ return ok;
122
+ } catch {
123
+ markUnverified(event);
124
+ return false;
125
+ }
126
+ }
127
+ //#endregion
128
+ export { publicKeyFromHex as a, getPublicKey as i, SecretKey as n, signEvent as o, finalizeEvent as r, verifyEvent as s, Keys as t };
129
+
130
+ //# sourceMappingURL=key-Dn-aX4x4.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-Dn-aX4x4.mjs","names":["#bytes"],"sources":["../src/core/key.ts"],"sourcesContent":["import { schnorr } from \"@noble/curves/secp256k1.js\";\nimport { CryptoError } from \"./error.ts\";\nimport {\n type Event,\n type EventTemplate,\n type UnsignedEvent,\n getEventHash,\n isMarkedFailed,\n isMarkedVerified,\n markUnverified,\n markVerified,\n validateEvent,\n validateSignedEvent,\n} 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 | null;\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) throw new CryptoError(\"secret key has been zeroized\");\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 = null;\n }\n }\n}\n\nexport type PublicKey = string;\n\nexport function publicKeyFromHex(hex: string): PublicKey {\n return assertHex32(hex, \"public key\");\n}\n\nexport function getPublicKey(secretKey: SecretKey | Uint8Array | string): PublicKey {\n const bytes =\n secretKey instanceof SecretKey\n ? secretKey.bytes\n : typeof secretKey === \"string\"\n ? hexToBytes(assertHex32(secretKey, \"secret key\"))\n : (assertSecretKeyBytes(secretKey), secretKey);\n return bytesToHex(schnorr.getPublicKey(bytes));\n}\n\n/** Keypair convenience wrapper. */\nexport class Keys {\n readonly secretKey: SecretKey;\n readonly publicKey: PublicKey;\n\n private constructor(secretKey: SecretKey) {\n this.secretKey = secretKey;\n this.publicKey = getPublicKey(secretKey);\n }\n\n static generate(): Keys {\n return new Keys(SecretKey.generate());\n }\n\n static fromSecretKey(secretKey: SecretKey | Uint8Array | string): Keys {\n const sk =\n secretKey instanceof SecretKey\n ? secretKey\n : typeof secretKey === \"string\"\n ? SecretKey.fromHex(secretKey)\n : SecretKey.fromBytes(secretKey);\n return new Keys(sk);\n }\n}\n\nfunction resolveSecretKeyBytes(secretKey: SecretKey | Uint8Array | string): Uint8Array {\n if (secretKey instanceof SecretKey) return secretKey.bytes;\n if (typeof secretKey === \"string\") return hexToBytes(assertHex32(secretKey, \"secret key\"));\n assertSecretKeyBytes(secretKey);\n return secretKey;\n}\n\n/** Fill pubkey/id/sig on a template and return a signed event. */\nexport function finalizeEvent(\n template: EventTemplate,\n secretKey: SecretKey | Uint8Array | string,\n): Event {\n const sk = resolveSecretKeyBytes(secretKey);\n const pubkey = bytesToHex(schnorr.getPublicKey(sk));\n const unsigned: UnsignedEvent = {\n kind: template.kind,\n tags: template.tags,\n content: template.content,\n created_at: template.created_at,\n pubkey,\n };\n return signEvent(unsigned, sk);\n}\n\n/**\n * Sign an already-assembled unsigned event.\n * Rejects when `unsigned.pubkey` does not match the secret key.\n */\nexport function signEvent(\n unsigned: UnsignedEvent,\n secretKey: SecretKey | Uint8Array | string,\n): Event {\n const sk = resolveSecretKeyBytes(secretKey);\n if (!validateEvent(unsigned)) {\n throw new CryptoError(\"cannot sign invalid unsigned event\");\n }\n\n const expected = bytesToHex(schnorr.getPublicKey(sk));\n if (unsigned.pubkey.toLowerCase() !== expected) {\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: expected,\n };\n\n const id = getEventHash(normalized);\n const sig = bytesToHex(schnorr.sign(hexToBytes(id), sk));\n const event: Event = { ...normalized, id, sig };\n markVerified(event);\n return event;\n}\n\n/** Verify event id and BIP-340 signature. Uses WeakSet cache (does not mutate the event). */\nexport function verifyEvent(event: Event): boolean {\n if (isMarkedVerified(event)) return true;\n if (isMarkedFailed(event)) return false;\n\n if (!validateSignedEvent(event)) {\n markUnverified(event);\n return false;\n }\n\n try {\n const hash = getEventHash(event);\n if (hash !== event.id.toLowerCase()) {\n markUnverified(event);\n return false;\n }\n const ok = schnorr.verify(\n hexToBytes(event.sig.toLowerCase()),\n hexToBytes(hash),\n hexToBytes(event.pubkey.toLowerCase()),\n );\n if (ok) markVerified(event);\n else markUnverified(event);\n return ok;\n } catch {\n markUnverified(event);\n return false;\n }\n}\n"],"mappings":";;;;;;AAiBA,IAAa,YAAb,MAAa,UAAU;CACrB;CAEA,YAAoB,OAAmB;EACrC,qBAAqB,KAAK;EAC1B,KAAKA,SAAS,IAAI,WAAW,KAAK;CACpC;CAEA,OAAO,WAAsB;EAC3B,OAAO,IAAI,UAAU,QAAQ,MAAM,gBAAgB,CAAC;CACtD;CAEA,OAAO,UAAU,OAA8B;EAC7C,OAAO,IAAI,UAAU,KAAK;CAC5B;CAEA,OAAO,QAAQ,KAAwB;EACrC,OAAO,IAAI,UAAU,WAAW,YAAY,KAAK,YAAY,CAAC,CAAC;CACjE;CAEA,IAAI,QAAoB;EACtB,IAAI,CAAC,KAAKA,QAAQ,MAAM,IAAI,YAAY,8BAA8B;EACtE,OAAO,IAAI,WAAW,KAAKA,MAAM;CACnC;CAEA,QAAgB;EACd,OAAO,WAAW,KAAK,KAAK;CAC9B;;CAGA,UAAgB;EACd,IAAI,KAAKA,QAAQ;GACf,KAAKA,OAAO,KAAK,CAAC;GAClB,KAAKA,SAAS;EAChB;CACF;AACF;AAIA,SAAgB,iBAAiB,KAAwB;CACvD,OAAO,YAAY,KAAK,YAAY;AACtC;AAEA,SAAgB,aAAa,WAAuD;CAClF,MAAM,QACJ,qBAAqB,YACjB,UAAU,QACV,OAAO,cAAc,WACnB,WAAW,YAAY,WAAW,YAAY,CAAC,KAC9C,qBAAqB,SAAS,GAAG;CAC1C,OAAO,WAAW,QAAQ,aAAa,KAAK,CAAC;AAC/C;;AAGA,IAAa,OAAb,MAAa,KAAK;CAChB;CACA;CAEA,YAAoB,WAAsB;EACxC,KAAK,YAAY;EACjB,KAAK,YAAY,aAAa,SAAS;CACzC;CAEA,OAAO,WAAiB;EACtB,OAAO,IAAI,KAAK,UAAU,SAAS,CAAC;CACtC;CAEA,OAAO,cAAc,WAAkD;EACrE,MAAM,KACJ,qBAAqB,YACjB,YACA,OAAO,cAAc,WACnB,UAAU,QAAQ,SAAS,IAC3B,UAAU,UAAU,SAAS;EACrC,OAAO,IAAI,KAAK,EAAE;CACpB;AACF;AAEA,SAAS,sBAAsB,WAAwD;CACrF,IAAI,qBAAqB,WAAW,OAAO,UAAU;CACrD,IAAI,OAAO,cAAc,UAAU,OAAO,WAAW,YAAY,WAAW,YAAY,CAAC;CACzF,qBAAqB,SAAS;CAC9B,OAAO;AACT;;AAGA,SAAgB,cACd,UACA,WACO;CACP,MAAM,KAAK,sBAAsB,SAAS;CAC1C,MAAM,SAAS,WAAW,QAAQ,aAAa,EAAE,CAAC;CAQlD,OAAO,UAAU;EANf,MAAM,SAAS;EACf,MAAM,SAAS;EACf,SAAS,SAAS;EAClB,YAAY,SAAS;EACrB;CAEsB,GAAG,EAAE;AAC/B;;;;;AAMA,SAAgB,UACd,UACA,WACO;CACP,MAAM,KAAK,sBAAsB,SAAS;CAC1C,IAAI,CAAC,cAAc,QAAQ,GACzB,MAAM,IAAI,YAAY,oCAAoC;CAG5D,MAAM,WAAW,WAAW,QAAQ,aAAa,EAAE,CAAC;CACpD,IAAI,SAAS,OAAO,YAAY,MAAM,UACpC,MAAM,IAAI,YAAY,iDAAiD;CAGzE,MAAM,aAA4B;EAChC,MAAM,SAAS;EACf,MAAM,SAAS;EACf,SAAS,SAAS;EAClB,YAAY,SAAS;EACrB,QAAQ;CACV;CAEA,MAAM,KAAK,aAAa,UAAU;CAClC,MAAM,MAAM,WAAW,QAAQ,KAAK,WAAW,EAAE,GAAG,EAAE,CAAC;CACvD,MAAM,QAAe;EAAE,GAAG;EAAY;EAAI;CAAI;CAC9C,aAAa,KAAK;CAClB,OAAO;AACT;;AAGA,SAAgB,YAAY,OAAuB;CACjD,IAAI,iBAAiB,KAAK,GAAG,OAAO;CACpC,IAAI,eAAe,KAAK,GAAG,OAAO;CAElC,IAAI,CAAC,oBAAoB,KAAK,GAAG;EAC/B,eAAe,KAAK;EACpB,OAAO;CACT;CAEA,IAAI;EACF,MAAM,OAAO,aAAa,KAAK;EAC/B,IAAI,SAAS,MAAM,GAAG,YAAY,GAAG;GACnC,eAAe,KAAK;GACpB,OAAO;EACT;EACA,MAAM,KAAK,QAAQ,OACjB,WAAW,MAAM,IAAI,YAAY,CAAC,GAClC,WAAW,IAAI,GACf,WAAW,MAAM,OAAO,YAAY,CAAC,CACvC;EACA,IAAI,IAAI,aAAa,KAAK;OACrB,eAAe,KAAK;EACzB,OAAO;CACT,QAAQ;EACN,eAAe,KAAK;EACpB,OAAO;CACT;AACF"}
@@ -0,0 +1,59 @@
1
+ //#region src/core/kind.ts
2
+ /** NIP-01 regular: stored by relays. */
3
+ function isRegularKind(kind) {
4
+ return kind === 1 || kind === 2 || kind >= 4 && kind < 45 || kind >= 1e3 && kind < 1e4;
5
+ }
6
+ /** Replaceable: latest per (pubkey, kind) wins. */
7
+ function isReplaceableKind(kind) {
8
+ return kind === 0 || kind === 3 || kind >= 1e4 && kind < 2e4;
9
+ }
10
+ /** Ephemeral: not expected to be stored. */
11
+ function isEphemeralKind(kind) {
12
+ return kind >= 2e4 && kind < 3e4;
13
+ }
14
+ /** Addressable (parameterized replaceable): latest per (pubkey, kind, d-tag) wins. */
15
+ function isAddressableKind(kind) {
16
+ return kind >= 3e4 && kind < 4e4;
17
+ }
18
+ function classifyKind(kind) {
19
+ if (isRegularKind(kind)) return "regular";
20
+ if (isReplaceableKind(kind)) return "replaceable";
21
+ if (isEphemeralKind(kind)) return "ephemeral";
22
+ if (isAddressableKind(kind)) return "addressable";
23
+ return "unknown";
24
+ }
25
+ /** Kind numbers used by this package. */
26
+ const Kind = {
27
+ Metadata: 0,
28
+ TextNote: 1,
29
+ Contacts: 3,
30
+ EventDeletion: 5,
31
+ Repost: 6,
32
+ Reaction: 7,
33
+ Seal: 13,
34
+ PrivateDirectMessage: 14,
35
+ GenericRepost: 16,
36
+ GiftWrap: 1059,
37
+ ZapRequest: 9734,
38
+ Zap: 9735,
39
+ MuteList: 1e4,
40
+ PinList: 10001,
41
+ RelayList: 10002,
42
+ BookmarkList: 10003,
43
+ FavoriteRelays: 10012,
44
+ UserEmojiList: 10030,
45
+ DirectMessageRelaysList: 10050,
46
+ BlossomServerList: 10063,
47
+ GiftWrapEphemeral: 21059,
48
+ ClientAuth: 22242,
49
+ NostrConnect: 24133,
50
+ BlobsAuth: 24242,
51
+ HttpAuth: 27235,
52
+ RelaySets: 30002,
53
+ EmojiSet: 30030,
54
+ StarterPack: 39089
55
+ };
56
+ //#endregion
57
+ export { isRegularKind as a, isEphemeralKind as i, classifyKind as n, isReplaceableKind as o, isAddressableKind as r, Kind as t };
58
+
59
+ //# sourceMappingURL=kind-BLl4cLOc.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kind-BLl4cLOc.mjs","names":[],"sources":["../src/core/kind.ts"],"sourcesContent":["/** NIP-01 regular: stored by relays. */\nexport function isRegularKind(kind: number): boolean {\n return kind === 1 || kind === 2 || (kind >= 4 && kind < 45) || (kind >= 1000 && kind < 10000);\n}\n\n/** Replaceable: latest per (pubkey, kind) wins. */\nexport function isReplaceableKind(kind: number): boolean {\n return kind === 0 || kind === 3 || (kind >= 10000 && kind < 20000);\n}\n\n/** Ephemeral: not expected to be stored. */\nexport function isEphemeralKind(kind: number): boolean {\n return kind >= 20000 && kind < 30000;\n}\n\n/** Addressable (parameterized replaceable): latest per (pubkey, kind, d-tag) wins. */\nexport function isAddressableKind(kind: number): boolean {\n return kind >= 30000 && kind < 40000;\n}\n\nexport type KindClassification =\n | \"regular\"\n | \"replaceable\"\n | \"ephemeral\"\n | \"addressable\"\n | \"unknown\";\n\nexport function classifyKind(kind: number): KindClassification {\n if (isRegularKind(kind)) return \"regular\";\n if (isReplaceableKind(kind)) return \"replaceable\";\n if (isEphemeralKind(kind)) return \"ephemeral\";\n if (isAddressableKind(kind)) return \"addressable\";\n return \"unknown\";\n}\n\n/** Kind numbers used by this package. */\nexport const Kind = {\n Metadata: 0,\n TextNote: 1,\n Contacts: 3,\n EventDeletion: 5,\n Repost: 6,\n Reaction: 7,\n Seal: 13,\n PrivateDirectMessage: 14,\n GenericRepost: 16,\n GiftWrap: 1059,\n ZapRequest: 9734,\n Zap: 9735,\n MuteList: 10000,\n PinList: 10001,\n RelayList: 10002,\n BookmarkList: 10003,\n FavoriteRelays: 10012,\n UserEmojiList: 10030,\n DirectMessageRelaysList: 10050,\n BlossomServerList: 10063,\n GiftWrapEphemeral: 21059,\n ClientAuth: 22242,\n NostrConnect: 24133,\n BlobsAuth: 24242,\n HttpAuth: 27235,\n RelaySets: 30002,\n EmojiSet: 30030,\n StarterPack: 39089,\n} as const;\n\nexport type KindName = keyof typeof Kind;\nexport type KnownKind = (typeof Kind)[KindName];\n"],"mappings":";;AACA,SAAgB,cAAc,MAAuB;CACnD,OAAO,SAAS,KAAK,SAAS,KAAM,QAAQ,KAAK,OAAO,MAAQ,QAAQ,OAAQ,OAAO;AACzF;;AAGA,SAAgB,kBAAkB,MAAuB;CACvD,OAAO,SAAS,KAAK,SAAS,KAAM,QAAQ,OAAS,OAAO;AAC9D;;AAGA,SAAgB,gBAAgB,MAAuB;CACrD,OAAO,QAAQ,OAAS,OAAO;AACjC;;AAGA,SAAgB,kBAAkB,MAAuB;CACvD,OAAO,QAAQ,OAAS,OAAO;AACjC;AASA,SAAgB,aAAa,MAAkC;CAC7D,IAAI,cAAc,IAAI,GAAG,OAAO;CAChC,IAAI,kBAAkB,IAAI,GAAG,OAAO;CACpC,IAAI,gBAAgB,IAAI,GAAG,OAAO;CAClC,IAAI,kBAAkB,IAAI,GAAG,OAAO;CACpC,OAAO;AACT;;AAGA,MAAa,OAAO;CAClB,UAAU;CACV,UAAU;CACV,UAAU;CACV,eAAe;CACf,QAAQ;CACR,UAAU;CACV,MAAM;CACN,sBAAsB;CACtB,eAAe;CACf,UAAU;CACV,YAAY;CACZ,KAAK;CACL,UAAU;CACV,SAAS;CACT,WAAW;CACX,cAAc;CACd,gBAAgB;CAChB,eAAe;CACf,yBAAyB;CACzB,mBAAmB;CACnB,mBAAmB;CACnB,YAAY;CACZ,cAAc;CACd,WAAW;CACX,UAAU;CACV,WAAW;CACX,UAAU;CACV,aAAa;AACf"}