Skip to content

Can BitcoinJS generate Taproot addresses? #1746

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

Closed
SuperHenkie opened this issue Nov 14, 2021 · 5 comments
Closed

Can BitcoinJS generate Taproot addresses? #1746

SuperHenkie opened this issue Nov 14, 2021 · 5 comments

Comments

@SuperHenkie
Copy link

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
Copy link

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

@SuperHenkie
Copy link
Author

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 [email protected] 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
Copy link
Member

junderw commented Nov 14, 2021

  • ECPair was removed and a new package called ecpair was created for legacy applications.
  • You should be using bip32 moving forward. Individual key management is a legacy concept, and should only be used with legacy wallet types to maintain backwards compatibility for old wallet restoration. Anyone trying to use taproot with a single-privatekey WIF key (starting with "K" and "L" or "5") is just asking for trouble. This can be supported by moving from single-key to HD key via bip32 (most wallets use bip39 mnemonic phrases in conjunction with bip32), and telling users of old single-keys "if you want to use taproot, move all your funds to a new HD wallet"
  • v6 also does not contain TransactionBuilder. So any app relying on TransactionBuilder must first switch to using Psbt before upgrading.
  • tiny-secp256k1 v2 with schnorr support uses WASM, so when bundling for the browser, care must be taken (webpack, for example has special config options to allow bundling WASM) and older browsers (less than 8% of total browser market share) will be unable to use it.

Also, github shows the latest is v6.0.0

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

Here's the CHANGELOG

@junderw
Copy link
Member

junderw commented Nov 14, 2021

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
Copy link
Member

junderw commented Nov 29, 2022

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

@junderw junderw closed this as completed Nov 29, 2022
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

4 participants
@AndreasGassmann @SuperHenkie @junderw and others