@nomicfoundation/hardhat-ethers
Version:
Hardhat plugin for ethers
44 lines • 2.01 kB
JavaScript
import { HardhatError } from "@nomicfoundation/hardhat-errors";
import { bytesToHexString } from "@nomicfoundation/hardhat-utils/bytes";
const HD_PATH_REGEX = /^m(:?\/\d+'?)+\/?$/;
export async function derivePrivateKeys(accounts) {
const mnemonic = await accounts.mnemonic.get();
const passphrase = await accounts.passphrase.get();
return derivePrivateKeysImpl(mnemonic, accounts.path, accounts.initialIndex, accounts.count, passphrase);
}
async function derivePrivateKeysImpl(mnemonic, hdpath, initialIndex, count, passphrase) {
if (!HD_PATH_REGEX.test(hdpath)) {
throw new HardhatError(HardhatError.ERRORS.CORE.NETWORK.INVALID_HD_PATH, {
path: hdpath,
});
}
if (!hdpath.endsWith("/")) {
hdpath += "/";
}
const privateKeys = [];
for (let i = initialIndex; i < initialIndex + count; i++) {
const privateKey = await deriveKeyFromMnemonicAndPath(mnemonic, hdpath + i.toString(), passphrase);
if (privateKey === undefined) {
throw new HardhatError(HardhatError.ERRORS.CORE.NETWORK.CANT_DERIVE_KEY, {
mnemonic,
path: hdpath,
});
}
privateKeys.push(privateKey);
}
return privateKeys;
}
async function deriveKeyFromMnemonicAndPath(mnemonic, hdPath, passphrase) {
const { mnemonicToSeedSync } = await import("ethereum-cryptography/bip39");
const { HDKey } = await import("ethereum-cryptography/hdkey");
// NOTE: If mnemonic has space or newline at the beginning or end, it will be trimmed.
// This is because mnemonic containing them may generate different private keys.
const trimmedMnemonic = mnemonic.trim();
const seed = mnemonicToSeedSync(trimmedMnemonic, passphrase);
const masterKey = HDKey.fromMasterSeed(seed);
const derived = masterKey.derive(hdPath);
return derived.privateKey === null
? undefined
: bytesToHexString(derived.privateKey);
}
//# sourceMappingURL=derive-private-key.js.map