> ## 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.

# Quick Start: Foundry

> Set up a Foundry project with @cofhe/foundry-plugin, write a contract, and test the encrypt → store → decrypt flow

Set up a Foundry project with `@cofhe/foundry-plugin`, write a contract that stores an encrypted `uint32`, and test the encrypt → store → decrypt flow under `forge test`.

<Tip>
  Want to skip the setup? Clone the [cofhe-foundry-starter](https://github.com/FhenixProtocol/cofhe-foundry-starter) template to get a pre-configured project with everything ready to go.
</Tip>

## Prerequisites

* [Foundry](https://book.getfoundry.sh/getting-started/installation) (`forge`, `cast`, `anvil`)
* Node.js 18+ with npm/pnpm/yarn (for installing the plugin's npm packages)

## 1. Install dependencies

The plugin and its CoFHE dependencies are distributed via npm. Install them as dev dependencies, then `forge install` for `forge-std`:

<CodeGroup>
  ```bash npm theme={null}
  npm install -D @cofhe/foundry-plugin@^0.5.1 @cofhe/mock-contracts@^0.5.1 @fhenixprotocol/cofhe-contracts@^0.1.3 @openzeppelin/contracts
  forge install foundry-rs/forge-std
  ```

  ```bash pnpm theme={null}
  pnpm add -D @cofhe/foundry-plugin@^0.5.1 @cofhe/mock-contracts@^0.5.1 @fhenixprotocol/cofhe-contracts@^0.1.3 @openzeppelin/contracts
  forge install foundry-rs/forge-std
  ```

  ```bash yarn theme={null}
  yarn add -D @cofhe/foundry-plugin@^0.5.1 @cofhe/mock-contracts@^0.5.1 @fhenixprotocol/cofhe-contracts@^0.1.3 @openzeppelin/contracts
  forge install foundry-rs/forge-std
  ```
</CodeGroup>

## 2. Configure `foundry.toml`

```toml foundry.toml theme={null}
[profile.default]
src = "src"
out = "out"
test = "test"
script = "script"
libs = ["node_modules"]
solc_version = "0.8.25"
evm_version = "cancun"
auto_detect_remappings = false
code_size_limit = 100000
```

<Warning>
  * `evm_version = "cancun"` is required — `MockACL` uses transient storage opcodes.
  * `code_size_limit = 100000` is required — the mock contracts exceed the EIP-170 24 KB limit.
</Warning>

## 3. Configure `remappings.txt`

```text remappings.txt theme={null}
forge-std/=node_modules/forge-std/src/
hardhat/=node_modules/forge-std/src/
@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/
@fhenixprotocol/cofhe-contracts/=node_modules/@fhenixprotocol/cofhe-contracts/
@cofhe/mock-contracts/=node_modules/@cofhe/mock-contracts/
@cofhe/foundry-plugin/=node_modules/@cofhe/foundry-plugin/
```

The `hardhat/=node_modules/forge-std/src/` line is **load-bearing** — `MockCoFHE.sol` imports `hardhat/console.sol`, and this alias resolves it to forge-std's compatible `console.sol`.

## 4. Write a contract

```solidity src/MyContract.sol theme={null}
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.25;

import "@fhenixprotocol/cofhe-contracts/FHE.sol";

contract MyContract {
    euint32 public storedValue;

    function setValue(InEuint32 memory inValue) external {
        storedValue = FHE.asEuint32(inValue);
        FHE.allowThis(storedValue);
        FHE.allowSender(storedValue);
    }
}
```

* `euint32` — an encrypted `uint32` stored on-chain as a ciphertext handle.
* `InEuint32` — the encrypted input struct produced by `CofheClient`.
* `FHE.allowThis` / `FHE.allowSender` — grant the contract and caller permission to read the encrypted value (required by the ACL).

## 5. Write a test

```solidity test/MyContract.t.sol theme={null}
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.25;

import { CofheTest } from "@cofhe/foundry-plugin/contracts/CofheTest.sol";
import { CofheClient } from "@cofhe/foundry-plugin/contracts/CofheClient.sol";
import { InEuint32 } from "@fhenixprotocol/cofhe-contracts/FHE.sol";
import { MyContract } from "../src/MyContract.sol";

contract MyContractTest is CofheTest {
    MyContract public myContract;
    CofheClient public bob;

    uint256 constant BOB_PKEY = 0xB0B;

    function setUp() public {
        deployMocks();

        bob = createCofheClient();
        bob.connect(BOB_PKEY);

        vm.prank(bob.account());
        myContract = new MyContract();
    }

    function test_StoresAndDecryptsAnEncryptedValue() public {
        // 1. Encrypt the input
        InEuint32 memory encrypted = bob.createInEuint32(42);

        // 2. Send to contract
        vm.prank(bob.account());
        myContract.setValue(encrypted);

        // 3. Assert the stored plaintext directly (mock-only, no permit needed)
        expectPlaintext(myContract.storedValue(), uint32(42));
    }
}
```

## 6. Run

```bash theme={null}
forge test -vvv
```

```
[PASS] test_StoresAndDecryptsAnEncryptedValue() (gas: …)

Test result: ok. 1 passed; 0 failed; 0 skipped; finished in …
```

## What just happened?

1. **`deployMocks()`** deployed the full CoFHE coprocessor mock stack (TaskManager, ACL, ZK verifier, threshold network) to the in-process EVM.
2. **`createCofheClient()` + `bob.connect(BOB_PKEY)`** spun up an in-Solidity SDK shim bound to `vm.addr(BOB_PKEY)`.
3. **`bob.createInEuint32(42)`** produced a signed `InEuint32` — the same shape your contract receives on testnet, signed by `MockZkVerifierSigner`.
4. **`vm.prank(bob.account())` + `setValue(...)`** called the contract as Bob. The contract stored the ciphertext handle and granted ACL access to itself and Bob.
5. **`expectPlaintext(myContract.storedValue(), 42)`** read the on-chain plaintext directly from `MockTaskManager.mockStorage` — no permit, no SDK round-trip.

## Next steps

* [Foundry Plugin → Getting Started](/client-sdk/foundry-plugin/getting-started) — full plugin configuration and features.
* [CofheTest](/client-sdk/foundry-plugin/cofhe-test) — `deployMocks`, `expectPlaintext`, log toggles.
* [CofheClient](/client-sdk/foundry-plugin/cofhe-client) — encrypt inputs, decrypt for view / tx, permits.
* [Testing](/client-sdk/foundry-plugin/testing) — canonical test patterns for ACL, public-decrypt, and fuzzing.
