Friday, September 20, 2024

signature – Error signing Taproot transaction in BitcoinJS: “Cannot signal for enter”

I am creating a operate to ship BTC on the testnet utilizing the bitcoinjs-lib library. I encounter an error throughout the signing of a Taproot transaction, and I am unable to work out the trigger.

Right here is my code:

import * as bitcoin from 'bitcoinjs-lib';
import BIP32Factory from 'bip32';
import ecc from '@bitcoinerlab/secp256k1';
import axios from 'axios';
import ECPairFactory from 'ecpair';

const bip32 = BIP32Factory(ecc);
bitcoin.initEccLib(ecc);
const ECPair = ECPairFactory(ecc);

kind UTXO = {
    txid: string;
    vout: quantity;
    standing: Standing;
    worth: quantity;
};


kind Vin = {
    txid: string;
    vout: quantity;
    prevout: Vout;
    scriptsig: string;
    scriptsig_asm: string;
    witness: string[];
    is_coinbase: boolean;
    sequence: quantity;
};

kind Vout = {
    scriptpubkey: string;
    scriptpubkey_asm: string;
    scriptpubkey_type: string;
    scriptpubkey_address: string;
    worth: quantity;
};

kind Standing = {
    confirmed: boolean;
    block_height: quantity;
    block_hash: string;
    block_time: quantity;
};

kind TransactionData = {
    txid: string;
    model: quantity;
    locktime: quantity;
    vin: Vin[];
    vout: Vout[];
    dimension: quantity;
    weight: quantity;
    sigops: quantity;
    price: quantity;
    standing: Standing;
};

async operate getUTXO(handle: string): Promise<UTXO[]> {
    const { information } = await axios.get(`https://mempool.house/testnet/api/handle/${handle}/utxo`);
    return information;
}

async operate getTx(tx: string): Promise<TransactionData> {
    const { information } = await axios.get(`https://mempool.house/testnet/api/tx/${tx}`);
    return information;
}

async operate broadcastTransaction(hex: string) {
    const { information } = await axios.publish('https://mempool.house/testnet/api/tx', { tx: hex });
    return information;
}

async operate sendBTC(senderWIF: string, receiverAddress: string, quantity: quantity) {
    const community = bitcoin.networks.testnet;

    const keyPair = ECPair.fromWIF(senderWIF, community);

    const senderAddress = bitcoin.funds.p2tr({
        internalPubkey: keyPair.publicKey.slice(1, 33),
        community
    }).handle;

    if (!senderAddress) {
        throw new Error('No sender handle')
    }

    const utxos = await getUTXO(senderAddress);
    if (utxos.size === 0) throw new Error('No UTXO out there');

    const utxo = utxos[0];

    const utxoTx: TransactionData = await getTx(utxo.txid);

    const scriptpubKey = utxoTx.vout[utxo.vout].scriptpubkey;

    const psbt = new bitcoin.Psbt({ community });
    psbt.addInput({
        hash: utxo.txid,
        index: utxo.vout,
        witnessUtxo: {
            script: Buffer.from(scriptpubKey, 'hex'),
            worth: utxo.worth,
        },
        tapInternalKey: keyPair.publicKey.slice(1, 33),
    });

    const price = 1000;
    const sendAmount = quantity;
    const changeAmount = utxo.worth - sendAmount - price;

    psbt.addOutput({
        handle: receiverAddress,
        worth: sendAmount,
    });

    if (changeAmount > 0) {
        psbt.addOutput({
            handle: senderAddress,
            worth: changeAmount,
        });
    }

    console.log(JSON.stringify(psbt.information));
    psbt.signInput(0, keyPair);
    psbt.finalizeAllInputs();

    const tx = psbt.extractTransaction();
    const txHex = tx.toHex();
    const broadcastResult = await broadcastTransaction(txHex);

    return broadcastResult;
}

(async () => {
    const senderWIF = '...'; //handle: tb1pnx3wn6yhtccqy9rml9emw8l4vkqnswfyz5wpghjd0ap3r002k9us8v0rgf
    const receiverAddress="tb1pmrqkqnql43a7usz407nkh2g5c5cndzzw20mhx3qwcp7kg92cycus0cu7ym";
    const quantity = 100;

    strive {
        const txId = await sendBTC(senderWIF, receiverAddress, quantity);
        console.log('Transaction broadcasted with ID:', txId);
    } catch (error) {
        console.error('Error sending BTC:', error);
    }
})();

Error message:

Error sending BTC: Error: Cannot signal for enter #0 with the important thing 026794e53df94a78beed78fa9380f661ca13d0f72d1fc6aa04e5bb0a1233d9cfa6
    at Psbt.checkTaprootHashesForSig (/house/person/Paperwork/testbtc/node_modules/bitcoinjs-lib/src/psbt.js:854:13)
    at Psbt._signTaprootInput (/house/person/Paperwork/testbtc/node_modules/bitcoinjs-lib/src/psbt.js:692:31)
    at Psbt.signInput (/house/person/Paperwork/testbtc/node_modules/bitcoinjs-lib/src/psbt.js:640:19)
    at sendBTC (/house/person/Paperwork/testbtc/index7.ts:131:10)
    at processTicksAndRejections (node:inside/course of/task_queues:95:5)
    at async /house/person/Paperwork/testbtc/index7.ts:147:22

PSBT information:

{
  "inputs":[
    {
      "unknownKeyVals":[],
      "witnessUtxo":{
        "script":{"kind":"Buffer","information":[81,32,153,162,233,232,151,94,48,2,20,123,249,115,183,31,245,101,129,56,57,36,21,28,20,94,77,127,67,17,189,234,177,121]},
        "worth":4900
      },
      "tapInternalKey":{"kind":"Buffer","information":[103,148,229,61,249,74,120,190,237,120,250,147,128,246,97,202,19,208,247,45,31,198,170,4,229,187,10,18,51,217,207,166]}
    }
  ],
  "outputs":[
    {"unknownKeyVals":[]},
    {"unknownKeyVals":[]}
  ],
  "globalMap":{"unsignedTx":{}}
}

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles