bitcoinjs / bitcoinjs-lib

A javascript Bitcoin library for node.js and browsers.
MIT License
5.65k stars 2.09k forks source link

Import BIP49 WIF (uprv key) #1647

Closed MoistCarrot closed 3 years ago

MoistCarrot commented 3 years ago

Hi,

I have the following code below that generates a BIP49 uprv key based on a mnemonic. Because this key is so long though, I am exporting it as a WIF to make it more readable. However, I have been unable to figure out how to import this WIF back into its original uprv format.

I tried encoding and decoding the uprv manually using the "wif" library, but decoding the privatekey in the decoded object returned by wif.decode() is not the same as the original uprv key. This is the code that I was using to do this:

const encodedWif = wif.encode(TESTNET.wif, root.__D, true);
console.log(encodedWif);
const decodedWif = wif.decode(encodedWif); // Not the same as the original uprv
console.log(Buffer.from(decodedWif.privateKey).toString('hex'));

I also tried using ECPair.fromWIF(), but again, I was unable to get the original uprv key back from its respective wif.

Here is the entire pseudocode for what I am trying to do:

const bitcoin = require('bitcoinjs-lib');
const TESTNET = bitcoin.networks.testnet;
const bip32 = require('bip32');
const bip39 = require('bip39');

const mnemonic = "point soldier hip mammal banana deer model nurse cross fun taste bomb";
const seed = bip39.mnemonicToSeedSync(mnemonic);
console.log("BIP39 Seed Hex: ", Buffer.from(seed).toString('hex'));
console.log();

const root = bip32.fromSeed(seed, TESTNET);
root.network.bip32.public = 71979618; // upub serialization hex: 0x044a5262 (testnet)
root.network.bip32.private = 71978536; // uprv serialization hex: 0044a4e28 (testnet)

const encodedWif = wif.encode(TESTNET.wif, root.__D, true);
console.log(encodedWif);
const decodedWif = wif.decode(encodedWif); // Not the same as the original uprv
console.log(Buffer.from(decodedWif.privateKey).toString('hex'));

const rootPrivateKey = root.toBase58();
console.log("BIP32 Root Private Key (Base58): ", rootPrivateKey);

const exportedWif = root.toWIF();
console.log("BIP32 Root Key (WIF): ", exportedWif);

const importedWif = "Code to import the WIF";
if (importedWif === rootPrivateKey) console.log(true);

I remember reading somewhere in the repo that this library does not support uprv/upub keys. Perhaps that is why I am unable to import the WIF back into its original uprv format? If this is the case, how can I go about converting the WIF back to its original uprv format?

junderw commented 3 years ago

Your problem has nothing to do with uprv/xprv difference.

Your problem has to do with wif / extended-key(xprv/uprv/yprv etc.) difference.

The extended key encodes a ton of info, private key, chaincode, depth, fingerprint, etc.

Wif only encodes a private key and a single byte "version".

You are essentially throwing the chaincode etc in the garbage can by encoding into WIF.

Solution: Don't use WIF.