applesauce-core 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/README.md +7 -13
  2. package/dist/event-store/{database.d.ts → event-set.d.ts} +35 -20
  3. package/dist/event-store/{database.js → event-set.js} +91 -60
  4. package/dist/event-store/event-store.d.ts +64 -25
  5. package/dist/event-store/event-store.js +163 -206
  6. package/dist/event-store/index.d.ts +1 -1
  7. package/dist/event-store/index.js +1 -1
  8. package/dist/event-store/interface.d.ts +71 -13
  9. package/dist/helpers/app-handlers.d.ts +23 -0
  10. package/dist/helpers/app-handlers.js +68 -0
  11. package/dist/helpers/article.d.ts +9 -0
  12. package/dist/helpers/article.js +21 -0
  13. package/dist/helpers/blossom.d.ts +2 -0
  14. package/dist/helpers/blossom.js +18 -0
  15. package/dist/helpers/bolt11.d.ts +1 -0
  16. package/dist/helpers/bolt11.js +2 -0
  17. package/dist/helpers/bookmarks.js +1 -2
  18. package/dist/helpers/emoji.d.ts +10 -2
  19. package/dist/helpers/emoji.js +21 -3
  20. package/dist/helpers/encrypted-content-cache.d.ts +15 -0
  21. package/dist/helpers/encrypted-content-cache.js +125 -0
  22. package/dist/helpers/encrypted-content.d.ts +48 -0
  23. package/dist/helpers/encrypted-content.js +65 -0
  24. package/dist/helpers/encryption.d.ts +5 -0
  25. package/dist/helpers/encryption.js +10 -0
  26. package/dist/helpers/event.d.ts +4 -1
  27. package/dist/helpers/event.js +13 -3
  28. package/dist/helpers/expiration.d.ts +6 -0
  29. package/dist/helpers/expiration.js +16 -0
  30. package/dist/helpers/filter.d.ts +1 -3
  31. package/dist/helpers/filter.js +1 -3
  32. package/dist/helpers/gift-wraps.d.ts +17 -5
  33. package/dist/helpers/gift-wraps.js +65 -27
  34. package/dist/helpers/groups.d.ts +5 -0
  35. package/dist/helpers/groups.js +12 -2
  36. package/dist/helpers/hidden-content.d.ts +27 -32
  37. package/dist/helpers/hidden-content.js +35 -65
  38. package/dist/helpers/hidden-tags.d.ts +23 -4
  39. package/dist/helpers/hidden-tags.js +39 -4
  40. package/dist/helpers/index.d.ts +11 -1
  41. package/dist/helpers/index.js +11 -1
  42. package/dist/helpers/legacy-messages.d.ts +21 -0
  43. package/dist/helpers/legacy-messages.js +39 -0
  44. package/dist/helpers/lists.d.ts +1 -1
  45. package/dist/helpers/lists.js +2 -2
  46. package/dist/helpers/messages.d.ts +11 -0
  47. package/dist/helpers/messages.js +19 -0
  48. package/dist/helpers/mutes.js +1 -1
  49. package/dist/helpers/pointers.d.ts +33 -9
  50. package/dist/helpers/pointers.js +80 -44
  51. package/dist/helpers/profile.d.ts +10 -2
  52. package/dist/helpers/profile.js +33 -4
  53. package/dist/helpers/reactions.d.ts +8 -0
  54. package/dist/helpers/reactions.js +56 -0
  55. package/dist/helpers/reports.d.ts +28 -0
  56. package/dist/helpers/reports.js +38 -0
  57. package/dist/helpers/share.d.ts +10 -1
  58. package/dist/helpers/share.js +22 -8
  59. package/dist/helpers/url.d.ts +4 -0
  60. package/dist/helpers/url.js +20 -0
  61. package/dist/helpers/user-status.js +2 -1
  62. package/dist/helpers/wrapped-messages.d.ts +23 -0
  63. package/dist/helpers/wrapped-messages.js +38 -0
  64. package/dist/helpers/zap.d.ts +8 -5
  65. package/dist/helpers/zap.js +11 -6
  66. package/dist/index.d.ts +2 -2
  67. package/dist/index.js +2 -2
  68. package/dist/models/blossom.d.ts +3 -0
  69. package/dist/models/blossom.js +8 -0
  70. package/dist/models/bookmarks.d.ts +8 -0
  71. package/dist/{queries → models}/bookmarks.js +9 -9
  72. package/dist/models/channels.d.ts +11 -0
  73. package/dist/{queries → models}/channels.js +9 -9
  74. package/dist/models/comments.d.ts +4 -0
  75. package/dist/models/comments.js +11 -0
  76. package/dist/models/common.d.ts +16 -0
  77. package/dist/models/common.js +176 -0
  78. package/dist/models/contacts.d.ts +8 -0
  79. package/dist/{queries → models}/contacts.js +10 -10
  80. package/dist/models/encrypted-content.d.ts +4 -0
  81. package/dist/models/encrypted-content.js +11 -0
  82. package/dist/models/gift-wrap.d.ts +7 -0
  83. package/dist/models/gift-wrap.js +20 -0
  84. package/dist/{queries → models}/index.d.ts +6 -2
  85. package/dist/{queries → models}/index.js +6 -2
  86. package/dist/models/legacy-messages.d.ts +8 -0
  87. package/dist/models/legacy-messages.js +29 -0
  88. package/dist/models/mailboxes.d.ts +6 -0
  89. package/dist/{queries → models}/mailboxes.js +2 -2
  90. package/dist/models/mutes.d.ts +8 -0
  91. package/dist/{queries → models}/mutes.js +9 -9
  92. package/dist/models/pins.d.ts +4 -0
  93. package/dist/{queries → models}/pins.js +3 -3
  94. package/dist/models/profile.d.ts +4 -0
  95. package/dist/models/profile.js +14 -0
  96. package/dist/models/reactions.d.ts +4 -0
  97. package/dist/{queries → models}/reactions.js +2 -2
  98. package/dist/models/relays.d.ts +27 -0
  99. package/dist/{queries → models}/relays.js +13 -13
  100. package/dist/{queries → models}/thread.d.ts +6 -5
  101. package/dist/{queries → models}/thread.js +4 -3
  102. package/dist/models/user-status.d.ts +11 -0
  103. package/dist/{queries → models}/user-status.js +5 -5
  104. package/dist/models/wrapped-messages.d.ts +25 -0
  105. package/dist/models/wrapped-messages.js +61 -0
  106. package/dist/models/zaps.d.ts +9 -0
  107. package/dist/{queries → models}/zaps.js +11 -3
  108. package/dist/observable/claim-events.d.ts +3 -3
  109. package/dist/observable/claim-events.js +4 -4
  110. package/dist/observable/claim-latest.d.ts +3 -3
  111. package/dist/observable/claim-latest.js +4 -4
  112. package/dist/observable/index.d.ts +5 -1
  113. package/dist/observable/index.js +6 -1
  114. package/dist/observable/map-events-timeline.d.ts +7 -0
  115. package/dist/observable/map-events-timeline.js +9 -0
  116. package/dist/observable/map-events-to-store.d.ts +5 -0
  117. package/dist/observable/map-events-to-store.js +12 -0
  118. package/dist/observable/simple-timeout.d.ts +1 -0
  119. package/dist/observable/simple-timeout.js +1 -0
  120. package/dist/observable/watch-event-updates.d.ts +7 -0
  121. package/dist/observable/watch-event-updates.js +25 -0
  122. package/package.json +11 -16
  123. package/dist/__tests__/fixtures.d.ts +0 -8
  124. package/dist/__tests__/fixtures.js +0 -20
  125. package/dist/event-store/__tests__/event-store.test.d.ts +0 -1
  126. package/dist/event-store/__tests__/event-store.test.js +0 -354
  127. package/dist/helpers/__tests__/blossom.test.d.ts +0 -1
  128. package/dist/helpers/__tests__/blossom.test.js +0 -13
  129. package/dist/helpers/__tests__/bookmarks.test.d.ts +0 -1
  130. package/dist/helpers/__tests__/bookmarks.test.js +0 -88
  131. package/dist/helpers/__tests__/comment.test.d.ts +0 -1
  132. package/dist/helpers/__tests__/comment.test.js +0 -249
  133. package/dist/helpers/__tests__/contacts.test.d.ts +0 -1
  134. package/dist/helpers/__tests__/contacts.test.js +0 -34
  135. package/dist/helpers/__tests__/emoji.test.d.ts +0 -1
  136. package/dist/helpers/__tests__/emoji.test.js +0 -15
  137. package/dist/helpers/__tests__/event.test.d.ts +0 -1
  138. package/dist/helpers/__tests__/event.test.js +0 -36
  139. package/dist/helpers/__tests__/events.test.d.ts +0 -1
  140. package/dist/helpers/__tests__/events.test.js +0 -32
  141. package/dist/helpers/__tests__/file-metadata.test.d.ts +0 -1
  142. package/dist/helpers/__tests__/file-metadata.test.js +0 -103
  143. package/dist/helpers/__tests__/hidden-tags.test.d.ts +0 -1
  144. package/dist/helpers/__tests__/hidden-tags.test.js +0 -29
  145. package/dist/helpers/__tests__/mailboxes.test.d.ts +0 -1
  146. package/dist/helpers/__tests__/mailboxes.test.js +0 -81
  147. package/dist/helpers/__tests__/mutes.test.d.ts +0 -1
  148. package/dist/helpers/__tests__/mutes.test.js +0 -55
  149. package/dist/helpers/__tests__/nip-19.test.d.ts +0 -1
  150. package/dist/helpers/__tests__/nip-19.test.js +0 -42
  151. package/dist/helpers/__tests__/relays.test.d.ts +0 -1
  152. package/dist/helpers/__tests__/relays.test.js +0 -21
  153. package/dist/helpers/__tests__/tags.test.d.ts +0 -1
  154. package/dist/helpers/__tests__/tags.test.js +0 -24
  155. package/dist/helpers/__tests__/threading.test.d.ts +0 -1
  156. package/dist/helpers/__tests__/threading.test.js +0 -41
  157. package/dist/helpers/direct-messages.d.ts +0 -4
  158. package/dist/helpers/direct-messages.js +0 -5
  159. package/dist/helpers/nip-19.d.ts +0 -18
  160. package/dist/helpers/nip-19.js +0 -56
  161. package/dist/observable/__tests__/claim-events.test.d.ts +0 -1
  162. package/dist/observable/__tests__/claim-events.test.js +0 -23
  163. package/dist/observable/__tests__/claim-latest.test.d.ts +0 -1
  164. package/dist/observable/__tests__/claim-latest.test.js +0 -37
  165. package/dist/observable/__tests__/listen-latest-updates.test.d.ts +0 -1
  166. package/dist/observable/__tests__/listen-latest-updates.test.js +0 -55
  167. package/dist/observable/__tests__/simple-timeout.test.d.ts +0 -1
  168. package/dist/observable/__tests__/simple-timeout.test.js +0 -34
  169. package/dist/observable/listen-latest-updates.d.ts +0 -5
  170. package/dist/observable/listen-latest-updates.js +0 -12
  171. package/dist/queries/blossom.d.ts +0 -2
  172. package/dist/queries/blossom.js +0 -5
  173. package/dist/queries/bookmarks.d.ts +0 -8
  174. package/dist/queries/channels.d.ts +0 -11
  175. package/dist/queries/comments.d.ts +0 -4
  176. package/dist/queries/comments.js +0 -11
  177. package/dist/queries/contacts.d.ts +0 -8
  178. package/dist/queries/mailboxes.d.ts +0 -6
  179. package/dist/queries/mutes.d.ts +0 -8
  180. package/dist/queries/pins.d.ts +0 -4
  181. package/dist/queries/profile.d.ts +0 -4
  182. package/dist/queries/profile.js +0 -7
  183. package/dist/queries/reactions.d.ts +0 -4
  184. package/dist/queries/relays.d.ts +0 -27
  185. package/dist/queries/simple.d.ts +0 -16
  186. package/dist/queries/simple.js +0 -21
  187. package/dist/queries/user-status.d.ts +0 -11
  188. package/dist/queries/zaps.d.ts +0 -5
  189. package/dist/query-store/__tests__/query-store.test.d.ts +0 -1
  190. package/dist/query-store/__tests__/query-store.test.js +0 -63
  191. package/dist/query-store/index.d.ts +0 -1
  192. package/dist/query-store/index.js +0 -1
  193. package/dist/query-store/query-store.d.ts +0 -54
  194. package/dist/query-store/query-store.js +0 -102
@@ -1,49 +1,87 @@
1
1
  import { verifyEvent } from "nostr-tools";
2
- import { getHiddenContent, isHiddenContentLocked, unlockHiddenContent } from "./hidden-content.js";
3
2
  import { getOrComputeCachedValue } from "./cache.js";
3
+ import { getEncryptedContent, isEncryptedContentLocked, lockEncryptedContent, unlockEncryptedContent, } from "./encrypted-content.js";
4
+ import { isEvent, notifyEventUpdate } from "./event.js";
4
5
  export const GiftWrapSealSymbol = Symbol.for("gift-wrap-seal");
5
- export const GiftWrapEventSymbol = Symbol.for("gift-wrap-event");
6
+ export const GiftWrapRumorSymbol = Symbol.for("gift-wrap-rumor");
6
7
  /** Returns the unsigned seal event in a gift-wrap event */
7
8
  export function getGiftWrapSeal(gift) {
8
- if (isHiddenContentLocked(gift))
9
+ if (isEncryptedContentLocked(gift))
10
+ return undefined;
11
+ const plaintext = getEncryptedContent(gift);
12
+ if (!plaintext)
9
13
  return undefined;
10
14
  return getOrComputeCachedValue(gift, GiftWrapSealSymbol, () => {
11
- const plaintext = getHiddenContent(gift);
12
- if (!plaintext)
13
- throw new Error("Gift-wrap is locked");
14
15
  const seal = JSON.parse(plaintext);
15
- // verify the seal is valid
16
16
  verifyEvent(seal);
17
17
  return seal;
18
18
  });
19
19
  }
20
- /** Returns the unsigned event in the gift-wrap seal */
21
- export function getGiftWrapEvent(gift) {
22
- if (isHiddenContentLocked(gift))
20
+ /** Checks if a seal event is locked */
21
+ export function isSealLocked(seal) {
22
+ return isEncryptedContentLocked(seal);
23
+ }
24
+ /** Gets the rumor from a seal event */
25
+ export function getSealRumor(seal) {
26
+ if (isEncryptedContentLocked(seal))
23
27
  return undefined;
24
- return getOrComputeCachedValue(gift, GiftWrapEventSymbol, () => {
25
- const seal = getGiftWrapSeal(gift);
26
- if (!seal)
27
- throw new Error("Gift is locked");
28
- const plaintext = getHiddenContent(seal);
29
- if (!plaintext)
30
- throw new Error("Gift-wrap seal is locked");
31
- const event = JSON.parse(plaintext);
32
- if (event.pubkey !== seal.pubkey)
33
- throw new Error("Seal author does not match content");
34
- return event;
28
+ const plaintext = getEncryptedContent(seal);
29
+ if (!plaintext)
30
+ return undefined;
31
+ return getOrComputeCachedValue(seal, GiftWrapRumorSymbol, () => {
32
+ const rumor = JSON.parse(plaintext);
33
+ if (rumor.pubkey !== seal.pubkey)
34
+ throw new Error("Seal author does not match rumor author");
35
+ return rumor;
35
36
  });
36
37
  }
38
+ /**
39
+ * Returns the unsigned event in the gift-wrap seal
40
+ * @throws {Error} If the author of the rumor event does not match the author of the seal
41
+ */
42
+ export function getGiftWrapRumor(gift) {
43
+ if (isEncryptedContentLocked(gift))
44
+ return undefined;
45
+ const seal = getGiftWrapSeal(gift);
46
+ if (!seal || isSealLocked(seal))
47
+ return undefined;
48
+ return getOrComputeCachedValue(gift, GiftWrapRumorSymbol, () => getSealRumor(seal));
49
+ }
37
50
  /** Returns if a gift-wrap event or gift-wrap seal is locked */
38
51
  export function isGiftWrapLocked(gift) {
39
- return isHiddenContentLocked(gift) || isHiddenContentLocked(getGiftWrapSeal(gift));
52
+ if (isEncryptedContentLocked(gift))
53
+ return true;
54
+ else {
55
+ const seal = getGiftWrapSeal(gift);
56
+ if (!seal || isEncryptedContentLocked(seal))
57
+ return true;
58
+ else
59
+ return false;
60
+ }
40
61
  }
41
62
  /** Unlocks and returns the unsigned seal event in a gift-wrap */
42
63
  export async function unlockGiftWrap(gift, signer) {
43
- if (isHiddenContentLocked(gift))
44
- await unlockHiddenContent(gift, signer);
64
+ // First unlock the gift-wrap event
65
+ if (isEncryptedContentLocked(gift))
66
+ await unlockEncryptedContent(gift, gift.pubkey, signer);
67
+ // Next get and unlock the seal
45
68
  const seal = getGiftWrapSeal(gift);
46
- if (isHiddenContentLocked(seal))
47
- await unlockHiddenContent(seal, signer);
48
- return getGiftWrapEvent(gift);
69
+ if (!seal)
70
+ throw new Error("Failed to read seal in gift wrap");
71
+ if (isEncryptedContentLocked(seal))
72
+ await unlockEncryptedContent(seal, seal.pubkey, signer);
73
+ // Finally get the rumor event
74
+ const rumor = getGiftWrapRumor(gift);
75
+ if (!rumor)
76
+ throw new Error("Failed to read rumor in gift wrap");
77
+ // if the event has been added to an event store, notify it
78
+ if (isEvent(gift))
79
+ notifyEventUpdate(gift);
80
+ return rumor;
81
+ }
82
+ /** Locks a gift-wrap event by removing its cached seal and encrypted content */
83
+ export function lockGiftWrap(gift) {
84
+ Reflect.deleteProperty(gift, GiftWrapSealSymbol);
85
+ Reflect.deleteProperty(gift, GiftWrapRumorSymbol);
86
+ lockEncryptedContent(gift);
49
87
  }
@@ -3,8 +3,11 @@ export declare const GROUPS_LIST_KIND = 10009;
3
3
  export declare const GROUP_MESSAGE_KIND = 9;
4
4
  /** NIP-29 group pointer */
5
5
  export type GroupPointer = {
6
+ /** the id of the group */
6
7
  id: string;
8
+ /** The url to the relay with wss:// or ws:// protocol */
7
9
  relay: string;
10
+ /** The name of the group */
8
11
  name?: string;
9
12
  };
10
13
  /**
@@ -16,6 +19,8 @@ export declare function decodeGroupPointer(str: string): GroupPointer;
16
19
  export declare function encodeGroupPointer(pointer: GroupPointer): string;
17
20
  export declare const GroupsPublicSymbol: unique symbol;
18
21
  export declare const GroupsHiddenSymbol: unique symbol;
22
+ /** gets a {@link GroupPointer} from a "h" tag if it has a relay hint */
23
+ export declare function getGroupPointerFromHTag(tag: string[]): GroupPointer | undefined;
19
24
  /** gets a {@link GroupPointer} from a "group" tag */
20
25
  export declare function getGroupPointerFromGroupTag(tag: string[]): GroupPointer;
21
26
  /** Returns all the public groups from a k:10009 list */
@@ -1,6 +1,6 @@
1
1
  import { getOrComputeCachedValue } from "./cache.js";
2
- import { processTags } from "./tags.js";
3
2
  import { getHiddenTags } from "./hidden-tags.js";
3
+ import { processTags } from "./tags.js";
4
4
  export const GROUPS_LIST_KIND = 10009;
5
5
  export const GROUP_MESSAGE_KIND = 9;
6
6
  /**
@@ -8,9 +8,12 @@ export const GROUP_MESSAGE_KIND = 9;
8
8
  * @throws
9
9
  */
10
10
  export function decodeGroupPointer(str) {
11
- const [relay, id] = str.split("'");
11
+ let [relay, id] = str.split("'");
12
12
  if (!relay)
13
13
  throw new Error("Group pointer missing relay");
14
+ // Prepend wss:// if missing
15
+ if (!relay.match(/^wss?:/))
16
+ relay = `wss://${relay}`;
14
17
  return { relay, id: id || "_" };
15
18
  }
16
19
  /** Converts a group pointer into a group identifier */
@@ -20,6 +23,13 @@ export function encodeGroupPointer(pointer) {
20
23
  }
21
24
  export const GroupsPublicSymbol = Symbol.for("groups-public");
22
25
  export const GroupsHiddenSymbol = Symbol.for("groups-hidden");
26
+ /** gets a {@link GroupPointer} from a "h" tag if it has a relay hint */
27
+ export function getGroupPointerFromHTag(tag) {
28
+ const [_, id, relay] = tag;
29
+ if (!id || !relay)
30
+ return undefined;
31
+ return { id, relay };
32
+ }
23
33
  /** gets a {@link GroupPointer} from a "group" tag */
24
34
  export function getGroupPointerFromGroupTag(tag) {
25
35
  const [_, id, relay, name] = tag;
@@ -1,18 +1,12 @@
1
- export declare const HiddenContentSymbol: unique symbol;
2
- export type HiddenContentSigner = {
3
- nip04?: {
4
- encrypt: (pubkey: string, plaintext: string) => Promise<string> | string;
5
- decrypt: (pubkey: string, ciphertext: string) => Promise<string> | string;
6
- };
7
- nip44?: {
8
- encrypt: (pubkey: string, plaintext: string) => Promise<string> | string;
9
- decrypt: (pubkey: string, ciphertext: string) => Promise<string> | string;
10
- };
11
- };
12
- /** Various event kinds that can have encrypted tags in their content and which encryption method they use */
13
- export declare const EventContentEncryptionMethod: Record<number, "nip04" | "nip44">;
14
- /** Sets the encryption method that is used for the contents of a specific event kind */
15
- export declare function setEventContentEncryptionMethod(kind: number, method: "nip04" | "nip44"): void;
1
+ import { EncryptedContentSigner, getEncryptedContentEncryptionMethods } from "./encrypted-content.js";
2
+ export declare const HiddenContentSymbol: symbol;
3
+ export interface HiddenContentSigner extends EncryptedContentSigner {
4
+ }
5
+ export declare const getHiddenContentEncryptionMethods: typeof getEncryptedContentEncryptionMethods;
6
+ /** Various event kinds that can have hidden content */
7
+ export declare const HiddenContentKinds: Set<number>;
8
+ /** Sets the encryption method for hidden content on a kind */
9
+ export declare function setHiddenContentEncryptionMethod(kind: number, method: "nip04" | "nip44"): number;
16
10
  /** Checks if an event can have hidden content */
17
11
  export declare function canHaveHiddenContent(kind: number): boolean;
18
12
  /** Checks if an event has hidden content */
@@ -20,29 +14,30 @@ export declare function hasHiddenContent<T extends {
20
14
  kind: number;
21
15
  content: string;
22
16
  }>(event: T): boolean;
23
- /** Returns the hidden tags for an event if they are unlocked */
24
- export declare function getHiddenContent<T extends object>(event: T): string | undefined;
25
- /** Checks if the hidden tags are locked */
17
+ /** Checks if the hidden content is locked */
26
18
  export declare function isHiddenContentLocked<T extends object>(event: T): boolean;
27
- /** Returns either nip04 or nip44 encryption methods depending on event kind */
28
- export declare function getHiddenContentEncryptionMethods(kind: number, signer: HiddenContentSigner): {
29
- encrypt: (pubkey: string, plaintext: string) => Promise<string> | string;
30
- decrypt: (pubkey: string, ciphertext: string) => Promise<string> | string;
31
- } | {
32
- encrypt: (pubkey: string, plaintext: string) => Promise<string> | string;
33
- decrypt: (pubkey: string, ciphertext: string) => Promise<string> | string;
34
- };
35
- export type HiddenContentEvent = {
19
+ /** Returns the hidden content for an event if they are unlocked */
20
+ export declare function getHiddenContent<T extends {
36
21
  kind: number;
37
- pubkey: string;
38
22
  content: string;
39
- };
23
+ }>(event: T): string | undefined;
40
24
  /**
41
- * Unlocks the encrypted content in an event
25
+ * Unlocks the hidden content in the event
42
26
  * @param event The event with content to decrypt
43
- * @param signer A signer to use to decrypt the tags
27
+ * @param signer A signer to use to decrypt the content
28
+ * @throws
29
+ */
30
+ export declare function unlockHiddenContent<T extends {
31
+ kind: number;
32
+ pubkey: string;
33
+ content: string;
34
+ }>(event: T, signer: EncryptedContentSigner): Promise<string>;
35
+ /**
36
+ * Sets the hidden content on an event and updates it if its part of an event store
44
37
  * @throws
45
38
  */
46
- export declare function unlockHiddenContent<T extends HiddenContentEvent>(event: T, signer: HiddenContentSigner): Promise<string>;
39
+ export declare function setHiddenContentCache<T extends {
40
+ kind: number;
41
+ }>(event: T, plaintext: string): void;
47
42
  /** Removes the unencrypted hidden content on an event */
48
43
  export declare function lockHiddenContent<T extends object>(event: T): void;
@@ -1,88 +1,58 @@
1
- import * as kinds from "nostr-tools/kinds";
2
- import { GROUPS_LIST_KIND } from "./groups.js";
3
- import { getParentEventStore, isEvent } from "./event.js";
4
- export const HiddenContentSymbol = Symbol.for("hidden-content");
5
- /** Various event kinds that can have encrypted tags in their content and which encryption method they use */
6
- export const EventContentEncryptionMethod = {
7
- // NIP-60 wallet
8
- 17375: "nip44",
9
- 375: "nip44",
10
- 7375: "nip44",
11
- 7376: "nip44",
12
- // DMs
13
- [kinds.EncryptedDirectMessage]: "nip04",
14
- // Gift wraps
15
- [kinds.GiftWrap]: "nip44",
16
- // NIP-51 lists
17
- [kinds.BookmarkList]: "nip04",
18
- [kinds.InterestsList]: "nip04",
19
- [kinds.Mutelist]: "nip04",
20
- [kinds.CommunitiesList]: "nip04",
21
- [kinds.PublicChatsList]: "nip04",
22
- [kinds.SearchRelaysList]: "nip04",
23
- [GROUPS_LIST_KIND]: "nip04",
24
- // NIP-51 sets
25
- [kinds.Bookmarksets]: "nip04",
26
- [kinds.Relaysets]: "nip04",
27
- [kinds.Followsets]: "nip04",
28
- [kinds.Curationsets]: "nip04",
29
- [kinds.Interestsets]: "nip04",
30
- };
31
- /** Sets the encryption method that is used for the contents of a specific event kind */
32
- export function setEventContentEncryptionMethod(kind, method) {
33
- EventContentEncryptionMethod[kind] = method;
1
+ import { kinds } from "nostr-tools";
2
+ import { canHaveEncryptedContent, EncryptedContentSymbol, getEncryptedContent, getEncryptedContentEncryptionMethods, hasEncryptedContent, isEncryptedContentLocked, lockEncryptedContent, setEncryptedContentCache, setEncryptedContentEncryptionMethod, } from "./encrypted-content.js";
3
+ // reexport from encrypted-content
4
+ export const HiddenContentSymbol = EncryptedContentSymbol;
5
+ export const getHiddenContentEncryptionMethods = getEncryptedContentEncryptionMethods;
6
+ /** Various event kinds that can have hidden content */
7
+ export const HiddenContentKinds = new Set([setEncryptedContentEncryptionMethod(kinds.DraftLong, "nip04")]);
8
+ /** Sets the encryption method for hidden content on a kind */
9
+ export function setHiddenContentEncryptionMethod(kind, method) {
10
+ HiddenContentKinds.add(setEncryptedContentEncryptionMethod(kind, method));
11
+ return kind;
34
12
  }
35
13
  /** Checks if an event can have hidden content */
36
14
  export function canHaveHiddenContent(kind) {
37
- return EventContentEncryptionMethod[kind] !== undefined;
15
+ return canHaveEncryptedContent(kind) && HiddenContentKinds.has(kind);
38
16
  }
39
17
  /** Checks if an event has hidden content */
40
18
  export function hasHiddenContent(event) {
41
- return canHaveHiddenContent(event.kind) && event.content.length > 0;
19
+ return canHaveHiddenContent(event.kind) && hasEncryptedContent(event);
42
20
  }
43
- /** Returns the hidden tags for an event if they are unlocked */
44
- export function getHiddenContent(event) {
45
- return Reflect.get(event, HiddenContentSymbol);
46
- }
47
- /** Checks if the hidden tags are locked */
21
+ /** Checks if the hidden content is locked */
48
22
  export function isHiddenContentLocked(event) {
49
- return Reflect.has(event, HiddenContentSymbol) === false;
23
+ return isEncryptedContentLocked(event);
50
24
  }
51
- /** Returns either nip04 or nip44 encryption methods depending on event kind */
52
- export function getHiddenContentEncryptionMethods(kind, signer) {
53
- const method = EventContentEncryptionMethod[kind];
54
- const encryption = signer[method];
55
- if (!encryption)
56
- throw new Error(`Signer does not support ${method} encryption`);
57
- return encryption;
25
+ /** Returns the hidden content for an event if they are unlocked */
26
+ export function getHiddenContent(event) {
27
+ if (!canHaveHiddenContent(event.kind) || isHiddenContentLocked(event))
28
+ return undefined;
29
+ return getEncryptedContent(event);
58
30
  }
59
31
  /**
60
- * Unlocks the encrypted content in an event
32
+ * Unlocks the hidden content in the event
61
33
  * @param event The event with content to decrypt
62
- * @param signer A signer to use to decrypt the tags
34
+ * @param signer A signer to use to decrypt the content
63
35
  * @throws
64
36
  */
65
37
  export async function unlockHiddenContent(event, signer) {
66
38
  if (!canHaveHiddenContent(event.kind))
67
39
  throw new Error("Event kind does not support hidden content");
68
- const encryption = getHiddenContentEncryptionMethods(event.kind, signer);
40
+ const encryption = getEncryptedContentEncryptionMethods(event.kind, signer);
69
41
  const plaintext = await encryption.decrypt(event.pubkey, event.content);
70
- Reflect.set(event, HiddenContentSymbol, plaintext);
71
- // if the event has been added to an event store, notify it
72
- if (isEvent(event)) {
73
- const eventStore = getParentEventStore(event);
74
- if (eventStore)
75
- eventStore.update(event);
76
- }
42
+ setHiddenContentCache(event, plaintext);
77
43
  return plaintext;
78
44
  }
45
+ /**
46
+ * Sets the hidden content on an event and updates it if its part of an event store
47
+ * @throws
48
+ */
49
+ export function setHiddenContentCache(event, plaintext) {
50
+ if (!canHaveHiddenContent(event.kind))
51
+ throw new Error("Event kind does not support hidden content");
52
+ // Set the encrypted content
53
+ setEncryptedContentCache(event, plaintext);
54
+ }
79
55
  /** Removes the unencrypted hidden content on an event */
80
56
  export function lockHiddenContent(event) {
81
- Reflect.deleteProperty(event, HiddenContentSymbol);
82
- // if the event has been added to an event store, notify it
83
- if (isEvent(event)) {
84
- const eventStore = getParentEventStore(event);
85
- if (eventStore)
86
- eventStore.update(event);
87
- }
57
+ lockEncryptedContent(event);
88
58
  }
@@ -1,14 +1,21 @@
1
- import { HiddenContentEvent, HiddenContentSigner } from "./hidden-content.js";
1
+ import { HiddenContentSigner } from "./hidden-content.js";
2
2
  export declare const HiddenTagsSymbol: unique symbol;
3
+ /** Various event kinds that can have hidden tags */
4
+ export declare const HiddenTagsKinds: Set<number>;
3
5
  /** Checks if an event can have hidden tags */
4
6
  export declare function canHaveHiddenTags(kind: number): boolean;
7
+ /** Sets the type of encryption to use for hidden tags on a kind */
8
+ export declare function setHiddenTagsEncryptionMethod(kind: number, method: "nip04" | "nip44"): number;
5
9
  /** Checks if an event has hidden tags */
6
10
  export declare function hasHiddenTags<T extends {
7
- content: string;
8
11
  kind: number;
12
+ content: string;
9
13
  }>(event: T): boolean;
10
14
  /** Returns the hidden tags for an event if they are unlocked */
11
- export declare function getHiddenTags<T extends object>(event: T): string[][] | undefined;
15
+ export declare function getHiddenTags<T extends {
16
+ kind: number;
17
+ content: string;
18
+ }>(event: T): string[][] | undefined;
12
19
  /** Checks if the hidden tags are locked */
13
20
  export declare function isHiddenTagsLocked<T extends object>(event: T): boolean;
14
21
  /** Returns either nip04 or nip44 encryption method depending on list kind */
@@ -26,5 +33,17 @@ export declare function getHiddenTagsEncryptionMethods(kind: number, signer: Hid
26
33
  * @param store An optional EventStore to notify about the update
27
34
  * @throws
28
35
  */
29
- export declare function unlockHiddenTags<T extends HiddenContentEvent>(event: T, signer: HiddenContentSigner): Promise<string[][]>;
36
+ export declare function unlockHiddenTags<T extends {
37
+ kind: number;
38
+ pubkey: string;
39
+ content: string;
40
+ }>(event: T, signer: HiddenContentSigner): Promise<string[][]>;
41
+ /**
42
+ * Sets the hidden tags on an event and updates it if its part of an event store
43
+ * @throws
44
+ */
45
+ export declare function setHiddenTagsCache<T extends {
46
+ kind: number;
47
+ }>(event: T, tags: string[][]): void;
48
+ /** Clears the cached hidden tags on an event */
30
49
  export declare function lockHiddenTags<T extends object>(event: T): void;
@@ -1,17 +1,41 @@
1
- import { canHaveHiddenContent, getHiddenContent, getHiddenContentEncryptionMethods, isHiddenContentLocked, lockHiddenContent, unlockHiddenContent, } from "./hidden-content.js";
1
+ import { kinds } from "nostr-tools";
2
2
  import { getOrComputeCachedValue } from "./cache.js";
3
+ import { canHaveHiddenContent, getHiddenContent, getHiddenContentEncryptionMethods, hasHiddenContent, isHiddenContentLocked, lockHiddenContent, setHiddenContentCache, setHiddenContentEncryptionMethod, unlockHiddenContent, } from "./hidden-content.js";
4
+ import { GROUPS_LIST_KIND } from "./groups.js";
3
5
  export const HiddenTagsSymbol = Symbol.for("hidden-tags");
6
+ /** Various event kinds that can have hidden tags */
7
+ export const HiddenTagsKinds = new Set([
8
+ // NIP-51 lists
9
+ setHiddenContentEncryptionMethod(kinds.BookmarkList, "nip04"),
10
+ setHiddenContentEncryptionMethod(kinds.InterestsList, "nip04"),
11
+ setHiddenContentEncryptionMethod(kinds.Mutelist, "nip04"),
12
+ setHiddenContentEncryptionMethod(kinds.CommunitiesList, "nip04"),
13
+ setHiddenContentEncryptionMethod(kinds.PublicChatsList, "nip04"),
14
+ setHiddenContentEncryptionMethod(kinds.SearchRelaysList, "nip04"),
15
+ setHiddenContentEncryptionMethod(GROUPS_LIST_KIND, "nip04"),
16
+ // NIP-51 sets
17
+ setHiddenContentEncryptionMethod(kinds.Bookmarksets, "nip04"),
18
+ setHiddenContentEncryptionMethod(kinds.Relaysets, "nip04"),
19
+ setHiddenContentEncryptionMethod(kinds.Followsets, "nip04"),
20
+ setHiddenContentEncryptionMethod(kinds.Curationsets, "nip04"),
21
+ setHiddenContentEncryptionMethod(kinds.Interestsets, "nip04"),
22
+ ]);
4
23
  /** Checks if an event can have hidden tags */
5
24
  export function canHaveHiddenTags(kind) {
6
- return canHaveHiddenContent(kind);
25
+ return canHaveHiddenContent(kind) && HiddenTagsKinds.has(kind);
26
+ }
27
+ /** Sets the type of encryption to use for hidden tags on a kind */
28
+ export function setHiddenTagsEncryptionMethod(kind, method) {
29
+ HiddenTagsKinds.add(setHiddenContentEncryptionMethod(kind, method));
30
+ return kind;
7
31
  }
8
32
  /** Checks if an event has hidden tags */
9
33
  export function hasHiddenTags(event) {
10
- return canHaveHiddenTags(event.kind) && event.content.length > 0;
34
+ return canHaveHiddenTags(event.kind) && hasHiddenContent(event);
11
35
  }
12
36
  /** Returns the hidden tags for an event if they are unlocked */
13
37
  export function getHiddenTags(event) {
14
- if (isHiddenTagsLocked(event))
38
+ if (!canHaveHiddenTags(event.kind) || isHiddenTagsLocked(event))
15
39
  return undefined;
16
40
  return getOrComputeCachedValue(event, HiddenTagsSymbol, () => {
17
41
  const plaintext = getHiddenContent(event);
@@ -45,6 +69,17 @@ export async function unlockHiddenTags(event, signer) {
45
69
  await unlockHiddenContent(event, signer);
46
70
  return getHiddenTags(event);
47
71
  }
72
+ /**
73
+ * Sets the hidden tags on an event and updates it if its part of an event store
74
+ * @throws
75
+ */
76
+ export function setHiddenTagsCache(event, tags) {
77
+ if (!canHaveHiddenTags(event.kind))
78
+ throw new Error("Event kind does not support hidden tags");
79
+ const plaintext = JSON.stringify(tags);
80
+ setHiddenContentCache(event, plaintext);
81
+ }
82
+ /** Clears the cached hidden tags on an event */
48
83
  export function lockHiddenTags(event) {
49
84
  Reflect.deleteProperty(event, HiddenTagsSymbol);
50
85
  lockHiddenContent(event);
@@ -1,3 +1,5 @@
1
+ export * from "./app-handlers.js";
2
+ export * from "./article.js";
1
3
  export * from "./blossom.js";
2
4
  export * from "./bolt11.js";
3
5
  export * from "./bookmarks.js";
@@ -7,10 +9,13 @@ export * from "./comment.js";
7
9
  export * from "./contacts.js";
8
10
  export * from "./content.js";
9
11
  export * from "./delete.js";
10
- export * from "./direct-messages.js";
11
12
  export * from "./dns-identity.js";
12
13
  export * from "./emoji.js";
14
+ export * from "./encrypted-content-cache.js";
15
+ export * from "./encrypted-content.js";
16
+ export * from "./encryption.js";
13
17
  export * from "./event.js";
18
+ export * from "./expiration.js";
14
19
  export * from "./external-id.js";
15
20
  export * from "./file-metadata.js";
16
21
  export * from "./filter.js";
@@ -20,15 +25,19 @@ export * from "./hashtag.js";
20
25
  export * from "./hidden-content.js";
21
26
  export * from "./hidden-tags.js";
22
27
  export * from "./json.js";
28
+ export * from "./legacy-messages.js";
23
29
  export * from "./lists.js";
24
30
  export * from "./lnurl.js";
25
31
  export * from "./lru.js";
26
32
  export * from "./mailboxes.js";
33
+ export * from "./messages.js";
27
34
  export * from "./mutes.js";
28
35
  export * from "./picture-post.js";
29
36
  export * from "./pointers.js";
30
37
  export * from "./profile.js";
38
+ export * from "./reactions.js";
31
39
  export * from "./relays.js";
40
+ export * from "./reports.js";
32
41
  export * from "./share.js";
33
42
  export * from "./string.js";
34
43
  export * from "./tags.js";
@@ -36,4 +45,5 @@ export * from "./threading.js";
36
45
  export * from "./time.js";
37
46
  export * from "./url.js";
38
47
  export * from "./user-status.js";
48
+ export * from "./wrapped-messages.js";
39
49
  export * from "./zap.js";
@@ -1,3 +1,5 @@
1
+ export * from "./app-handlers.js";
2
+ export * from "./article.js";
1
3
  export * from "./blossom.js";
2
4
  export * from "./bolt11.js";
3
5
  export * from "./bookmarks.js";
@@ -7,10 +9,13 @@ export * from "./comment.js";
7
9
  export * from "./contacts.js";
8
10
  export * from "./content.js";
9
11
  export * from "./delete.js";
10
- export * from "./direct-messages.js";
11
12
  export * from "./dns-identity.js";
12
13
  export * from "./emoji.js";
14
+ export * from "./encrypted-content-cache.js";
15
+ export * from "./encrypted-content.js";
16
+ export * from "./encryption.js";
13
17
  export * from "./event.js";
18
+ export * from "./expiration.js";
14
19
  export * from "./external-id.js";
15
20
  export * from "./file-metadata.js";
16
21
  export * from "./filter.js";
@@ -20,15 +25,19 @@ export * from "./hashtag.js";
20
25
  export * from "./hidden-content.js";
21
26
  export * from "./hidden-tags.js";
22
27
  export * from "./json.js";
28
+ export * from "./legacy-messages.js";
23
29
  export * from "./lists.js";
24
30
  export * from "./lnurl.js";
25
31
  export * from "./lru.js";
26
32
  export * from "./mailboxes.js";
33
+ export * from "./messages.js";
27
34
  export * from "./mutes.js";
28
35
  export * from "./picture-post.js";
29
36
  export * from "./pointers.js";
30
37
  export * from "./profile.js";
38
+ export * from "./reactions.js";
31
39
  export * from "./relays.js";
40
+ export * from "./reports.js";
32
41
  export * from "./share.js";
33
42
  export * from "./string.js";
34
43
  export * from "./tags.js";
@@ -36,4 +45,5 @@ export * from "./threading.js";
36
45
  export * from "./time.js";
37
46
  export * from "./url.js";
38
47
  export * from "./user-status.js";
48
+ export * from "./wrapped-messages.js";
39
49
  export * from "./zap.js";
@@ -0,0 +1,21 @@
1
+ import { NostrEvent } from "nostr-tools";
2
+ import { EncryptedContentSigner } from "./encrypted-content.js";
3
+ /** Checks if a legacy direct message content is encrypted */
4
+ export declare function isLegacyMessageLocked(event: NostrEvent): boolean;
5
+ /**
6
+ * Returns the corraspondant of a legacy direct message
7
+ * @throws if no corraspondant is found
8
+ */
9
+ export declare function getLegacyMessageCorraspondant(message: NostrEvent, self: string): string;
10
+ /** Returns the parent message id of a legacy message */
11
+ export declare function getLegacyMessageParent(message: NostrEvent): string | undefined;
12
+ /**
13
+ * Returns the decrypted content of a direct message
14
+ * @param message - The message to decrypt
15
+ * @param self - The public key of the user
16
+ * @param signer - The signer to use to decrypt the message
17
+ * @returns The decrypted content of the message
18
+ */
19
+ export declare function unlockLegacyMessage(message: NostrEvent, self: string, signer: EncryptedContentSigner): Promise<string>;
20
+ /** Clears the cached plaintext of a direct message */
21
+ export declare function lockLegacyMessage(message: NostrEvent): Promise<void>;
@@ -0,0 +1,39 @@
1
+ import { getEncryptedContent, isEncryptedContentLocked, lockEncryptedContent, unlockEncryptedContent, } from "./encrypted-content.js";
2
+ import { getTagValue } from "./index.js";
3
+ /** Checks if a legacy direct message content is encrypted */
4
+ export function isLegacyMessageLocked(event) {
5
+ return isEncryptedContentLocked(event);
6
+ }
7
+ /**
8
+ * Returns the corraspondant of a legacy direct message
9
+ * @throws if no corraspondant is found
10
+ */
11
+ export function getLegacyMessageCorraspondant(message, self) {
12
+ const corraspondant = message.pubkey === self ? getTagValue(message, "p") : message.pubkey;
13
+ if (!corraspondant)
14
+ throw new Error("No corraspondant found");
15
+ return corraspondant;
16
+ }
17
+ /** Returns the parent message id of a legacy message */
18
+ export function getLegacyMessageParent(message) {
19
+ return getTagValue(message, "e");
20
+ }
21
+ /**
22
+ * Returns the decrypted content of a direct message
23
+ * @param message - The message to decrypt
24
+ * @param self - The public key of the user
25
+ * @param signer - The signer to use to decrypt the message
26
+ * @returns The decrypted content of the message
27
+ */
28
+ export async function unlockLegacyMessage(message, self, signer) {
29
+ const cached = getEncryptedContent(message);
30
+ if (cached)
31
+ return cached;
32
+ const corraspondant = getLegacyMessageCorraspondant(message, self);
33
+ // Unlock the encrypted content
34
+ return await unlockEncryptedContent(message, corraspondant, signer);
35
+ }
36
+ /** Clears the cached plaintext of a direct message */
37
+ export async function lockLegacyMessage(message) {
38
+ lockEncryptedContent(message);
39
+ }
@@ -1,5 +1,5 @@
1
- import { AddressPointer, EventPointer, ProfilePointer } from "nostr-tools/nip19";
2
1
  import { NostrEvent } from "nostr-tools";
2
+ import { AddressPointer, EventPointer, ProfilePointer } from "nostr-tools/nip19";
3
3
  export declare const FAVORITE_RELAYS_KIND = 10012;
4
4
  export type ReadListTags = "public" | "hidden" | "all";
5
5
  /** Returns all the tags of a list or set */