3

I have a Hardhat script that queries the RIF token balance on Rootstock. However the RIF address is hardcoded in my script: ​

const rifTokenAddress = '0x2aCc95758f8b5F583470bA265Eb685a8f45fC9D5';
​
async function main() {
  const erc20 = await ethers.getContractAt(
    ['function balanceOf(address owner) view returns (uint)'],
    rifTokenAddress.toLowerCase(),
  );
  const walletAddress = (await ethers.getSigner(0)).address;
  const rifBalance = await erc20.balanceOf(walletAddress);
  console.log(ethers.utils.formatEther(rifBalance));
}
​
main();

​ Now I am using this command to run the script: ​

npx hardhat run scripts/balances.js --network rskmainnet

​ I would like to be able to specify a token address in the command line like this: ​

npx hardhat run scripts/balances.js --network rskmainnet --token 0x2d919f19D4892381d58EdEbEcA66D5642ceF1A1F

​ Is there a way to modify Hardhat script so that it could read token address from the command line, similar to how I select the network with --network parameter? ​ For reference, this is my hardhat.config.js file: ​

require('@nomicfoundation/hardhat-toolbox');
const { mnemonic } = require('./.secret.json');
​
const accounts = {
  mnemonic,
  path: "m/44'/60'/0'/0",
};
​
module.exports = {
  solidity: '0.8.9',
  networks: {
    hardhat: {},
    rsktestnet: {
      chainId: 31,
      url: 'https://public-node.testnet.rsk.co/',
      accounts,
    },
    rskmainnet: {
      chainId: 30,
      url: 'https://public-node.rsk.co/',
      accounts,
    },
  },
};
bguiz
  • 27,371
  • 47
  • 154
  • 243
Adil6
  • 31
  • 3

2 Answers2

4

One quick solution that I can think of is, put your npx hardhat command as a script in your package.json.

"hardhat-runner": "npx hardhat run --network rskmainnet scripts/balances.js"

Now you can invoke this using the following command. Now pass your arg 'token'.

npm run hardhat-runner --token=0x2d919f19D4892381d58EdEbEcA66D5642ceF1A1F

In your js code, you will get this as env variable.

process.env.npm_config_token

IMO, hardhat does not accept custom args hence passing any args directly will lead to HH308 error. This may change in future though.

Note: This solution has been tested on NPM 7 only.

Cheers.

Rajesh Panda
  • 636
  • 6
  • 10
3

There is no way to do it with Hardhat scripts. This is because scripts only allow Hardhat's built in CLI parameters (including --network), but does not allow you to define your own custom CLI parameters.

However it's easy to accomplish by converting your script to a task, which does allow you to define your own custom CLI parameters.

See the Hardhat task docs.

To address your specific question:

Create a file tasks/balance.js and copy-paste the following task definition:

const { task } = require('hardhat/config');

const rifTokenAddress = '0x2aCc95758f8b5F583470bA265Eb685a8f45fC9D5';

module.exports = task('balance', 'Displays token balance')
  .addOptionalParam('token', 'ERC20 token name')
  .setAction(async ({ token }) => {
    const erc20 = await ethers.getContractAt(
      ['function balanceOf(address owner) view returns (uint)'],
      token?.toLowerCase() || rifTokenAddress.toLowerCase(),
    );
    const walletAddress = (await ethers.getSigner(0)).address;
    const erc20Balance = await erc20.balanceOf(walletAddress);
    console.log(ethers.utils.formatEther(erc20Balance));
  });

Note that the above code is based on your original Hardhat script, and has been adapted to convert it into a Hardhat task; plus add parameters.

This code defines a balance task with one optional --token parameter which accepts ERC20 token address. If --token is unspecified, its default value is rifTokenAddress.

Import the task at the top of the hardhat.config.js:

require('@nomicfoundation/hardhat-toolbox');
require('./tasks/balance.js');

Now you can query token balances from the command line like this:

# queries default token balance
npx hardhat balance
  --network rsktestnet

or like this:

# queries specified token balance
npx hardhat balance
  --network rsktestnet \
  --token 0x19f64674D8a5b4e652319F5e239EFd3bc969a1FE
Aleks Shenshin
  • 2,117
  • 5
  • 18
  • nitpick: `0x2aCc95758f8b5F583470bA265Eb685a8f45fC9D5` is the address of RIF token on RSK Mainnet (chain ID = 30), not RSK Testnet. – bguiz Nov 26 '22 at 12:08
  • Good catch, [@bguiz](https://stackoverflow.com/users/194982/bguiz), thank you! On the Rootstock Testnet its address is `0x19f64674D8a5b4e652319F5e239EFd3bc969a1FE` – Aleks Shenshin Nov 26 '22 at 12:30