# Deploy 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. You can also find this tutorial in our [API Examples repository on Github](https://github.com/FordefiHQ/api-examples/tree/main/typescript/evm/fordefi-evm-contracts-deployer). ## Install Fordefi JSON-RPC provider and its requirements - Run `npm install --save-dev @nomicfoundation/hardhat-ethers ethers` to install [Hardhat’s ethers](https://hardhat.org/hardhat-runner/plugins/nomicfoundation-hardhat-ethers#hardhat-ethers) package. - Run `npm install --save @fordefi/web3-provider` to install [Fordefi’s provider](https://web3provider-docs.fordefi.com/classes/FordefiWeb3Provider.html). ## Prepare the Hardhat network configuration Make sure your hardhat configuration `hardhat.config.ts` contains the network's URL and chain id as follows: ```typescript // 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: ```typescript // 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](https://github.com/FordefiHQ/web3-provider?tab=readme-ov-file#api-reference). 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 `rpcUrl`can be taken from the Hardhat configuration. ```typescript const networkConfig = hre.network.config as HttpNetworkUserConfig; const fordefiProvider = new FordefiWeb3Provider({ address: "", apiUserToken: "", apiPayloadSignKey: "", chainId: networkConfig.chainId as EvmChainId, rpcUrl: networkConfig.url, }); ``` 3. Create an `ethers.Signer`: ```typescript const provider = new hre.ethers.BrowserProvider(fordefiProvider); const signer = await provider.getSigner(); ``` 4. Use the `ethers.Signer` as a parameter to `getContractFactory` ```typescript const factory = await hre.ethers.getContractFactory("", signer); const contract = await factory.deploy(/* any params */); ``` # Example To deploy the `Lock`contract from Hardhat’s [example](https://hardhat.org/hardhat-runner/docs/guides/project-setup), defined in `contracts/Lock.sol`, you can use the following script. Note that the contract has two runtime values that are passed during deployment. ```typescript // 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: "", apiUserToken: "", apiPayloadSignKey: "", 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`