Initialize Bitcoin ECC before address derivation

This commit is contained in:
lemon
2026-05-17 01:16:56 -07:00
parent b87b70fa72
commit 3926a1c886
2 changed files with 28 additions and 14 deletions
+11 -3
View File
@@ -11,10 +11,17 @@ const VBYTES_PER_OUTPUT = 43;
const VBYTES_OVERHEAD = 10.5;
let _ECPair: ECPairAPI | null = null;
let eccInitialized = false;
function initBitcoinEcc(): void {
if (eccInitialized) return;
bitcoin.initEccLib(ecc);
eccInitialized = true;
}
function getECPair(): ECPairAPI {
initBitcoinEcc();
if (!_ECPair) {
bitcoin.initEccLib(ecc);
_ECPair = ECPairFactory(ecc);
}
return _ECPair;
@@ -28,6 +35,7 @@ export function nostrPubkeyToBitcoinAddress(pubkeyHex: string): string {
if (!isValidPubkeyHex(pubkeyHex)) return '';
try {
initBitcoinEcc();
const pubkeyBuffer = Buffer.from(pubkeyHex, 'hex');
const { address } = bitcoin.payments.p2tr({
internalPubkey: pubkeyBuffer,
@@ -502,7 +510,7 @@ export function buildUnsignedMultiOutputPsbt(
}
export function signPsbtLocal(psbtHex: string, privateKeyHex: string): string {
bitcoin.initEccLib(ecc);
initBitcoinEcc();
const psbt = bitcoin.Psbt.fromHex(psbtHex, { network: bitcoin.networks.bitcoin });
const keyPair = getECPair().fromPrivateKey(Buffer.from(privateKeyHex, 'hex'));
@@ -531,7 +539,7 @@ export function signPsbtLocal(psbtHex: string, privateKeyHex: string): string {
}
export function finalizePsbt(psbtHex: string): string {
bitcoin.initEccLib(ecc);
initBitcoinEcc();
const psbt = bitcoin.Psbt.fromHex(psbtHex, { network: bitcoin.networks.bitcoin });
psbt.finalizeAllInputs();
return psbt.extractTransaction().toHex();
+17 -11
View File
@@ -99,18 +99,24 @@ export function BitcoinPage() {
<SendBitcoinDialog isOpen={sendOpen} onClose={() => setSendOpen(false)} btcPrice={btcPrice} />
<div className="rounded-2xl bg-white p-4 shadow-sm">
<QRCodeCanvas value={bitcoinAddress} size={200} level="M" />
</div>
{bitcoinAddress ? (
<div className="rounded-2xl bg-white p-4 shadow-sm">
<QRCodeCanvas value={bitcoinAddress} size={200} level="M" />
</div>
) : (
<Skeleton className="size-[232px] rounded-2xl" />
)}
<button
type="button"
onClick={copyAddress}
className="flex items-center gap-2 rounded-full border px-4 py-2 font-mono text-sm text-muted-foreground transition-colors hover:bg-muted/50"
>
{truncatedAddress}
{copiedAddress ? <Check className="size-3.5 text-green-500" /> : <Copy className="size-3.5" />}
</button>
{bitcoinAddress && (
<button
type="button"
onClick={copyAddress}
className="flex items-center gap-2 rounded-full border px-4 py-2 font-mono text-sm text-muted-foreground transition-colors hover:bg-muted/50"
>
{truncatedAddress}
{copiedAddress ? <Check className="size-3.5 text-green-500" /> : <Copy className="size-3.5" />}
</button>
)}
{transactions && transactions.length > 0 && (
<>