@hashtree/nostr 0.1.3 → 0.1.5

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 (46) hide show
  1. package/README.md +51 -0
  2. package/dist/events.d.ts +66 -0
  3. package/dist/events.d.ts.map +1 -0
  4. package/dist/events.js +426 -0
  5. package/dist/events.js.map +1 -0
  6. package/dist/index.d.ts +4 -1
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +6 -2
  9. package/dist/index.js.map +1 -1
  10. package/dist/resolver/nostr.d.ts +2 -0
  11. package/dist/resolver/nostr.d.ts.map +1 -1
  12. package/dist/resolver/nostr.js +122 -31
  13. package/dist/resolver/nostr.js.map +1 -1
  14. package/dist/snapshot.d.ts +30 -0
  15. package/dist/snapshot.d.ts.map +1 -0
  16. package/dist/snapshot.js +157 -0
  17. package/dist/snapshot.js.map +1 -0
  18. package/dist/treeEventSnapshots.d.ts +30 -0
  19. package/dist/treeEventSnapshots.d.ts.map +1 -0
  20. package/dist/treeEventSnapshots.js +186 -0
  21. package/dist/treeEventSnapshots.js.map +1 -0
  22. package/dist/webrtc/index.d.ts +3 -2
  23. package/dist/webrtc/index.d.ts.map +1 -1
  24. package/dist/webrtc/index.js +3 -2
  25. package/dist/webrtc/index.js.map +1 -1
  26. package/dist/webrtc/peer.d.ts +12 -1
  27. package/dist/webrtc/peer.d.ts.map +1 -1
  28. package/dist/webrtc/peer.js +39 -5
  29. package/dist/webrtc/peer.js.map +1 -1
  30. package/dist/webrtc/peerSelector.d.ts +31 -0
  31. package/dist/webrtc/peerSelector.d.ts.map +1 -0
  32. package/dist/webrtc/peerSelector.js +348 -0
  33. package/dist/webrtc/peerSelector.js.map +1 -0
  34. package/dist/webrtc/protocol.d.ts +15 -4
  35. package/dist/webrtc/protocol.d.ts.map +1 -1
  36. package/dist/webrtc/protocol.js +31 -17
  37. package/dist/webrtc/protocol.js.map +1 -1
  38. package/dist/webrtc/store.d.ts +31 -4
  39. package/dist/webrtc/store.d.ts.map +1 -1
  40. package/dist/webrtc/store.js +362 -99
  41. package/dist/webrtc/store.js.map +1 -1
  42. package/dist/webrtc/types.d.ts +66 -4
  43. package/dist/webrtc/types.d.ts.map +1 -1
  44. package/dist/webrtc/types.js +71 -9
  45. package/dist/webrtc/types.js.map +1 -1
  46. package/package.json +8 -2
package/README.md CHANGED
@@ -22,10 +22,20 @@ const store = new WebRTCStore({
22
22
  decrypt,
23
23
  localStore,
24
24
  relays: ['wss://relay.example.com'],
25
+ requestSelectionStrategy: 'titForTat',
26
+ requestFairnessEnabled: true,
27
+ requestDispatch: {
28
+ initialFanout: 2,
29
+ hedgeFanout: 1,
30
+ maxFanout: 8,
31
+ hedgeIntervalMs: 120,
32
+ },
25
33
  });
26
34
 
27
35
  await store.start();
36
+ await store.loadPeerMetadata(); // optional warm start
28
37
  const data = await store.get(hash);
38
+ await store.persistPeerMetadata(); // optional shutdown/save step
29
39
  ```
30
40
 
31
41
  ## Nostr Ref Resolver
@@ -72,6 +82,47 @@ const resolver = createNostrRefResolver({
72
82
  const root = await resolver.resolve('npub1.../myfiles');
73
83
  ```
74
84
 
85
+ ## Signed Tree Snapshots
86
+
87
+ For immutable permalinks, store a copy of the signed kind `30078` root event as a plain hashtree blob. The snapshot gives you one signed root even when relays do not answer, and you can still watch for newer events later.
88
+
89
+ ```typescript
90
+ import {
91
+ storeTreeEventSnapshot,
92
+ readTreeEventSnapshot,
93
+ fetchLatestTreeEventSnapshot,
94
+ watchLatestTreeEventSnapshot,
95
+ } from '@hashtree/nostr';
96
+ import { HashTree } from '@hashtree/core';
97
+
98
+ const hashTree = new HashTree({ store });
99
+
100
+ const snapshot = await storeTreeEventSnapshot(hashTree, nip19, signedRootEvent);
101
+ const sameSnapshot = snapshot
102
+ ? await readTreeEventSnapshot(hashTree, nip19, snapshot.snapshotCid)
103
+ : null;
104
+
105
+ const latest = await fetchLatestTreeEventSnapshot(
106
+ { snapshotTarget: hashTree, nip19, fetchEvents },
107
+ 'npub1...owner',
108
+ 'videos/demo',
109
+ );
110
+
111
+ const stop = watchLatestTreeEventSnapshot(
112
+ { snapshotTarget: hashTree, nip19, fetchEvents, subscribeEvents },
113
+ 'npub1...owner',
114
+ 'videos/demo',
115
+ (nextSnapshot) => {
116
+ console.log(nextSnapshot.snapshotNhash, nextSnapshot.rootCid);
117
+ },
118
+ );
119
+
120
+ // later
121
+ stop();
122
+ ```
123
+
124
+ The library does not keep a global snapshot cache for you. It provides stateless helpers plus a live watcher; route caching and reuse policy stay with the app. Pass a `HashTree` when you already have one controlling write policy, or a raw `Store` when the default wrapper is enough.
125
+
75
126
  ## License
76
127
 
77
128
  MIT
@@ -0,0 +1,66 @@
1
+ import { type CID, type Store } from '@hashtree/core';
2
+ export interface StoredNostrEvent {
3
+ id: string;
4
+ pubkey: string;
5
+ created_at: number;
6
+ kind: number;
7
+ tags: string[][];
8
+ content: string;
9
+ sig: string;
10
+ }
11
+ export interface NostrEventManifest {
12
+ byId: CID | null;
13
+ byAuthorTime: CID | null;
14
+ byAuthorKindTime: CID | null;
15
+ byKindTime: CID | null;
16
+ byTime: CID | null;
17
+ byTag: CID | null;
18
+ replaceable: CID | null;
19
+ parameterizedReplaceable: CID | null;
20
+ }
21
+ export interface ListEventsOptions {
22
+ limit?: number;
23
+ since?: number;
24
+ until?: number;
25
+ }
26
+ export declare class NostrEventStore {
27
+ private readonly tree;
28
+ private readonly index;
29
+ constructor(store: Store);
30
+ encodeEvent(event: StoredNostrEvent): Uint8Array;
31
+ decodeEvent(data: Uint8Array): StoredNostrEvent;
32
+ add(root: CID | null, event: StoredNostrEvent): Promise<CID>;
33
+ build(root: CID | null, events: StoredNostrEvent[]): Promise<CID | null>;
34
+ getById(root: CID | null, eventId: string): Promise<StoredNostrEvent | null>;
35
+ listByAuthor(root: CID | null, pubkey: string, options?: ListEventsOptions): Promise<StoredNostrEvent[]>;
36
+ listByAuthorAndKind(root: CID | null, pubkey: string, kind: number, options?: ListEventsOptions): Promise<StoredNostrEvent[]>;
37
+ getReplaceable(root: CID | null, pubkey: string, kind: number): Promise<StoredNostrEvent | null>;
38
+ listRecent(root: CID | null, options?: ListEventsOptions): Promise<StoredNostrEvent[]>;
39
+ listByTag(root: CID | null, tagName: string, tagValue: string, options?: ListEventsOptions): Promise<StoredNostrEvent[]>;
40
+ getParameterizedReplaceable(root: CID | null, pubkey: string, kind: number, dTag: string): Promise<StoredNostrEvent | null>;
41
+ getManifest(root: CID | null): Promise<NostrEventManifest>;
42
+ listByKind(root: CID | null, kind: number, options?: ListEventsOptions): Promise<StoredNostrEvent[]>;
43
+ private collectEvents;
44
+ private readStoredEvent;
45
+ private upsertWinner;
46
+ private writeManifest;
47
+ private authorTimeKey;
48
+ private authorKindTimeKey;
49
+ private kindTimeKey;
50
+ private timeKey;
51
+ private createdAtFromIndexKey;
52
+ private tagKeys;
53
+ private tagPrefix;
54
+ private normalizeTagName;
55
+ private normalizeTagValue;
56
+ private replaceableKey;
57
+ private parameterizedReplaceableKey;
58
+ private validateEventShape;
59
+ private validateEvent;
60
+ private validateHex64;
61
+ private validateHex128;
62
+ private validateCreatedAt;
63
+ private validateKind;
64
+ private validateContent;
65
+ }
66
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"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"}
package/dist/events.js ADDED
@@ -0,0 +1,426 @@
1
+ import { decode, encode } from '@msgpack/msgpack';
2
+ import { HashTree, LinkType, toHex, sha256 } from '@hashtree/core';
3
+ import { BTree } from '@hashtree/index';
4
+ const EVENT_ENVELOPE_VERSION = 1;
5
+ const MAX_U64 = (1n << 64n) - 1n;
6
+ const HEX_64 = /^[0-9a-f]{64}$/;
7
+ const HEX_128 = /^[0-9a-f]{128}$/;
8
+ const MANIFEST_BY_ID = 'by-id';
9
+ const MANIFEST_BY_AUTHOR_TIME = 'by-author-time';
10
+ const MANIFEST_BY_AUTHOR_KIND_TIME = 'by-author-kind-time';
11
+ const MANIFEST_BY_KIND_TIME = 'by-kind-time';
12
+ const MANIFEST_BY_TIME = 'by-time';
13
+ const MANIFEST_BY_TAG = 'by-tag';
14
+ const MANIFEST_REPLACEABLE = 'replaceable';
15
+ const MANIFEST_PARAMETERIZED_REPLACEABLE = 'parameterized-replaceable';
16
+ function canonicalEventIdPayload(event) {
17
+ return JSON.stringify([0, event.pubkey, event.created_at, event.kind, event.tags, event.content]);
18
+ }
19
+ async function computeCanonicalEventId(event) {
20
+ const payload = canonicalEventIdPayload(event);
21
+ return toHex(await sha256(new TextEncoder().encode(payload)));
22
+ }
23
+ function padKind(kind) {
24
+ return kind.toString(16).padStart(8, '0');
25
+ }
26
+ function reverseTimestamp(createdAt) {
27
+ return (MAX_U64 - BigInt(createdAt)).toString(16).padStart(16, '0');
28
+ }
29
+ function isReplaceableKind(kind) {
30
+ return kind === 0 || kind === 3 || (kind >= 10_000 && kind < 20_000);
31
+ }
32
+ function isParameterizedReplaceableKind(kind) {
33
+ return kind >= 30_000 && kind < 40_000;
34
+ }
35
+ function getDTag(event) {
36
+ for (const tag of event.tags) {
37
+ if (tag[0] === 'd' && typeof tag[1] === 'string' && tag[1].length > 0) {
38
+ return tag[1];
39
+ }
40
+ }
41
+ return null;
42
+ }
43
+ function compareEvents(a, b) {
44
+ if (a.created_at !== b.created_at) {
45
+ return a.created_at - b.created_at;
46
+ }
47
+ return a.id.localeCompare(b.id);
48
+ }
49
+ function assertStringArray(tags) {
50
+ if (!Array.isArray(tags)) {
51
+ throw new Error('Nostr event tags must be an array');
52
+ }
53
+ for (const tag of tags) {
54
+ if (!Array.isArray(tag) || tag.some(value => typeof value !== 'string')) {
55
+ throw new Error('Nostr event tags must be an array of string arrays');
56
+ }
57
+ }
58
+ }
59
+ export class NostrEventStore {
60
+ tree;
61
+ index;
62
+ constructor(store) {
63
+ this.tree = new HashTree({ store });
64
+ this.index = new BTree(store);
65
+ }
66
+ encodeEvent(event) {
67
+ const normalized = this.validateEventShape(event);
68
+ return encode([
69
+ EVENT_ENVELOPE_VERSION,
70
+ normalized.id,
71
+ normalized.pubkey,
72
+ normalized.created_at,
73
+ normalized.kind,
74
+ normalized.tags,
75
+ normalized.content,
76
+ normalized.sig,
77
+ ]);
78
+ }
79
+ decodeEvent(data) {
80
+ const decoded = decode(data);
81
+ if (!Array.isArray(decoded) || decoded.length !== 8) {
82
+ throw new Error('Invalid Nostr event envelope');
83
+ }
84
+ const [version, id, pubkey, createdAt, kind, tags, content, sig,] = decoded;
85
+ if (version !== EVENT_ENVELOPE_VERSION) {
86
+ throw new Error(`Unsupported Nostr event envelope version: ${String(version)}`);
87
+ }
88
+ if (typeof id !== 'string' || typeof pubkey !== 'string' || typeof content !== 'string' || typeof sig !== 'string') {
89
+ throw new Error('Invalid Nostr event envelope fields');
90
+ }
91
+ if (typeof createdAt !== 'number' || !Number.isInteger(createdAt) || createdAt < 0) {
92
+ throw new Error('Invalid Nostr event created_at');
93
+ }
94
+ if (typeof kind !== 'number' || !Number.isInteger(kind) || kind < 0) {
95
+ throw new Error('Invalid Nostr event kind');
96
+ }
97
+ assertStringArray(tags);
98
+ return this.validateEventShape({
99
+ id,
100
+ pubkey,
101
+ created_at: createdAt,
102
+ kind,
103
+ tags,
104
+ content,
105
+ sig,
106
+ });
107
+ }
108
+ async add(root, event) {
109
+ const normalized = await this.validateEvent(event);
110
+ const manifest = await this.getManifest(root);
111
+ const eventBytes = this.encodeEvent(normalized);
112
+ const { cid: eventCid } = await this.tree.putFile(eventBytes);
113
+ const nextManifest = {
114
+ byId: await this.index.insertLink(manifest.byId, normalized.id, eventCid),
115
+ byAuthorTime: await this.index.insertLink(manifest.byAuthorTime, this.authorTimeKey(normalized), eventCid),
116
+ byAuthorKindTime: await this.index.insertLink(manifest.byAuthorKindTime, this.authorKindTimeKey(normalized), eventCid),
117
+ byKindTime: await this.index.insertLink(manifest.byKindTime, this.kindTimeKey(normalized), eventCid),
118
+ byTime: await this.index.insertLink(manifest.byTime, this.timeKey(normalized), eventCid),
119
+ byTag: manifest.byTag,
120
+ replaceable: manifest.replaceable,
121
+ parameterizedReplaceable: manifest.parameterizedReplaceable,
122
+ };
123
+ for (const tagKey of this.tagKeys(normalized)) {
124
+ nextManifest.byTag = await this.index.insertLink(nextManifest.byTag, tagKey, eventCid);
125
+ }
126
+ if (isReplaceableKind(normalized.kind)) {
127
+ nextManifest.replaceable = await this.upsertWinner(manifest.replaceable, this.replaceableKey(normalized.pubkey, normalized.kind), normalized, eventCid);
128
+ }
129
+ if (isParameterizedReplaceableKind(normalized.kind)) {
130
+ const dTag = getDTag(normalized);
131
+ if (dTag) {
132
+ nextManifest.parameterizedReplaceable = await this.upsertWinner(manifest.parameterizedReplaceable, this.parameterizedReplaceableKey(normalized.pubkey, normalized.kind, dTag), normalized, eventCid);
133
+ }
134
+ }
135
+ const manifestRoot = await this.writeManifest(nextManifest);
136
+ if (!manifestRoot) {
137
+ throw new Error('Failed to create Nostr event manifest');
138
+ }
139
+ return manifestRoot;
140
+ }
141
+ async build(root, events) {
142
+ const normalized = await Promise.all(events.map(event => this.validateEvent(event)));
143
+ normalized.sort(compareEvents);
144
+ let current = root;
145
+ for (const event of normalized) {
146
+ current = await this.add(current, event);
147
+ }
148
+ return current;
149
+ }
150
+ async getById(root, eventId) {
151
+ if (!HEX_64.test(eventId)) {
152
+ throw new Error('Event id must be a lowercase 64-character hex string');
153
+ }
154
+ const manifest = await this.getManifest(root);
155
+ if (!manifest.byId) {
156
+ return null;
157
+ }
158
+ const eventCid = await this.index.getLink(manifest.byId, eventId);
159
+ if (!eventCid) {
160
+ return null;
161
+ }
162
+ return this.readStoredEvent(eventCid);
163
+ }
164
+ async listByAuthor(root, pubkey, options = {}) {
165
+ const manifest = await this.getManifest(root);
166
+ if (!manifest.byAuthorTime) {
167
+ return [];
168
+ }
169
+ return this.collectEvents(manifest.byAuthorTime, `${this.validateHex64(pubkey, 'pubkey')}:`, options);
170
+ }
171
+ async listByAuthorAndKind(root, pubkey, kind, options = {}) {
172
+ const manifest = await this.getManifest(root);
173
+ if (!manifest.byAuthorKindTime) {
174
+ return [];
175
+ }
176
+ return this.collectEvents(manifest.byAuthorKindTime, `${this.validateHex64(pubkey, 'pubkey')}:${padKind(this.validateKind(kind))}:`, options);
177
+ }
178
+ async getReplaceable(root, pubkey, kind) {
179
+ const manifest = await this.getManifest(root);
180
+ if (!manifest.replaceable) {
181
+ return null;
182
+ }
183
+ const eventCid = await this.index.getLink(manifest.replaceable, this.replaceableKey(this.validateHex64(pubkey, 'pubkey'), this.validateKind(kind)));
184
+ return eventCid ? this.readStoredEvent(eventCid) : null;
185
+ }
186
+ async listRecent(root, options = {}) {
187
+ const manifest = await this.getManifest(root);
188
+ if (!manifest.byTime) {
189
+ return [];
190
+ }
191
+ return this.collectEvents(manifest.byTime, '', options);
192
+ }
193
+ async listByTag(root, tagName, tagValue, options = {}) {
194
+ const manifest = await this.getManifest(root);
195
+ if (!manifest.byTag) {
196
+ return [];
197
+ }
198
+ return this.collectEvents(manifest.byTag, this.tagPrefix(tagName, tagValue), options);
199
+ }
200
+ async getParameterizedReplaceable(root, pubkey, kind, dTag) {
201
+ const manifest = await this.getManifest(root);
202
+ if (!manifest.parameterizedReplaceable) {
203
+ return null;
204
+ }
205
+ if (dTag.length === 0) {
206
+ throw new Error('Parameterized replaceable events require a non-empty d tag');
207
+ }
208
+ const eventCid = await this.index.getLink(manifest.parameterizedReplaceable, this.parameterizedReplaceableKey(this.validateHex64(pubkey, 'pubkey'), this.validateKind(kind), dTag));
209
+ return eventCid ? this.readStoredEvent(eventCid) : null;
210
+ }
211
+ async getManifest(root) {
212
+ if (!root) {
213
+ return {
214
+ byId: null,
215
+ byAuthorTime: null,
216
+ byAuthorKindTime: null,
217
+ byKindTime: null,
218
+ byTime: null,
219
+ byTag: null,
220
+ replaceable: null,
221
+ parameterizedReplaceable: null,
222
+ };
223
+ }
224
+ const entries = await this.tree.listDirectory(root);
225
+ const getCid = (name) => entries.find(entry => entry.name === name)?.cid ?? null;
226
+ return {
227
+ byId: getCid(MANIFEST_BY_ID),
228
+ byAuthorTime: getCid(MANIFEST_BY_AUTHOR_TIME),
229
+ byAuthorKindTime: getCid(MANIFEST_BY_AUTHOR_KIND_TIME),
230
+ byKindTime: getCid(MANIFEST_BY_KIND_TIME),
231
+ byTime: getCid(MANIFEST_BY_TIME),
232
+ byTag: getCid(MANIFEST_BY_TAG),
233
+ replaceable: getCid(MANIFEST_REPLACEABLE),
234
+ parameterizedReplaceable: getCid(MANIFEST_PARAMETERIZED_REPLACEABLE),
235
+ };
236
+ }
237
+ async listByKind(root, kind, options = {}) {
238
+ const manifest = await this.getManifest(root);
239
+ if (!manifest.byKindTime) {
240
+ return [];
241
+ }
242
+ return this.collectEvents(manifest.byKindTime, `${padKind(this.validateKind(kind))}:`, options);
243
+ }
244
+ async collectEvents(root, prefix, options = {}) {
245
+ const events = [];
246
+ const entries = prefix.length === 0
247
+ ? this.index.linksEntries(root)
248
+ : this.index.prefixLinks(root, prefix);
249
+ for await (const [key, eventCid] of entries) {
250
+ const createdAt = this.createdAtFromIndexKey(key);
251
+ if (options.until !== undefined && createdAt > options.until) {
252
+ continue;
253
+ }
254
+ if (options.since !== undefined && createdAt < options.since) {
255
+ break;
256
+ }
257
+ events.push(await this.readStoredEvent(eventCid));
258
+ if (options.limit !== undefined && events.length >= options.limit) {
259
+ break;
260
+ }
261
+ }
262
+ return events;
263
+ }
264
+ async readStoredEvent(eventCid) {
265
+ const data = await this.tree.readFile(eventCid);
266
+ if (!data) {
267
+ throw new Error('Stored Nostr event blob is missing');
268
+ }
269
+ return this.decodeEvent(data);
270
+ }
271
+ async upsertWinner(root, key, event, eventCid) {
272
+ const existingCid = root ? await this.index.getLink(root, key) : null;
273
+ if (!existingCid) {
274
+ return this.index.insertLink(root, key, eventCid);
275
+ }
276
+ const existingEvent = await this.readStoredEvent(existingCid);
277
+ if (compareEvents(event, existingEvent) > 0) {
278
+ return this.index.insertLink(root, key, eventCid);
279
+ }
280
+ return root;
281
+ }
282
+ async writeManifest(manifest) {
283
+ const entries = [];
284
+ if (manifest.byId) {
285
+ entries.push({ name: MANIFEST_BY_ID, cid: manifest.byId, size: 0, type: LinkType.Dir });
286
+ }
287
+ if (manifest.byAuthorTime) {
288
+ entries.push({ name: MANIFEST_BY_AUTHOR_TIME, cid: manifest.byAuthorTime, size: 0, type: LinkType.Dir });
289
+ }
290
+ if (manifest.byAuthorKindTime) {
291
+ entries.push({ name: MANIFEST_BY_AUTHOR_KIND_TIME, cid: manifest.byAuthorKindTime, size: 0, type: LinkType.Dir });
292
+ }
293
+ if (manifest.byKindTime) {
294
+ entries.push({ name: MANIFEST_BY_KIND_TIME, cid: manifest.byKindTime, size: 0, type: LinkType.Dir });
295
+ }
296
+ if (manifest.byTime) {
297
+ entries.push({ name: MANIFEST_BY_TIME, cid: manifest.byTime, size: 0, type: LinkType.Dir });
298
+ }
299
+ if (manifest.byTag) {
300
+ entries.push({ name: MANIFEST_BY_TAG, cid: manifest.byTag, size: 0, type: LinkType.Dir });
301
+ }
302
+ if (manifest.replaceable) {
303
+ entries.push({ name: MANIFEST_REPLACEABLE, cid: manifest.replaceable, size: 0, type: LinkType.Dir });
304
+ }
305
+ if (manifest.parameterizedReplaceable) {
306
+ entries.push({
307
+ name: MANIFEST_PARAMETERIZED_REPLACEABLE,
308
+ cid: manifest.parameterizedReplaceable,
309
+ size: 0,
310
+ type: LinkType.Dir,
311
+ });
312
+ }
313
+ if (entries.length === 0) {
314
+ return null;
315
+ }
316
+ const { cid } = await this.tree.putDirectory(entries);
317
+ return cid;
318
+ }
319
+ authorTimeKey(event) {
320
+ return `${event.pubkey}:${reverseTimestamp(event.created_at)}:${event.id}`;
321
+ }
322
+ authorKindTimeKey(event) {
323
+ return `${event.pubkey}:${padKind(event.kind)}:${reverseTimestamp(event.created_at)}:${event.id}`;
324
+ }
325
+ kindTimeKey(event) {
326
+ return `${padKind(event.kind)}:${reverseTimestamp(event.created_at)}:${event.id}`;
327
+ }
328
+ timeKey(event) {
329
+ return `${reverseTimestamp(event.created_at)}:${event.id}`;
330
+ }
331
+ createdAtFromIndexKey(key) {
332
+ const parts = key.split(':');
333
+ if (parts.length < 2) {
334
+ throw new Error(`Invalid Nostr index key: ${key}`);
335
+ }
336
+ const reversed = parts[parts.length - 2];
337
+ const reversedTimestamp = BigInt(`0x${reversed}`);
338
+ const createdAt = MAX_U64 - reversedTimestamp;
339
+ if (createdAt > BigInt(Number.MAX_SAFE_INTEGER)) {
340
+ throw new Error(`Created_at exceeds safe integer range in Nostr index key: ${key}`);
341
+ }
342
+ return Number(createdAt);
343
+ }
344
+ tagKeys(event) {
345
+ return event.tags.flatMap((tag) => {
346
+ const [name, value] = tag;
347
+ if (!name || !value) {
348
+ return [];
349
+ }
350
+ const normalizedName = name.toLowerCase();
351
+ const normalizedValue = this.normalizeTagValue(normalizedName, value);
352
+ return [`${normalizedName}:${normalizedValue}:${reverseTimestamp(event.created_at)}:${event.id}`];
353
+ });
354
+ }
355
+ tagPrefix(tagName, tagValue) {
356
+ const normalizedName = this.normalizeTagName(tagName);
357
+ return `${normalizedName}:${this.normalizeTagValue(normalizedName, tagValue)}:`;
358
+ }
359
+ normalizeTagName(tagName) {
360
+ if (tagName.length === 0) {
361
+ throw new Error('tag name must be non-empty');
362
+ }
363
+ return tagName.toLowerCase();
364
+ }
365
+ normalizeTagValue(tagName, tagValue) {
366
+ return tagName === 't' ? tagValue.toLowerCase() : tagValue;
367
+ }
368
+ replaceableKey(pubkey, kind) {
369
+ return `${pubkey}:${padKind(kind)}`;
370
+ }
371
+ parameterizedReplaceableKey(pubkey, kind, dTag) {
372
+ return `${pubkey}:${padKind(kind)}:${dTag}`;
373
+ }
374
+ validateEventShape(event) {
375
+ const normalized = {
376
+ id: this.validateHex64(event.id, 'event id'),
377
+ pubkey: this.validateHex64(event.pubkey, 'pubkey'),
378
+ created_at: this.validateCreatedAt(event.created_at),
379
+ kind: this.validateKind(event.kind),
380
+ tags: event.tags,
381
+ content: this.validateContent(event.content),
382
+ sig: this.validateHex128(event.sig, 'signature'),
383
+ };
384
+ assertStringArray(normalized.tags);
385
+ return normalized;
386
+ }
387
+ async validateEvent(event) {
388
+ const normalized = this.validateEventShape(event);
389
+ const computedId = await computeCanonicalEventId(normalized);
390
+ if (computedId !== normalized.id) {
391
+ throw new Error(`Event id mismatch: expected ${computedId}, got ${normalized.id}`);
392
+ }
393
+ return normalized;
394
+ }
395
+ validateHex64(value, label) {
396
+ if (!HEX_64.test(value)) {
397
+ throw new Error(`${label} must be a lowercase 64-character hex string`);
398
+ }
399
+ return value;
400
+ }
401
+ validateHex128(value, label) {
402
+ if (!HEX_128.test(value)) {
403
+ throw new Error(`${label} must be a lowercase 128-character hex string`);
404
+ }
405
+ return value;
406
+ }
407
+ validateCreatedAt(value) {
408
+ if (!Number.isInteger(value) || value < 0) {
409
+ throw new Error('created_at must be a non-negative integer');
410
+ }
411
+ return value;
412
+ }
413
+ validateKind(value) {
414
+ if (!Number.isInteger(value) || value < 0) {
415
+ throw new Error('kind must be a non-negative integer');
416
+ }
417
+ return value;
418
+ }
419
+ validateContent(value) {
420
+ if (typeof value !== 'string') {
421
+ throw new Error('content must be a string');
422
+ }
423
+ return value;
424
+ }
425
+ }
426
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -3,6 +3,9 @@
3
3
  *
4
4
  * Provides WebRTC P2P storage and Nostr ref resolver
5
5
  */
6
- export { WebRTCStore, DEFAULT_RELAYS, Peer, PeerId, generateUuid, MAX_HTL, MSG_TYPE_REQUEST, MSG_TYPE_RESPONSE, FRAGMENT_SIZE, encodeRequest, encodeResponse, parseMessage, createRequest, createResponse, createFragmentResponse, hashToKey, verifyHash, generatePeerHTLConfig, decrementHTL, shouldForward, type SignalingMessage, type WebRTCStoreConfig, type PeerStatus, type WebRTCStoreEvent, type WebRTCStoreEventHandler, type EventSigner, type EventEncrypter, type EventDecrypter, type GiftWrapper, type GiftUnwrapper, type SignedEvent, type PeerPool, type PeerClassifier, type PoolConfig, type WebRTCStats, type BandwidthSample, type DataRequest, type DataResponse, type PeerHTLConfig, type PendingRequest, } from './webrtc/index.js';
6
+ export { WebRTCStore, DEFAULT_RELAYS, Peer, PeerSelector, PeerId, generateUuid, MAX_HTL, MSG_TYPE_REQUEST, MSG_TYPE_RESPONSE, FRAGMENT_SIZE, encodeRequest, encodeResponse, parseMessage, createRequest, createResponse, createFragmentResponse, hashToKey, verifyHash, generatePeerHTLConfig, decrementHTLWithPolicy, decrementHTL, shouldForwardHTL, peerPrincipal, normalizeDispatchConfig, buildHedgedWavePlan, syncSelectorPeers, shouldForward, type SignalingMessage, type WebRTCStoreConfig, type PeerStatus, type WebRTCStoreEvent, type WebRTCStoreEventHandler, type EventSigner, type EventEncrypter, type EventDecrypter, type GiftWrapper, type GiftUnwrapper, type SignedEvent, type PeerPool, type PeerClassifier, type PoolConfig, type SelectionStrategy, type RequestDispatchConfig, type PersistedPeerMetadata, type PeerMetadataSnapshot, type MeshStats, type WebRTCStats, type BandwidthSample, type DataRequest, type DataResponse, type PeerHTLConfig, type PendingRequest, } from './webrtc/index.js';
7
7
  export { createNostrRefResolver, createNostrRefResolver as createNostrRootResolver, type NostrRefResolverConfig, type NostrRefResolverConfig as NostrRootResolverConfig, type NostrEvent, type NostrFilter, type Nip19Like, type VisibilityCallbacks, type ParsedTreeVisibility, } from './resolver/index.js';
8
+ export { NostrEventStore, type StoredNostrEvent, type NostrEventManifest, type ListEventsOptions, } from './events.js';
9
+ export { encodeSignedNostrEventJson, decodeSignedNostrEventJson, storeSignedNostrEventSnapshot, readSignedNostrEventSnapshot, parseHashtreeRootEvent, type ParsedHashtreeRootEvent, type SnapshotTreeLike, type SnapshotTarget, } from './snapshot.js';
10
+ export { storeTreeEventSnapshot, readTreeEventSnapshot, fetchLatestTreeEventSnapshot, watchLatestTreeEventSnapshot, compareTreeEventSnapshots, isNewerTreeEventSnapshot, snapshotMatchesRootCid, resolveSnapshotRootCid, type TreeEventSnapshotInfo, type TreeEventSnapshotQuery, type FetchLatestTreeEventSnapshotConfig, type WatchTreeEventSnapshotsConfig, } from './treeEventSnapshots.js';
8
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,WAAW,EACX,cAAc,EACd,IAAI,EACJ,MAAM,EACN,YAAY,EACZ,OAAO,EACP,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EAEb,aAAa,EACb,cAAc,EACd,YAAY,EACZ,aAAa,EACb,cAAc,EACd,sBAAsB,EACtB,SAAS,EACT,UAAU,EACV,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,EAC5B,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,cAAc,GACpB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,sBAAsB,EAEtB,sBAAsB,IAAI,uBAAuB,EACjD,KAAK,sBAAsB,EAE3B,KAAK,sBAAsB,IAAI,uBAAuB,EACtD,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,GAC1B,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,WAAW,EACX,cAAc,EACd,IAAI,EACJ,YAAY,EACZ,MAAM,EACN,YAAY,EACZ,OAAO,EACP,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EAEb,aAAa,EACb,cAAc,EACd,YAAY,EACZ,aAAa,EACb,cAAc,EACd,sBAAsB,EACtB,SAAS,EACT,UAAU,EACV,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,uBAAuB,EACvB,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,EACb,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,EAC5B,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,cAAc,GACpB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,sBAAsB,EAEtB,sBAAsB,IAAI,uBAAuB,EACjD,KAAK,sBAAsB,EAE3B,KAAK,sBAAsB,IAAI,uBAAuB,EACtD,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,GAC1B,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,eAAe,EACf,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,GACvB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,6BAA6B,EAC7B,4BAA4B,EAC5B,sBAAsB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,EACrB,KAAK,cAAc,GACpB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,4BAA4B,EAC5B,4BAA4B,EAC5B,yBAAyB,EACzB,wBAAwB,EACxB,sBAAsB,EACtB,sBAAsB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,kCAAkC,EACvC,KAAK,6BAA6B,GACnC,MAAM,yBAAyB,CAAC"}
package/dist/index.js CHANGED
@@ -4,11 +4,15 @@
4
4
  * Provides WebRTC P2P storage and Nostr ref resolver
5
5
  */
6
6
  // WebRTC P2P store
7
- export { WebRTCStore, DEFAULT_RELAYS, Peer, PeerId, generateUuid, MAX_HTL, MSG_TYPE_REQUEST, MSG_TYPE_RESPONSE, FRAGMENT_SIZE,
7
+ export { WebRTCStore, DEFAULT_RELAYS, Peer, PeerSelector, PeerId, generateUuid, MAX_HTL, MSG_TYPE_REQUEST, MSG_TYPE_RESPONSE, FRAGMENT_SIZE,
8
8
  // Protocol functions
9
- encodeRequest, encodeResponse, parseMessage, createRequest, createResponse, createFragmentResponse, hashToKey, verifyHash, generatePeerHTLConfig, decrementHTL, shouldForward, } from './webrtc/index.js';
9
+ encodeRequest, encodeResponse, parseMessage, createRequest, createResponse, createFragmentResponse, hashToKey, verifyHash, generatePeerHTLConfig, decrementHTLWithPolicy, decrementHTL, shouldForwardHTL, peerPrincipal, normalizeDispatchConfig, buildHedgedWavePlan, syncSelectorPeers, shouldForward, } from './webrtc/index.js';
10
10
  // Ref resolvers
11
11
  export { createNostrRefResolver,
12
12
  // Legacy alias
13
13
  createNostrRefResolver as createNostrRootResolver, } from './resolver/index.js';
14
+ // Event storage and indexing
15
+ export { NostrEventStore, } from './events.js';
16
+ export { encodeSignedNostrEventJson, decodeSignedNostrEventJson, storeSignedNostrEventSnapshot, readSignedNostrEventSnapshot, parseHashtreeRootEvent, } from './snapshot.js';
17
+ export { storeTreeEventSnapshot, readTreeEventSnapshot, fetchLatestTreeEventSnapshot, watchLatestTreeEventSnapshot, compareTreeEventSnapshots, isNewerTreeEventSnapshot, snapshotMatchesRootCid, resolveSnapshotRootCid, } from './treeEventSnapshots.js';
14
18
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,mBAAmB;AACnB,OAAO,EACL,WAAW,EACX,cAAc,EACd,IAAI,EACJ,MAAM,EACN,YAAY,EACZ,OAAO,EACP,gBAAgB,EAChB,iBAAiB,EACjB,aAAa;AACb,qBAAqB;AACrB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,aAAa,EACb,cAAc,EACd,sBAAsB,EACtB,SAAS,EACT,UAAU,EACV,qBAAqB,EACrB,YAAY,EACZ,aAAa,GAqBd,MAAM,mBAAmB,CAAC;AAE3B,gBAAgB;AAChB,OAAO,EACL,sBAAsB;AACtB,eAAe;AACf,sBAAsB,IAAI,uBAAuB,GASlD,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,mBAAmB;AACnB,OAAO,EACL,WAAW,EACX,cAAc,EACd,IAAI,EACJ,YAAY,EACZ,MAAM,EACN,YAAY,EACZ,OAAO,EACP,gBAAgB,EAChB,iBAAiB,EACjB,aAAa;AACb,qBAAqB;AACrB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,aAAa,EACb,cAAc,EACd,sBAAsB,EACtB,SAAS,EACT,UAAU,EACV,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,uBAAuB,EACvB,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,GA0Bd,MAAM,mBAAmB,CAAC;AAE3B,gBAAgB;AAChB,OAAO,EACL,sBAAsB;AACtB,eAAe;AACf,sBAAsB,IAAI,uBAAuB,GASlD,MAAM,qBAAqB,CAAC;AAE7B,6BAA6B;AAC7B,OAAO,EACL,eAAe,GAIhB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,6BAA6B,EAC7B,4BAA4B,EAC5B,sBAAsB,GAIvB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,4BAA4B,EAC5B,4BAA4B,EAC5B,yBAAyB,EACzB,wBAAwB,EACxB,sBAAsB,EACtB,sBAAsB,GAKvB,MAAM,yBAAyB,CAAC"}
@@ -36,6 +36,8 @@ export interface NostrFilter {
36
36
  export interface ParsedTreeVisibility {
37
37
  hash: string;
38
38
  visibility: TreeVisibility;
39
+ /** All l-tags attached to the tree event */
40
+ labels?: string[];
39
41
  /** Plaintext key (for public trees) */
40
42
  key?: string;
41
43
  /** Encrypted key (for link-visible trees) - decrypt with link key */