Bitcoinjs-lib: deriving BIP49 addresses from extended pub key

Created on 20 Feb 2019  路  6Comments  路  Source: bitcoinjs/bitcoinjs-lib

I'm trying to generate an extended pub key from a mnemonic seed so I can derive BIP49 addresses from it.

So far I have something like this:

const seed = bip39.mnemonicToSeed(<mnemonic>)
const node = bip32.fromSeed(seed)
const xpub = node.neutered().toBase58()

function getAddress (node, network) {
    const { address } = bitcoin.payments.p2sh({
        redeem: bitcoin.payments.p2wpkh({ pubkey: node.publicKey, network: network }),
        network: network
    })
    return address;
}

path = `m/49/0/0/0/0`
network = bitcoin.networks.mainnet
const address = getAddress(xpub).derivePath(path), network);

Tools like this don't generate the same xpubs or addresses as me.
I'm thinking its because I'm generating an xpub and not a ypub, does this library support ypubs?

Most helpful comment

Thanks, you helped me a lot.

For anyone who's wondering how to do the xpub to ypub using the bs58check library:

function xpub_to_ypub(xpub) {
  var data = bs58check.decode(xpub)
  data = data.slice(4)
  data = Buffer.concat([Buffer.from('049d7cb2','hex'), data])
  return bs58check.encode(data)
}

I would suggest showing some examples like this in that libraries readme

All 6 comments

  1. Your path is incorrect. Please check BIP49 to see the correct path. ' is used to denote a hardened derivation.
  2. xpub is a string, and you are passing it to getAddress, which accepts a bip32 node as the first... you should remove the .toBase58() if you want to make xpub into a bip32 node object.
  3. Extended Public Keys are exported as the final hard derivation. So when you export an xpub, you need to derive up to the last hardened layer, then export the xpub, then when you read the xpub you need to derive the non-hardened layers.

Thanks for your help.

I will post my solution so if anyone else was confused as I was then maybe it will help them out too.

Don't worry this is just a random mnemonic as an example, no funds tied to it.

const seed = bip39.mnemonicToSeed("grit tooth direct now mushroom rent raven safe meadow flock bubble mesh")
const node = bip32.fromSeed(seed)
const xpub = node.derivePath(`m/49'/0'/0'`).neutered().toBase58() // Import/Export this
// xpub6GPVbpBHJMUEK8BzF4ntoP1mdtpMgXJhNSfRQew9vMLLzHB9JyRfj5C5wmqyoRfRQiRL7V7GJkqKEnDEXn1cTBnodPyBW69ao498pg6stm6
const restored = bip32.fromBase58(xpub);

function getAddress (node, network) {
    const { address } = bitcoin.payments.p2sh({
        redeem: bitcoin.payments.p2wpkh({ pubkey: node.publicKey, network: network }),
        network: network
    })
    return address;
}

var network = bitcoin.networks.mainnet
var address = getAddress(restored.derive(0).derive(0), network);

I basically had to derive the path I wanted before exporting it to an xpub which is what you said in 3.

One final question, should I be concerned that its not a ypub? On this website its deriving the same public keys as me but it generates a different xpub.

ypub is just an xpub that uses a different version byte to denote "you should make this a p2sh-p2pkh address with BIP49"

If you want to support apps that import ypub only, you can decode then reencode using bs58check library.

Thanks, you helped me a lot.

For anyone who's wondering how to do the xpub to ypub using the bs58check library:

function xpub_to_ypub(xpub) {
  var data = bs58check.decode(xpub)
  data = data.slice(4)
  data = Buffer.concat([Buffer.from('049d7cb2','hex'), data])
  return bs58check.encode(data)
}

I would suggest showing some examples like this in that libraries readme

ypub is not widely supported, nor is it a BIP, so unfortunately this library explaining how to deal with it opens the floodgates to supporting every single home-made protocol that any wallet makes.

@junderw i believe this is now a part of BIP49. See Extended Key Version
What do you think ?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

prahaladbelavadi picture prahaladbelavadi  路  3Comments

namnv04 picture namnv04  路  3Comments

coingeek picture coingeek  路  4Comments

hoshsadiq picture hoshsadiq  路  3Comments

rbndg picture rbndg  路  3Comments