Can we test the contract locally

Hi, I’ve deployed the EncryptedERC20 contract locally. Is it possible to interact with the deployed contract in the local environment? Also, can we write tests for it? Specifically, are there any mocks available or commonly used for this purpose?

1 Like

Hi Kanna! Thank you for your interest in Zama’s FHEVM protocol.
To run/test your FHEVM contract locally, simply run:

  • From a separate terminal, in the hardhat project directory: “npx hardhat node” to start a new FHEVM-ready local node
  • From the hardhat project directory : “npx hardhat test --network localhost”
    For a detailed explanation you can check : Deploy contracts and run tests | Protocol

For mock testing, have a look at the FHEVM Hardhat Template: GitHub - zama-ai/fhevm-hardhat-template: FHEVM hardhat template

1 Like

Thanks, Alex!
I actually did the same thing, but instead of writing a Hardhat task, I wanted to use a standalone JavaScript file to interact with the contract.

I followed some of the standard steps to initialize and interact with the contract. However, when I tried to use the created instance to decrypt data for the user, I ran into some errors.

I’ll share the code below.

async function main() {
// Initialize FHEVM
if (hre.fhevm) {
await hre.fhevm.initializeCLIApi();
console.log(“:white_check_mark: FHEVM initialized via hre”);
}

// Create fhevmjs instance
const instance = await createInstance(SepoliaConfig); // This is used later for decryption

// Get signers
const [signer, _, bob] = await ethers.getSigners();
const contract = new ethers.Contract(contractAddress, abi, signer);

const supplyAfter = await contract.totalSupply();
console.log("📦 Total Supply:", supplyAfter.toString());

// --- Skipped: Allowlist, Minting, Transfer (Uncomment if needed) ---
// const mintAmount = ethers.parseUnits("100", 18);
// const mintTx = await contract.mint(mintAmount);
// await mintTx.wait();
// console.log(`✅ Minted ${mintAmount.toString()} tokens`);

// --- Get Encrypted Balance for Bob ---
const encryptedBalance = await contract.balanceOf(bob.address);

// 🔐 Attempt Decryption
try {
    const decryptedBalance = await hre.fhevm.userDecryptEuint(
        FhevmType.euint64,
        encryptedBalance,
        contractAddress,
        bob
    );
    console.log("🔓 Decrypted balance of Bob:", decryptedBalance);
} catch (error) {
    console.error("❌ Error during decryption:", error);
}

// --- If using instance-based decryption instead ---
/*
const keypair = instance.generateKeypair();
const startTimeStamp = Math.floor(Date.now() / 1000).toString();
const durationDays = "10";
const eip712 = instance.createEIP712(keypair.publicKey, [contractAddress], startTimeStamp, durationDays);

const signature = await signer.signTypedData(
    eip712.domain,
    {
        UserDecryptRequestVerification: eip712.types.UserDecryptRequestVerification,
    },
    eip712.message
);

const result = await instance.userDecrypt(
    [{ handle: encryptedBalance, contractAddress }],
    keypair.privateKey,
    keypair.publicKey,
    signature.replace("0x", ""),
    [contractAddress],
    bob.address,
    startTimeStamp,
    durationDays
);

console.log("🔓 Decrypted (via instance):", result[encryptedBalance]);
*/

}

main().catch(console.error);

if i use the hre.fhevm.userDecrypt it was working fine but when i used instance.userDecrypt i ran into error

1 Like

The fhevm-hardhat-template is meant to be used along with the @fhevm/hardhat-plugin which exposes a dedicated FHEVM Runtime environment (usually ‘hre.fhevm’). Using the relayer-sdk directly is not supported. You should not mix the 2 as it may cause unexpected behaviors. If you want to test your contract against Sepolia Ethereum, please have a look at:

2 Likes