bitcoinjs-lib
bitcoinjs-lib copied to clipboard
Can I parse a zpub key with this library and generate derived keys?
Electrum wallet exports a zpub master public key. I need to generate derived public addresses from it. Can I do it with this library?
I was just wondering the same. I'm looking at https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.spec.ts#L16 and it seems the answer may be yes. I'll report back later.
Same thing I am wondering. Any luck you had with it so far?
Yes it's possible. You need to manipulate a particular part.
// Thank you https://github.com/bitcoinjs/bitcoinjs-lib/issues/1238#issuecomment-426880691
const fixNetworkVersionBytes = (xkey: string, network: bitcoin.Network): string => {
let type = undefined;
if (xkey.slice(1, 4) == "prv") type = "private";
if (xkey.slice(1, 4) == "pub") type = "public";
if (type === undefined) throw new Error("Bad xkey prefix");
let data = bs58.decode(xkey);
data = data.slice(4);
data = Buffer.concat([Buffer.from((network.bip32 as any)[type].toString(16).padStart(8, '0'),'hex'), data]);
return bs58.encode(data);
};
// Derive a new key-pair
const deriveBitcoinPrivateKey = (xprv: string, account: number, index: number, network: bitcoin.Network): string => {
const node = bip32.fromBase58(fixNetworkVersionBytes(xprv, network), network);
return node.derive(account).derive(index).toWIF();
};
Beautiful, thank you. Espcially for the typescript example.
I've just found this one as well if that helps anyone any further: https://github.com/bitcoinjs/bitcoinjs-lib/issues/966#issuecomment-356346515
For reference. an implementation that worked for me for deriving public addresses and making sure that it's not a private key that's used as input:
import * as bitcoinjs from 'bitcoinjs-lib';
import * as ecc from 'tiny-secp256k1';
import b58 from 'bs58check';
import BIP32Factory from 'bip32';
const bip32 = BIP32Factory(ecc);
const fixNetworkVersionBytes = (mpk: string, network: bitcoinjs.Network): string => {
let type = undefined;
if (mpk.slice(1, 4) == "pub") type = "public";
if (type === undefined) throw new Error("Bad MPK prefix");
let data = b58.decode(mpk);
data = data.slice(4);
data = Buffer.concat([Buffer.from((network.bip32 as any)[type].toString(16).padStart(8, '0'),'hex'), data]);
return b58.encode(data);
};
const deriveBitcoinNativeSegWitAddress = (mpk: string, index: number, network: bitcoinjs.Network): string => {
const node = bip32.fromBase58(fixNetworkVersionBytes(mpk, network), network);
const child = node.derive(0).derive(index);
return bitcoinjs.payments.p2wpkh({ pubkey: child.publicKey, network }).address!;
};
Thanks for the help @LeeKorbisCa
I believe this was the original question.
These are the examples
https://github.com/bitcoinjs/bitcoinjs-lib/blob/1f92ada3fda587c1c0a6aa93649afa04e8382b93/test/integration/bip32.spec.ts
const bitcoin = require("bitcoinjs-lib");
const ecc = require("tiny-secp256k1");
const { BIP32Factory } = require("bip32");
const bip32 = BIP32Factory(ecc);
const b58 = require("bs58check");
function convert_z(z) {
let data = b58.decode(z);
data = data.slice(4);
data = Buffer.concat([Buffer.from("0488b21e", "hex"), data]);
return b58.encode(data);
}
const xpub = convert_z("YOUR ZPUB HERE");
const node = bip32.fromBase58(xpub).derivePath("0/0");
const address = bitcoin.payments.p2wpkh({ pubkey: node.publicKey }).address;
I took that function from someone here I can't find that.