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

/**
* 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);
}