Search code examples
ethers.jshardhatrsk

How to get a specific number of signers while testing smart contracts in Hardhat?


I am developing my smart contracts in Hardhat and testing on RSK Testnet. To create signer accounts, I am using a mnemonic seed phrase and the following Hardhat configuration: ​

require('@nomicfoundation/hardhat-toolbox');
const { mnemonic } = require('./.secret.json');
​
/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
  solidity: '0.8.16',
  networks: {
    hardhat: {},
    rsktestnet: {
      chainId: 31,
      url: 'https://public-node.testnet.rsk.co/',
      accounts: { // <-- here
        mnemonic,
        path: "m/44'/60'/0'/0",
      },
    },
  },
  // ...
};

​ In my tests, I usually use an ethers.js helper function to get an array of signers in my tests: ​

const signers = await hre.ethers.getSigners();

​ However this function returns 20 signer wallets. Is there a way to get a specific amount of wallets, if I don't want this default amount?


Solution

  • You can use the Wallet.fromMnemonic function from ethers.js to do this.

    Within hardhat.config.js, or anywhere where you import the hre variable, you can do so by invoking it like so: hre.ethers.Wallet.fromMnemonic(mnemonic, derivationPath?, wordList?)

    This function is used to generate a single wallet. The function's second argument is the BIP-32 derivation path. Since the one that you are using in config is m/44'/60'/0'/0, then by default the function will append /0, resulting in m/44'/60'/0'/0/0 to generate the 1st wallet.

    If you want to generate another one, you could specify m/44'/60'/0'/0/1 (with /1 appended).

    To generate a specific number of wallets, simply do the above in a loop, changing the final index in the derivation path in each iteration.

    For example, the following function will obtain 10:

    function getSigners(amount = 40) {
      // getting seed phrase and derivation path from the hardhat config
      const { mnemonic, path } = hre.network.config.accounts
      return [...Array(amount).keys()].map((i) =>
        hre.ethers.Wallet.fromMnemonic(mnemonic, `${path}/${i}`)
          .connect(hre.ethers.provider),
      )
    }