> ## Documentation Index
> Fetch the complete documentation index at: https://cofhe-docs.fhenix.zone/llms.txt
> Use this file to discover all available pages before exploring further.

# Mock Contracts

> Read plaintext values and call the CoFHE mock contracts in Hardhat 3 tests

The plugin deploys mock versions of the CoFHE contracts on every simulated chain. The mocks compute FHE operations onchain and keep each result's plaintext in storage, so a test can read any encrypted value without the offchain services.

## What the mocks deploy

| Contract | Address | Role |
| - | - | - |
| `MockTaskManager` | `0xeA30c4B8b44078Bbf8a6ef5b9f1eC1626C7848D9` | Runs FHE operations and stores each result's plaintext |
| `MockACL` | Assigned at deployment | Access control for encrypted handles |
| `ACPTimestampRevoker` | Assigned at deployment | Default revoker for ACPs |
| `ACPShareRegistry` | Assigned at deployment | Onchain hand-off for shared ACPs |
| `MockZkVerifier` | `0x0000000000000000000000000000000000005001` | Verifies encrypted inputs |
| `MockThresholdNetwork` | `0x0000000000000000000000000000000000005002` | Answers decryption requests |

The plugin writes the fixed-address contracts' bytecode directly with `hardhat_setCode`. It deploys `MockACL` and the two ACP contracts as normal transactions, because they need their constructors to run.

The SDK detects the mocks by checking for code at the `MockZkVerifier` address. When it finds them, it skips ZK proof generation and lets the mocks verify inputs.

## Call a mock directly

`cofhe.mocks` exposes four of the mocks as viem `{ address, abi }` descriptors. Spread one into `readContract` or `writeContract`:

```typescript theme={null}
import { network } from 'hardhat';

const { viem, cofhe } = await network.create();
const publicClient = await viem.getPublicClient();

const aclAddress = await publicClient.readContract({
  ...cofhe.mocks.MockTaskManager,
  functionName: 'acl',
});
```

| Descriptor | Contract |
| - | - |
| `cofhe.mocks.MockTaskManager` | `MockTaskManager` |
| `cofhe.mocks.MockACL` | `MockACL` |
| `cofhe.mocks.MockZkVerifier` | `MockZkVerifier` |
| `cofhe.mocks.MockThresholdNetwork` | `MockThresholdNetwork` |

The ABIs are typed, so viem checks `functionName` and `args` at compile time.

## Read plaintext values

Because `MockTaskManager` stores plaintexts, you can assert on encrypted state without an ACP or a decryption request. Both helpers accept the handle as a hex string, which is what viem returns for an `euint32` getter, or as a `bigint`.

### `getPlaintext(ctHash)`

Returns the stored plaintext as a `bigint`:

```typescript theme={null}
const counter = await viem.deployContract('Counter');
await counter.write.increment();

const count = await cofhe.mocks.getPlaintext(await counter.read.count());
// count === 1n
```

`getPlaintext` returns `0n` for a handle that has no stored value, so a typo in the handle reads as zero.

### `expectPlaintext(ctHash, expectedValue)`

Throws when the stored plaintext differs from `expectedValue`, or when the handle has no stored value:

```typescript theme={null}
await cofhe.mocks.expectPlaintext(await counter.read.count(), 1n);
```

A mismatch throws an `Error` whose message names both values:

```text theme={null}
mock_expectPlaintext: expected 2, got 1 for ctHash 0xf4b9...0400
```

<Warning>
  On a network without the mocks, `getPlaintext` throws, but `expectPlaintext` prints a message and returns without asserting anything. A test that relies on `expectPlaintext` passes silently against a testnet.
</Warning>

## Redeploy the mocks

`cofhe.mocks.deployMocks(options?)` runs the deployment again on the current chain:

```typescript theme={null}
await cofhe.mocks.deployMocks({ gasWarning: false, mocksDeployVerbosity: '' });
```

| Option | Type | Default |
| - | - | - |
| `gasWarning` | `boolean` | `true` |
| `mocksDeployVerbosity` | `'' \| 'v' \| 'vv'` | `'v'` |

These defaults apply to the call itself. `deployMocks` does not read the `cofhe` block of your Hardhat config, so a bare call prints the gas warning even when the config turns it off.

<Warning>
  A redeploy is not a reset. It deploys a new `MockACL` and points `MockTaskManager` at it, but `cofhe.mocks.MockACL` keeps the old address, and handles created before the redeploy lose their permissions. The next FHE operation on one of those handles reverts with `ACLNotAllowed` (selector `0x4d13139e`). For a clean state, open a new connection with `network.create()` instead.
</Warning>
