UNPKG

@nostr-dev-kit/ndk

Version:

NDK - Nostr Development Kit

117 lines (96 loc) 3.4 kB
import type { NostrEvent } from "../../index.js"; import type { NDK } from "../../ndk/index.js"; import { NDKPrivateKeySigner } from "../../signers/private-key/index.js"; import { NDKEvent } from "../index.js"; /** * Represents a project event in Nostr (kind 31933). * Projects are a special type of article event used by TENEX and other project management tools. */ export class NDKProject extends NDKEvent { static kind = 31933; static kinds = [NDKProject.kind]; private _signer: NDKPrivateKeySigner | undefined; constructor(ndk?: NDK, rawEvent?: NostrEvent) { super(ndk, rawEvent); this.kind = 31933; } static from(event: NDKEvent): NDKProject { return new NDKProject(event.ndk, event.rawEvent()); } set repo(value: string | undefined) { this.removeTag("repo"); if (value) this.tags.push(["repo", value]); } set hashtags(values: string[]) { this.removeTag("hashtags"); if (values.filter((t) => t.length > 0).length) this.tags.push(["hashtags", ...values]); } get hashtags(): string[] { const tag = this.tags.find((tag) => tag[0] === "hashtags"); return tag ? tag.slice(1) : []; } get repo(): string | undefined { return this.tagValue("repo"); } get title(): string | undefined { return this.tagValue("title"); } set title(value: string | undefined) { this.removeTag("title"); if (value) this.tags.push(["title", value]); } get picture(): string | undefined { return this.tagValue("picture"); } set picture(value: string | undefined) { this.removeTag("picture"); if (value) this.tags.push(["picture", value]); } set description(value: string) { this.content = value; } get description(): string { return this.content; } /** * The project slug, derived from the 'd' tag. */ get slug(): string { return this.dTag ?? "empty-dtag"; } public async getSigner(): Promise<NDKPrivateKeySigner> { if (this._signer) return this._signer; const encryptedKey = this.tagValue("key"); if (!encryptedKey) { this._signer = NDKPrivateKeySigner.generate(); await this.encryptAndSaveNsec(); } else { const decryptedKey = await this.ndk?.signer?.decrypt( this.ndk.activeUser!, encryptedKey ); if (!decryptedKey) { throw new Error("Failed to decrypt project key or missing signer context."); } this._signer = new NDKPrivateKeySigner(decryptedKey); } return this._signer; } public async getNsec(): Promise<string> { const signer = await this.getSigner(); return signer.privateKey!; } public async setNsec(value: string) { this._signer = new NDKPrivateKeySigner(value); await this.encryptAndSaveNsec(); } private async encryptAndSaveNsec() { if (!this._signer) throw new Error("Signer is not set."); const key = this._signer.privateKey!; const encryptedKey = await this.ndk?.signer?.encrypt(this.ndk.activeUser!, key); if (encryptedKey) { this.removeTag("key"); this.tags.push(["key", encryptedKey]); } } }