Use hre.cofhe.createClientWithBatteries in a before hook. It creates and connects a fully configured CofheClient — including a self-permit — so the client is ready for every test in the suite:
import hre from 'hardhat';import { CofheClient } from '@cofhe/sdk';import { HardhatEthersSigner } from '@nomicfoundation/hardhat-ethers/signers';let cofheClient: CofheClient;let signer: HardhatEthersSigner;before(async () => { [signer] = await hre.ethers.getSigners(); cofheClient = await hre.cofhe.createClientWithBatteries(signer);});
In tests you can bypass the normal decrypt flow and read the raw plaintext stored by the mock contracts. This is useful for asserting contract state without needing a permit:
import hre from 'hardhat';// Get raw plaintext valueconst plaintext = await hre.cofhe.mocks.getPlaintext(ctHash);// Or use the assertion shorthandawait hre.cofhe.mocks.expectPlaintext(ctHash, 100n);
createClientWithBatteries pre-generates a self-permit, so decryptForView and decryptForTx().withPermit() work immediately. For tests that need named permits or multiple signers, create them explicitly:
import { PermitUtils } from '@cofhe/sdk/permits';const permit = await cofheClient.permits.createSelf({ issuer: signer.address, name: 'My Test Permit',});// Select it as the active permitconst permitHash = PermitUtils.getHash(permit);cofheClient.permits.selectActivePermit(permitHash);
Alternatively, create a separate client for each signer:
import hre from 'hardhat';const [bob, alice] = await hre.ethers.getSigners();const bobClient = await hre.cofhe.createClientWithBatteries(bob);const aliceClient = await hre.cofhe.createClientWithBatteries(alice);