bitcoinjs / bitcoinjs-lib

A javascript Bitcoin library for node.js and browsers.
MIT License
5.6k stars 2.08k forks source link

"Error adding output." - uninformative error logs with psbt structure. #1486

Closed drewstone closed 4 years ago

drewstone commented 4 years ago

I'm trying to create a raw bitcoin tx using this library, a simple CTLV p2sh where I fund the p2sh address. Yet, I am getting uninformative errors about why it can't add this final output.

  const { address } = bitcoin.payments.p2sh({
    redeem: {
      output: redeemScript,
      network: network
    },
    network: network
  });

  const psbt = new bitcoin.Psbt();
  unspentOutputs.forEach(output => {
    if (output.length > 0) {
      let splitOutput = output.split('-');
      psbt.addInput(idToHash(splitOutput[0]), Number(splitOutput[1]), 0xfffffffe);
    }
  });
  // Send amount of satoshis to the P2SH time lock transaction
  psbt.addOutput(address, Number(amount));

The error I get is:

(node:74229) UnhandledPromiseRejectionWarning: Error: Error adding output.
    at PsbtTransaction.addOutput (/Users/drewstone/code/commonwealth/supernova-lockdrop/node_modules/bitcoinjs-lib/src/psbt.js:555:13)
    at Psbt.addOutput (/Users/drewstone/code/commonwealth/supernova-lockdrop/node_modules/bip174/src/lib/psbt.js:103:31)
    at Psbt.addOutput (/Users/drewstone/code/commonwealth/supernova-lockdrop/node_modules/bitcoinjs-lib/src/psbt.js:174:15)
junderw commented 4 years ago

Psbt doesn't know how to make CLTVs so you must do it manually via the Transaction API. See our integration tests for examples.

As for Error:

"Incorrect argument type" is better?

Your arguments are formatted for Transaction API, not Psbt. See the integration tests. But again, it does not support CLTV.

drewstone commented 4 years ago

@junderw even if I'm only trying to send money to a P2SH CTLV contract? This is not the redeem script but rather the funding of the address.

junderw commented 4 years ago

Sending to is fine.

you can specify the scriptPubkey in the script parameter or specify the address in the address parameter.

drewstone commented 4 years ago

@junderw I must be not-very proficient at this. I am now getting

(node:18800) UnhandledPromiseRejectionWarning: Error: 2MyE9w28eB8iT9omT2VxcmZQymxKhkr3h86 has no matching Script

Is there any way you can provide me an example of what I am doing wrong? I am only trying to fund a P2SH address. I have changed for adding the output below:

  const redeemScript = createScript(locktime, key.publicKey);
  const { address } = bitcoin.payments.p2sh({
    redeem: {
      output: redeemScript,
      network: network,
    },
    network: network,
  });
.
.
.
  // Send amount of satoshis to the P2SH time lock transaction
  psbt.addOutput({
    address: address,
    value: Number(amount),
    network: network,
  });

EDIT: Using both script and address properties seemed to solve it.

junderw commented 4 years ago

to use address you must pass the network object to Psbt when creating it.

script does not need a network object, so when you pass both, it will just ignore the address.

junderw commented 4 years ago

You pass the network when making const psbt = new Psbt({ network });

junderw commented 4 years ago

or const psbt = Psbt.fromBase64(text, { network }) etc