You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
64 lines
1.9 KiB
64 lines
1.9 KiB
/** |
|
* Nsec signer (direct private key, NIP-49 encrypted) |
|
*/ |
|
|
|
import { decryptPrivateKey } from '../security/key-management.js'; |
|
import { getPublicKey, finalizeEvent } from 'nostr-tools'; |
|
import type { NostrEvent } from '../../types/nostr.js'; |
|
|
|
/** |
|
* Convert hex string to Uint8Array |
|
*/ |
|
function hexToBytes(hex: string): Uint8Array { |
|
if (hex.length !== 64) { |
|
throw new Error('Invalid hex string: must be 64 characters (32 bytes)'); |
|
} |
|
const bytes = new Uint8Array(32); |
|
for (let i = 0; i < 32; i++) { |
|
const hexByte = hex.slice(i * 2, i * 2 + 2); |
|
bytes[i] = parseInt(hexByte, 16); |
|
} |
|
return bytes; |
|
} |
|
|
|
/** |
|
* Sign event with nsec (private key) |
|
* Uses proper secp256k1 cryptography via nostr-tools finalizeEvent |
|
*/ |
|
export async function signEventWithNsec( |
|
event: Omit<NostrEvent, 'sig' | 'id'>, |
|
ncryptsec: string, |
|
password: string |
|
): Promise<NostrEvent> { |
|
// Decrypt private key - NEVER log the nsec, password, or ncryptsec |
|
const nsec = await decryptPrivateKey(ncryptsec, password); |
|
|
|
// Convert hex string to Uint8Array for finalizeEvent |
|
const privkey = hexToBytes(nsec); |
|
|
|
// Use nostr-tools finalizeEvent to properly sign the event |
|
// This computes the event ID (SHA256) and secp256k1 signature |
|
return finalizeEvent(event, privkey); |
|
} |
|
|
|
/** |
|
* Get public key from private key (hex string) |
|
* Uses proper secp256k1 cryptography via nostr-tools |
|
*/ |
|
export async function getPublicKeyFromNsec(nsec: string): Promise<string> { |
|
// Convert hex string to Uint8Array |
|
// nsec is a 64-character hex string representing 32 bytes |
|
if (nsec.length !== 64) { |
|
throw new Error('Invalid nsec: must be 64 hex characters (32 bytes)'); |
|
} |
|
|
|
// Convert hex string to bytes |
|
const bytes = new Uint8Array(32); |
|
for (let i = 0; i < 32; i++) { |
|
const hexByte = nsec.slice(i * 2, i * 2 + 2); |
|
bytes[i] = parseInt(hexByte, 16); |
|
} |
|
|
|
// Use nostr-tools to get the proper public key |
|
return getPublicKey(bytes); |
|
}
|
|
|