diff --git a/packages/cli/src.ts/cli.ts b/packages/cli/src.ts/cli.ts index 5fc3a388f..2c9e77288 100644 --- a/packages/cli/src.ts/cli.ts +++ b/packages/cli/src.ts/cli.ts @@ -397,7 +397,7 @@ async function loadAccount(arg: string, plugin: Plugin, preventFile?: boolean): // Secure entry; use prompt with mask if (arg === "-") { - const content = await getPassword("Private Key / Mnemonic:"); + const content = await getPassword("Private Key / Mnemonic: "); return loadAccount(content, plugin, true); } @@ -413,7 +413,7 @@ async function loadAccount(arg: string, plugin: Plugin, preventFile?: boolean): let signerPromise: Promise = null; if (plugin.mnemonicPassword) { signerPromise = getPassword("Password (mnemonic): ").then((password) => { - let node = ethers.utils.HDNode.fromMnemonic(mnemonic, password).derivePath(ethers.utils.defaultPath); + let node = ethers.utils.HDNode.fromMnemonic(mnemonic, password).derivePath(plugin.mnemonicPath); return new ethers.Wallet(node.privateKey, plugin.provider); }); @@ -425,7 +425,7 @@ async function loadAccount(arg: string, plugin: Plugin, preventFile?: boolean): let progressBar = getProgressBar("Decrypting"); return scrypt.scrypt(passwordBytes, saltBytes, (1 << 20), 8, 1, 32, progressBar).then((key) => { const derivedPassword = ethers.utils.hexlify(key).substring(2); - const node = ethers.utils.HDNode.fromMnemonic(mnemonic, derivedPassword).derivePath(ethers.utils.defaultPath); + const node = ethers.utils.HDNode.fromMnemonic(mnemonic, derivedPassword).derivePath(plugin.mnemonicPath); return new ethers.Wallet(node.privateKey, plugin.provider); }); }); @@ -495,6 +495,7 @@ export abstract class Plugin { accounts: ReadonlyArray; mnemonicPassword: boolean; + mnemonicPath: string; _xxxMnemonicPasswordHard: boolean; gasLimit: ethers.BigNumber; @@ -566,6 +567,18 @@ export abstract class Plugin { // Accounts ethers.utils.defineReadOnly(this, "mnemonicPassword", argParser.consumeFlag("mnemonic-password")); + + ethers.utils.defineReadOnly(this, "mnemonicPath", (function() { + let mnemonicPath = argParser.consumeOption("mnemonic-path"); + if (mnemonicPath) { + if (mnemonicPath.match(/^[0-9]+$/)) { + return `m/44'/60'/${ mnemonicPath }'/0/0`; + } + return mnemonicPath; + } + return ethers.utils.defaultPath; + })()); + ethers.utils.defineReadOnly(this, "_xxxMnemonicPasswordHard", argParser.consumeFlag("xxx-mnemonic-password")); let accounts: Array = [ ]; @@ -859,6 +872,7 @@ export class CLI { console.log(" --account-rpc ADDRESS Add the address from a JSON-RPC provider"); console.log(" --account-rpc INDEX Add the index from a JSON-RPC provider"); console.log(" --mnemonic-password Prompt for a password for mnemonics"); + console.log(" --mnemonic-path BIP-43 mnemonic path"); console.log(" --xxx-mnemonic-password Prompt for a (experimental) hard password"); console.log(""); }