bitcoinjs / bitcoinjs-lib

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

From mnemonic passphrase to bitcoin wallet address #1708

Closed didotsonev closed 3 years ago

didotsonev commented 3 years ago

Goal

I'm trying to create a script which converts mnemonic BIP39 12 words passphrase to bitcoin (exodus) wallet address.

Script (from issue in this repo)

const Bitcoin = require('bitcoinjs-lib');
const Bip39 = require('bip39');
const Bip32 = require('bip32');

function getAddress (node, network) {
  return Bitcoin.payments.p2pkh({ pubkey: node.publicKey, network }).address
}

const mnemonic = `some mnemonic`;
const seed = Bip39.mnemonicToSeedSync(mnemonic);
const root = Bip32.fromSeed(seed, Bitcoin.networks.bitcoin);
const child1 = root.derivePath("m/44'/0'/0'/0/0");
const child2 = root.deriveHardened(44).deriveHardened(0).deriveHardened(0).derive(0).derive(0);

console.log(getAddress(child1));
console.log(getAddress(child2));

While I send the correct mnemonic I don't get the expected addres. Do I miss some convertion or?

Other scripts I tried: https://bitcoin.stackexchange.com/a/75334 https://github.com/bitcoinjs/bitcoinjs-lib/issues/997#issuecomment-360706692

junderw commented 3 years ago

Use BIP84 not BIP44. (the derivation path) Use p2wpkh not p2pkh.

didotsonev commented 3 years ago

It works now. Thank you.

End result (for anyone reading)

const bitcoin = require('bitcoinjs-lib');
const bip39 = require('bip39');
const bip32 = require('bip32');

function getAddress (node, network) {
  return bitcoin.payments.p2wpkh({ pubkey: node.publicKey, network }).address
}

const mnemonic = `fsome mnemonic`;

const seed = bip39.mnemonicToSeedSync(mnemonic);

const root = bip32.fromSeed(seed, bitcoin.networks.bitcoin);

const child1 = root.derivePath("m/84'/0'/0'/0/0");
const child2 = root.deriveHardened(84).deriveHardened(0).deriveHardened(0).derive(0).derive(0);

console.log(getAddress(child1));
console.log(getAddress(child2));
TheRadioGuy commented 3 years ago

Hello! It doesnt work now:

TypeError: Cannot read property 'p2wpkh' of undefined
junderw commented 3 years ago

Yes it still does.

Please check to make sure you are importing the bitcoinjs-lib library to bitcoin variable, and make sure the version of bitcoinjs-lib is the correct version (v4.x.x and above)

TheRadioGuy commented 3 years ago

Yep, it was an old version :D

By the way, what's the difference between child1 and child2?

junderw commented 3 years ago

Nothing, they are the same. I was just showing 2 ways to get the same result.

TheRadioGuy commented 3 years ago

Thanks you!

TheRadioGuy commented 3 years ago

It's me again. I have the code above and it generates "bc1..." address. Can I get address as "1Avqtgyqd81DEcRYcDkjf1dQdhf3H7Rd5V"?

junderw commented 3 years ago
p2wpkh -> p2pkh
"m/84'/0'/0'/0/0" -> "m/44'/0'/0'/0/0"
CookLand commented 1 year ago

I didn’t get it right away, but this option helped.


const bip39 = require('bip39');
const ecc = require('tiny-secp256k1')
const { BIP32Factory } = require('bip32')
const bip32 = BIP32Factory(ecc);
const bitcoin = require('bitcoinjs-lib');

function getAddress (node, network) {
    return bitcoin.payments.p2wpkh({ pubkey: node.publicKey, network }).address
}

const mnemonic = `fsome mnemonic`;

const seed = bip39.mnemonicToSeedSync(mnemonic);

const root = bip32.fromSeed(seed, bitcoin.networks.bitcoin);

const child1 = root.derivePath("m/84'/0'/0'/0/0");
const child2 = root.deriveHardened(84).deriveHardened(0).deriveHardened(0).derive(0).derive(0);

console.log(getAddress(child1));
console.log(getAddress(child2));
luckyboy125 commented 1 year ago

It works now. Thank you.

End result (for anyone reading)

const bitcoin = require('bitcoinjs-lib');
const bip39 = require('bip39');
const bip32 = require('bip32');

function getAddress (node, network) {
  return bitcoin.payments.p2wpkh({ pubkey: node.publicKey, network }).address
}

const mnemonic = `fsome mnemonic`;

const seed = bip39.mnemonicToSeedSync(mnemonic);

const root = bip32.fromSeed(seed, bitcoin.networks.bitcoin);

const child1 = root.derivePath("m/84'/0'/0'/0/0");
const child2 = root.deriveHardened(84).deriveHardened(0).deriveHardened(0).derive(0).derive(0);

console.log(getAddress(child1));
console.log(getAddress(child2));

When I run this code, I got an error below.

const root = bip32.fromSeed(seed, bitcoin.networks.bitcoin); ^ TypeError: bip32.fromSeed is not a function at E:\Work\BeePay\BeePay_BE\routes\api\seeds.js:20:22 at Layer.handle [as handle_request] (E:\Work\BeePay\BeePay_BE\node_modules\express\lib\router\layer.js:95:5) at next (E:\Work\BeePay\BeePay_BE\node_modules\express\lib\router\route.js:144:13) at Route.dispatch (E:\Work\BeePay\BeePay_BE\node_modules\express\lib\router\route.js:114:3) at Layer.handle [as handle_request] (E:\Work\BeePay\BeePay_BE\node_modules\express\lib\router\layer.js:95:5) at E:\Work\BeePay\BeePay_BE\node_modules\express\lib\router\index.js:284:15 at Function.process_params (E:\Work\BeePay\BeePay_BE\node_modules\express\lib\router\index.js:346:12)
at next (E:\Work\BeePay\BeePay_BE\node_modules\express\lib\router\index.js:280:10) at Function.handle (E:\Work\BeePay\BeePay_BE\node_modules\express\lib\router\index.js:175:3) at router (E:\Work\BeePay\BeePay_BE\node_modules\express\lib\router\index.js:47:12)

What's wrong?

junderw commented 1 year ago

What's wrong?

The example is based off of the version that was out at the time. Since then all of these libraries have release major version updates that changed the API.

ROHITTH-C commented 2 months ago

use

const ecc = require('tiny-secp256k1') const { BIP32Factory } = require('bip32') // You must wrap a tiny-secp256k1 compatible implementation const bip32 = BIP32Factory(ecc)

With this you should be able to access these methods.

fromSeed, fromBase58, fromPublicKey, fromPrivateKey