> ## Documentation Index
> Fetch the complete documentation index at: https://cosmos-docs-sync-security-docs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Step 5: Configure and Start Attestors

> Configure and start the attestor services that sign packet state for the Proof API

An attestor is a lightweight service ([cosmos/ibc-attestor](https://github.com/cosmos/ibc-attestor)) that watches a chain and signs statements about its state on demand. When the Proof API needs to prove that a packet was committed on a chain, it queries the attestor for a signed attestation over the relevant block state.

In this demo, one attestor is watching the EVM chain and one is watching the Cosmos chain. Each attestor signs with a secp256k1 key; the corresponding Ethereum address was registered with both light clients in the [create-clients step](/ibc/next/cosmos-evm/tutorial/walkthrough/03-clients). When a packet arrives, the light client recovers the signer address from the attestation signature and checks it against its registered set.

Both attestors in this demo share a single signing key, so only one address needs to be registered. In production, you would run multiple attestors per chain with distinct keys and configure the light clients with a quorum threshold greater than one.

Run the following:

```bash theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
./setup.sh attestors
```

The logic for this command is in [`lib/ibc.sh`](https://github.com/cosmos/ibc-e2e-docs-example/blob/main/demo/cosmos-evm/lib/ibc.sh)

## What it does

### Key generation

If no keystore exists, the script generates a new secp256k1 signing key and stores it at `ibc/local/.ibc-attestor/ibc-attestor-keystore`. The Ethereum address can be retrieved at any time:

```bash theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
ibc_attestor key show
```

This address is what gets registered with both light clients in the [create-clients step](/ibc/next/cosmos-evm/tutorial/walkthrough/03-clients). In this demo, the same keystore is mounted into both attestor containers so both sign with the same address.

### Config rendering

The script renders two config files from templates:

* [`ibc/attestor-config.toml.tmpl`](https://github.com/cosmos/ibc-e2e-docs-example/blob/main/demo/cosmos-evm/ibc/attestor-config.toml.tmpl) into `ibc/local/attestor-config.toml` for the EVM watcher
* [`ibc/attestor-cosmos-config.toml.tmpl`](https://github.com/cosmos/ibc-e2e-docs-example/blob/main/demo/cosmos-evm/ibc/attestor-cosmos-config.toml.tmpl) into `ibc/local/attestor-cosmos-config.toml` for the Cosmos watcher

The EVM config requires `ICS26_ROUTER_ADDR` from the deploy step.

See [below](#configuration) for the configuration reference for both the EVM and Cosmos attestors.

### Starting the containers

```
attestor        — ibc_attestor server --config /config/attestor-config.toml --chain-type evm --signer-type local
attestor-cosmos — ibc_attestor server --config /config/attestor-cosmos-config.toml --chain-type cosmos --signer-type local
```

Both containers mount the keystore from `ibc/local/.ibc-attestor/` and listen on port `9101` within the Docker network.

## Configuration

### EVM attestor

Below is an example of the EVM attestor config for this demo:

```toml theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
[server]
listen_addr = "0.0.0.0:9101"   # gRPC — queried by the Proof API
health_addr = "0.0.0.0:9102"   # HTTP health check

[adapter]
url = "<EVM_JSON_RPC_ENDPOINT>"
router_address = "<ICS26_ROUTER_ADDR>"   # ICS26Router address from the deploy step
finality_offset = 0                       # set to N to attest latest-N instead of the finalized tag

[signer]
keystore_path = "/config/.ibc-attestor/ibc-attestor-keystore"
```

<Note>
  `adapter.finality_offset` determines at which block height the attestor reads and signs chain state. If omitted, the attestor uses the chain's native `finalized` block tag. If set to `N`, it attests `latest - N`. This value must match `finality_offset` in the relayer config. See [Finality offset](/ibc/next/cosmos-evm/tutorial/walkthrough/06-relayer#finality-offset) for more details.
</Note>

### Cosmos attestor

The Cosmos attestor only requires the CometBFT RPC endpoint:

```toml theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
[server]
listen_addr = "0.0.0.0:9101"
health_addr = "0.0.0.0:9102"

[adapter]
url = "<COMETBFT_RPC_ENDPOINT>"

[signer]
keystore_path = "/config/.ibc-attestor/ibc-attestor-keystore"
```

### Config field reference

| Field                     | Required | Description                                                                                                                                                                                         |
| ------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `server.listen_addr`      | Yes      | gRPC address the Proof API connects to                                                                                                                                                              |
| `server.health_addr`      | Yes      | HTTP health endpoint (`GET /healthz`)                                                                                                                                                               |
| `adapter.url`             | Yes      | Chain RPC endpoint: EVM JSON-RPC or CometBFT RPC                                                                                                                                                    |
| `adapter.router_address`  | EVM only | Address of the `ICS26Router` contract from the deploy step                                                                                                                                          |
| `adapter.finality_offset` | No       | Blocks to subtract from latest when determining finality — must match the relayer's `finality_offset` (see [Finality offset](/ibc/next/cosmos-evm/tutorial/walkthrough/06-relayer#finality-offset)) |
| `signer.keystore_path`    | Yes      | Path to the keystore file                                                                                                                                                                           |

## Production deployment

For more information on production deployment (remote signers, key rotation, multi-instance quorum, finality configuration, and health checking), see the [IBC Attestor deployment guide](/ibc/next/infra/attestor/attestor-guide).

## Next steps

The next step is to [configure and start the relayer and Proof API](/ibc/next/cosmos-evm/tutorial/walkthrough/06-relayer).
