bitcoinjs / bitcoinjs-lib

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

Can BitcoinJS generate Taproot addresses? #1746

Closed SuperHenkie closed 1 year ago

SuperHenkie commented 2 years ago

Given a private key (in Hex of WIF format) is there a way to get BitcoinJS to generate the corresponding Taproot (P2TR) address for that?

I sortof extracted this from the Taproot Key Spend example:

const dummyExampleWif = 'L4m2jm8B2vnN5c3FCaCRtbk7Ao9tavipfKKJZTecwLKAQzpGWBT7';
const keyPair = ECPair.fromWIF( dummyExampleWif );
// or: const keyPair = ECPair.makeRandom();

const output = Buffer.concat([
  // witness v1, PUSH_DATA 32 bytes
  Buffer.from([0x51, 0x20]),
  // x-only pubkey (remove 1 byte y parity)
  keyPair.publicKey.slice(1, 33),
]);

const p2trAddress = address.fromOutputScript( output );

However this results in an error:

Uncaught Error: OP_1 9902b7ca58529074db3c0e98f6101753f5978be6ff9ab9acdf8aee7539468048 has no matching Address

What am I doing wrong here?

P.S. I'm using bitcoinjs-lib 4.0.3.

AndreasGassmann commented 2 years ago

You will have to update bitcoinjs-lib to 6.x: https://github.com/bitcoinjs/bitcoinjs-lib/pull/1745

There is still active development going on, so not all features are supported yet, see https://github.com/bitcoinjs/bitcoinjs-lib/issues/1522

SuperHenkie commented 2 years ago

You will have to update bitcoinjs-lib to 6.x: #1745

There is still active development going on, so not all features are supported yet, see #1522

I see, thanks. Instead of the latest release according to github (4.0.3) I have now taken just the latest from npm, which is currently 6.0.0.

However, I'm now having a problem in my test scripts, it doesn't seem to know ECPair anymore.

I have this index.js:

var bitcoin_js = require('bitcoinjs-lib')
bitcoin_js.Buffer = require('safe-buffer').Buffer
module.exports = bitcoin_js

I build a standalone bitcoinjs.js like this:

nvm use 14
npm install bitcoinjs-lib
browserify -r . --standalone bitcoin_js > bitcoinjs.js

Then I have a test.html in which I include bitcoinjs.js and do this:

const keyPair = bitcoin_js.ECPair.makeRandom();

I'm now getting this error:

Uncaught TypeError: bitcoin_js.ECPair is undefined

Instead if I do npm install bitcoinjs-lib@4.0.3 above, and leave everything else the same, this works fine.

I think I noticed a commit somewhere in which ECPair requirement was removed or something, but can't find it anymore. Is there a way I can still export ECPair along with bitcoinjs so I can use the various keypair functions?

junderw commented 2 years ago

Also, github shows the latest is v6.0.0

https://github.com/bitcoinjs/bitcoinjs-lib/tags

Here's the CHANGELOG

junderw commented 2 years ago

I have updated the taproot example. It has become a bit more complicated.

/test/integration/taproot.md

  1. BIP341 says that if you are doing a key-spend only you should tweak your public key to create the output key.
  2. Tweaking the public key means you need to tweak the private key before signing which is a tad complicated.
  3. BIP86 (HD derivation for p2tr key-only spends) requires this tweaking.

Also, tiny-secp256k1 should add a negate method for private keys, since it looks like we will make great use of it in taproot.

junderw commented 1 year ago

Taproot support is added now in v6.1.0-rc.0