UNPKG

bitcoin-tx-lib

Version:

A Typescript library for building and signing Bitcoin transactions

109 lines (91 loc) 4.16 kB
import { mnemonicToSeedSync } from '@scure/bip39'; import { HDKManager } from '.'; import { ECPairKey } from '../ecpairkey'; import { HDKey } from "@scure/bip32"; const TEST_MNEMONIC = 'pistol lesson rigid season script crouch clog spin lottery canal deal leaf'; const TEST_PASSWORD = 'test-password'; describe('HDKManager', () => { test('should create an instance from mnemonic without password', () => { const hdk = HDKManager.fromMnemonic(TEST_MNEMONIC); expect(hdk).toBeInstanceOf(HDKManager); }); test('should create an instance from mnemonic with password', () => { const hdk = HDKManager.fromMnemonic(TEST_MNEMONIC, TEST_PASSWORD); expect(hdk).toBeInstanceOf(HDKManager); }); test('should create an instance from master seed (hex string)', () => { const masterSeed = mnemonicToSeedSync(TEST_MNEMONIC); const hdk = HDKManager.fromMasterSeed(masterSeed); expect(hdk).toBeInstanceOf(HDKManager); }); test('should derive private key at index 0', () => { const hdk = HDKManager.fromMnemonic(TEST_MNEMONIC); const key = hdk.derivatePrivateKey(0); expect(key).toBeInstanceOf(Uint8Array); expect(key.length).toBeGreaterThan(0); }); test('should derive multiple keys using listHDKeys', () => { const hdk = HDKManager.fromMnemonic(TEST_MNEMONIC); const keys = hdk.deriveMultiplePrivateKeys(5); expect(keys.length).toBe(5); keys.forEach(key => { expect(key).toBeInstanceOf(Uint8Array); expect(key.length).toBeGreaterThan(0); }); }); test('should return a valid ECPairKey for index 0 (mainnet)', () => { const hdk = HDKManager.fromMnemonic(TEST_MNEMONIC); const pairKey = hdk.derivatePairKey(0, { network: 'mainnet' }); expect(pairKey).toBeInstanceOf(ECPairKey); expect(pairKey.getAddress('p2wpkh')).toMatch(/^bc1/); }); test('should return a valid ECPairKey for index 0 (testnet)', () => { const hdk = HDKManager.fromMnemonic(TEST_MNEMONIC); const pairKey = hdk.derivatePairKey(0, { network: 'testnet' }); expect(pairKey).toBeInstanceOf(ECPairKey); expect(pairKey.getAddress('p2wpkh')).toMatch(/^tb1/); }); test('should return multiple ECPairKeys with listPairKeys', () => { const hdk = HDKManager.fromMnemonic(TEST_MNEMONIC); const keys = hdk.derivateMultiplePairKeys(3, { network: 'testnet' }); expect(keys.length).toBe(3); keys.forEach(key => { expect(key).toBeInstanceOf(ECPairKey); expect(key.getAddress('p2wpkh')).toMatch(/^tb1/); }); }); test('should throw error if derived key has no private key', () => { const hdk = HDKManager.fromMnemonic(TEST_MNEMONIC); // monkey-patch internal derive to simulate error const original = hdk['_rootKey'].derive; hdk['_rootKey'].derive = () => ({ privateKey: undefined } as any); expect(() => hdk.derivatePrivateKey(0)).toThrow(); hdk['_rootKey'].derive = original; // restore }); test('should use default BIP44 path components when not provided', () => { const hdk = HDKManager.fromMnemonic(TEST_MNEMONIC); expect(hdk.purpose).toBe(84); expect(hdk.coinType).toBe(0); expect(hdk.account).toBe(0); expect(hdk.change).toBe(0); }); test('should allow custom BIP44 path components via constructor', () => { const masterSeed = mnemonicToSeedSync(TEST_MNEMONIC); const hdk = new HDKManager({ rootKey: HDKey.fromMasterSeed(masterSeed), purpose: 84, coinType: 1, account: 2, change: 1 }); expect(hdk.purpose).toBe(84); expect(hdk.coinType).toBe(1); expect(hdk.account).toBe(2); expect(hdk.change).toBe(1); }); test('should generate the correct derivation path', () => { const hdk = HDKManager.fromMnemonic(TEST_MNEMONIC); const path = hdk.getDerivationPath(5); expect(path).toBe("m/84'/0'/0'/0/5"); }); });