UNPKG

btc-hdkey

Version:

Hierarchical Deterministic Wallet support for BTC

126 lines (125 loc) 4.52 kB
"use strict"; 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;