bitcoinjs/bitcoinjs-lib

typeError: Argument must be a Buffer

divyangkhatri opened this issue · 3 comments

Hello,
I am getting following error while signing the input for Taproot.
"typeError: Argument must be a Buffer". I like to inform that other BTC type is working like segwit, native segwit, legacy.

ENV:
"react-native": "^0.71.7",
"bitcoinjs-lib": "^6.1.5"

Following is my code snippet.

const getTransactionFees = async ({
  fromAddress,
  amount,
  toAddress,
  privateKey,
  chain_name,
}) => {
  // Get all utxos from sender using Mempool API.
  const {data: utxos} = await BitcoinMempool.getBitcoinUTXO(fromAddress);
  const value = new BigNumber(amount);

  const ECPair = ECPairFactory(ecc);
  const keyPair = ECPair.fromWIF(privateKey, config.BITCOIN_NETWORK_STRING);
  
  //Below commented code verify that private key is proper and address is same equal to fromAddress
  // const {address} = bitcoin.payments.p2tr({
   // internalPubkey: toXOnly(keyPair.publicKey),
  //  network: config.BITCOIN_NETWORK_STRING,
  // });
 // console.log('adddress', address);
 
   // Only use the required utxos
  const [usedUTXOs, sum] = utxos.reduce(
    ([utxoAcc, total], utxo) =>
      total.lt(value)
        ? [[...utxoAcc, utxo], total.plus(utxo.value)]
        : [utxoAcc, total],
    [[], new BigNumber(0)],
  );
 // here network is testnet
  const tx = new bitcoin.Psbt({network: config.BITCOIN_NETWORK_STRING});
 
  const fetchTransactionData = usedUTXOs.map(item => ({
    txid: item.txid,
    value: item.value,
    fromAddress,
    vout: item.vout,
  }));

  const childNodeXOnlyPubkey = toXOnly(keyPair.publicKey);
  console.log('childNodeXOnlyPubkey', childNodeXOnlyPubkey); // get valid buffer
 // fetching more details of transaction from transactionId
  const resp = await BitcoinMempool.fetchTransactionDetails(
    fetchTransactionData,
  );
  const inputData = resp?.data;
  console.log('Inpute data', inputData); // here also getting proper input data nothing is undefined or null
  inputData.map(utxo => {
    if (utxo.scriptpubkey) {
      const tempInputData = {
        hash: utxo.txid,
        index: utxo.vout,
        witnessUtxo: {
          // eslint-disable-next-line no-undef
          script: Buffer.from(utxo.scriptpubkey, 'hex'),
          value: utxo.value, // value in satoshi
        },
      };
      console.log('UTXOSS', utxo);
      console.log('chain_name', chain_name);

      if (chain_name === 'bitcoin_taproot') {
        tempInputData.tapInternalKey = childNodeXOnlyPubkey;
      }
      console.log('tempss', tempInputData); // here also the proper data
      tx.addInput(tempInputData);
    } else if (utxo.txhash) {
      // this else if part is not executing
      const tempInputData = {
        hash: utxo.txid,
        index: utxo.vout,
        // eslint-disable-next-line no-undef
        nonWitnessUtxo: Buffer.from(utxo.txhash, 'hex'),
      };
      tx.addInput(tempInputData);
    }
  });
  const change = sum.minus(value);
  // Add outputs
  tx.addOutput({
    address: toAddress,
    value: value.toNumber(),
  });
  if (change.gt(0)) {
    tx.addOutput({
      address: fromAddress,
      value: change.toNumber(),
    });
  }
  console.log('txxx', tx); // getting this log also
  // Sign inputs
  for (let i = 0; i < inputData.length; i++) {
    if (chain_name === 'bitcoin_taproot') {
      const tweakedChildNode = keyPair.tweak(
        bitcoin.crypto.taggedHash('TapTweak', childNodeXOnlyPubkey),
      );
      console.log('twaieee', tweakedChildNode); // getting this log also
      await tx.signInput(i, tweakedChildNode); // here i am facing above mention error
    } else {
      await tx.signInput(i, keyPair);
    }
  }
  console.log('signed input'); // this log is not executing because above line have error
  tx.finalizeAllInputs();
  console.log('finalize');
  const createdTx = tx.extractTransaction();
  const virtualSize = createdTx.virtualSize();
  const feeRate = await BitcoinMempool.fetchTransactionFees();
  const feeRateNumber = validateNumber(feeRate?.data) || 20;
  return Math.round(feeRateNumber * virtualSize);
};

@junderw Can you please checkout this issues?

This is not enough information.

Please post a minimal reproduction case that I can run.

Pasting a huge blob of code that I can't run locally and pointing to something that throws the error will only help if the problem is a dumb mistake or obvious problem. This is not that.

So I need to be able to run it locally, but all I have are our test suite examples... which all work perfectly.

Posting a full stack trace might help to pinpoint exactly where the problem is.

Taking a stab in the dark, have you run initEccLib after importing bitcoinjs-lib?

It looks like this question has no follow-up, let's close it