@cofhe/foundry-plugin is the Foundry counterpart to @cofhe/hardhat-plugin. It provides two abstract Solidity contracts — CofheTest (test base, deploys all CoFHE mocks) and CofheClient (per-account encrypt/decrypt/permit shim) — that let you exercise FHE contracts under forge test with no JS SDK required.
What the plugin provides
CofheTest— abstract test base that inheritsforge-std/Testand deploys the full CoFHE mock stack (MockTaskManager,MockACL,MockZkVerifier,MockThresholdNetwork).CofheClient— in-Solidity SDK shim. One client per “user” in your scenario; each client carries a private key and produces encrypted inputs and signed permits as if it were that user’s frontend SDK.- Plaintext assertions —
expectPlaintext(handle, value)reads the on-chain plaintext from the mock task manager. Faster thandecryptForViewand needs no permit.
Prerequisites
- Foundry (
forge,cast,anvil) - Node.js 18+ with npm/pnpm/yarn (for installing the plugin’s npm dependencies)
Installation
Install the npm packages
The plugin and its dependencies are distributed via npm. Install them as dev dependencies in your Foundry project:
Configure foundry.toml
The CoFHE contracts and mocks have specific Solidity / EVM requirements. Set them in
foundry.toml:foundry.toml
Configure remappings.txt
remappings.txt
@cofhe/mock-contracts/points at the package root, not…/contracts/. The plugin’s own imports already include thecontracts/segment (e.g.@cofhe/mock-contracts/contracts/MockTaskManager.sol). Pointing at…/contracts/will break those imports.hardhat/=node_modules/forge-std/src/is load-bearing.MockCoFHE.solinside the mock contracts importshardhat/console.sol; this alias resolves it to forge-std’s compatibleconsole.sol. Drop it andforge builderrors withSource "hardhat/console.sol" not found.
Verify the setup
forge build succeeds, your remappings and foundry.toml are correct. From here, write a test that inherits CofheTest:
test/MyTest.t.sol
Version pinning
The plugin and@cofhe/mock-contracts pin @fhenixprotocol/cofhe-contracts exactly (no caret). Keep the three CoFHE packages aligned — otherwise npm install may resolve cofhe-contracts to a newer version that the mocks don’t implement, producing MockTaskManager should be marked as abstract at compile time.
Known-aligned tuple as of writing:
| Package | Version |
|---|---|
@cofhe/foundry-plugin | 0.5.1 |
@cofhe/mock-contracts | 0.5.1 |
@fhenixprotocol/cofhe-contracts | 0.1.3 |
Mocks vs production
The mocks are the same@cofhe/mock-contracts package the Hardhat plugin uses. Behaviorally:
- Plaintext lives on-chain in
MockTaskManager.mockStorage(soexpectPlaintextandgetPlaintextwork). - No real ZK proving; encrypted inputs are signed by
MockZkVerifierSigner. - Decryption is synchronous —
decryptForTx_withoutPermitreturns the result immediately. - Mock signatures are accepted by the same
FHE.verifyDecryptResultyour contract uses on testnet.
Next steps
- CofheTest — the test base contract:
deployMocks,expectPlaintext,getPlaintext, log toggles. - CofheClient — per-user shim:
createInEuintN,decryptForTx_withoutPermit,decryptForView, permits. - Testing — canonical test patterns and the migration mapping from the old
@cofhe/mock-contracts/foundry/CoFheTest.solAPI.