45 lines
1.5 KiB
JavaScript
45 lines
1.5 KiB
JavaScript
// Generated, do not edit. sha256:48d09dbb5cf2116c2b2c3990d8d1b662451d072fe40458fddcaa483e74bb3100
|
|
import { bech32, hexToBytes, bytesToHex, schnorr } from '../vendor/crypto/noble-scure.js';
|
|
|
|
const HEX64 = /^[0-9a-f]{64}$/;
|
|
|
|
export function npubFromHex(hex) {
|
|
const v = String(hex ?? '').toLowerCase();
|
|
if (!HEX64.test(v)) return null;
|
|
return bech32.encode('npub', bech32.toWords(hexToBytes(v)));
|
|
}
|
|
|
|
export function shortKey(key, keep = 8) {
|
|
const k = String(key ?? '');
|
|
return k.length > keep * 2 + 1 ? `${k.slice(0, keep)}…${k.slice(-keep)}` : k;
|
|
}
|
|
|
|
function validSecret(bytes) {
|
|
try { schnorr.getPublicKey(bytes); return true; } catch { return false; }
|
|
}
|
|
|
|
export function secretFromText(text) {
|
|
const v = String(text ?? '').trim();
|
|
if (v.startsWith('npub1')) return { error: 'npub' };
|
|
let bytes = null;
|
|
if (HEX64.test(v.toLowerCase())) bytes = hexToBytes(v.toLowerCase());
|
|
else if (v.startsWith('nsec1')) {
|
|
try {
|
|
const { prefix, words } = bech32.decode(v);
|
|
if (prefix === 'nsec') bytes = Uint8Array.from(bech32.fromWords(words));
|
|
} catch { bytes = null; }
|
|
}
|
|
return bytes && bytes.length === 32 && validSecret(bytes) ? { secret: bytes } : { error: 'invalid' };
|
|
}
|
|
|
|
export const publicKeyOf = (secret) => bytesToHex(schnorr.getPublicKey(secret));
|
|
|
|
export const nsecFromSecret = (secret) => bech32.encode('nsec', bech32.toWords(secret));
|
|
|
|
export function newSecret(random = (n) => crypto.getRandomValues(new Uint8Array(n))) {
|
|
for (;;) {
|
|
const bytes = random(32);
|
|
if (validSecret(bytes)) return bytes;
|
|
}
|
|
}
|