How do I generate HDM wallet addresses

I am using the Coinbase Multisig Vault and would like to build something similar that is able to replicate the entire HDM wallet using bitcore instead of bitcoinjs. The idea is: input xpubs, output addresses. I would eventually like to do this for the Copay wallet as well.

But I don’t think I am deriving the public keys correctly. This is how I do it: on the bitcore playground I input each xpub into http://bitcore.io/playground/#/hdkeys and then copy and paste the m/0 derived public key into http://bitcore.io/playground/#/multisig. When I do this for

xpub661MyMwAqRbcEk2YrSM37a5skePAXy1CDyyKKBbVBvu6BxKqGb4C7WMFzrwEFHV3b9gQHy9oQVAf19Uw3SG5by68bM22HsHgC7zEZCr1EsC
xpub661MyMwAqRbcFLhshwUHjzPiB6NH84E7jXwPhQvxcPrn5i7Wz2qJFETbiT2DiepNDqzHFegTvs71RMEQLgVs7J2fX1brxT9vJpiGe6RgG9U
xpub661MyMwAqRbcFg8HBDBzvqUY8gj4Dp6pDo9Zkbn6SNA8QHHubeyUtvvaHYqD7xrze8pZTdGx1XyocyHjcX3sS1xEX7KVM7BAfgqYf6M4dGx

I get derived public keys

029bf98e493ad24ddda53897b032bc1e5d1599bd96e868b7c350b2a73e06e57df7
028b2762533b723fa5c3aa196ad522114aaffb668a97e81b43dcab879304a67971
02e1832295cef3b37327e1a114feef37c998a790d3716e090c6e2f67a7eee982a6

And then I paste that into the multisig page with “2-of-3” selected and out comes address

 3JZsXW5TVvXMa1ikC6aTZjNxzLsryahgfW 

which does not match the

33mKr4JZWcpYMGxmcuc3t5c4aNozFaxsL7 

in the Coinbase tool :sob:

Am I doing this correctly? It worked on Coinkite.

Hey Andrew,

I believe the difference lies in that coinbase is using uncompressed pubkeys. If you use the uncompressed versions of your 3 pubkeys:

"048b2762533b723fa5c3aa196ad522114aaffb668a97e81b43dcab879304a6797142124a62ed25bf1b1768017e1bacf27e49188b7bb4ffaf04c82c352ad0fe9df4"
"049bf98e493ad24ddda53897b032bc1e5d1599bd96e868b7c350b2a73e06e57df79323035dd7ecb26af754e6a26ede6f28d10d862e61cde9fb67bf0630bc9691d4"
“04e1832295cef3b37327e1a114feef37c998a790d3716e090c6e2f67a7eee982a61d0ff2bb8368433cfab0fff3fd4fc8757d65096040b76b7acad55d27ff269cc6”

Then it gives the address you are asking for.

Most services (e.g. bitgo, bip32.org etc) use the compressed pubkey to create a multisig redeem script because you can pack more pubkeys into the script (limit 500 bytes iirc)

1 Like

Ah thank you so much. There’s no way I would have figured that out unless I knew the bitcoin scripting language and what arguments it accepted for public keys.

For anyone who runs into this problem into the future, here is a quick way to generate uncompressed public keys using bitcore!

var pub = new bitcore.HDPublicKey('xpub661MyMwAqRbcEk2YrSM37a5skePAXy1CDyyKKBbVBvu6BxKqGb4C7WMFzrwEFHV3b9gQHy9oQVAf19Uw3SG5by68bM22HsHgC7zEZCr1EsC');
var derivedHdPublicKey = pub.derive('m/0'); 
var derivedPublicKey = derivedHdPublicKey.publicKey;
/* Derive bitcoin uncompressed public key from compressed public key  */    
'04' + derivedPublicKey.point.x.toString('hex') + derivedPublicKey.point.y.toString('hex')