commit c592084edfc46f3ed3441081fa920856d5b0e191
parent 4001dfc948a57aa6b5acb900013506ea805364bc
Author: triesap <137732411+triesap@users.noreply.github.com>
Date: Fri, 23 May 2025 02:45:31 +0000
utils-nostr: add nip-22 comments events, refactor tags utils, refactor ndk utils. add/edit types
Diffstat:
6 files changed, 138 insertions(+), 55 deletions(-)
diff --git a/utils-nostr/src/lib/ndk.ts b/utils-nostr/src/lib/ndk.ts
@@ -1,17 +1,30 @@
-import { INostrClassified, INostrFollow, INostrJobRequest, INostrReaction, NostrEventTags, tags_classified, tags_follow_list, tags_job_request, tags_reaction, time_now_ms, type INostrMetadata } from '$root';
-import NDK, { NDKEvent, NDKKind, NDKPrivateKeySigner, NDKUser } from '@nostr-dev-kit/ndk';
+import { INostrClassified, INostrComment, INostrFollow, INostrJobRequest, INostrReaction, NostrEventTags, tags_classified, tags_comment, tags_follow_list, tags_job_request, tags_reaction, time_now_ms, type INostrMetadata } from '$root';
+import NDK, { NDKCacheAdapter, NDKEvent, NDKKind, NDKPrivateKeySigner, NDKUser } from '@nostr-dev-kit/ndk';
export type NDKEventFigure<T extends object> = {
- $ndk: NDK;
- $ndk_user: NDKUser;
+ ndk: NDK;
+ ndk_user: NDKUser;
+ date_published?: Date;
} & T;
+export const create_ndk = (explicitRelayUrls: string[], cacheAdapter?: NDKCacheAdapter): NDK => {
+ return new NDK({
+ explicitRelayUrls,
+ enableOutboxModel: false,
+ cacheAdapter
+ });
+};
+
+export const create_ndk_signer = (secret_key: string): NDKPrivateKeySigner => {
+ return new NDKPrivateKeySigner(secret_key);
+};
+
export const ndk_init = async (opts: {
- $ndk: NDK;
+ ndk: NDK;
secret_key: string;
}): Promise<NDKUser | undefined> => {
try {
- const { $ndk: ndk, secret_key } = opts;
+ const { ndk, secret_key } = opts;
const signer = new NDKPrivateKeySigner(secret_key);
ndk.signer = signer;
const user = await signer.user();
@@ -32,10 +45,12 @@ export const ndk_event = async (opts: NDKEventFigure<{
}
}>): Promise<NDKEvent | undefined> => {
try {
- const { $ndk: ndk, $ndk_user: ndk_user, basis } = opts;
+ const { ndk: ndk, ndk_user: ndk_user, basis } = opts;
const time_now = time_now_ms();
+ const published_at = opts.date_published ? Math.floor(opts.date_published.getTime() / 1000).toString()
+ : time_now.toString()
const tags: NostrEventTags = [
- ['published_at', time_now.toString()],
+ ['published_at', published_at],
];
if (basis.tags?.length) tags.push(...basis.tags);
const ev = new NDKEvent(ndk, {
@@ -52,12 +67,12 @@ export const ndk_event = async (opts: NDKEventFigure<{
};
export const ndk_event_metadata = async (opts: NDKEventFigure<{
- metadata: INostrMetadata
+ data: INostrMetadata
}>): Promise<NDKEvent | undefined> => {
- const { $ndk, $ndk_user, metadata: data } = opts;
+ const { ndk, ndk_user, data } = opts;
return await ndk_event({
- $ndk,
- $ndk_user,
+ ndk,
+ ndk_user,
basis: {
kind: 0,
content: JSON.stringify(data),
@@ -66,27 +81,27 @@ export const ndk_event_metadata = async (opts: NDKEventFigure<{
};
export const ndk_event_follows = async (opts: NDKEventFigure<{
- list: INostrFollow[];
+ data: INostrFollow;
}>): Promise<NDKEvent | undefined> => {
- const { $ndk, $ndk_user, list: data } = opts;
+ const { ndk, ndk_user, data } = opts;
return await ndk_event({
- $ndk,
- $ndk_user,
+ ndk,
+ ndk_user,
basis: {
kind: 3,
content: ``,
- tags: tags_follow_list(data),
+ tags: tags_follow_list(data.list),
},
});
};
export const ndk_event_classified = async (opts: NDKEventFigure<{
- classified: INostrClassified;
+ data: INostrClassified;
}>): Promise<NDKEvent | undefined> => {
- const { $ndk, $ndk_user, classified: data } = opts;
+ const { ndk, ndk_user, data } = opts;
return await ndk_event({
- $ndk,
- $ndk_user,
+ ndk,
+ ndk_user,
basis: {
kind: NDKKind.Classified,
content: ``,
@@ -98,10 +113,10 @@ export const ndk_event_classified = async (opts: NDKEventFigure<{
export const ndk_event_job_request = async (opts: NDKEventFigure<{
data: INostrJobRequest;
}>): Promise<NDKEvent | undefined> => {
- const { $ndk, $ndk_user, data } = opts;
+ const { ndk, ndk_user, data } = opts;
return await ndk_event({
- $ndk,
- $ndk_user,
+ ndk,
+ ndk_user,
basis: {
kind: NDKKind.DVMReqDiscoveryNostrContent,
content: ``,
@@ -113,10 +128,10 @@ export const ndk_event_job_request = async (opts: NDKEventFigure<{
export const ndk_event_reaction = async (opts: NDKEventFigure<{
data: INostrReaction;
}>): Promise<NDKEvent | undefined> => {
- const { $ndk, $ndk_user, data } = opts;
+ const { ndk, ndk_user, data } = opts;
return await ndk_event({
- $ndk,
- $ndk_user,
+ ndk,
+ ndk_user,
basis: {
kind: NDKKind.Reaction,
content: data.content,
@@ -124,3 +139,19 @@ export const ndk_event_reaction = async (opts: NDKEventFigure<{
},
});
};
+
+export const ndk_event_comment = async (opts: NDKEventFigure<{
+ data: INostrComment;
+}>): Promise<NDKEvent | undefined> => {
+ const { ndk, ndk_user, data } = opts;
+ return await ndk_event({
+ ndk,
+ ndk_user,
+ basis: {
+ kind: NDKKind.GenericReply,
+ content: data.content,
+ tags: tags_comment(data)
+ },
+ });
+};
+
diff --git a/utils-nostr/src/lib/tags.ts b/utils-nostr/src/lib/tags.ts
@@ -1,4 +1,4 @@
-import { INostrClassified, INostrJobRequest, INostrReaction, NostrEventTagClient, NostrEventTagLocation, NostrEventTagMediaUpload, NostrEventTagPrice, NostrEventTagPriceDiscount, NostrEventTagQuantity, type INostrFollow, type NostrEventTag, type NostrEventTags } from "$root";
+import { INostrClassified, INostrComment, INostrFollowList, INostrJobRequest, INostrReaction, NostrEventTagClient, NostrEventTagLocation, NostrEventTagMediaUpload, NostrEventTagPrice, NostrEventTagPriceDiscount, NostrEventTagQuantity, type NostrEventTag, type NostrEventTags } from "$root";
import ngeotags, { type InputData as NostrGeotagsInputData } from "nostr-geotags";
export const tag_client = (opts: NostrEventTagClient, d_tag?: string): NostrEventTag => {
@@ -8,7 +8,7 @@ export const tag_client = (opts: NostrEventTagClient, d_tag?: string): NostrEven
return tag;
};
-export const tags_follow_list = (list: INostrFollow[]): NostrEventTags => {
+export const tags_follow_list = (list: INostrFollowList[]): NostrEventTags => {
return list.map(({ public_key, relay_url, contact_name }) => {
const entry = [`p`, public_key];
if (relay_url) entry.push(relay_url);
@@ -113,3 +113,38 @@ export const tags_reaction = (opts: INostrReaction): NostrEventTags => {
if (ref_event.d_tag) tags.push([`a`, `${ref_kind}:${ref_author}:${ref_event.d_tag}`, ...ref_event.relays || ``])
return tags;
};
+
+export const tags_comment = (opts: INostrComment): NostrEventTags => {
+ const { root_event, ref_event } = opts;
+
+ const root = {
+ kind: root_event.kind.toString(),
+ author: root_event.author,
+ id: root_event.id,
+ d_tag: root_event.d_tag,
+ relays: root_event.relays || [],
+ };
+
+ const parent = (ref_event && ref_event.id)
+ ? {
+ kind: ref_event.kind.toString(),
+ author: ref_event.author,
+ id: ref_event.id,
+ d_tag: ref_event.d_tag,
+ relays: ref_event.relays || [],
+ }
+ : root;
+
+ const tags: NostrEventTags = [
+ ["E", root.id, ...root.relays],
+ ["P", root.author],
+ ["K", root.kind],
+ ...(root.d_tag ? [["A", `${root.kind}:${root.author}:${root.d_tag}`, ...root.relays]] : []),
+ ["e", parent.id, ...parent.relays],
+ ["p", parent.author],
+ ["k", parent.kind],
+ ...(parent.d_tag ? [["a", `${parent.kind}:${parent.author}:${parent.d_tag}`, ...parent.relays]] : []),
+ ];
+
+ return tags;
+};
+\ No newline at end of file
diff --git a/utils-nostr/src/lib/types.ts b/utils-nostr/src/lib/types.ts
@@ -1,3 +1,4 @@
+import { NostrEventReferenced } from "$root";
import { ListingOrder } from "@radroots/radroots-common-bindings";
import { type EventTemplate as NostrToolsEventTemplate } from "nostr-tools";
@@ -14,12 +15,16 @@ export type INostrMetadata = {
bot?: boolean;
};
-export type INostrFollow = {
+export type INostrFollowList = {
public_key: string;
relay_url?: string;
contact_name?: string;
};
+export type INostrFollow = {
+ list: INostrFollowList[]
+};
+
export type NostrEventTagQuantity = {
amt: string;
unit: string;
@@ -140,12 +145,12 @@ export type NostrEventTagClient = {
};
export type INostrReaction = {
- ref_event: {
- id: string;
- kind: number;
- author: string;
- relays?: string[];
- d_tag?: string;
- },
+ ref_event: NostrEventReferenced;
+ content: string;
+};
+
+export type INostrComment = {
+ root_event: NostrEventReferenced;
+ ref_event?: NostrEventReferenced;
content: string;
};
\ No newline at end of file
diff --git a/utils-nostr/src/services/events/lib.ts b/utils-nostr/src/services/events/lib.ts
@@ -40,12 +40,12 @@ export class NostrEventService implements INostrEventService {
return lib_nostr_nevent_encode(opts);
};
- public metadata = async ($ndk: NDK, opts: INostrMetadata): Promise<INostrEventServiceEventResolve> => {
- const $ndk_user = await this.resolve_ndk_user($ndk);
- if (`err` in $ndk_user) return $ndk_user;
+ public metadata = async (ndk: NDK, opts: INostrMetadata): Promise<INostrEventServiceEventResolve> => {
+ const ndk_user = await this.resolve_ndk_user(ndk);
+ if (`err` in ndk_user) return ndk_user;
const ev = await ndk_event({
- $ndk,
- $ndk_user,
+ ndk,
+ ndk_user,
basis: {
kind: NDKKind.Metadata,
content: JSON.stringify(opts),
@@ -54,24 +54,24 @@ export class NostrEventService implements INostrEventService {
return this.resolve_ndk_event(ev);
}
- public follows = async ($ndk: NDK, list: INostrFollow[]): Promise<INostrEventServiceEventResolve> => {
- const $ndk_user = await this.resolve_ndk_user($ndk);
- if (`err` in $ndk_user) return $ndk_user;
+ public follows = async (ndk: NDK, data: INostrFollow): Promise<INostrEventServiceEventResolve> => {
+ const ndk_user = await this.resolve_ndk_user(ndk);
+ if (`err` in ndk_user) return ndk_user;
const ev = await ndk_event_follows({
- $ndk,
- $ndk_user,
- list
+ ndk,
+ ndk_user,
+ data
});
return this.resolve_ndk_event(ev);
}
- public classified = async ($ndk: NDK, classified: INostrClassified): Promise<INostrEventServiceEventResolve> => {
- const $ndk_user = await this.resolve_ndk_user($ndk);
- if (`err` in $ndk_user) return $ndk_user;
+ public classified = async (ndk: NDK, data: INostrClassified): Promise<INostrEventServiceEventResolve> => {
+ const ndk_user = await this.resolve_ndk_user(ndk);
+ if (`err` in ndk_user) return ndk_user;
const ev = await ndk_event_classified({
- $ndk,
- $ndk_user,
- classified
+ ndk,
+ ndk_user,
+ data
});
return this.resolve_ndk_event(ev);
}
diff --git a/utils-nostr/src/services/events/types.ts b/utils-nostr/src/services/events/types.ts
@@ -19,6 +19,6 @@ export type INostrEventService = {
nostr_event_verify: (event: NostrToolsEvent) => boolean;
nevent_encode: (opts: INostrEventServiceNeventEncode) => string;
metadata: (ndk: NDK, opts: INostrMetadata) => Promise<INostrEventServiceEventResolve>;
- follows: (ndk: NDK, opts: INostrFollow[]) => Promise<INostrEventServiceEventResolve>;
+ follows: (ndk: NDK, opts: INostrFollow) => Promise<INostrEventServiceEventResolve>;
classified: (ndk: NDK, opts: INostrClassified) => Promise<INostrEventServiceEventResolve>;
};
diff --git a/utils-nostr/src/types.ts b/utils-nostr/src/types.ts
@@ -1,4 +1,14 @@
+import { NDKEvent } from "@nostr-dev-kit/ndk";
+
+export type NostrNdkEvent = NDKEvent;
export type NostrEventTag = string[];
export type NostrEventTags = NostrEventTag[];
export type ErrorMessage<T extends string> = { err: T };
export type ResolveError<T> = T | ErrorMessage<string>;
+export type NostrEventReferenced = {
+ id: string;
+ kind: number;
+ author: string;
+ relays?: string[];
+ d_tag?: string;
+}
+\ No newline at end of file