How to Create a Custom "faucet" Task With Hardhat
Published: 2021-11-19 20:59:02

## Intro

When working locally to build your web3 project, you'll get to a point where you want to test the interactions with your smart contract. When you get to this point, you will need a wallet address with some ETH to pay for your gas fees. If you are using [Hardhat](https://hardhat.org/) as your development environment there is no out of the box command to achieve this. Luckily, Hardhat provides a mechanism for creating custom `tasks` which we can leverage to create a `faucet` to send ETH to our wallet for testing. To learn more about Hardhat tasks, you can read about them [here](https://hardhat.org/guides/create-task.html).

## Solution

The following code snippet is inspired by [this](https://hardhat.org/tutorial/hackathon-boilerplate-project.html) boilerplate project and when done, you should have access to a new task called `faucet`. 


```ts
// faucet.ts or faucet.js
import { task } from 'hardhat/config';

task('faucet', 'Sends ETH to an address')
  .addPositionalParam('receiver', 'The address that will receive them')
  .setAction(async ({ receiver }, hre) => {
    if (hre.network.name === 'hardhat') {
      console.warn(
        `You are running the faucet task with Hardhat network, which gets automatically created
        and destroyed every time. Use the Hardhat option '--network localhost'`,
      );
    }

    const [sender] = await hre.ethers.getSigners();
    const tx = await sender.sendTransaction({
      to: receiver,
      value: hre.ethers.constants.WeiPerEther.mul(5),
    });

    await tx.wait();

    console.log(`Transferred 5 ETH ${receiver}`);
  });
```

then in your `hardhat.config.ts` (or `hardhat.config.js`) you just need to import the task

```ts
// hardhat.config.ts
import * as dotenv from 'dotenv';

import { HardhatUserConfig, task } from 'hardhat/config';
import '@nomiclabs/hardhat-etherscan';
import '@nomiclabs/hardhat-waffle';
import '@typechain/hardhat';
import 'hardhat-gas-reporter';
import 'solidity-coverage';
import '@nomiclabs/hardhat-ethers';

// Tasks
import './tasks/faucet.ts'; // <--IMPORTED FAUCET TASK

dotenv.config();

// This is a sample Hardhat task. To learn how to create your own go to
// https://hardhat.org/guides/create-task.html
task('accounts', 'Prints the list of accounts', async (taskArgs, hre) => {
  const accounts = await hre.ethers.getSigners();

  for (const account of accounts) {
    console.log(account.address);
  }
});
// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more

const config: HardhatUserConfig = {
  solidity: {
    version: '0.8.4',
  },
  networks: {
    hardhat: {
      chainId: 1337,
    },
    ropsten: {
      url: process.env.ROPSTEN_URL || '',
      accounts:
        process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [],
    },
  },
  gasReporter: {
    enabled: process.env.REPORT_GAS !== undefined,
    currency: 'USD',
  },
  etherscan: {
    apiKey: process.env.ETHERSCAN_API_KEY,
  },
};

export default config;


```
(note your config file may look a little different)

Running this task requires you to have your local hardhat node running via `npx hardhat node`. When the node spins up you will see a bunch of addresses generated with ETH associated with them. This task gets reference to one of these addresses via `await hre.ethers.getSigners()` and sends ETH to the `receiver` param passed into the `.setAction` callback. The value is just set to wei and is using built in utilities to (in this case) send the equivalent of 5 ETH to the `receiver` via the `sendTransaction` call.


Now once you have done all this if you type `npx hardhat` in your hardhat project in your terminal, you should see `faucet` in your task list.![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b21n2k2pr7fwh426gbx5.png)

If everything has worked and you see your new task, all you need to do now to use it is call the following command in your terminal `npx hardhat --network localhost faucet WALLET_ADDRESS_HERE`