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?
' is used to denote a hardened derivation..toBase58() if you want to make xpub into a bip32 node object.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 ?
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:
I would suggest showing some examples like this in that libraries readme