bitcoinjs / bip32-utils

A small set of utilities for use with BIP32 HD key nodes
MIT License
74 stars 52 forks source link

Unable to derivate xPub from Account #6

Closed ivanminutillo closed 8 years ago

ivanminutillo commented 8 years ago

Hello :) I am trying to derive the xPub having the account, if I use the code in readme: account.getChildrenMap(account.getAllAddresses()) what I return is not the xpub but the entire hdnode like this :

mn.....gKR {
  chainCode:Uint8Array[32]
  depth:5
  index:0
  keyPair:ECPair
  parentFingerprint:61...83
}

Then If I use the .toBase58 method on the resulting keyPair I obtain the xprv... What I am doing wrong?

dcousens commented 8 years ago

It is generally best practice to use a .neutered() HDNode for most of your code, and only "escalate" to a xpriv when needed.

Reference:

var account = new bip32utils.Account([
    new bip32utils.Chain(external.neutered())
    new bip32utils.Chain(internal.neutered())
])

...

console.log(account.getChildrenMap(account.getAllAddresses()))
// => {
//  "1QEj2WQD9vxTzsGEvnmLpvzeLVrpzyKkGt": "xpub6A5Fz4JZg4kd8pLTTaMBKsvVgzRBrvai6ChoxWNTtYQ3UDVG1VyAWQqi6SNqkpsfsx9F8pRqwtKUbU4j4gqpuN2gpgQs4DiJxsJQvTjdzfA",
//  ...
// }

console.log(account.getChildrenMap(account.getAllAddresses(), [external, internal]))
// => {
//  "1QEj2WQD9vxTzsGEvnmLpvzeLVrpzyKkGt": "xprv9vodQPEygdPGUWeKUVNd6M2N533PvEYP21tYxznauyhrYBBCmdKxRJzmnsTsSNqfTJPrDF98GbLCm6xRnjceZ238Qkf5GQGHk79CrFqtG4d",
//  ...
// }
// NOTE: passing in the parent nodes allows for private key escalation (see xprv vs xpub)
ivanminutillo commented 8 years ago

I think there is a simpler and clearer solution that I still don't see, but in the meanwhile I I created this gist with a very raw solution... Basically I copied your .toBase58() method but with a second argoument that add the possibility to decide if you want to return the xpub or the xprv... Am I doing something conceptually wrong? btw many thanks for your work 👍

ivanminutillo commented 8 years ago

great! now it worked fine without implementing anything :) thanks

dcousens commented 8 years ago

Basically I copied your .toBase58() method but with a second argoument that add the possibility to decide if you want to return the xpub or the xprv...

You are fundamentally assuming that the HDNode always has a private key component... which may or may not be the case. Is there any reason why you're struggling to just use .neutered() and the private key escalation?

dcousens commented 8 years ago

Alternatively... if you're still having issues, just do node.neutered().toBase58(), that will give you the xpub.

ivanminutillo commented 8 years ago

I didn't understand why and how use .neutered(), now it's clear :)