fix: alternating address derivation

This commit is contained in:
kyranjamie
2020-07-08 17:54:33 +02:00
committed by kyranjamie
parent e838926f27
commit edc7b304dc
3 changed files with 99 additions and 13 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "@blockstack/keychain",
"version": "0.7.5",
"version": "0.8.5",
"description": "A package for managing Blockstack keychains",
"main": "./dist/index.js",
"umd:main": "./dist/keychain.umd.production.js",

View File

@@ -1,10 +1,16 @@
import { ChainID, getAddressFromPrivateKey } from '@blockstack/stacks-transactions';
import {
ChainID,
getAddressFromPrivateKey,
TransactionVersion,
} from '@blockstack/stacks-transactions';
import { BIP32Interface, ECPair } from 'bitcoinjs-lib';
import { ecPairToHexString } from 'blockstack';
const networkDerivationPath = `m/44'/5757'/0'/0/0`;
export const derivationPaths = {
[ChainID.Mainnet]: `m/44'/5757'/0'/0/0`,
[ChainID.Testnet]: `m/44'/1'/0'/0/0`,
[ChainID.Mainnet]: networkDerivationPath,
[ChainID.Testnet]: networkDerivationPath,
};
export function getDerivationPath(chain: ChainID) {
@@ -19,9 +25,11 @@ export function deriveStxAddressChain(chain: ChainID) {
}
const ecPair = ECPair.fromPrivateKey(childKey.privateKey);
const privateKey = ecPairToHexString(ecPair);
const txVersion =
chain === ChainID.Mainnet ? TransactionVersion.Mainnet : TransactionVersion.Testnet;
return {
childKey,
address: getAddressFromPrivateKey(privateKey),
address: getAddressFromPrivateKey(privateKey, txVersion),
privateKey,
};
};

View File

@@ -1,13 +1,13 @@
import { ChainID } from '@blockstack/stacks-transactions';
import { BIP32Interface } from 'bitcoinjs-lib';
import { deriveStxAddressChain } from '../../src/address-derivation';
import { deriveRootKeychainFromMnemonic } from '../../src/mnemonic';
const phrase =
'humble ramp winner eagle stumble follow gravity roast receive quote buddy start demise issue egg jewel return hurdle ball blind pulse physical uncle room';
describe('deriveStxAddressChain()', () => {
test('it returns mainnet derived keys', async () => {
test('it returns mainnet derived keys, pt. 1', async () => {
const phrase =
'humble ramp winner eagle stumble follow gravity roast receive quote buddy start demise issue egg jewel return hurdle ball blind pulse physical uncle room';
const deriveStxMainnetAddressChain = deriveStxAddressChain(ChainID.Mainnet);
const rootNode = await deriveRootKeychainFromMnemonic(phrase);
const result = deriveStxMainnetAddressChain(rootNode);
@@ -16,12 +16,90 @@ describe('deriveStxAddressChain()', () => {
);
});
test('it returns testnet derived keys', async () => {
const deriveStxTestnetAddressChain = deriveStxAddressChain(ChainID.Testnet);
test('it returns mainnet derived keys, pt. 2', async () => {
const phrase =
'oblige boat easily source clip remind steel hockey nut arrow swallow keep run fragile fresh river expire stay monster black defy box fiber wave';
const deriveStxMainnetAddressChain = deriveStxAddressChain(ChainID.Mainnet);
const rootNode = await deriveRootKeychainFromMnemonic(phrase);
const result = deriveStxTestnetAddressChain(rootNode);
const result = deriveStxMainnetAddressChain(rootNode);
expect(result.privateKey).toEqual(
'4cf240ef1e9b467c64b196b6ff3d24d9709f287f667939056fbcfc54e4a1642901'
'd7c71a427b8a9ed870c9552f67beadc2710dbee7f29a0cf6cfd1dd96a703bf1801'
);
expect(result.address).toEqual('SP2JSAXXTH90R04677F6JDS5D4DXWNW4T3KWNFDR5');
});
describe('it behaves according to CLI library for mainnet', () => {
const phrase =
'parade vacant kitten museum voice shift tell embrace security page praise cloud stove canal sketch huge ignore cotton island hand wall blush empower movie';
const deriveStxTestnetAddressChain = deriveStxAddressChain(ChainID.Mainnet);
let rootNode: BIP32Interface;
let result: ReturnType<typeof deriveStxTestnetAddressChain>;
beforeEach(async () => {
rootNode = await deriveRootKeychainFromMnemonic(phrase);
result = deriveStxTestnetAddressChain(rootNode);
});
test('private key is derive accurately for cli mainnet', () => {
expect(result.privateKey).toEqual(
'4587afc14878fd97aa01032bfae21ab01ae9a087abeecc7d867d39393e22ce2101'
);
});
test('address is derived accurately for cli mainnet', () => {
expect(result.address).toEqual('SP398525PZNCJTPNM6K4NW0T40YXJFEZ9DEQR12TR');
});
});
//
// This test should pass if testnet key derivation is
// supposed to use derivation path `m/44'/5757'/0'/0/0`,
describe(`should pass if testnet should use derivation path "m/44'/5757'/0'/0/0"`, () => {
const phrase =
'decorate confirm shoulder gain develop name tone source potato march maple company blanket discover ship clown virus broccoli room adapt praise oak west canoe';
const deriveStxTestnetAddressChain = deriveStxAddressChain(ChainID.Testnet);
let rootNode: BIP32Interface;
let result: ReturnType<typeof deriveStxTestnetAddressChain>;
beforeEach(async () => {
rootNode = await deriveRootKeychainFromMnemonic(phrase);
result = deriveStxTestnetAddressChain(rootNode);
});
test('private key is derive accurately for cli testnet', () => {
expect(result.privateKey).toEqual(
'cbaa7cbb821fdd17077fa24529803d351eb038fd6ec8eb14fc92344dbb244da901'
);
});
test('address is derived accurately for cli testnet', () => {
expect(result.address).toEqual('ST8SHKQXP59D65B1X0PHDHTWMKKPM94N9A2RNXE6');
});
});
//
// This test should pass if testnet key derivation is
// supposed to use derivation path `m/44'/1'/0'/0/0`,
// describe(`should pass if testnet should use derivation path "m/44'/1'/0'/0/0"`, () => {
// const phrase =
// 'trumpet hole school slim beauty advance evoke chapter random broom account twice state panel grant unfair empower spy asset depend acquire potato scatter atom';
// const deriveStxTestnetAddressChain = deriveStxAddressChain(ChainID.Testnet);
// let rootNode: BIP32Interface;
// let result: ReturnType<typeof deriveStxTestnetAddressChain>;
// beforeEach(async () => {
// rootNode = await deriveRootKeychainFromMnemonic(phrase);
// result = deriveStxTestnetAddressChain(rootNode);
// });
// test('private key is derive accurately for cli testnet', () => {
// expect(result.privateKey).toEqual(
// '65d49e09d57c07951b34cdac6b4ef6bdb8ee18ac7884c31a6876b086e7131b2d01'
// );
// });
// test('address is derived accurately for cli testnet', () => {
// expect(result.address).toEqual('ST1MED1C7R0V4FAZBAEF3FPD3JVHBP000FKTTG64T');
// });
// });
});