Skip to content

Set Up Local Development with Hardhat

Fordefi integrates with Hardhat, letting you test smart contract deployments and interactions on a local node while using Fordefi's MPC signing and transaction policies. This means you can validate your entire workflow (including transaction signing through your Fordefi vault) before deploying to mainnet or testnets.

How it works

The integration connects your local Hardhat node to Fordefi by exposing it through a tunnel (like ngrok) and registering it as a custom EVM chain on Fordefi. Once configured, transactions submitted through the Fordefi webapp or API are signed by your Fordefi EVM vault and broadcast to your local node, mirroring exactly how production deployments work.

Getting started

You'll need an EVM vault, API credentials, and the API Signer running. The setup involves:

  1. Exposing your local Hardhat node via ngrok.
  2. Adding Hardhat (chain ID 31337) as a custom chain in the Fordefi console.
  3. Funding your vault with test ETH from Hardhat's pre-funded accounts.

From there, you can deploy contracts using Hardhat Ignition and interact with them through Fordefi-signed transactions.

Troubleshooting

Nonce mismatch: If you restart the Hardhat node, Fordefi's cached nonce may be stale. Override it manually, so:

export const txParams = {
  // ...
  custom_nonce: "0"
};

Check the expected nonce with:

cast nonce YOUR_VAULT_ADDRESS --rpc-url http://127.0.0.1:8545

Example

Prerequisites

Make sure you have fulfilled all the requirements in Getting Started, above.

Setup

  1. Configure environment variables:

    Create a .env file with your Fordefi credentials:

    FORDEFI_API_USER_TOKEN=your_api_token
    FORDEFI_EVM_VAULT_ID=your_vault_id
    FORDEFI_EVM_VAULT_ADDRESS=your_vault_address

    Place your API user private key at ./fordefi_secret/private.pem.

  2. Add Hardhat as a custom chain. Since Hardhat runs locally, you need to expose it using a tunnel and add it as a custom chain in Fordefi:

    1. Start ngrok to expose your local node:

      ngrok http 8545

    2. In the Fordefi web console, add a custom chain:

      • Chain ID: 31337
      • RPC URL: Your ngrok URL (for example: https://abc123.ngrok.io)

      See Add Custom Chain for detailed instructions.

Workflow

  1. Start your Hardhat node:

    npx hardhat node

  2. Fund your vault. Transfer test ETH from a Hardhat account to your Fordefi vault:

    const sender = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"; // Hardhat account #0
    const recipient = "YOUR_FORDEFI_VAULT_ADDRESS";
    
    const tx = await provider.send("eth_sendTransaction", [{
    from: sender,
    to: recipient,
    value: "0x56BC75E2D63100000" // 100 ETH
    }]);
  3. Deploy your contract:

    npx hardhat ignition deploy ignition/modules/YourContract.ts --network localhost

  4. Configure the transaction:

    In your config file, set:

    export const txParams = {
    evmChain: "31337",
    to: "YOUR_CONTRACT_ADDRESS",
    amount: "0",
    gas_limit: "50000",
    max_fee_per_gas: "1000000000",
    max_priority_fee_per_gas: "1000000000",
    };
    
    export const contractAbi = [
    "function yourFunction(uint256 param)",
    ];
  5. Send the transaction following this flow:

    1. Encode call data using ethers.
    2. Sign the API payload with your private key.
    3. Submit to Fordefi API for MPC signing.
    4. Poll for the transaction hash
    5. Confirm on the local Hardhat node:
      // Encode the function call
      const callData = encodeCallData(contractAbi, "yourFunction", [123]);
      
      // Submit to Fordefi
      const response = await createAndSignTx(config, txParams, callData);
      const txHash = await pollForTxHash(response.data.id, accessToken);
      
      // Wait for confirmation on Hardhat
      const provider = new ethers.JsonRpcProvider("http://127.0.0.1:8545");
      const receipt = await provider.waitForTransaction(txHash);