lib.ts (2837B)
1 import { bytesToHex, hexToBytes } from "@noble/hashes/utils"; 2 import { 3 generateSecretKey, 4 getPublicKey, 5 nip19, 6 } from "nostr-tools"; 7 8 export const REGEX_NOSTR_KEY = /^[a-f0-9]{64}$/; 9 10 export const nostr_key_bytes_from_hex = (hex: string): Uint8Array => { 11 return hexToBytes(hex); 12 }; 13 14 export const nostr_key_hex_from_bytes = (bytes: Uint8Array): string => { 15 return bytesToHex(bytes); 16 }; 17 18 export const nostr_key_generate = (): string => { 19 const bytes = generateSecretKey(); 20 return nostr_key_hex_from_bytes(bytes); 21 }; 22 23 export const nostr_npub_encode = (public_key_hex?: string): string | undefined => { 24 try { 25 if (!public_key_hex) return undefined; 26 const npub = nip19.npubEncode(public_key_hex); 27 return npub; 28 } catch { 29 return undefined; 30 } 31 }; 32 33 export const nostr_npub_decode = (npub?: string): string | undefined => { 34 try { 35 if (!npub) return undefined; 36 const { type, data } = nip19.decode(npub); 37 if (type === "npub" && data) return data; 38 } catch { 39 return undefined; 40 } 41 }; 42 43 export const nostr_nsec_encode = (secret_key_hex?: string): string | undefined => { 44 try { 45 if (!secret_key_hex) return undefined; 46 const bytes = nostr_key_bytes_from_hex(secret_key_hex); 47 return nip19.nsecEncode(bytes); 48 } catch { 49 return undefined; 50 } 51 }; 52 53 export const nostr_nsec_decode = (nsec?: string): string | undefined => { 54 try { 55 if (!nsec) return undefined; 56 const decode = nip19.decode(nsec); 57 if (decode && decode.type === "nsec" && decode.data) return bytesToHex(decode.data); 58 return undefined; 59 } catch { 60 return undefined; 61 } 62 }; 63 64 export const nostr_nprofile_encode = ( 65 public_key_hex: string, 66 relays: string[], 67 ): string | undefined => { 68 try { 69 if (!public_key_hex || !relays.length) return undefined; 70 const nprofile = nip19.nprofileEncode({ pubkey: public_key_hex, relays }); 71 return nprofile; 72 } catch { 73 return undefined; 74 } 75 }; 76 77 export const nostr_nprofile_decode = ( 78 nprofile?: string, 79 ): nip19.ProfilePointer | undefined => { 80 try { 81 if (!nprofile) return undefined; 82 const { type, data } = nip19.decode(nprofile); 83 if (type === "nprofile" && data) return data; 84 } catch { 85 return undefined; 86 } 87 }; 88 89 export const nostr_public_key_from_secret = (secret_key_hex: string): string => { 90 const bytes = nostr_key_bytes_from_hex(secret_key_hex); 91 return getPublicKey(bytes); 92 }; 93 94 export const nostr_secret_key_validate = (secret_key: string): string | undefined => { 95 const trimmed = secret_key.trim(); 96 if (REGEX_NOSTR_KEY.test(trimmed)) return trimmed; 97 const decoded = nostr_nsec_decode(trimmed); 98 if (decoded) return decoded; 99 return undefined; 100 };