-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Trezor generated xPub - 'Invalid network version' #966
Comments
it says ypub. ypub is not supported in bitcoinjs-lib. You can base58 decode, replace the version with xpub and re-do if you'd like, but getAddress will not get you the Trezor's "3" addresses. |
Is there some way to generate such addresses? Sorry, I am quite a noob on this topic. Not sure what topic to even search :D |
var bjs = require('bitcoinjs-lib')
var b58 = require('bs58check')
// this function takes ypub and turns into xpub
function ypubToXpub(ypub) {
var data = b58.decode(ypub)
data = data.slice(4)
data = Buffer.concat([Buffer.from('0488b21e','hex'), data])
return b58.encode(data)
}
// this function takes an HDNode, and turns the pubkey of that node into a Segwit P2SH address
function nodeToP2shSegwitAddress(hdNode) {
var pubkeyBuf = hdNode.keyPair.getPublicKeyBuffer()
var hash = bjs.crypto.hash160(pubkeyBuf)
var redeemScript = bjs.script.witnessPubKeyHash.output.encode(hash)
var hash2 = bjs.crypto.hash160(redeemScript)
var scriptPubkey = bjs.script.scriptHash.output.encode(hash2)
return bjs.address.fromOutputScript(scriptPubkey)
}
// convert ypub string into xpub string
var xpub = ypubToXpub('ypub6XTWVFLfqkFYarn9NArqtBLziffJttqf1Utaur3sTbTGtgfNaTzkGcRpFgiiieBjQ6rV1rJ7iJ9r9oXGpPXZpkq71yfss2mrKLaauxhjXD4')
// grab the HDNode object from the xpub
var hdNode = bjs.HDNode.fromBase58(xpub)
// generate as usual, but instead of getAddress, feed into above function
var address = nodeToP2shSegwitAddress(hdNode.derive(0).derive(0))
// 3FkFtj43U6UDZ7wberPtZwUrR3GLMw2S6x |
@dabura667 Doing some testing with an Electrum wallet and the default option in version 3.0.5 is to use zpub and P2WSH addresses. Do you know of any good libraries similar to bitcoinjs-lib that can derive wallet addresses from a zpub? |
You can basically do the same thing as above. Slightly modified. var bjs = require('bitcoinjs-lib')
var b58 = require('bs58check')
// this function takes zpub and turns into xpub
function zpubToXpub(zpub) {
var data = b58.decode(zpub)
data = data.slice(4)
data = Buffer.concat([Buffer.from('0488b21e','hex'), data])
return b58.encode(data)
}
// this function takes an HDNode, and turns the pubkey of that node into a Segwit bech32 address
function nodeToP2wpkhSegwitAddress(hdNode) {
var pubkeyBuf = hdNode.keyPair.getPublicKeyBuffer()
var hash = bjs.crypto.hash160(pubkeyBuf)
var scriptPubkey = bjs.script.witnessPubKeyHash.output.encode(hash)
return bjs.address.fromOutputScript(scriptPubkey)
}
// convert zpub string into xpub string
var xpub = zpubToXpub('zpub6oFHEbYeAMTVmmmcZA5KJinUFVoGZfQhc4dBfzCMwrL1AsxopkyLv9zCKHezgHJNskU8pRUQ9AZqZjAjdZeM1ehkALJE1UNPboorWDfhPSB')
// grab the HDNode object from the xpub
var hdNode = bjs.HDNode.fromBase58(xpub)
// generate as usual, but instead of getAddress, feed into above function
var address = nodeToP2wpkhSegwitAddress(hdNode.derive(0).derive(0))
// bc1qr8mrj8lsmnl5rpewfphj0rrprs7gkqccmn4z4l |
@dabura667 much appreciated. |
Closing in favour of #927 |
@dabura667 could you please explain a little bit of |
@jackylimel Since xpubs and ypubs can not derive hardened layers, usually apps show the xpub of the last hardened layer. In Electrum’s case, they use BIP44 which is H H H S S (hard hard hard soft soft) The last two softs are 0|1 for is_change and the address index. So to derive the “first non-change address” is derive(0).derive(0) first change would be 1 0 Second non-change is 0 1 Tenth non-change is 0 9 |
Hi @dabura667, thanks for your quick reply. Yeah, I've read BIP0044 and BIP0032 and things are much clear now. However, I still don't quite understand this sentence "Since xpubs and ypubs can not derive hardened layers", may I ask where can I get more information about |
btw, I tried to use @dabura667 's solution to derive address from testnet public key:
however, I cannot get a correct address out of it... |
Ok, I got it now:
|
any idea on how to make this work with latest version (4.0.1) ? i'm having trouble with the so I do I get a publickeyBuffer from a node that was created with thx for the feedback |
ok I was able to do this with
|
If anyone is still looking for a complete example of how to get addresses from the ypub trezor provides. Consolidated from off all the answers above (working with version 4.0.2 of bitcoinjs-lib):
|
@Jasonvdb thanks for the great example - I've been toying with these a lot recently and appreciate the clarity. Any chance anyone has gotten this process working for the other funny extended keys trezor uses such as dogecoin (dgub*******...) or dash (drkp*******...) etc ? Seems a bit backwards to require a separate adaptation for each token but I'm hoping I'm missing something. |
@alexander-morris the function given in the example does not care what the prefix of the input is: If you look at the function it literally is just throwing away the old prefix without checking it and adding the xpub prefix. function ypubToXpub(ypub) {
var data = b58.decode(ypub) // decode... this could be dgub or drkp or whatever
data = data.slice(4) // throw away first four letters
data = Buffer.concat([Buffer.from('0488b21e','hex'), data]) // add "xpub"
return b58.encode(data) // re-encode
} |
@Jasonvdb @junderw thanks for examples, I have been looking for ypub solution for endless hours. I have tried above ypubToXpub function with input:
received:
What am I missing? |
@mareksip looks like that maybe a P2WPKH of a ypub format but you're looking for a P2WSH version. Not sure of the difference myself but Jameson Lopp made a handy open source convertor. You should be able to input your version and get what you're looking for: |
@mareksip |
You used: |
@Jasonvdb thanks for the reply, I was using bs58 instead bs58check lib. |
Hi. So I am trying to generate HD addresses from xPub that is generated inside the Trezor.
Any clues why? It does work with
const xpub = 'xpub661MyMwAqRbcG4PQrRAT3N2uxTkXWeRq5kpjyDvStBQP7eW65Lu5rZ3MLoBZJQuZFS9FC7mZZEcgxFZxccRdnqSxopraUB6wVjTqp8ZsS4H'
The text was updated successfully, but these errors were encountered: