Deploying EVM contracts with Hardhat
The following assumes you are using a Hardhat project configured as “TypeScript project (with Viem)”. Other types of projects might require minor modifications.
Install Fordefi JSON-RPC provider and its requirements
- Run
npm install --save-dev @nomicfoundation/hardhat-ethers ethers
to install Hardhat’s ethers package. - Run
npm install --save @fordefi/web3-provider
to install Fordefi’s provider.
Prepare the Hardhat network configuration
Make sure your hardhat configuration hardhat.config.ts
contains the network's URL and chain id as follows:
// hardhat.config.js
const config: HardhatUserConfig = {
solidity: "0.8.24", // Other configurations..
networks: {
polygon: {
url: "https://polygon.llamarpc.com", // JSON-RPC URL
chainId: 137, // Decimal value of the chain id
}
}
};
export default config;
Use the Fordefi Web3 provider as a signer in your deployment script
-
In your deployment script, include the necessary dependencies:
// scripts/deploy.ts import hre from "hardhat"; import "@nomicfoundation/hardhat-ethers"; import { HttpNetworkUserConfig } from "hardhat/types"; import { EvmChainId, FordefiWeb3Provider } from "@fordefi/web3-provider";
-
Create a Fordefi Web3 Provider. Make sure to correct set the parameter values, as described here. Specifically,
address
should be the address of your Fordefi EVM vault used for deploying the contractapiUserToken
is the access token of your API UserapiPayloadSignKey
should be set to the private key of your API User (this is the content of thepem
file you have generated; make sure to set the private key as a single-line base64 string without any spaces).chainId
andrpcUrl
can be taken from the Hardhat configuration.
const networkConfig = hre.network.config as HttpNetworkUserConfig; const fordefiProvider = new FordefiWeb3Provider({ address: "<fordefi-vault-address>", apiUserToken: "<api-user-access-token>", apiPayloadSignKey: "<api-user-private-key.pem-file-contents>", chainId: networkConfig.chainId as EvmChainId, rpcUrl: networkConfig.url, });
-
Create an
ethers.Signer
:const provider = new hre.ethers.BrowserProvider(fordefiProvider); const signer = await provider.getSigner();
-
Use the
ethers.Signer
as a parameter togetContractFactory
const factory = await hre.ethers.getContractFactory("<your-contract-name>", signer); const contract = await factory.deploy(/* any params */);
Example
To deploy the Lock
contract from Hardhat’s example, defined in contracts/Lock.sol
, you can use the following script. Note that the contract has two runtime values that are passed during deployment.
// scripts/deploy.ts
import { parseEther } from "viem";
import hre from "hardhat";
import "@nomicfoundation/hardhat-ethers";
import { HttpNetworkUserConfig } from "hardhat/types";
import { EvmChainId, FordefiWeb3Provider } from "@fordefi/web3-provider";
// Some vars...
const JAN_1ST_2030 = 1893456000;
const ONE_GWEI: bigint = parseEther("0.001");
async function main() {
const networkConfig = hre.network.config as HttpNetworkUserConfig;
const fordefiProvider = new FordefiWeb3Provider({
address: "<fordefi-vault-address>",
apiUserToken: "<api-user-access-token>",
apiPayloadSignKey: "<api-user-private-key.pem-file-contents>",
chainId: networkConfig.chainId as EvmChainId,
rpcUrl: networkConfig.url,
});
const provider = new hre.ethers.BrowserProvider(fordefiProvider);
const signer = await provider.getSigner();
const factory = await hre.ethers.getContractFactory("Lock", signer);
console.log('Deploying Lock...');
// Deploy contract with values.
const lock = await factory.deploy(JAN_1ST_2030, { value: ONE_GWEI });
await lock.waitForDeployment();
console.log('Lock deployed to:', await lock.getAddress());
}
main()
.then(() => process.exit(0))
.catch(error => {
console.error(error);
process.exit(1);
});
Run the deployment script: npx hardhat run --network polygon scripts/deploy.ts