node-red-contrib-nostr
Version:
Node-RED nodes for seamless Nostr protocol integration. Features robust WebSocket handling, event filtering, and NPUB-based routing. Built with TypeScript for type safety and extensive testing. Perfect for Nostr automation flows.
81 lines (80 loc) • 3.27 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.KeyManager = void 0;
exports.getDefaultReaderKeys = getDefaultReaderKeys;
exports.generateKeyPair = generateKeyPair;
exports.hexToNpub = hexToNpub;
exports.npubToHex = npubToHex;
exports.getPublicKey = getPublicKey;
const secp256k1_js_1 = require("@noble/curves/secp256k1.js");
const bech32_1 = require("bech32");
const utils_js_1 = require("@noble/hashes/utils.js");
const sha2_js_1 = require("@noble/hashes/sha2.js");
// Lazily-initialized ephemeral key pair for read-only operations.
// Generated at first use so no secret material is stored in source code.
let _defaultReaderKeys = null;
async function getDefaultReaderKeys() {
if (!_defaultReaderKeys) {
_defaultReaderKeys = await generateKeyPair();
}
return _defaultReaderKeys;
}
/**
* Generate a new Nostr key pair
* @returns {Promise<Object>} Object containing private and public keys
*/
async function generateKeyPair() {
const privateKey = secp256k1_js_1.secp256k1.utils.randomSecretKey();
const publicKey = secp256k1_js_1.secp256k1.getPublicKey(privateKey, true);
return {
privateKey: (0, utils_js_1.bytesToHex)(privateKey),
publicKey: (0, utils_js_1.bytesToHex)(publicKey)
};
}
/**
* Convert a hex public key to npub format
* @param {string} publicKeyHex - Public key in hex format
* @returns {string} npub formatted public key
*/
function hexToNpub(publicKeyHex) {
const words = bech32_1.bech32.toWords(Buffer.from(publicKeyHex, 'hex'));
return bech32_1.bech32.encode('npub', words);
}
/**
* Convert an npub to hex format
* @param {string} npub - npub formatted public key
* @returns {string} Public key in hex format
*/
function npubToHex(npub) {
const { words } = bech32_1.bech32.decode(npub);
return Buffer.from(bech32_1.bech32.fromWords(words)).toString('hex');
}
/**
* Get public key from private key
* @param {string} privateKeyHex - Private key in hex format
* @returns {Promise<string>} Public key in hex format
*/
async function getPublicKey(privateKeyHex) {
const publicKey = secp256k1_js_1.secp256k1.getPublicKey((0, utils_js_1.hexToBytes)(privateKeyHex), true);
return (0, utils_js_1.bytesToHex)(publicKey);
}
class KeyManager {
async generatePrivateKey() {
const privateKey = secp256k1_js_1.secp256k1.utils.randomSecretKey();
return (0, utils_js_1.bytesToHex)(privateKey);
}
async getPublicKey(privateKey) {
const publicKey = secp256k1_js_1.secp256k1.getPublicKey((0, utils_js_1.hexToBytes)(privateKey), true);
return (0, utils_js_1.bytesToHex)(publicKey);
}
async sign(privateKey, message) {
const messageHash = (0, sha2_js_1.sha256)(new TextEncoder().encode(message));
const signature = secp256k1_js_1.secp256k1.sign(messageHash, (0, utils_js_1.hexToBytes)(privateKey));
return (0, utils_js_1.bytesToHex)(signature);
}
async verify(publicKey, message, signature) {
const messageHash = (0, sha2_js_1.sha256)(new TextEncoder().encode(message));
return secp256k1_js_1.secp256k1.verify((0, utils_js_1.hexToBytes)(signature), messageHash, (0, utils_js_1.hexToBytes)(publicKey));
}
}
exports.KeyManager = KeyManager;