applesauce-core 0.0.0-next-20250815164532 → 0.0.0-next-20250820215033

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 (78) hide show
  1. package/dist/helpers/__tests__/exports.test.js +4 -2
  2. package/dist/helpers/event.d.ts +1 -4
  3. package/dist/helpers/event.js +2 -10
  4. package/package.json +1 -1
  5. package/dist/event-store/database.d.ts +0 -67
  6. package/dist/event-store/database.js +0 -316
  7. package/dist/event-store/event-store.test.d.ts +0 -1
  8. package/dist/event-store/event-store.test.js +0 -74
  9. package/dist/helpers/__tests__/nip-19.test.d.ts +0 -1
  10. package/dist/helpers/__tests__/nip-19.test.js +0 -42
  11. package/dist/helpers/direct-messages.d.ts +0 -4
  12. package/dist/helpers/direct-messages.js +0 -5
  13. package/dist/helpers/file-metadata.test.d.ts +0 -1
  14. package/dist/helpers/file-metadata.test.js +0 -103
  15. package/dist/helpers/hidden-tags.test.d.ts +0 -1
  16. package/dist/helpers/hidden-tags.test.js +0 -29
  17. package/dist/helpers/legacy-direct-messages.d.ts +0 -8
  18. package/dist/helpers/legacy-direct-messages.js +0 -17
  19. package/dist/helpers/mailboxes.test.d.ts +0 -1
  20. package/dist/helpers/mailboxes.test.js +0 -81
  21. package/dist/helpers/nip-19.d.ts +0 -4
  22. package/dist/helpers/nip-19.js +0 -27
  23. package/dist/helpers/tags.test.d.ts +0 -1
  24. package/dist/helpers/tags.test.js +0 -16
  25. package/dist/helpers/threading.test.d.ts +0 -1
  26. package/dist/helpers/threading.test.js +0 -41
  27. package/dist/helpers/wrapped-direct-messages.d.ts +0 -6
  28. package/dist/helpers/wrapped-direct-messages.js +0 -11
  29. package/dist/observable/getValue.d.ts +0 -2
  30. package/dist/observable/getValue.js +0 -13
  31. package/dist/observable/share-behavior.d.ts +0 -2
  32. package/dist/observable/share-behavior.js +0 -7
  33. package/dist/observable/share-latest-value.d.ts +0 -6
  34. package/dist/observable/share-latest-value.js +0 -24
  35. package/dist/observable/stateful.d.ts +0 -10
  36. package/dist/observable/stateful.js +0 -60
  37. package/dist/observable/throttle.d.ts +0 -3
  38. package/dist/observable/throttle.js +0 -23
  39. package/dist/queries/blossom.d.ts +0 -2
  40. package/dist/queries/blossom.js +0 -10
  41. package/dist/queries/bookmarks.d.ts +0 -8
  42. package/dist/queries/bookmarks.js +0 -23
  43. package/dist/queries/channels.d.ts +0 -11
  44. package/dist/queries/channels.js +0 -73
  45. package/dist/queries/comments.d.ts +0 -4
  46. package/dist/queries/comments.js +0 -14
  47. package/dist/queries/contacts.d.ts +0 -3
  48. package/dist/queries/contacts.js +0 -12
  49. package/dist/queries/index.d.ts +0 -13
  50. package/dist/queries/index.js +0 -13
  51. package/dist/queries/mailboxes.d.ts +0 -6
  52. package/dist/queries/mailboxes.js +0 -13
  53. package/dist/queries/mutes.d.ts +0 -8
  54. package/dist/queries/mutes.js +0 -23
  55. package/dist/queries/pins.d.ts +0 -3
  56. package/dist/queries/pins.js +0 -12
  57. package/dist/queries/profile.d.ts +0 -4
  58. package/dist/queries/profile.js +0 -12
  59. package/dist/queries/reactions.d.ts +0 -4
  60. package/dist/queries/reactions.js +0 -19
  61. package/dist/queries/simple.d.ts +0 -16
  62. package/dist/queries/simple.js +0 -38
  63. package/dist/queries/thread.d.ts +0 -25
  64. package/dist/queries/thread.js +0 -92
  65. package/dist/queries/user-status.d.ts +0 -11
  66. package/dist/queries/user-status.js +0 -39
  67. package/dist/queries/zaps.d.ts +0 -5
  68. package/dist/queries/zaps.js +0 -21
  69. package/dist/query-store/__tests__/query-store.test.d.ts +0 -1
  70. package/dist/query-store/__tests__/query-store.test.js +0 -63
  71. package/dist/query-store/index.d.ts +0 -1
  72. package/dist/query-store/index.js +0 -1
  73. package/dist/query-store/query-store.d.ts +0 -53
  74. package/dist/query-store/query-store.js +0 -97
  75. package/dist/query-store/query-store.test.d.ts +0 -1
  76. package/dist/query-store/query-store.test.js +0 -33
  77. package/dist/utils/lru.d.ts +0 -32
  78. package/dist/utils/lru.js +0 -148
@@ -23,7 +23,7 @@ describe("exports", () => {
23
23
  "FromCacheSymbol",
24
24
  "GROUPS_LIST_KIND",
25
25
  "GROUP_MESSAGE_KIND",
26
- "GiftWrapEventSymbol",
26
+ "GiftWrapRumorSymbol",
27
27
  "GiftWrapSealSymbol",
28
28
  "GroupsHiddenSymbol",
29
29
  "GroupsPublicSymbol",
@@ -124,7 +124,7 @@ describe("exports", () => {
124
124
  "getExternalPointerFromTag",
125
125
  "getFileMetadata",
126
126
  "getFileMetadataFromImetaTag",
127
- "getGiftWrapEvent",
127
+ "getGiftWrapRumor",
128
128
  "getGiftWrapSeal",
129
129
  "getGroupPointerFromGroupTag",
130
130
  "getGroupPointerFromHTag",
@@ -175,6 +175,7 @@ describe("exports", () => {
175
175
  "getReplaceableIdentifier",
176
176
  "getReplaceableUID",
177
177
  "getReported",
178
+ "getSealRumor",
178
179
  "getSeenRelays",
179
180
  "getSha256FromURL",
180
181
  "getSharedAddressPointer",
@@ -230,6 +231,7 @@ describe("exports", () => {
230
231
  "isReplaceable",
231
232
  "isSafeRelayURL",
232
233
  "isSameURL",
234
+ "isSealLocked",
233
235
  "isSha256",
234
236
  "isStreamURL",
235
237
  "isTTag",
@@ -39,10 +39,7 @@ export declare function isFromCache(event: NostrEvent): boolean;
39
39
  export declare function getParentEventStore<T extends object>(event: T): IEventStore | undefined;
40
40
  /** Notifies the events parent store that an event has been updated */
41
41
  export declare function notifyEventUpdate(event: NostrEvent): void;
42
- /**
43
- * Returns the replaceable identifier for a replaceable event
44
- * @throws {Error} if the event is not addressable or missing the "d" tag
45
- */
42
+ /** Returns the replaceable identifier for a replaceable event */
46
43
  export declare function getReplaceableIdentifier(event: NostrEvent): string;
47
44
  /** Checks if an event is a NIP-70 protected event */
48
45
  export declare function isProtectedEvent(event: NostrEvent): boolean;
@@ -85,18 +85,10 @@ export function notifyEventUpdate(event) {
85
85
  if (eventStore)
86
86
  eventStore.update(event);
87
87
  }
88
- /**
89
- * Returns the replaceable identifier for a replaceable event
90
- * @throws {Error} if the event is not addressable or missing the "d" tag
91
- */
88
+ /** Returns the replaceable identifier for a replaceable event */
92
89
  export function getReplaceableIdentifier(event) {
93
- if (!isAddressableKind(event.kind))
94
- throw new Error("Event is not addressable");
95
90
  return getOrComputeCachedValue(event, ReplaceableIdentifierSymbol, () => {
96
- const d = event.tags.find((t) => t[0] === "d")?.[1];
97
- if (d === undefined)
98
- throw new Error("Event missing identifier");
99
- return d;
91
+ return event.tags.find((t) => t[0] === "d")?.[1] ?? "";
100
92
  });
101
93
  }
102
94
  /** Checks if an event is a NIP-70 protected event */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "applesauce-core",
3
- "version": "0.0.0-next-20250815164532",
3
+ "version": "0.0.0-next-20250820215033",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,67 +0,0 @@
1
- import { Filter, NostrEvent } from "nostr-tools";
2
- import { Subject } from "rxjs";
3
- import { LRU } from "../helpers/lru.js";
4
- /**
5
- * An in-memory database for nostr events
6
- * NOTE: does not handle replaceable events
7
- */
8
- export declare class Database {
9
- protected log: import("debug").Debugger;
10
- /** Indexes */
11
- protected kinds: Map<number, Set<import("nostr-tools").Event>>;
12
- protected authors: Map<string, Set<import("nostr-tools").Event>>;
13
- protected tags: LRU<Set<import("nostr-tools").Event>>;
14
- protected created_at: NostrEvent[];
15
- /** LRU cache of last events touched */
16
- events: LRU<import("nostr-tools").Event>;
17
- /** A sorted array of replaceable events by uid */
18
- protected replaceable: Map<string, import("nostr-tools").Event[]>;
19
- /** A stream of events inserted into the database */
20
- inserted: Subject<import("nostr-tools").Event>;
21
- /** A stream of events that have been updated */
22
- updated: Subject<import("nostr-tools").Event>;
23
- /** A stream of events removed from the database */
24
- removed: Subject<import("nostr-tools").Event>;
25
- /** A method thats called before a new event is inserted */
26
- onBeforeInsert?: (event: NostrEvent) => void;
27
- get size(): number;
28
- protected claims: WeakMap<import("nostr-tools").Event, any>;
29
- /** Index helper methods */
30
- protected getKindIndex(kind: number): Set<import("nostr-tools").Event>;
31
- protected getAuthorsIndex(author: string): Set<import("nostr-tools").Event>;
32
- protected getTagIndex(tagAndValue: string): Set<import("nostr-tools").Event>;
33
- /** Moves an event to the top of the LRU cache */
34
- touch(event: NostrEvent): void;
35
- /** Checks if the database contains an event without touching it */
36
- hasEvent(id: string): boolean;
37
- /** Gets a single event based on id */
38
- getEvent(id: string): NostrEvent | undefined;
39
- /** Checks if the database contains a replaceable event without touching it */
40
- hasReplaceable(kind: number, pubkey: string, d?: string): boolean;
41
- /** Gets an array of replaceable events */
42
- getReplaceable(kind: number, pubkey: string, d?: string): NostrEvent[] | undefined;
43
- /** Inserts an event into the database and notifies all subscriptions */
44
- addEvent(event: NostrEvent): NostrEvent;
45
- /** Inserts and event into the database and notifies all subscriptions that the event has updated */
46
- updateEvent(event: NostrEvent): NostrEvent;
47
- /** Removes an event from the database and notifies all subscriptions */
48
- removeEvent(eventOrId: string | NostrEvent): boolean;
49
- /** Sets the claim on the event and touches it */
50
- claimEvent(event: NostrEvent, claim: any): void;
51
- /** Checks if an event is claimed by anything */
52
- isClaimed(event: NostrEvent): boolean;
53
- /** Removes a claim from an event */
54
- removeClaim(event: NostrEvent, claim: any): void;
55
- /** Removes all claims on an event */
56
- clearClaim(event: NostrEvent): void;
57
- iterateAuthors(authors: Iterable<string>): Generator<NostrEvent>;
58
- iterateTag(tag: string, values: Iterable<string>): Generator<NostrEvent>;
59
- iterateKinds(kinds: Iterable<number>): Generator<NostrEvent>;
60
- iterateTime(since: number | undefined, until: number | undefined): Generator<NostrEvent>;
61
- iterateIds(ids: Iterable<string>): Generator<NostrEvent>;
62
- /** Returns all events that match the filter */
63
- getEventsForFilter(filter: Filter): Set<NostrEvent>;
64
- getEventsForFilters(filters: Filter[]): Set<NostrEvent>;
65
- /** Remove the oldest events that are not claimed */
66
- prune(limit?: number): number;
67
- }
@@ -1,316 +0,0 @@
1
- import { binarySearch, insertEventIntoDescendingList } from "nostr-tools/utils";
2
- import { Subject } from "rxjs";
3
- import { getEventUID, getIndexableTags, getReplaceableUID, isReplaceable } from "../helpers/event.js";
4
- import { INDEXABLE_TAGS } from "./common.js";
5
- import { logger } from "../logger.js";
6
- import { LRU } from "../helpers/lru.js";
7
- /**
8
- * An in-memory database for nostr events
9
- * NOTE: does not handle replaceable events
10
- */
11
- export class Database {
12
- log = logger.extend("Database");
13
- /** Indexes */
14
- kinds = new Map();
15
- authors = new Map();
16
- tags = new LRU();
17
- created_at = [];
18
- /** LRU cache of last events touched */
19
- events = new LRU();
20
- /** A sorted array of replaceable events by uid */
21
- replaceable = new Map();
22
- /** A stream of events inserted into the database */
23
- inserted = new Subject();
24
- /** A stream of events that have been updated */
25
- updated = new Subject();
26
- /** A stream of events removed from the database */
27
- removed = new Subject();
28
- /** A method thats called before a new event is inserted */
29
- onBeforeInsert;
30
- get size() {
31
- return this.events.size;
32
- }
33
- claims = new WeakMap();
34
- /** Index helper methods */
35
- getKindIndex(kind) {
36
- if (!this.kinds.has(kind))
37
- this.kinds.set(kind, new Set());
38
- return this.kinds.get(kind);
39
- }
40
- getAuthorsIndex(author) {
41
- if (!this.authors.has(author))
42
- this.authors.set(author, new Set());
43
- return this.authors.get(author);
44
- }
45
- getTagIndex(tagAndValue) {
46
- if (!this.tags.has(tagAndValue)) {
47
- // build new tag index from existing events
48
- const events = new Set();
49
- const ts = Date.now();
50
- for (const event of this.events.values()) {
51
- if (getIndexableTags(event).has(tagAndValue)) {
52
- events.add(event);
53
- }
54
- }
55
- const took = Date.now() - ts;
56
- if (took > 100)
57
- this.log(`Built index ${tagAndValue} took ${took}ms`);
58
- this.tags.set(tagAndValue, events);
59
- }
60
- return this.tags.get(tagAndValue);
61
- }
62
- /** Moves an event to the top of the LRU cache */
63
- touch(event) {
64
- this.events.set(event.id, event);
65
- }
66
- /** Checks if the database contains an event without touching it */
67
- hasEvent(id) {
68
- return this.events.has(id);
69
- }
70
- /** Gets a single event based on id */
71
- getEvent(id) {
72
- return this.events.get(id);
73
- }
74
- /** Checks if the database contains a replaceable event without touching it */
75
- hasReplaceable(kind, pubkey, d) {
76
- const events = this.replaceable.get(getReplaceableUID(kind, pubkey, d));
77
- return !!events && events.length > 0;
78
- }
79
- /** Gets an array of replaceable events */
80
- getReplaceable(kind, pubkey, d) {
81
- return this.replaceable.get(getReplaceableUID(kind, pubkey, d));
82
- }
83
- /** Inserts an event into the database and notifies all subscriptions */
84
- addEvent(event) {
85
- const id = event.id;
86
- const current = this.events.get(id);
87
- if (current)
88
- return current;
89
- this.onBeforeInsert?.(event);
90
- this.events.set(id, event);
91
- this.getKindIndex(event.kind).add(event);
92
- this.getAuthorsIndex(event.pubkey).add(event);
93
- for (const tag of getIndexableTags(event)) {
94
- if (this.tags.has(tag)) {
95
- this.getTagIndex(tag).add(event);
96
- }
97
- }
98
- // insert into time index
99
- insertEventIntoDescendingList(this.created_at, event);
100
- // insert into replaceable index
101
- if (isReplaceable(event.kind)) {
102
- const uid = getEventUID(event);
103
- let array = this.replaceable.get(uid);
104
- if (!this.replaceable.has(uid)) {
105
- // add an empty array if there is no array
106
- array = [];
107
- this.replaceable.set(uid, array);
108
- }
109
- // insert the event into the sorted array
110
- insertEventIntoDescendingList(array, event);
111
- }
112
- this.inserted.next(event);
113
- return event;
114
- }
115
- /** Inserts and event into the database and notifies all subscriptions that the event has updated */
116
- updateEvent(event) {
117
- const inserted = this.addEvent(event);
118
- this.updated.next(inserted);
119
- return inserted;
120
- }
121
- /** Removes an event from the database and notifies all subscriptions */
122
- removeEvent(eventOrId) {
123
- let event = typeof eventOrId === "string" ? this.events.get(eventOrId) : eventOrId;
124
- if (!event)
125
- throw new Error("Missing event");
126
- const id = event.id;
127
- // only remove events that are known
128
- if (!this.events.has(id))
129
- return false;
130
- this.getAuthorsIndex(event.pubkey).delete(event);
131
- this.getKindIndex(event.kind).delete(event);
132
- for (const tag of getIndexableTags(event)) {
133
- if (this.tags.has(tag)) {
134
- this.getTagIndex(tag).delete(event);
135
- }
136
- }
137
- // remove from created_at index
138
- const i = this.created_at.indexOf(event);
139
- this.created_at.splice(i, 1);
140
- this.events.delete(id);
141
- // remove from replaceable index
142
- if (isReplaceable(event.kind)) {
143
- const uid = getEventUID(event);
144
- const array = this.replaceable.get(uid);
145
- if (array && array.includes(event)) {
146
- const idx = array.indexOf(event);
147
- array.splice(idx, 1);
148
- }
149
- }
150
- // remove any claims this event has
151
- this.claims.delete(event);
152
- // notify subscribers this event was removed
153
- this.removed.next(event);
154
- return true;
155
- }
156
- /** Sets the claim on the event and touches it */
157
- claimEvent(event, claim) {
158
- if (!this.claims.has(event)) {
159
- this.claims.set(event, claim);
160
- }
161
- // always touch event
162
- this.touch(event);
163
- }
164
- /** Checks if an event is claimed by anything */
165
- isClaimed(event) {
166
- return this.claims.has(event);
167
- }
168
- /** Removes a claim from an event */
169
- removeClaim(event, claim) {
170
- const current = this.claims.get(event);
171
- if (current === claim)
172
- this.claims.delete(event);
173
- }
174
- /** Removes all claims on an event */
175
- clearClaim(event) {
176
- this.claims.delete(event);
177
- }
178
- *iterateAuthors(authors) {
179
- for (const author of authors) {
180
- const events = this.authors.get(author);
181
- if (events) {
182
- for (const event of events)
183
- yield event;
184
- }
185
- }
186
- }
187
- *iterateTag(tag, values) {
188
- for (const value of values) {
189
- const events = this.getTagIndex(tag + ":" + value);
190
- if (events) {
191
- for (const event of events)
192
- yield event;
193
- }
194
- }
195
- }
196
- *iterateKinds(kinds) {
197
- for (const kind of kinds) {
198
- const events = this.kinds.get(kind);
199
- if (events) {
200
- for (const event of events)
201
- yield event;
202
- }
203
- }
204
- }
205
- *iterateTime(since, until) {
206
- let untilIndex = 0;
207
- let sinceIndex = this.created_at.length - 1;
208
- let start = until
209
- ? binarySearch(this.created_at, (mid) => {
210
- return mid.created_at - until;
211
- })
212
- : undefined;
213
- if (start)
214
- untilIndex = start[0];
215
- const end = since
216
- ? binarySearch(this.created_at, (mid) => {
217
- return mid.created_at - since;
218
- })
219
- : undefined;
220
- if (end)
221
- sinceIndex = end[0];
222
- for (let i = untilIndex; i < sinceIndex; i++) {
223
- yield this.created_at[i];
224
- }
225
- }
226
- *iterateIds(ids) {
227
- for (const id of ids) {
228
- if (this.events.has(id))
229
- yield this.events.get(id);
230
- }
231
- }
232
- /** Returns all events that match the filter */
233
- getEventsForFilter(filter) {
234
- // search is not supported, return an empty set
235
- if (filter.search)
236
- return new Set();
237
- let first = true;
238
- let events = new Set();
239
- const and = (iterable) => {
240
- const set = iterable instanceof Set ? iterable : new Set(iterable);
241
- if (first) {
242
- events = set;
243
- first = false;
244
- }
245
- else {
246
- for (const event of events) {
247
- if (!set.has(event))
248
- events.delete(event);
249
- }
250
- }
251
- return events;
252
- };
253
- if (filter.ids)
254
- and(this.iterateIds(filter.ids));
255
- let time = null;
256
- // query for time first if since is set
257
- if (filter.since !== undefined) {
258
- time = Array.from(this.iterateTime(filter.since, filter.until));
259
- and(time);
260
- }
261
- for (const t of INDEXABLE_TAGS) {
262
- const key = `#${t}`;
263
- const values = filter[key];
264
- if (values?.length)
265
- and(this.iterateTag(t, values));
266
- }
267
- if (filter.authors)
268
- and(this.iterateAuthors(filter.authors));
269
- if (filter.kinds)
270
- and(this.iterateKinds(filter.kinds));
271
- // query for time last if only until is set
272
- if (filter.since === undefined && filter.until !== undefined) {
273
- time = Array.from(this.iterateTime(filter.since, filter.until));
274
- and(time);
275
- }
276
- // if the filter queried on time and has a limit. truncate the events now
277
- if (filter.limit && time) {
278
- const limited = new Set();
279
- for (const event of time) {
280
- if (limited.size >= filter.limit)
281
- break;
282
- if (events.has(event))
283
- limited.add(event);
284
- }
285
- return limited;
286
- }
287
- return events;
288
- }
289
- getEventsForFilters(filters) {
290
- if (filters.length === 0)
291
- throw new Error("No Filters");
292
- let events = new Set();
293
- for (const filter of filters) {
294
- const filtered = this.getEventsForFilter(filter);
295
- for (const event of filtered)
296
- events.add(event);
297
- }
298
- return events;
299
- }
300
- /** Remove the oldest events that are not claimed */
301
- prune(limit = 1000) {
302
- let removed = 0;
303
- let cursor = this.events.first;
304
- while (cursor) {
305
- const event = cursor.value;
306
- if (!this.isClaimed(event)) {
307
- this.removeEvent(event);
308
- removed++;
309
- if (removed >= limit)
310
- break;
311
- }
312
- cursor = cursor.next;
313
- }
314
- return removed;
315
- }
316
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,74 +0,0 @@
1
- import { beforeEach, describe, expect, it, vi } from "vitest";
2
- import { kinds } from "nostr-tools";
3
- import { EventStore } from "./event-store.js";
4
- import { addSeenRelay, getSeenRelays } from "../helpers/relays.js";
5
- let eventStore;
6
- beforeEach(() => {
7
- eventStore = new EventStore();
8
- });
9
- const event = {
10
- content: '{"name":"hzrd149","picture":"https://cdn.hzrd149.com/5ed3fe5df09a74e8c126831eac999364f9eb7624e2b86d521521b8021de20bdc.png","about":"JavaScript developer working on some nostr stuff\\n- noStrudel https://nostrudel.ninja/ \\n- Blossom https://github.com/hzrd149/blossom \\n- Applesauce https://hzrd149.github.io/applesauce/","website":"https://hzrd149.com","nip05":"_@hzrd149.com","lud16":"hzrd1499@minibits.cash","pubkey":"266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5","display_name":"hzrd149","displayName":"hzrd149","banner":""}',
11
- created_at: 1738362529,
12
- id: "e9df8d5898c4ccfbd21fcd59f3f48abb3ff0ab7259b19570e2f1756de1e9306b",
13
- kind: 0,
14
- pubkey: "266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5",
15
- sig: "465a47b93626a587bf81dadc2b306b8f713a62db31d6ce1533198e9ae1e665a6eaf376a03250bf9ffbb02eb9059c8eafbd37ae1092d05d215757575bd8357586",
16
- tags: [],
17
- };
18
- describe("add", () => {
19
- it("should return original event in case of duplicates", () => {
20
- const a = { ...event };
21
- expect(eventStore.add(a)).toBe(a);
22
- const b = { ...event };
23
- expect(eventStore.add(b)).toBe(a);
24
- const c = { ...event };
25
- expect(eventStore.add(c)).toBe(a);
26
- });
27
- it("should merge seen relays on duplicate events", () => {
28
- const a = { ...event };
29
- addSeenRelay(a, "wss://relay.a.com");
30
- eventStore.add(a);
31
- const b = { ...event };
32
- addSeenRelay(b, "wss://relay.b.com");
33
- eventStore.add(b);
34
- expect(eventStore.getEvent(event.id)).toBeDefined();
35
- expect([...getSeenRelays(eventStore.getEvent(event.id))]).toEqual(expect.arrayContaining(["wss://relay.a.com", "wss://relay.b.com"]));
36
- });
37
- it("should ignore deleted events", () => {
38
- const deleteEvent = {
39
- id: "delete event id",
40
- kind: kinds.EventDeletion,
41
- created_at: event.created_at + 100,
42
- pubkey: event.pubkey,
43
- tags: [["e", event.id]],
44
- sig: "this should be ignored for the test",
45
- content: "test",
46
- };
47
- // add delete event first
48
- eventStore.add(deleteEvent);
49
- // now event should be ignored
50
- eventStore.add(event);
51
- expect(eventStore.getEvent(event.id)).toBeUndefined();
52
- });
53
- });
54
- describe("verifyEvent", () => {
55
- it("should be called for all events added", () => {
56
- const verifyEvent = vi.fn().mockReturnValue(true);
57
- eventStore.verifyEvent = verifyEvent;
58
- eventStore.add(event);
59
- expect(verifyEvent).toHaveBeenCalledWith(event);
60
- });
61
- it("should not be called for duplicate events", () => {
62
- const verifyEvent = vi.fn().mockReturnValue(true);
63
- eventStore.verifyEvent = verifyEvent;
64
- const a = { ...event };
65
- eventStore.add(a);
66
- expect(verifyEvent).toHaveBeenCalledWith(a);
67
- const b = { ...event };
68
- eventStore.add(b);
69
- expect(verifyEvent).toHaveBeenCalledTimes(1);
70
- const c = { ...event };
71
- eventStore.add(c);
72
- expect(verifyEvent).toHaveBeenCalledTimes(1);
73
- });
74
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,42 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { bytesToHex } from "@noble/hashes/utils";
3
- import { normalizeToPubkey, normalizeToSecretKey } from "../nip-19.js";
4
- describe("normalizeToPubkey", () => {
5
- it("should get pubkey from npub", () => {
6
- expect(normalizeToPubkey("npub1ye5ptcxfyyxl5vjvdjar2ua3f0hynkjzpx552mu5snj3qmx5pzjscpknpr")).toEqual("266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5");
7
- });
8
- it("should get pubkey from nprofile", () => {
9
- expect(normalizeToPubkey("nprofile1qyw8wumn8ghj7umpw3jkcmrfw3jju6r6wfjrzdpe9e3k7mf0qyf8wumn8ghj7mn0wd68yat99e3k7mf0qqszv6q4uryjzr06xfxxew34wwc5hmjfmfpqn229d72gfegsdn2q3fg5g7lja")).toEqual("266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5");
10
- });
11
- it("should return hex pubkey", () => {
12
- expect(normalizeToPubkey("266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5")).toEqual("266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5");
13
- });
14
- it("should throw on invalid hex pubkey", () => {
15
- expect(() => {
16
- normalizeToPubkey("5028372");
17
- }).toThrow();
18
- });
19
- it("should throw on invalid string", () => {
20
- expect(() => {
21
- normalizeToPubkey("testing");
22
- }).toThrow();
23
- });
24
- });
25
- describe("normalizeToSecretKey", () => {
26
- it("should get secret key from nsec", () => {
27
- expect(bytesToHex(normalizeToSecretKey("nsec1xe7znq745x5n68566l32ru72aajz3pk2cys9lnf3tuexvkw0dldsj8v2lm"))).toEqual("367c2983d5a1a93d1e9ad7e2a1f3caef642886cac1205fcd315f326659cf6fdb");
28
- });
29
- it("should get secret key from raw hex", () => {
30
- expect(bytesToHex(normalizeToSecretKey("367c2983d5a1a93d1e9ad7e2a1f3caef642886cac1205fcd315f326659cf6fdb"))).toEqual("367c2983d5a1a93d1e9ad7e2a1f3caef642886cac1205fcd315f326659cf6fdb");
31
- });
32
- it("should throw on invalid hex key", () => {
33
- expect(() => {
34
- normalizeToSecretKey("209573290");
35
- }).toThrow();
36
- });
37
- it("should throw on npub", () => {
38
- expect(() => {
39
- normalizeToSecretKey("npub1ye5ptcxfyyxl5vjvdjar2ua3f0hynkjzpx552mu5snj3qmx5pzjscpknpr");
40
- }).toThrow();
41
- });
42
- });
@@ -1,4 +0,0 @@
1
- import { NostrEvent } from "nostr-tools";
2
- import { HiddenContentSigner } from "./hidden-content.js";
3
- /** Returns the decrypted content of a direct message */
4
- export declare function decryptDirectMessage(message: NostrEvent, signer: HiddenContentSigner): Promise<string>;
@@ -1,5 +0,0 @@
1
- import { getHiddenContent, unlockHiddenContent } from "./hidden-content.js";
2
- /** Returns the decrypted content of a direct message */
3
- export async function decryptDirectMessage(message, signer) {
4
- return getHiddenContent(message) || (await unlockHiddenContent(message, signer));
5
- }
@@ -1 +0,0 @@
1
- export {};