Skip to content

Commit

Permalink
add custom derivation path
Browse files Browse the repository at this point in the history
  • Loading branch information
kieled committed Mar 7, 2024
1 parent 47b285a commit 0187199
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 75 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
src
package-lock.json
package-lock.json
bun.lockb
Binary file removed bun.lockb
Binary file not shown.
13 changes: 1 addition & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"src"
],
"dependencies": {
"@noble/hashes": "^1.3.2",
"@noble/hashes": "^1.3.3",
"belcoinjs-lib": "^0.0.4",
"bells-secp256k1": "^0.1.0",
"belpair": "^0.0.8",
Expand All @@ -45,25 +45,14 @@
"browser-hdkey": "^0.1.7"
},
"devDependencies": {
"@types/hdkey": "^2.0.3",
"@types/bn.js": "^5.1.1",
"@types/bs58": "^4.0.0",
"@types/bs58check": "^2.1.0",
"@types/chai": "^4.3.6",
"@types/mocha": "^5.2.7",
"@types/node": "^20.5.9",
"@types/proxyquire": "^1.3.28",
"@types/randombytes": "^2.0.0",
"@typescript-eslint/eslint-plugin": "^5.45.0",
"@typescript-eslint/parser": "^5.45.0",
"better-npm-audit": "^3.7.3",
"chai": "^4.3.8",
"mocha": "^10.0.0",
"nyc": "^15.1.0",
"prettier": "^2.8.0",
"randombytes": "^2.1.0",
"rimraf": "^2.6.3",
"ts-node": "^8.3.0",
"typescript": "^4.4.4"
},
"license": "MIT"
Expand Down
93 changes: 31 additions & 62 deletions ts_src/hd/private.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import type {
SerializedHDKey,
Hex,
ToSignInput,
AddressType,
FromSeedOpts,
FromMnemonicOpts,
} from "./types";
import { BaseWallet } from "./base";
import * as tinysecp from "bells-secp256k1";
Expand All @@ -21,7 +22,7 @@ import { sha256 } from "@noble/hashes/sha256";

const ECPair = ECPairFactory(tinysecp);

const hdPathString = "m/44'/0'/0'/0";
const DEFAULT_HD_PATH = "m/44'/0'/0'/0";

class HDPrivateKey extends BaseWallet implements Keyring<SerializedHDKey> {
hideRoot?: boolean;
Expand All @@ -34,7 +35,7 @@ class HDPrivateKey extends BaseWallet implements Keyring<SerializedHDKey> {
private seed?: Uint8Array;
private hdWallet?: HDKey;
private root?: HDKey;
private hdPath: string = hdPathString;
private hdPath: string = DEFAULT_HD_PATH;

constructor(options?: PrivateKeyOptions) {
super();
Expand Down Expand Up @@ -179,6 +180,7 @@ class HDPrivateKey extends BaseWallet implements Keyring<SerializedHDKey> {
async fromOptions(options: PrivateKeyOptions) {
this.fromSeed({
seed: Buffer.from(options.seed),
hdPath: options.hdPath,
});
return this;
}
Expand All @@ -187,43 +189,28 @@ class HDPrivateKey extends BaseWallet implements Keyring<SerializedHDKey> {
return new this().fromOptions(options);
}

fromSeed({
seed,
hideRoot,
addressType,
}: {
seed: Uint8Array;
hideRoot?: boolean;
addressType?: AddressType;
}) {
fromSeed(opts: FromSeedOpts) {
this.childIndex = 0;
this.seed = seed;
this.hdWallet = HDKey.fromMasterSeed(Buffer.from(seed));
this.seed = opts.seed;
this.hdWallet = HDKey.fromMasterSeed(Buffer.from(opts.seed));

if (opts.hdPath) {
this.hdPath = opts.hdPath;
}

this.root = this.hdWallet.derive(this.hdPath);
this.hideRoot = hideRoot;
this.hideRoot = opts.hideRoot;

this.privateKey = this.root.privateKey!;
this.publicKey = this.root.publicKey!;

this.addressType = addressType;
this.addressType = opts.addressType;

return this;
}

static fromSeed({
seed,
hideRoot,
addressType,
}: {
seed: Uint8Array;
hideRoot?: boolean;
addressType?: AddressType;
}): HDPrivateKey {
return new this().fromSeed({
seed,
hideRoot,
addressType,
});
static fromSeed(opts: FromSeedOpts): HDPrivateKey {
return new this().fromSeed(opts);
}

toggleHideRoot(): void {
Expand All @@ -233,44 +220,24 @@ class HDPrivateKey extends BaseWallet implements Keyring<SerializedHDKey> {
}
}

async fromMnemonic({
mnemonic,
passphrase,
hideRoot,
addressType,
}: {
mnemonic: string;
passphrase?: string;
hideRoot?: boolean;
addressType?: AddressType;
}): Promise<HDPrivateKey> {
const seed = await mnemonicToSeed(mnemonic, passphrase ?? "bells");
async fromMnemonic(opts: FromMnemonicOpts): Promise<HDPrivateKey> {
const seed = await mnemonicToSeed(
opts.mnemonic,
opts.passphrase ?? "bells"
);

this.fromSeed({
seed,
hideRoot,
addressType,
hideRoot: opts.hideRoot,
addressType: opts.addressType,
hdPath: opts.hdPath,
});

return this;
}

static fromMnemonic({
mnemonic,
passphrase,
hideRoot,
addressType,
}: {
mnemonic: string;
passphrase?: string;
hideRoot?: boolean;
addressType?: AddressType;
}): Promise<HDPrivateKey> {
return new this().fromMnemonic({
mnemonic,
passphrase,
hideRoot,
addressType,
});
static fromMnemonic(opts: FromMnemonicOpts): Promise<HDPrivateKey> {
return new this().fromMnemonic(opts);
}

fromPrivateKey(_key: Uint8Array) {
Expand All @@ -285,13 +252,14 @@ class HDPrivateKey extends BaseWallet implements Keyring<SerializedHDKey> {
return this.accounts.length;
}

serialize() {
serialize(): SerializedHDKey {
if (this.childIndex !== 0)
throw new Error("You should use only root wallet to serializing");
return {
numberOfAccounts: this.getChildCount(),
seed: toHex(this.seed!),
addressType: this.addressType!,
hdPath: this.hdPath !== DEFAULT_HD_PATH ? this.hdPath : undefined,
};
}

Expand All @@ -306,6 +274,7 @@ class HDPrivateKey extends BaseWallet implements Keyring<SerializedHDKey> {
seed: fromHex(opts.seed),
hideRoot: opts.hideRoot,
addressType: opts.addressType,
hdPath: opts.hdPath,
});

root.addAccounts(opts.numberOfAccounts);
Expand Down
17 changes: 17 additions & 0 deletions ts_src/hd/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,22 @@ export type Base58String = string;

export interface PrivateKeyOptions {
seed: string;
hdPath?: string;
}

export interface FromSeedOpts {
seed: Uint8Array;
hideRoot?: boolean;
addressType?: AddressType;
hdPath?: string;
}

export interface FromMnemonicOpts {
mnemonic: string;
passphrase?: string;
hideRoot?: boolean;
addressType?: AddressType;
hdPath?: string;
}

export interface PublicKeyOptions
Expand All @@ -20,6 +36,7 @@ export interface SerializedHDKey extends SerializedBase {
seed: string;
numberOfAccounts?: number;
hideRoot?: boolean;
hdPath?: string;
}

export interface SerializedSimpleKey extends SerializedBase {
Expand Down

0 comments on commit 0187199

Please sign in to comment.