commit 916633c3fc76f478838d1f54ac57e3e846aef7d0
parent 91ea2917c65cf38c440587700fa9ce47b8467f75
Author: triesap <137732411+triesap@users.noreply.github.com>
Date: Sun, 25 Aug 2024 11:58:06 +0000
utils: add nostr tools
Diffstat:
8 files changed, 177 insertions(+), 2 deletions(-)
diff --git a/utils/package.json b/utils/package.json
@@ -10,9 +10,16 @@
"dev": "tsc -w"
},
"devDependencies": {
+ "@types/uuid": "^10.0.0",
"typescript": "^5.3.3"
},
"publishConfig": {
"access": "public"
+ },
+ "dependencies": {
+ "@noble/hashes": "^1.4.0",
+ "jshashes": "^1.0.8",
+ "nostr-tools": "^2.7.2",
+ "uuid": "^10.0.0"
}
}
\ No newline at end of file
diff --git a/utils/src/global.d.ts b/utils/src/global.d.ts
@@ -0,0 +1 @@
+declare module "jshashes";
+\ No newline at end of file
diff --git a/utils/src/index.ts b/utils/src/index.ts
@@ -1,3 +1,6 @@
import "./global.d.ts";
+export * from "./jshashes"
+export * from "./nostr-tools"
+export * from "./types"
export * from "./utils"
diff --git a/utils/src/jshashes.ts b/utils/src/jshashes.ts
@@ -0,0 +1,19 @@
+import * as jshashes from "jshashes";
+
+export function hash(str: string): string {
+ const hasher = new jshashes.SHA256();
+ const hash = hasher.b64(str);
+ return String(hash);
+};
+
+export function hash_obj(obj: any): string {
+ const hasher = new jshashes.SHA256();
+ const hash = hasher.b64(JSON.stringify(obj));
+ return String(hash);
+};
+
+export function hashHmac(l: string, hmac_iv: string): string {
+ const hasher = new jshashes.SHA256();
+ const hash = hasher.b64_hmac(hmac_iv, l);
+ return String(hash);
+};
diff --git a/utils/src/nostr-tools.ts b/utils/src/nostr-tools.ts
@@ -0,0 +1,116 @@
+import { bytesToHex, hexToBytes } from '@noble/hashes/utils';
+import { Relay, generateSecretKey, getPublicKey, nip19, } from 'nostr-tools';
+
+export class NostrTools {
+ 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<{ url: string, connected: boolean } | 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 | undefined {
+ if (!public_key_hex) return undefined;
+ const npub = nip19.npubEncode(public_key_hex)
+ return npub;
+ }
+
+ /**
+ *
+ * @returns public key hex from npub
+ */
+ public npub_decode(npub: string): string {
+ // if (!npub) return undefined;
+ 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/utils/src/types.ts b/utils/src/types.ts
@@ -0,0 +1,3 @@
+export type ErrorResponse = {
+ error: string;
+};
+\ No newline at end of file
diff --git a/utils/src/utils.ts b/utils/src/utils.ts
@@ -1,3 +1,26 @@
+import { v4 } from "uuid";
+import { ErrorResponse } from "./types";
+
+export const regex: Record<string, RegExp> = {
+ word_only: /^[a-zA-Z]+$/,
+ alpha: /[a-zA-Z ]$/,
+ num: /^[0-9.]+$/,
+};
+
+export function uuidv4() {
+ return v4();
+};
+
export function time_now_ms(): number {
return Math.floor(new Date().getTime() / 1000);
};
+
+export function time_created_on(): string {
+ return new Date().toUTCString();
+};
+
+export function err_msg(e: unknown, append?: string): ErrorResponse {
+ const msg = (e as Error).message ? (e as Error).message : String(e);
+ const error = `${msg}${append ? ` ${append}` : ``}`;
+ return { error };
+};
diff --git a/utils/tsconfig.json b/utils/tsconfig.json
@@ -1,12 +1,13 @@
{
"compilerOptions": {
"lib": [
- "es2021"
+ "es2021",
+ "dom"
],
"module": "CommonJS",
"outDir": "./dist",
"rootDir": "./src",
- "noEmit": true
+ "noEmit": true,
},
"include": [
"src"