commit 9be97c83006f2a88302d8b5705c4e6755a215170
parent b9af45317927dddd4b6f8f82d211e55afcb5dbd3
Author: triesap <137732411+triesap@users.noreply.github.com>
Date: Fri, 30 Aug 2024 21:19:42 +0000
client: add iclientnostrlib
Diffstat:
4 files changed, 144 insertions(+), 3 deletions(-)
diff --git a/client/package.json b/client/package.json
@@ -21,6 +21,7 @@
"@capacitor/share": "^6.0.0",
"@capacitor/splash-screen": "^6.0.0",
"@capacitor/status-bar": "^6.0.0",
+ "@noble/hashes": "^1.4.0",
"@nostr-dev-kit/ndk": "^2.7.1",
"@radroots/capacitor-bluetooth-le": "workspace:*",
"@radroots/capacitor-date-picker": "workspace:*",
@@ -29,7 +30,8 @@
"@radroots/capacitor-sqlite": "workspace:*",
"@radroots/capacitor-wifi": "workspace:*",
"@radroots/models": "workspace:*",
- "@radroots/utils": "workspace:*"
+ "@radroots/utils": "workspace:*",
+ "nostr-tools": "^2.7.2"
},
"devDependencies": {
"typescript": "^5.3.3"
diff --git a/client/src/nostr/index.ts b/client/src/nostr/index.ts
@@ -1,10 +1,16 @@
import type { IClientNostr } from "../types";
import { ClientNostrEvents } from "./events";
+import { ClientNostrLib } from "./lib";
export class ClientNostr implements IClientNostr {
private _ev: ClientNostrEvents = new ClientNostrEvents();
+ private _lib: ClientNostrLib = new ClientNostrLib();
public get ev() {
return this._ev;
}
+
+ public get lib() {
+ return this._lib;
+ }
}
\ No newline at end of file
diff --git a/client/src/nostr/lib.ts b/client/src/nostr/lib.ts
@@ -0,0 +1,116 @@
+import { bytesToHex, hexToBytes } from '@noble/hashes/utils';
+import { Relay, generateSecretKey, getPublicKey, nip19, } from 'nostr-tools';
+import type { IClientNostrLib, IClientNostrLibRelayConnectResponse } from '../types';
+
+export class ClientNostrLib implements IClientNostrLib {
+ private generate_key_bytes(): Uint8Array {
+ const secret_key = generateSecretKey();
+ return secret_key;
+ };
+
+ private get_key_hex(bytes: Uint8Array): string {
+ const hex = bytesToHex(bytes);
+ return hex;
+ };
+
+ private get_key_bytes(hex: string): Uint8Array {
+ const bytes = hexToBytes(hex);
+ return bytes;
+ };
+
+ public async relay_connect(url: string): Promise<IClientNostrLibRelayConnectResponse | undefined> {
+ try {
+
+ if (!url) return undefined;
+ const conn = await Relay.connect(url);
+ if (conn && typeof conn.connected === `boolean` && typeof conn.url === `string` && conn.url) return { url: conn.url, connected: conn.connected };
+ return undefined;
+ } catch (e) {
+ return undefined;
+ };
+ }
+
+ /**
+ *
+ * @returns nostr secret key hex
+ */
+ public generate_key(): string {
+ const bytes = this.generate_key_bytes();
+ const hex = this.get_key_hex(bytes);
+ return hex;
+ };
+
+ /**
+ *
+ * @returns nostr public key hex
+ */
+ public public_key(secret_key_hex: string | undefined): string {
+ if (!secret_key_hex) throw new Error('Error: Secret key hex');
+ const bytes = this.get_key_bytes(secret_key_hex);
+ const hex = getPublicKey(bytes)
+ return hex;
+ }
+
+ /**
+ *
+ * @returns nostr public key npub
+ */
+ public npub(public_key_hex: string | undefined): string {
+ if (!public_key_hex) throw new Error(`Error: public_key_hex must be defined`);
+ const npub = nip19.npubEncode(public_key_hex)
+ return npub;
+ }
+
+ /**
+ *
+ * @returns public key hex from npub
+ */
+ public npub_decode(npub: string): string {
+ const hex = nip19.decode(npub);
+ if (hex && hex.type === `npub` && hex.data) return hex.data
+ return ``;
+ }
+
+ /**
+ *
+ * @returns nostr secret key nsec
+ */
+ public nsec(secret_key_hex: string | undefined): string {
+ if (!secret_key_hex) return ``;
+ const bytes = this.get_key_bytes(secret_key_hex);
+ const nsec = nip19.nsecEncode(bytes);
+ return nsec;
+ }
+
+ /**
+ *
+ * @returns nostr secret key hex from nsec
+ */
+ public nsec_decode(nsec: string): string | undefined {
+ if (!nsec) return undefined;
+ const decode = nip19.decode(nsec);
+ if (decode && decode.type === `nsec` && decode.data && typeof decode.data === `string`) return decode.data
+ return undefined;
+ }
+
+ /**
+ *
+ * @returns nostr public key nprofile
+ */
+ public nprofile(public_key_hex: string, relays: string[]): string {
+ if (!public_key_hex || !relays.length) return ``;
+ const nprofile = nip19.nprofileEncode({ pubkey: public_key_hex, relays })
+ return nprofile;
+ }
+
+ /**
+ *
+ * @returns nostr public key nprofile
+ */
+ public nprofile_decode(nprofile: string): [string, string[]] | undefined {
+ if (!nprofile) return undefined;
+ const decode = nip19.decode(nprofile);
+ if (decode && decode.type === `nprofile` && decode.data && decode.data.pubkey && decode.data.relays) return [decode.data.pubkey, decode.data.relays]
+ return undefined;
+ }
+};
diff --git a/client/src/types.ts b/client/src/types.ts
@@ -27,6 +27,7 @@ export type IClient = {
export type IClientNostr = {
ev: IClientNostrEvents;
+ lib: IClientNostrLib
};
export type IClientPlatform = `androiď` | `ios` | `web`;
@@ -260,4 +261,21 @@ export type IClientSettings = {
export type IClientNostrEvents = {
first_tag_value(event: NDKEvent, tag_name: string): string;
-};
-\ No newline at end of file
+};
+
+export type IClientNostrLibRelayConnectResponse = {
+ url: string;
+ connected: boolean;
+};
+
+export type IClientNostrLib = {
+ relay_connect(url: string): Promise<IClientNostrLibRelayConnectResponse | undefined>;
+ generate_key(): string;
+ public_key(secret_key_hex: string | undefined): string;
+ npub(public_key_hex: string | undefined): string;
+ npub_decode(npub: string): string;
+ nsec(secret_key_hex: string | undefined): string;
+ nsec_decode(nsec: string): string | undefined;
+ nprofile(public_key_hex: string, relays: string[]): string;
+ nprofile_decode(nprofile: string): [string, string[]] | undefined;
+};