applesauce-common 0.0.0-next-20251203172109

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 (225) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +59 -0
  3. package/dist/blueprints/app-data.d.ts +5 -0
  4. package/dist/blueprints/app-data.js +10 -0
  5. package/dist/blueprints/calendar.d.ts +5 -0
  6. package/dist/blueprints/calendar.js +7 -0
  7. package/dist/blueprints/channels.d.ts +6 -0
  8. package/dist/blueprints/channels.js +13 -0
  9. package/dist/blueprints/comment.d.ts +12 -0
  10. package/dist/blueprints/comment.js +15 -0
  11. package/dist/blueprints/delete.d.ts +9 -0
  12. package/dist/blueprints/delete.js +14 -0
  13. package/dist/blueprints/file-metadata.d.ts +8 -0
  14. package/dist/blueprints/file-metadata.js +11 -0
  15. package/dist/blueprints/follow-set.d.ts +11 -0
  16. package/dist/blueprints/follow-set.js +21 -0
  17. package/dist/blueprints/gift-wrap.d.ts +5 -0
  18. package/dist/blueprints/gift-wrap.js +6 -0
  19. package/dist/blueprints/group.d.ts +9 -0
  20. package/dist/blueprints/group.js +17 -0
  21. package/dist/blueprints/highlight.d.ts +20 -0
  22. package/dist/blueprints/highlight.js +12 -0
  23. package/dist/blueprints/index.d.ts +23 -0
  24. package/dist/blueprints/index.js +24 -0
  25. package/dist/blueprints/legacy-message.d.ts +7 -0
  26. package/dist/blueprints/legacy-message.js +29 -0
  27. package/dist/blueprints/live-stream.d.ts +6 -0
  28. package/dist/blueprints/live-stream.js +9 -0
  29. package/dist/blueprints/note.d.ts +16 -0
  30. package/dist/blueprints/note.js +30 -0
  31. package/dist/blueprints/picture-post.d.ts +12 -0
  32. package/dist/blueprints/picture-post.js +17 -0
  33. package/dist/blueprints/poll.d.ts +41 -0
  34. package/dist/blueprints/poll.js +33 -0
  35. package/dist/blueprints/profile.d.ts +3 -0
  36. package/dist/blueprints/profile.js +7 -0
  37. package/dist/blueprints/reaction.d.ts +10 -0
  38. package/dist/blueprints/reaction.js +14 -0
  39. package/dist/blueprints/share.d.ts +12 -0
  40. package/dist/blueprints/share.js +25 -0
  41. package/dist/blueprints/stream.d.ts +6 -0
  42. package/dist/blueprints/stream.js +7 -0
  43. package/dist/blueprints/torrent.d.ts +23 -0
  44. package/dist/blueprints/torrent.js +25 -0
  45. package/dist/blueprints/wrapped-message.d.ts +20 -0
  46. package/dist/blueprints/wrapped-message.js +64 -0
  47. package/dist/helpers/app-data.d.ts +39 -0
  48. package/dist/helpers/app-data.js +68 -0
  49. package/dist/helpers/app-handler.d.ts +22 -0
  50. package/dist/helpers/app-handler.js +67 -0
  51. package/dist/helpers/article.d.ts +14 -0
  52. package/dist/helpers/article.js +24 -0
  53. package/dist/helpers/blossom.d.ts +11 -0
  54. package/dist/helpers/blossom.js +40 -0
  55. package/dist/helpers/bolt11.d.ts +10 -0
  56. package/dist/helpers/bolt11.js +17 -0
  57. package/dist/helpers/bookmark.d.ts +30 -0
  58. package/dist/helpers/bookmark.js +96 -0
  59. package/dist/helpers/calendar-event.d.ts +39 -0
  60. package/dist/helpers/calendar-event.js +121 -0
  61. package/dist/helpers/calendar-rsvp.d.ts +15 -0
  62. package/dist/helpers/calendar-rsvp.js +38 -0
  63. package/dist/helpers/calendar.d.ts +6 -0
  64. package/dist/helpers/calendar.js +11 -0
  65. package/dist/helpers/channels.d.ts +13 -0
  66. package/dist/helpers/channels.js +27 -0
  67. package/dist/helpers/comment.d.ts +47 -0
  68. package/dist/helpers/comment.js +185 -0
  69. package/dist/helpers/content.d.ts +3 -0
  70. package/dist/helpers/content.js +8 -0
  71. package/dist/helpers/emoji.d.ts +21 -0
  72. package/dist/helpers/emoji.js +34 -0
  73. package/dist/helpers/encrypted-content-cache.d.ts +22 -0
  74. package/dist/helpers/encrypted-content-cache.js +138 -0
  75. package/dist/helpers/file-metadata.d.ts +55 -0
  76. package/dist/helpers/file-metadata.js +130 -0
  77. package/dist/helpers/gift-wrap.d.ts +66 -0
  78. package/dist/helpers/gift-wrap.js +204 -0
  79. package/dist/helpers/groups-helper.d.ts +6 -0
  80. package/dist/helpers/groups-helper.js +9 -0
  81. package/dist/helpers/groups.d.ts +26 -0
  82. package/dist/helpers/groups.js +49 -0
  83. package/dist/helpers/hashtag.d.ts +2 -0
  84. package/dist/helpers/hashtag.js +7 -0
  85. package/dist/helpers/highlight.d.ts +45 -0
  86. package/dist/helpers/highlight.js +76 -0
  87. package/dist/helpers/index.d.ts +37 -0
  88. package/dist/helpers/index.js +37 -0
  89. package/dist/helpers/legacy-messages.d.ts +31 -0
  90. package/dist/helpers/legacy-messages.js +49 -0
  91. package/dist/helpers/lists.d.ts +58 -0
  92. package/dist/helpers/lists.js +110 -0
  93. package/dist/helpers/lnurl.d.ts +8 -0
  94. package/dist/helpers/lnurl.js +44 -0
  95. package/dist/helpers/mailboxes.d.ts +7 -0
  96. package/dist/helpers/mailboxes.js +49 -0
  97. package/dist/helpers/messages.d.ts +31 -0
  98. package/dist/helpers/messages.js +57 -0
  99. package/dist/helpers/mute.d.ts +33 -0
  100. package/dist/helpers/mute.js +111 -0
  101. package/dist/helpers/picture-post.d.ts +5 -0
  102. package/dist/helpers/picture-post.js +6 -0
  103. package/dist/helpers/poll.d.ts +46 -0
  104. package/dist/helpers/poll.js +78 -0
  105. package/dist/helpers/reaction.d.ts +8 -0
  106. package/dist/helpers/reaction.js +56 -0
  107. package/dist/helpers/relay-discovery.d.ts +87 -0
  108. package/dist/helpers/relay-discovery.js +126 -0
  109. package/dist/helpers/reports.d.ts +28 -0
  110. package/dist/helpers/reports.js +38 -0
  111. package/dist/helpers/share.d.ts +19 -0
  112. package/dist/helpers/share.js +58 -0
  113. package/dist/helpers/stream-chat.d.ts +4 -0
  114. package/dist/helpers/stream-chat.js +9 -0
  115. package/dist/helpers/stream.d.ts +31 -0
  116. package/dist/helpers/stream.js +81 -0
  117. package/dist/helpers/threading.d.ts +55 -0
  118. package/dist/helpers/threading.js +94 -0
  119. package/dist/helpers/torrent.d.ts +55 -0
  120. package/dist/helpers/torrent.js +270 -0
  121. package/dist/helpers/user-status.d.ts +18 -0
  122. package/dist/helpers/user-status.js +22 -0
  123. package/dist/helpers/wrapped-messages.d.ts +14 -0
  124. package/dist/helpers/wrapped-messages.js +23 -0
  125. package/dist/helpers/zap.d.ts +46 -0
  126. package/dist/helpers/zap.js +125 -0
  127. package/dist/index.d.ts +5 -0
  128. package/dist/index.js +6 -0
  129. package/dist/models/blossom.d.ts +11 -0
  130. package/dist/models/blossom.js +18 -0
  131. package/dist/models/bookmarks.d.ts +8 -0
  132. package/dist/models/bookmarks.js +24 -0
  133. package/dist/models/calendar.d.ts +6 -0
  134. package/dist/models/calendar.js +15 -0
  135. package/dist/models/channels.d.ts +11 -0
  136. package/dist/models/channels.js +61 -0
  137. package/dist/models/comments.d.ts +11 -0
  138. package/dist/models/comments.js +17 -0
  139. package/dist/models/gift-wrap.d.ts +7 -0
  140. package/dist/models/gift-wrap.js +20 -0
  141. package/dist/models/index.d.ts +15 -0
  142. package/dist/models/index.js +16 -0
  143. package/dist/models/legacy-messages.d.ts +14 -0
  144. package/dist/models/legacy-messages.js +64 -0
  145. package/dist/models/mutes.d.ts +16 -0
  146. package/dist/models/mutes.js +34 -0
  147. package/dist/models/pins.d.ts +4 -0
  148. package/dist/models/pins.js +10 -0
  149. package/dist/models/reactions.d.ts +11 -0
  150. package/dist/models/reactions.js +21 -0
  151. package/dist/models/thread.d.ts +33 -0
  152. package/dist/models/thread.js +93 -0
  153. package/dist/models/user-status.d.ts +11 -0
  154. package/dist/models/user-status.js +32 -0
  155. package/dist/models/wrapped-messages.d.ts +31 -0
  156. package/dist/models/wrapped-messages.js +76 -0
  157. package/dist/models/zaps.d.ts +9 -0
  158. package/dist/models/zaps.js +26 -0
  159. package/dist/operations/app-data.d.ts +6 -0
  160. package/dist/operations/app-data.js +21 -0
  161. package/dist/operations/blossom.d.ts +5 -0
  162. package/dist/operations/blossom.js +13 -0
  163. package/dist/operations/calendar-event.d.ts +34 -0
  164. package/dist/operations/calendar-event.js +72 -0
  165. package/dist/operations/calendar-rsvp.d.ts +10 -0
  166. package/dist/operations/calendar-rsvp.js +35 -0
  167. package/dist/operations/calendar.d.ts +9 -0
  168. package/dist/operations/calendar.js +15 -0
  169. package/dist/operations/channel.d.ts +4 -0
  170. package/dist/operations/channel.js +10 -0
  171. package/dist/operations/client.d.ts +4 -0
  172. package/dist/operations/client.js +23 -0
  173. package/dist/operations/comment.d.ts +4 -0
  174. package/dist/operations/comment.js +11 -0
  175. package/dist/operations/file-metadata.d.ts +4 -0
  176. package/dist/operations/file-metadata.js +21 -0
  177. package/dist/operations/geohash.d.ts +5 -0
  178. package/dist/operations/geohash.js +17 -0
  179. package/dist/operations/gift-wrap.d.ts +13 -0
  180. package/dist/operations/gift-wrap.js +93 -0
  181. package/dist/operations/group.d.ts +11 -0
  182. package/dist/operations/group.js +34 -0
  183. package/dist/operations/hashtags.d.ts +7 -0
  184. package/dist/operations/hashtags.js +17 -0
  185. package/dist/operations/highlight.d.ts +18 -0
  186. package/dist/operations/highlight.js +47 -0
  187. package/dist/operations/index.d.ts +28 -0
  188. package/dist/operations/index.js +28 -0
  189. package/dist/operations/legacy-message.d.ts +6 -0
  190. package/dist/operations/legacy-message.js +13 -0
  191. package/dist/operations/list.d.ts +7 -0
  192. package/dist/operations/list.js +14 -0
  193. package/dist/operations/live-stream.d.ts +4 -0
  194. package/dist/operations/live-stream.js +11 -0
  195. package/dist/operations/media-attachment.d.ts +4 -0
  196. package/dist/operations/media-attachment.js +12 -0
  197. package/dist/operations/note.d.ts +9 -0
  198. package/dist/operations/note.js +42 -0
  199. package/dist/operations/picture-post.d.ts +4 -0
  200. package/dist/operations/picture-post.js +14 -0
  201. package/dist/operations/poll-response.d.ts +9 -0
  202. package/dist/operations/poll-response.js +20 -0
  203. package/dist/operations/poll.d.ts +19 -0
  204. package/dist/operations/poll.js +42 -0
  205. package/dist/operations/reaction.d.ts +7 -0
  206. package/dist/operations/reaction.js +39 -0
  207. package/dist/operations/share.d.ts +8 -0
  208. package/dist/operations/share.js +34 -0
  209. package/dist/operations/stream-chat.d.ts +7 -0
  210. package/dist/operations/stream-chat.js +27 -0
  211. package/dist/operations/stream.d.ts +41 -0
  212. package/dist/operations/stream.js +83 -0
  213. package/dist/operations/tag/bookmarks.d.ts +6 -0
  214. package/dist/operations/tag/bookmarks.js +20 -0
  215. package/dist/operations/tag/index.d.ts +1 -0
  216. package/dist/operations/tag/index.js +1 -0
  217. package/dist/operations/torrent.d.ts +33 -0
  218. package/dist/operations/torrent.js +66 -0
  219. package/dist/operations/wrapped-message.d.ts +12 -0
  220. package/dist/operations/wrapped-message.js +28 -0
  221. package/dist/operations/zap-split.d.ts +10 -0
  222. package/dist/operations/zap-split.js +20 -0
  223. package/dist/register.d.ts +11 -0
  224. package/dist/register.js +13 -0
  225. package/package.json +91 -0
@@ -0,0 +1,14 @@
1
+ import { blueprint } from "applesauce-core/event-factory";
2
+ import { kinds } from "applesauce-core/helpers/event";
3
+ import { includeEmojis } from "applesauce-core/operations/content";
4
+ import { setReaction, setReactionParent } from "../operations/reaction.js";
5
+ // Import EventFactory as a value (class) to modify its prototype
6
+ import { EventFactory } from "applesauce-core/event-factory";
7
+ /** blueprint for kind 7 reaction event */
8
+ export function ReactionBlueprint(event, emoji = "+") {
9
+ return blueprint(kinds.Reaction, setReaction(emoji), setReactionParent(event), typeof emoji !== "string" ? includeEmojis([emoji]) : undefined);
10
+ }
11
+ // Register this blueprint with EventFactory
12
+ EventFactory.prototype.reaction = function (event, emoji = "+") {
13
+ return this.create(ReactionBlueprint, event, emoji);
14
+ };
@@ -0,0 +1,12 @@
1
+ import { MetaTagOptions } from "applesauce-core/operations/event";
2
+ import { EventTemplate, NostrEvent } from "applesauce-core/helpers/event";
3
+ import { ZapOptions } from "../operations/zap-split.js";
4
+ export type ShareBlueprintOptions = MetaTagOptions & ZapOptions;
5
+ /** Blueprint for a NIP-18 repost event */
6
+ export declare function ShareBlueprint(event: NostrEvent, options?: ShareBlueprintOptions): import("applesauce-core/event-factory").EventBlueprint;
7
+ declare module "applesauce-core/event-factory" {
8
+ interface EventFactory {
9
+ /** Create a NIP-18 repost event */
10
+ share(event: NostrEvent, options?: ShareBlueprintOptions): Promise<EventTemplate>;
11
+ }
12
+ }
@@ -0,0 +1,25 @@
1
+ import { setMetaTags } from "applesauce-core/operations/event";
2
+ import { embedSharedEvent, setShareKind, setShareTags } from "../operations/share.js";
3
+ import { blueprint } from "applesauce-core/event-factory";
4
+ import { kinds } from "applesauce-core/helpers/event";
5
+ import { setZapSplit } from "../operations/zap-split.js";
6
+ // Import EventFactory as a value (class) to modify its prototype
7
+ import { EventFactory } from "applesauce-core/event-factory";
8
+ /** Blueprint for a NIP-18 repost event */
9
+ export function ShareBlueprint(event, options) {
10
+ return blueprint(kinds.Repost,
11
+ // set the kind to 6 or 16 based on the kind of event being shared
12
+ setShareKind(event),
13
+ // embed the shared event as a JSON string
14
+ embedSharedEvent(event),
15
+ // include the NIP-18 repost tags
16
+ setShareTags(event),
17
+ // include the meta tags
18
+ setMetaTags(options),
19
+ // include the zap split tags
20
+ setZapSplit(options));
21
+ }
22
+ // Register this blueprint with EventFactory
23
+ EventFactory.prototype.share = function (event, options) {
24
+ return this.create(ShareBlueprint, event, options);
25
+ };
@@ -0,0 +1,6 @@
1
+ import { TextContentOptions } from "applesauce-core/operations";
2
+ import { AddressPointer } from "applesauce-core/helpers/pointers";
3
+ import { NostrEvent } from "applesauce-core/helpers/event";
4
+ import { EventBlueprint } from "applesauce-core/event-factory";
5
+ /** Creates a stream chat message */
6
+ export declare function StreamChatMessage(stream: AddressPointer | NostrEvent, content: string, options?: TextContentOptions): EventBlueprint;
@@ -0,0 +1,7 @@
1
+ import { blueprint } from "applesauce-core/event-factory";
2
+ import { kinds } from "applesauce-core/helpers/event";
3
+ import { setMessage, setStream } from "../operations/stream-chat.js";
4
+ /** Creates a stream chat message */
5
+ export function StreamChatMessage(stream, content, options) {
6
+ return blueprint(kinds.LiveChatMessage, setMessage(content, options), setStream(stream));
7
+ }
@@ -0,0 +1,23 @@
1
+ import { MetaTagOptions } from "applesauce-core/operations/event";
2
+ import { TorrentExternalIdentifier, TorrentFile } from "../helpers/torrent.js";
3
+ export type TorrentBlueprintOptions = MetaTagOptions & {
4
+ /** Torrent title */
5
+ title?: string;
6
+ /** File entries in the torrent */
7
+ files?: TorrentFile[];
8
+ /** Tracker URLs */
9
+ trackers?: string[];
10
+ /** Newznab category ID */
11
+ category?: number;
12
+ /** Search tags for searchability (t tags) */
13
+ searchTags?: string[];
14
+ /** Category path (tcat) */
15
+ categoryPath?: string;
16
+ /** External identifiers */
17
+ externalIdentifiers?: TorrentExternalIdentifier[];
18
+ };
19
+ /**
20
+ * NIP-35 Torrent event (kind 2003) blueprint
21
+ * Creates a torrent event with info hash and optional metadata
22
+ */
23
+ export declare function TorrentBlueprint(infoHash: string, content: string, options?: TorrentBlueprintOptions): import("applesauce-core/event-factory").EventBlueprint;
@@ -0,0 +1,25 @@
1
+ import { blueprint } from "applesauce-core/event-factory";
2
+ import { eventPipe } from "applesauce-core/helpers/pipeline";
3
+ import { setContent } from "applesauce-core/operations/content";
4
+ import { setMetaTags } from "applesauce-core/operations/event";
5
+ import { TORRENT_KIND } from "../helpers/torrent.js";
6
+ import { addTorrentExternalIdentifier, addTorrentFile, addTorrentSearchTag, addTorrentTracker, setTorrentCategory, setTorrentCategoryPath, setTorrentInfoHash, setTorrentTitle, } from "../operations/torrent.js";
7
+ /**
8
+ * NIP-35 Torrent event (kind 2003) blueprint
9
+ * Creates a torrent event with info hash and optional metadata
10
+ */
11
+ export function TorrentBlueprint(infoHash, content, options) {
12
+ return blueprint(TORRENT_KIND, setTorrentInfoHash(infoHash), setContent(content), options?.title ? setTorrentTitle(options.title) : undefined, options?.categoryPath ? setTorrentCategoryPath(options.categoryPath) : undefined,
13
+ // Add files
14
+ options?.files ? eventPipe(...options.files.map((file) => addTorrentFile(file))) : undefined,
15
+ // Add trackers
16
+ options?.trackers ? eventPipe(...options.trackers.map((tracker) => addTorrentTracker(tracker))) : undefined,
17
+ // Set newznab category
18
+ options?.category !== undefined ? setTorrentCategory(options.category) : undefined,
19
+ // Add search tags
20
+ options?.searchTags ? eventPipe(...options.searchTags.map((tag) => addTorrentSearchTag(tag))) : undefined,
21
+ // Add external identifiers
22
+ options?.externalIdentifiers
23
+ ? eventPipe(...options.externalIdentifiers.map((id) => addTorrentExternalIdentifier(id)))
24
+ : undefined, setMetaTags({ ...options, alt: options?.alt ?? `Torrent: ${options?.title ?? infoHash}` }));
25
+ }
@@ -0,0 +1,20 @@
1
+ import { Emoji } from "applesauce-core/event-factory";
2
+ import { EventBlueprint } from "applesauce-core/event-factory";
3
+ import { Rumor } from "../helpers/gift-wrap.js";
4
+ export type WrappedMessageBlueprintOptions = {
5
+ emojis?: Emoji[];
6
+ subject?: string;
7
+ };
8
+ /**
9
+ * A blueprint that creates a wrapped message event to a conversation
10
+ * @param participants - The conversation identifier (pubkey1:pubkey2:pubkey3), a users pubkey, or a list of participant pubkeys
11
+ * @param message - The message to wrap
12
+ * @returns A blueprint that creates a wrapped message event to a conversation
13
+ */
14
+ export declare function WrappedMessageBlueprint(participants: string | string[], message: string, opts?: WrappedMessageBlueprintOptions): EventBlueprint<Rumor>;
15
+ /**
16
+ * A blueprint that creates a reply to a wrapped message event
17
+ * @param message - The message to wrap
18
+ * @returns A blueprint that creates a wrapped message event to a conversation
19
+ */
20
+ export declare function WrappedMessageReplyBlueprint(parent: Rumor, message: string, opts?: WrappedMessageBlueprintOptions): EventBlueprint<Rumor>;
@@ -0,0 +1,64 @@
1
+ import { blueprint } from "applesauce-core/event-factory";
2
+ import { kinds } from "applesauce-core/helpers/event";
3
+ import { repairNostrLinks, setContent } from "applesauce-core/operations";
4
+ import { setConversation, setParent, setSubject } from "../operations/wrapped-message.js";
5
+ import { includeEmojis } from "applesauce-core/operations/content";
6
+ import { toRumor } from "../operations/gift-wrap.js";
7
+ import { getConversationParticipants } from "../helpers/messages.js";
8
+ /**
9
+ * A blueprint that creates a wrapped message event to a conversation
10
+ * @param participants - The conversation identifier (pubkey1:pubkey2:pubkey3), a users pubkey, or a list of participant pubkeys
11
+ * @param message - The message to wrap
12
+ * @returns A blueprint that creates a wrapped message event to a conversation
13
+ */
14
+ export function WrappedMessageBlueprint(participants, message, opts) {
15
+ return async (context) => {
16
+ if (!context.signer)
17
+ throw new Error("Missing signer");
18
+ const self = await context.signer.getPublicKey();
19
+ return blueprint(kinds.PrivateDirectMessage,
20
+ // set text content
21
+ setContent(message),
22
+ // fix @ mentions
23
+ repairNostrLinks(),
24
+ // Include the "p" tags for the conversation
25
+ setConversation(participants, self),
26
+ // include "emoji" tags
27
+ opts?.emojis ? includeEmojis(opts.emojis) : undefined,
28
+ // Include the subject if provided
29
+ opts?.subject ? setSubject(opts.subject) : undefined,
30
+ // Convert the event to a rumor
31
+ toRumor())(context);
32
+ };
33
+ }
34
+ /**
35
+ * A blueprint that creates a reply to a wrapped message event
36
+ * @param message - The message to wrap
37
+ * @returns A blueprint that creates a wrapped message event to a conversation
38
+ */
39
+ export function WrappedMessageReplyBlueprint(parent, message, opts) {
40
+ return async (context) => {
41
+ if (typeof parent !== "string" && parent.kind !== kinds.PrivateDirectMessage)
42
+ throw new Error("Parent must be a wrapped message event (kind 14)");
43
+ if (!context.signer)
44
+ throw new Error("Missing signer");
45
+ const self = await context.signer.getPublicKey();
46
+ // Get the identifier for the conversation
47
+ const participants = getConversationParticipants(parent);
48
+ return blueprint(kinds.PrivateDirectMessage,
49
+ // set text content
50
+ setContent(message),
51
+ // fix @ mentions
52
+ repairNostrLinks(),
53
+ // Include the "p" tags for the conversation
54
+ setConversation(participants, self),
55
+ // Include the parent message id
56
+ setParent(parent),
57
+ // include "emoji" tags
58
+ opts?.emojis ? includeEmojis(opts.emojis) : undefined,
59
+ // Include the subject if provided
60
+ opts?.subject ? setSubject(opts.subject) : undefined,
61
+ // Convert the event to a rumor
62
+ toRumor())(context);
63
+ };
64
+ }
@@ -0,0 +1,39 @@
1
+ import { EncryptionMethod } from "applesauce-core/helpers/encrypted-content";
2
+ import { NostrEvent } from "applesauce-core/helpers/event";
3
+ import { HiddenContentSigner } from "applesauce-core/helpers/hidden-content";
4
+ export declare const APP_DATA_KIND = 30078;
5
+ /** A symbol used to cache the application data content */
6
+ export declare const AppDataContentSymbol: unique symbol;
7
+ /** Checks if an event has application data */
8
+ export declare function hasAppData<T extends {
9
+ kind: number;
10
+ content: string;
11
+ }>(event: T): boolean;
12
+ /** Checks if the application data is encrypted */
13
+ export declare function getAppDataEncryption<T extends {
14
+ kind: number;
15
+ content: string;
16
+ }>(event: T): EncryptionMethod | undefined;
17
+ /** Checks if the application data is locked (encrypted and not decrypted) */
18
+ export declare function isAppDataUnlocked<T extends {
19
+ kind: number;
20
+ }>(event: T): boolean;
21
+ /** Returns the parsed application data for an event if it's unlocked */
22
+ export declare function getAppDataContent<R extends unknown = unknown, T extends {
23
+ kind: number;
24
+ content: string;
25
+ } = NostrEvent>(event: T): R | undefined;
26
+ /**
27
+ * Unlocks the encrypted application data in the event
28
+ * @param event The event with encrypted content to decrypt
29
+ * @param signer A signer to use to decrypt the content
30
+ * @param override The encryption method to use instead of the default
31
+ * @returns The decrypted application data
32
+ */
33
+ export declare function unlockAppData<R extends unknown = unknown, T extends {
34
+ kind: number;
35
+ pubkey: string;
36
+ content: string;
37
+ } = NostrEvent>(event: T, signer: HiddenContentSigner, override?: EncryptionMethod): Promise<R>;
38
+ /** Removes the unencrypted application data cache on an event */
39
+ export declare function lockAppData<T extends object>(event: T): void;
@@ -0,0 +1,68 @@
1
+ import { isNIP04Encrypted } from "applesauce-core/helpers/encryption";
2
+ import { getHiddenContent, isHiddenContentUnlocked, lockHiddenContent, setHiddenContentEncryptionMethod, unlockHiddenContent, } from "applesauce-core/helpers/hidden-content";
3
+ import { safeParse } from "applesauce-core/helpers/json";
4
+ // NIP-78 Application Data event kind
5
+ export const APP_DATA_KIND = 30078;
6
+ /** A symbol used to cache the application data content */
7
+ export const AppDataContentSymbol = Symbol.for("app-data-content");
8
+ // Set the encryption method for app data events (default to nip44)
9
+ setHiddenContentEncryptionMethod(APP_DATA_KIND, "nip44");
10
+ /** Checks if an event has application data */
11
+ export function hasAppData(event) {
12
+ return event.kind === APP_DATA_KIND && event.content.length > 0;
13
+ }
14
+ /** Checks if the application data is encrypted */
15
+ export function getAppDataEncryption(event) {
16
+ // If content is empty, it can't be encrypted
17
+ if (event.content.length === 0)
18
+ return undefined;
19
+ // Try to parse as JSON - if it fails, it's likely encrypted
20
+ const parsed = safeParse(event.content);
21
+ if (parsed !== undefined)
22
+ return undefined;
23
+ return isNIP04Encrypted(event.content) ? "nip04" : "nip44";
24
+ }
25
+ /** Checks if the application data is locked (encrypted and not decrypted) */
26
+ export function isAppDataUnlocked(event) {
27
+ return isHiddenContentUnlocked(event);
28
+ }
29
+ /** Returns the parsed application data for an event if it's unlocked */
30
+ export function getAppDataContent(event) {
31
+ const cached = Reflect.get(event, AppDataContentSymbol);
32
+ if (cached)
33
+ return cached;
34
+ // If content is empty, return undefined
35
+ if (event.content.length === 0)
36
+ return undefined;
37
+ let data = getAppDataEncryption(event) ? undefined : safeParse(event.content);
38
+ if (!data) {
39
+ const decrypted = getHiddenContent(event);
40
+ if (decrypted)
41
+ data = safeParse(decrypted);
42
+ }
43
+ if (!data)
44
+ return undefined;
45
+ Reflect.set(event, AppDataContentSymbol, data);
46
+ return data;
47
+ }
48
+ /**
49
+ * Unlocks the encrypted application data in the event
50
+ * @param event The event with encrypted content to decrypt
51
+ * @param signer A signer to use to decrypt the content
52
+ * @param override The encryption method to use instead of the default
53
+ * @returns The decrypted application data
54
+ */
55
+ export async function unlockAppData(event, signer, override) {
56
+ if (!getAppDataEncryption(event))
57
+ return getAppDataContent(event);
58
+ const method = override ?? getAppDataEncryption(event);
59
+ const plaintext = await unlockHiddenContent(event, signer, method);
60
+ const parsed = safeParse(plaintext);
61
+ if (parsed === undefined)
62
+ throw new Error("Failed to parse decrypted application data as JSON");
63
+ return parsed;
64
+ }
65
+ /** Removes the unencrypted application data cache on an event */
66
+ export function lockAppData(event) {
67
+ lockHiddenContent(event);
68
+ }
@@ -0,0 +1,22 @@
1
+ import { NostrEvent } from "applesauce-core/helpers/event";
2
+ import { AddressPointer, DecodeResult, EventPointer, ProfilePointer } from "applesauce-core/helpers/pointers";
3
+ export type HandlerLinkPlatform = "web" | "ios" | "android";
4
+ export type HandlerLinkType = DecodeResult["type"];
5
+ /** Returns an array of supported kinds for a given handler */
6
+ export declare function getHandlerSupportedKinds(handler: NostrEvent): number[];
7
+ /** Returns the name of the handler */
8
+ export declare function getHandlerName(handler: NostrEvent): string;
9
+ /** Returns the picture of the handler */
10
+ export declare function getHandlerPicture(handler: NostrEvent, fallback?: string): string | undefined;
11
+ /** Returns the description of the handler */
12
+ export declare function getHandlerDescription(handler: NostrEvent): string | undefined;
13
+ /** Returns the web link template for a handler and type */
14
+ export declare function getHandlerLinkTemplate(handler: NostrEvent, platform?: HandlerLinkPlatform, type?: HandlerLinkType): string | undefined;
15
+ /** Returns a link for a Profile Pointer */
16
+ export declare function createHandlerProfileLink(handler: NostrEvent, pointer: ProfilePointer, platform?: HandlerLinkPlatform): string | undefined;
17
+ /** Returns a link for an Event Pointer */
18
+ export declare function createHandlerEventLink(handler: NostrEvent, pointer: EventPointer, platform?: HandlerLinkPlatform): string | undefined;
19
+ /** Returns a link for an Address Pointer */
20
+ export declare function createHandlerAddressLink(handler: NostrEvent, pointer: AddressPointer, platform?: HandlerLinkPlatform): string | undefined;
21
+ /** Creates a handler link for a pointer and optionally fallsback to a web link */
22
+ export declare function createHandlerLink(handler: NostrEvent, pointer: AddressPointer | EventPointer | ProfilePointer, platform?: HandlerLinkPlatform, webFallback?: boolean): string | undefined;
@@ -0,0 +1,67 @@
1
+ import { isAddressPointer, isEventPointer, naddrEncode, neventEncode, noteEncode, nprofileEncode, npubEncode, } from "applesauce-core/helpers/pointers";
2
+ import { getDisplayName, getProfileContent, getProfilePicture, isValidProfile } from "applesauce-core/helpers/profile";
3
+ import { processTags } from "applesauce-core/helpers/tags";
4
+ /** Returns an array of supported kinds for a given handler */
5
+ export function getHandlerSupportedKinds(handler) {
6
+ return processTags(handler.tags, (t) => (t[0] === "k" && t[1] ? parseInt(t[1]) : undefined));
7
+ }
8
+ /** Returns the name of the handler */
9
+ export function getHandlerName(handler) {
10
+ return getDisplayName(handler);
11
+ }
12
+ /** Returns the picture of the handler */
13
+ export function getHandlerPicture(handler, fallback) {
14
+ if (!isValidProfile(handler))
15
+ return fallback;
16
+ return getProfilePicture(handler, fallback);
17
+ }
18
+ /** Returns the description of the handler */
19
+ export function getHandlerDescription(handler) {
20
+ if (!isValidProfile(handler))
21
+ return;
22
+ return getProfileContent(handler).about;
23
+ }
24
+ /** Returns the web link template for a handler and type */
25
+ export function getHandlerLinkTemplate(handler, platform = "web", type) {
26
+ // Get all tags for this platform
27
+ const tags = handler.tags.filter((t) => t[0] === platform);
28
+ // Find the tag for this type, otherwise use default
29
+ if (type)
30
+ return tags.find((t) => t[2] === type)?.[1];
31
+ else
32
+ return tags.find((t) => t[2] === undefined || t[2] === "")?.[1];
33
+ }
34
+ /** Returns a link for a Profile Pointer */
35
+ export function createHandlerProfileLink(handler, pointer, platform = "web") {
36
+ // First attempt to use a nprofile link, then fallback to npub
37
+ return (getHandlerLinkTemplate(handler, platform, "nprofile")?.replace("<bech32>", nprofileEncode(pointer)) ||
38
+ getHandlerLinkTemplate(handler, platform, "npub")?.replace("<bech32>", npubEncode(pointer.pubkey)) ||
39
+ getHandlerLinkTemplate(handler, platform)?.replace("<bech32>", nprofileEncode(pointer)));
40
+ }
41
+ /** Returns a link for an Event Pointer */
42
+ export function createHandlerEventLink(handler, pointer, platform = "web") {
43
+ // First attempt to use a nevent link, then fallback to note
44
+ return (getHandlerLinkTemplate(handler, platform, "nevent")?.replace("<bech32>", neventEncode(pointer)) ||
45
+ getHandlerLinkTemplate(handler, platform, "note")?.replace("<bech32>", noteEncode(pointer.id)) ||
46
+ getHandlerLinkTemplate(handler, platform)?.replace("<bech32>", neventEncode(pointer)));
47
+ }
48
+ /** Returns a link for an Address Pointer */
49
+ export function createHandlerAddressLink(handler, pointer, platform = "web") {
50
+ // First attempt to use a nevent link, then fallback to note
51
+ return (getHandlerLinkTemplate(handler, platform, "naddr")?.replace("<bech32>", naddrEncode(pointer)) ||
52
+ getHandlerLinkTemplate(handler, platform)?.replace("<bech32>", naddrEncode(pointer)));
53
+ }
54
+ /** Creates a handler link for a pointer and optionally fallsback to a web link */
55
+ export function createHandlerLink(handler, pointer, platform, webFallback = true) {
56
+ let link = undefined;
57
+ if (isEventPointer(pointer))
58
+ link = createHandlerEventLink(handler, pointer, platform);
59
+ else if (isAddressPointer(pointer))
60
+ link = createHandlerAddressLink(handler, pointer, platform);
61
+ else
62
+ link = createHandlerProfileLink(handler, pointer, platform);
63
+ // Fallback to a web link if one cant be found for the platform
64
+ if (!link && platform && platform !== "web" && webFallback)
65
+ link = createHandlerLink(handler, pointer, "web");
66
+ return link;
67
+ }
@@ -0,0 +1,14 @@
1
+ import { kinds, KnownEvent, NostrEvent } from "applesauce-core/helpers/event";
2
+ /** Type for validated article events */
3
+ export type ArticleEvent = KnownEvent<kinds.LongFormArticle>;
4
+ /** Returns an articles title, if it exists */
5
+ export declare function getArticleTitle(article: ArticleEvent): string;
6
+ export declare function getArticleTitle(article: NostrEvent): string | undefined;
7
+ /** Returns an articles image, if it exists */
8
+ export declare function getArticleImage(article: NostrEvent): string | undefined;
9
+ /** Returns an articles summary, if it exists */
10
+ export declare function getArticleSummary(article: NostrEvent): string | undefined;
11
+ /** Returns an articles published date, if it exists */
12
+ export declare function getArticlePublished(article: NostrEvent): number;
13
+ /** validates that an event is a valid article event */
14
+ export declare function isValidArticle(article: NostrEvent): article is ArticleEvent;
@@ -0,0 +1,24 @@
1
+ import { getTagValue, kinds } from "applesauce-core/helpers/event";
2
+ export function getArticleTitle(article) {
3
+ return getTagValue(article, "title");
4
+ }
5
+ /** Returns an articles image, if it exists */
6
+ export function getArticleImage(article) {
7
+ return getTagValue(article, "image");
8
+ }
9
+ /** Returns an articles summary, if it exists */
10
+ export function getArticleSummary(article) {
11
+ return getTagValue(article, "summary");
12
+ }
13
+ /** Returns an articles published date, if it exists */
14
+ export function getArticlePublished(article) {
15
+ const ts = getTagValue(article, "published_at");
16
+ if (ts && !Number.isNaN(parseInt(ts)))
17
+ return parseInt(ts);
18
+ else
19
+ return article.created_at;
20
+ }
21
+ /** validates that an event is a valid article event */
22
+ export function isValidArticle(article) {
23
+ return article.kind === kinds.LongFormArticle && getArticleTitle(article) !== undefined && article.content.length > 0;
24
+ }
@@ -0,0 +1,11 @@
1
+ export declare const BLOSSOM_SERVER_LIST_KIND = 10063;
2
+ /** Check if two servers are the same */
3
+ export declare function areBlossomServersEqual(a: string | URL, b: string | URL): boolean;
4
+ /** Checks if a string is a sha256 hash */
5
+ export declare function isSha256(str: string): boolean;
6
+ /** Returns an ordered array of servers found in a server list event (10063) */
7
+ export declare function getBlossomServersFromList(event: {
8
+ tags: string[][];
9
+ } | string[][]): URL[];
10
+ /** A method that merges multiple arrays of blossom servers into a single array of unique servers */
11
+ export declare function mergeBlossomServers<T extends URL | string | (string | URL)>(...servers: (T | null | undefined | T[])[]): T[];
@@ -0,0 +1,40 @@
1
+ import { isNameValueTag, processTags } from "applesauce-core/helpers/tags";
2
+ export const BLOSSOM_SERVER_LIST_KIND = 10063;
3
+ /** Check if two servers are the same */
4
+ export function areBlossomServersEqual(a, b) {
5
+ const hostnameA = new URL("/", a).toString();
6
+ const hostnameB = new URL("/", b).toString();
7
+ return hostnameA === hostnameB;
8
+ }
9
+ /** Checks if a string is a sha256 hash */
10
+ export function isSha256(str) {
11
+ return !!str.match(/^[0-9a-f]{64}$/);
12
+ }
13
+ /** Returns an ordered array of servers found in a server list event (10063) */
14
+ export function getBlossomServersFromList(event) {
15
+ const tags = Array.isArray(event) ? event : event.tags;
16
+ return processTags(tags, (tag) => {
17
+ if (isNameValueTag(tag, "server") && URL.canParse(tag[1]))
18
+ return new URL("/", tag[1]);
19
+ else
20
+ return undefined;
21
+ });
22
+ }
23
+ /** A method that merges multiple arrays of blossom servers into a single array of unique servers */
24
+ export function mergeBlossomServers(...servers) {
25
+ let merged = [];
26
+ const seen = new Set();
27
+ for (const arg of servers) {
28
+ let arr = Array.isArray(arg) ? arg : [arg];
29
+ for (const s of arr) {
30
+ if (s === null || s === undefined)
31
+ continue;
32
+ const key = new URL("/", s).toString();
33
+ if (seen.has(key))
34
+ continue;
35
+ seen.add(key);
36
+ merged.push(s);
37
+ }
38
+ }
39
+ return merged;
40
+ }
@@ -0,0 +1,10 @@
1
+ export type ParsedInvoice = {
2
+ paymentRequest: string;
3
+ description: string;
4
+ amount?: number;
5
+ timestamp: number;
6
+ expiry: number;
7
+ paymentHash?: string;
8
+ };
9
+ /** Parses a lightning invoice */
10
+ export declare function parseBolt11(paymentRequest: string): ParsedInvoice;
@@ -0,0 +1,17 @@
1
+ import { decode } from "light-bolt11-decoder";
2
+ /** Parses a lightning invoice */
3
+ export function parseBolt11(paymentRequest) {
4
+ const decoded = decode(paymentRequest);
5
+ const timestamp = decoded.sections.find((s) => s.name === "timestamp")?.value ?? 0;
6
+ const description = decoded.sections.find((s) => s.name === "description")?.value ?? "";
7
+ const amount = parseInt(decoded.sections.find((s) => s.name === "amount")?.value ?? "0");
8
+ const paymentHash = decoded.sections.find((s) => s.name === "payment_hash");
9
+ return {
10
+ paymentRequest: decoded.paymentRequest,
11
+ description: description,
12
+ amount: amount,
13
+ timestamp: timestamp,
14
+ expiry: timestamp + decoded.expiry,
15
+ paymentHash: paymentHash?.value,
16
+ };
17
+ }
@@ -0,0 +1,30 @@
1
+ import { NostrEvent } from "applesauce-core/helpers/event";
2
+ import { HiddenContentSigner } from "applesauce-core/helpers/hidden-content";
3
+ import { AddressPointer, EventPointer } from "applesauce-core/helpers/pointers";
4
+ export declare const BookmarkPublicSymbol: unique symbol;
5
+ export declare const BookmarkHiddenSymbol: unique symbol;
6
+ /** Type for unlocked bookmarks events */
7
+ export type UnlockedBookmarks = {
8
+ [BookmarkHiddenSymbol]: Bookmarks;
9
+ };
10
+ export type Bookmarks = {
11
+ notes: EventPointer[];
12
+ articles: AddressPointer[];
13
+ hashtags: string[];
14
+ urls: string[];
15
+ };
16
+ /** Parses an array of tags into a {@link Bookmarks} object */
17
+ export declare function parseBookmarkTags(tags: string[][]): Bookmarks;
18
+ /** Merges any number of {@link Bookmarks} objects */
19
+ export declare function mergeBookmarks(...bookmarks: (Bookmarks | undefined)[]): Bookmarks;
20
+ /** Returns all the bookmarks of the event */
21
+ export declare function getBookmarks(bookmark: NostrEvent): Bookmarks;
22
+ /** Returns the public bookmarks of the event */
23
+ export declare function getPublicBookmarks(bookmark: NostrEvent): Bookmarks;
24
+ /** Checks if the hidden bookmarks are unlocked */
25
+ export declare function isHiddenBookmarksUnlocked<T extends NostrEvent>(bookmark: T): bookmark is T & UnlockedBookmarks;
26
+ /** Returns the bookmarks of the event if its unlocked */
27
+ export declare function getHiddenBookmarks<T extends NostrEvent & UnlockedBookmarks>(bookmark: T): Bookmarks;
28
+ export declare function getHiddenBookmarks<T extends NostrEvent>(bookmark: T): Bookmarks | undefined;
29
+ /** Unlocks the hidden bookmarks on a bookmarks event */
30
+ export declare function unlockHiddenBookmarks(bookmark: NostrEvent, signer: HiddenContentSigner): Promise<Bookmarks>;