EVM Deploy Contract

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 & its requirements

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

  1. 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";
    
  2. 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 contract
    • apiUserToken is the access token of your API User
    • apiPayloadSignKey should be set to the private key of your API User (this is the content of the pem file you have generated; make sure to set the private key as a single-line base64 string without any spaces).
    • chainId and rpcUrlcan 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,
    });
    
    
  3. Create an ethers.Signer:

    const provider = new hre.ethers.BrowserProvider(fordefiProvider);
    const signer = await provider.getSigner();
    
  4. Use the ethers.Signer as a parameter to getContractFactory

    const factory = await hre.ethers.getContractFactory("<your-contract-name>", signer);
    const contract = await factory.deploy(/* any params */);
    

Example

To deploy the Lockcontract 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