bitcoinjs / bitcoinjs-lib

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

tapBip32Derivation don't accept my buffers, bip32Derivation do #2014

Closed simongltr closed 10 months ago

simongltr commented 10 months ago

I'm using bitcoinjs-lib@6.1.5 this node v20.6.1 I did read the transactions integration tests

I can't generate a taproot PSBT including tapBip32Derivation because I get this error:

Error: Data for input key tapBip32Derivation is incorrect: 
Expected { masterFingerprint: Buffer; pubkey: Buffer; path: string; leafHashes: Buffer[]; } 
and got [{"masterFingerprint":{"type":"Buffer","data":[168,5,168,44]},"pubkey":{"type":"Buffer","data":[3,98,159,176,150,108,203,120,157,137,231,231,92,144,114,20,111,95,127,119,113,81,186,59,18,79,98,84,201,50,182,11,249]},"path":"m/48'/0'/0'/2'/0/4"}]

The exact same code using bip32Derivation works.

I don't know if this error is due to my lack of understanding of nodejs buffers or something else, but I already spent hours trying to convert my buffers so I'm asking here ...

My code:

import * as ecc from 'tiny-secp256k1'
import bs58check from 'bs58check';
import { BIP32Factory } from 'bip32';
import * as bitcoin from 'bitcoinjs-lib';

const mainnet = bitcoin.networks.bitcoin;
bitcoin.initEccLib(ecc);
const bip32 = BIP32Factory(ecc);

let xpub = "xpub6Eh2MKVj1NQ8QzbiEvWmVDEsyHA79LEtZfpD5XvMvkwKNJqjEVJJJNqHAMDMWstiCtRa5czqdPX8oVjrhBY56ZciPv91AZWVpaNZQ2pYTcD";

let extendedPubkey = Buffer.from(bs58check.decode(xpub));
let masterFingerprint = Buffer.from("a805a82c", "hex");
let path = "m/48'/0'/0'/2'";

let psbt = new bitcoin.Psbt({ network: mainnet });

psbt.updateGlobal({
  globalXpub: [
    {
      extendedPubkey,
      masterFingerprint,
      path,
    }
  ]
});

psbt.addInput({
  hash: "e7a52809e405a7e42bdcd4e24f8aff6360e986665f1b6ec87ce73e59d4988c29",
  index: 0,
  // Removing witnessUtxo and nonWitnessUtxo to simplify
  tapBip32Derivation: [
    {
      masterFingerprint,
      pubkey: bip32.fromBase58(xpub, mainnet).derivePath("0/4").publicKey,
      path: path + "/0/4",
    },
  ]
});

psbt.addOutput({
  address: "bc1qp4g72hs2fzm0h297kutt93szvcm85pp56duqep",
  value: 1000,
});

console.log(psbt.toBase64());

Thank you for the help ! Simon

junderw commented 10 months ago

You're missing leafHashes.

The PSBT needs to know which leaves of the tapscript you are using.

If you are not doing a script spend but are doing a key spend, then you don't need to use tapBip32Derivation

simongltr commented 10 months ago

Oh okay, I'm doing a key spend ...

Thank you !