btc-hdkey
Version:
Hierarchical Deterministic Wallet support for BTC
126 lines (125 loc) • 4.52 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const hdKey = require('hdkey');
const bitcoin = require('bitcoinjs-lib');
const bip39 = require('bip39');
const assert = require('bsert');
class HDKey {
/**
* Generate a BIP39 menemonic
*/
randomMenemonic() {
return bip39.generateMnemonic();
}
/**
* Generate a pseudo-random seed from BIP39 menemonic
* @param menemonic
*/
seedFromMenemonic(menemonic) {
assert(bip39.validateMnemonic(menemonic));
return bip39.mnemonicToSeedSync(menemonic).toString('hex');
}
/**
* Derive an extended keypair from seed
* @param seed The seed-string to use for generating the HDKey
* @param net Network to use ("testnet", "mainnet")
* @param n n-th derived keypair default:0
*/
deriveAccount(seed, net = "mainnet", n = 0) {
assert(n >= 0);
let version;
if (net === 'testnet') {
version = { private: 0x04358394, public: 0x043587CF }; // HDKey does not support testnet keys out of the box
}
let rootKey = hdKey.fromMasterSeed(seed, version);
let childKey = rootKey.derive('m/' + n + '\'');
childKey.network = version;
return childKey;
}
//doc https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
//lib https://github.com/cryptocoinjs/hdkey
//gen http://bip32.org/
// enter bip32 key of the following formats:
// - extended public mainnet key (xpub prefix)
// - extended private mainnet key (xprv prefix) (not reccomended)
// - extended public testnet key (tpub prefix)
// - extended private testnet key (tprv prefix) (not reccomended)
/**
*
* @param extendedKey Extended key to generate address from
* @param networkName Network to use ("testnet", "mainnet")
* @param n n-th derived address default:0
*/
generateAddress(extendedKey, n = 0) {
assert(n >= 0);
let version;
let t = this.checkHDKey(extendedKey);
if (!t) {
throw new Error("Not an extended key: " + extendedKey);
}
if (t.net == "testnet") {
version = { private: 0x04358394, public: 0x043587CF }; //HDKey does not support testnet keys out of the box
}
const hdkey = hdKey.fromExtendedKey(extendedKey, version);
const childkey = hdkey.derive('m/0/' + n);
const address = bitcoin.payments.p2pkh({ pubkey: childkey._publicKey, network: bitcoin.networks[t.net] }).address;
return address;
}
HDKeyFromExtendedKey(extendedKeyB58) {
let key;
let version;
let t = this.checkHDKey(extendedKeyB58);
if (!t) {
return false;
}
if (t.net === 'testnet') {
version = { private: 0x04358394, public: 0x043587CF }; // HDKey does not support testnet keys out of the box
}
if (t.type === 'public') {
key = hdKey.fromExtendedKey(extendedKeyB58, version);
}
else {
key = hdKey.fromExtendedKey(extendedKeyB58, version);
}
return key;
}
checkHDKey(key) {
if (key.startsWith('x')) {
if (key.startsWith('xpub')) {
return { net: 'mainnet', type: 'public' };
}
else {
return { net: 'mainnet', type: 'private' };
}
}
if (key.startsWith('t')) {
if (key.startsWith('tpub')) {
return { net: 'testnet', type: 'public' };
}
else {
return { net: 'testnet', type: 'private' };
}
}
return false;
}
deriveAddress(extendedKey, n, derivationPrefix = 'm/0/') {
let t = this.checkHDKey(extendedKey);
let childkey = this.deriveKey(extendedKey, n, derivationPrefix);
if (!t || !childkey) {
return false;
}
return this.addressFromHDKey(childkey._publicKey, t.net);
}
deriveKey(extendedKey, n, derivationPrefix = 'm/0/') {
let t = this.checkHDKey(extendedKey);
let hdkey = this.HDKeyFromExtendedKey(extendedKey);
if (!t || !hdkey) {
return false;
}
return hdkey.derive(derivationPrefix + n);
}
addressFromHDKey(hdkey, net = "mainnet") {
return bitcoin.payments.p2pkh({ pubkey: Buffer.from(hdkey), network: bitcoin.networks[net] }).address;
}
}
exports.HDKey = HDKey;