Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

typeError: Argument must be a Buffer #2005

Open
divyangkhatri opened this issue Nov 18, 2023 · 2 comments
Open

typeError: Argument must be a Buffer #2005

divyangkhatri opened this issue Nov 18, 2023 · 2 comments

Comments

@divyangkhatri
Copy link

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);
};

@divyangkhatri
Copy link
Author

@junderw Can you please checkout this issues?

@junderw
Copy link
Member

junderw commented Nov 24, 2023

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants