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

# Client

> Create and connect a CofheClient in a Hardhat 3 test

Every network connection carries a `cofhe` object with three methods for building a `CofheClient`. Use `createClientWithBatteries` in most tests, and the manual path when you need to change the client config.

The examples on this page run inside an `async describe` callback that opens a connection first:

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

const { viem, cofhe } = await network.create();
const publicClient = await viem.getPublicClient();
const [walletClient] = await viem.getWalletClients();
```

## Batteries included

`cofhe.createClientWithBatteries(walletClient?)` returns a client that is ready to encrypt and decrypt. It:

1. Creates a config for the Hardhat mock environment, with `supportedChains: [hardhat]` and a zero `mocks.encryptDelay`.
2. Creates the client and connects it with the connection's public client and your wallet client.
3. Signs a self ACP (Access Control Permission) for the wallet's address and makes it the active ACP.

```typescript theme={null}
const client = await cofhe.createClientWithBatteries(walletClient);

client.connected; // true
```

Called with no argument, it signs with the first account of the connection:

```typescript theme={null}
const client = await cofhe.createClientWithBatteries();
```

Because the self ACP exists from the start, `decryptForView` and `decryptForTx().withACP()` work without any further setup.

## Manual setup

Build the client step by step when a test needs a different config, for example a non-zero `encryptDelay`.

<Steps>
  <Step title="Create the config">
    ```typescript theme={null}
    const config = await cofhe.createConfig({ mocks: { encryptDelay: 100 } });
    ```

    `cofhe.createConfig` wraps `createCofheConfig` from `@cofhe/sdk/node`. It sets `environment: 'hardhat'` and `supportedChains: [hardhat]`, defaults `mocks.encryptDelay` to `0`, and merges your overrides on top.
  </Step>

  <Step title="Create the client">
    ```typescript theme={null}
    const client = cofhe.createClient(config);
    ```

    The client is not connected yet: `client.connected` is `false`.
  </Step>

  <Step title="Connect it">
    ```typescript theme={null}
    await client.connect(publicClient, walletClient);
    ```

    `connect` takes viem clients directly, so the clients from `@nomicfoundation/hardhat-viem` pass straight in.
  </Step>
</Steps>

A manually built client also creates a self ACP when it connects, so `decryptForView` works without extra setup here too.

## Several signers

Create one client per wallet. Each client signs its own encrypted inputs and holds its own ACP.

```typescript theme={null}
const [alice, bob] = await viem.getWalletClients();

const aliceClient = await cofhe.createClientWithBatteries(alice);
const bobClient = await cofhe.createClientWithBatteries(bob);
```

An encrypted input is bound to the account that encrypted it. Send the transaction from that same wallet, or the contract reverts with `InvalidSigner`, which viem reports as the selector `0x7ba5ffb5`.

## API summary

| Method | Returns | Description |
| - | - | - |
| <code style={{ whiteSpace: "nowrap" }}>createClientWithBatteries</code> | `Promise<CofheClient>` | Connected client with a self ACP. Takes an optional `WalletClient` and defaults to the first account of the connection. |
| <code style={{ whiteSpace: "nowrap" }}>createConfig</code> | `Promise<CofheConfig>` | Config for the Hardhat mock environment. Takes optional overrides. |
| <code style={{ whiteSpace: "nowrap" }}>createClient</code> | `CofheClient` | Unconnected client built from a config. |

## Using the client

Once connected, the client is the standard SDK client. See:

* [Encrypting inputs](/client-sdk/guides/encrypting-inputs)
* [Decrypt to view](/client-sdk/guides/decrypt-to-view)
* [Decrypt to transact](/client-sdk/guides/decrypt-to-tx)
* [Access Control Permissions](/client-sdk/guides/acps)
