diff --git a/.gitignore b/.gitignore index d639844..682edaf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules src -package-lock.json \ No newline at end of file +package-lock.json +bun.lockb \ No newline at end of file diff --git a/bun.lockb b/bun.lockb deleted file mode 100755 index cd5c25e..0000000 Binary files a/bun.lockb and /dev/null differ diff --git a/package.json b/package.json index 3eaa7c5..2c8f309 100644 --- a/package.json +++ b/package.json @@ -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", @@ -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" diff --git a/ts_src/hd/private.ts b/ts_src/hd/private.ts index 364747a..061a4a1 100644 --- a/ts_src/hd/private.ts +++ b/ts_src/hd/private.ts @@ -9,7 +9,8 @@ import type { SerializedHDKey, Hex, ToSignInput, - AddressType, + FromSeedOpts, + FromMnemonicOpts, } from "./types"; import { BaseWallet } from "./base"; import * as tinysecp from "bells-secp256k1"; @@ -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 { hideRoot?: boolean; @@ -34,7 +35,7 @@ class HDPrivateKey extends BaseWallet implements Keyring { private seed?: Uint8Array; private hdWallet?: HDKey; private root?: HDKey; - private hdPath: string = hdPathString; + private hdPath: string = DEFAULT_HD_PATH; constructor(options?: PrivateKeyOptions) { super(); @@ -179,6 +180,7 @@ class HDPrivateKey extends BaseWallet implements Keyring { async fromOptions(options: PrivateKeyOptions) { this.fromSeed({ seed: Buffer.from(options.seed), + hdPath: options.hdPath, }); return this; } @@ -187,43 +189,28 @@ class HDPrivateKey extends BaseWallet implements Keyring { 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 { @@ -233,44 +220,24 @@ class HDPrivateKey extends BaseWallet implements Keyring { } } - async fromMnemonic({ - mnemonic, - passphrase, - hideRoot, - addressType, - }: { - mnemonic: string; - passphrase?: string; - hideRoot?: boolean; - addressType?: AddressType; - }): Promise { - const seed = await mnemonicToSeed(mnemonic, passphrase ?? "bells"); + async fromMnemonic(opts: FromMnemonicOpts): Promise { + 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 { - return new this().fromMnemonic({ - mnemonic, - passphrase, - hideRoot, - addressType, - }); + static fromMnemonic(opts: FromMnemonicOpts): Promise { + return new this().fromMnemonic(opts); } fromPrivateKey(_key: Uint8Array) { @@ -285,13 +252,14 @@ class HDPrivateKey extends BaseWallet implements Keyring { 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, }; } @@ -306,6 +274,7 @@ class HDPrivateKey extends BaseWallet implements Keyring { seed: fromHex(opts.seed), hideRoot: opts.hideRoot, addressType: opts.addressType, + hdPath: opts.hdPath, }); root.addAccounts(opts.numberOfAccounts); diff --git a/ts_src/hd/types.ts b/ts_src/hd/types.ts index a5ec4b3..2b5e66f 100644 --- a/ts_src/hd/types.ts +++ b/ts_src/hd/types.ts @@ -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 @@ -20,6 +36,7 @@ export interface SerializedHDKey extends SerializedBase { seed: string; numberOfAccounts?: number; hideRoot?: boolean; + hdPath?: string; } export interface SerializedSimpleKey extends SerializedBase {