# Run an Attester Node

The Othentic CLI includes built-in node software that AVS Operators run to participate in consensus.

#### Read More

* [Node Operators: Attesters](https://docs.othentic.xyz/main/learn/core-concepts/operator-roles#attesters)
* [CLI Command Reference ](https://docs.othentic.xyz/main/reference/otnode/attester)

### Prerequisites

1. [Othentic Node Software installed](https://docs.othentic.xyz/main/welcome/getting-started/install-othentic-cli)
2. [**Registered** Operator on EigenLayer and AVS](https://docs.othentic.xyz/main/user-guide/operator-management/register-to-avs)
3. **Non zero** Voting Power in the AVS Attestation center contract
4. AVS Contract addresses&#x20;

{% stepper %}
{% step %}

### Environment Setup

Create or edit a `.env` file with your configuration:

* `AVS_WEBAPI_HOST` is the address where Validation Service is running
* ﻿﻿`AVS_WEBAPI_PORT` is the port exposed by the Validation Service
* ﻿﻿Specify `L1_CHAIN` and `L2_CHAIN` variables; See Supported Networks page for chain names
* ﻿﻿Specify `L1_RPC` and `L2_RPC`, ensure you are using paid, reliable RPC endpoints
* ﻿﻿Specify the
  * `PRIVATE_KEY`: Set this to the Consensus Key
  * `OPERATOR_ADDRESS`: Set this to the public address of the Controller Key.\
    the public address of the account that has signed up with the shared security protocol - the address to which stakers delegate their staked assets

```sh
# Network Configuration
BOOTSTRAP_NODE_ID=12D3KooW... # Bootstrap Peer ID
AVS_WEBAPI_HOST=localhost
AVS_WEBAPI_PORT=8080

# Chain Configuration
L1_CHAIN=holesky              # Single L1 chain
L2_CHAIN=amoy,base-sepolia    # Comma-separated L2 chains

# RPC Endpoints
L1_RPC=<HOLESKY_RPC_URL>
L2_RPC=amoy@<AMOY_RPC_URL>,base-sepolia@<BASE_SEPOLIA_RPC_URL> # Comma-separated L2 names@RPCs

# Operator Configuration
OPERATOR_ADDRESS=0x...        # Operator public address
PRIVATE_KEY=0x...             # Consensus Key if separating operator keys
```

{% endstep %}

{% step %}

### Running Attester Nodes

{% tabs %}
{% tab title="Basic Command" %}

<pre><code><strong>otnode run attester \
</strong>  /ip4/127.0.0.1/tcp/9876/p2p/&#x3C;BOOTSTRAP_NODE_ID> \
  --avs-webapi &#x3C;AVS_WEBAPI_HOST> \
  --avs-webapi-port &#x3C;AVS_WEBAPI_PORT> \
  --json-rpc \
  --l1-chain holesky \
  --l2-chain amoy,base-sepolia
</code></pre>

{% endtab %}

{% tab title="Multiple Aggregators" %}

```sh
otnode run attester \
  "/ip4/192.168.1.10/tcp/9876/p2p/${BOOTSTRAP_ID1},/ip4/192.168.1.11/tcp/9876/p2p/${BOOTSTRAP_ID2},/ip4/192.168.1.12/tcp/9876/p2p/${BOOTSTRAP_ID3}" \
  --avs-webapi localhost \
  --avs-webapi-port 8080 \
  --l1-chain holesky \
  --l2-chain amoy,base-sepolia
```

{% endtab %}

{% tab title="Production Command" %}

```
otnode run attester \
  "/ip4/10.0.1.100/tcp/9876/p2p/12D3KooWAgg1,/ip4/10.0.1.101/tcp/9876/p2p/12D3KooWAgg2" \
  --avs-webapi api.myavs.com \
  --avs-webapi-port 443 \
  --l1-chain mainnet \
  --l2-chain base,polygon \
  --metrics \
  --p2p.datadir ./attester-data \
  --status-check-interval 8000 \
  --announced-addresses "/dnsaddr/attester.mynode.com/tcp/9876/p2p/12D3KooWMyPeerID"
```

{% endtab %}
{% endtabs %}
{% endstep %}
{% endstepper %}

***

## Advanced Features

<details>

<summary>Custom P2P Messaging</summary>

Use `--json-rpc.custom-message-enabled`  flag to enable custom p2p messaging if required by the AVS.

```
otnode run attester \
    /ip4/127.0.0.1/tcp/9876/p2p/<BOOTSTRAP_NODE_ID> \
    --json-rpc \
    --json-rpc.custom-message-enabled
```

For more information, see the [Custom Messaging](#custom-p2p-messaging) page.

</details>

<details>

<summary>Operator Status Throttling</summary>

Use `--status-check-interval` to enable throttling mechanism to reduce idle RPC usage, with a default of 5000 milliseconds.

```
otnode run attester \
  /ip4/127.0.0.1/tcp/9876/p2p/<BOOTSTRAP_NODE_ID> \
  --avs-webapi localhost \
  --avs-webapi-port 8080 \
  --json-rpc \
  --status-check-interval 8000 
```

</details>

The following configurations are **mandatory** for production AVSs.

<details>

<summary>Metric Collection &#x26; Monitoring</summary>

Enable performance metrics collection:

```
otnode run attester \
  /ip4/127.0.0.1/tcp/9876/p2p/<BOOTSTRAP_NODE_ID> \
  --avs-webapi localhost \
  --avs-webapi-port 8080 \
  --json-rpc \
  --metrics
```

For more information, see the [**Metrics and Monitoring**](https://docs.othentic.xyz/main/learn/advanced-concepts/p2p-networking/metrics-and-monitoring) page.

</details>

<details>

<summary>Persistent Storage</summary>

Enable P2P layer data caching and peerStore usage:

```
otnode run attester \
  /ip4/127.0.0.1/tcp/9876/p2p/<BOOTSTRAP_NODE_ID> \
  --avs-webapi localhost \
  --avs-webapi-port 8080 \
  --p2p.datadir ./data
```

For more information, see the [**Persistent Storage**](https://docs.othentic.xyz/main/learn/advanced-concepts/p2p-networking/persistent-storage) page.

</details>

<details>

<summary>Announced Addresses (NAT/Load Balancer Support)</summary>

The `announce` option in libp2p allows nodes to explicitly define which addresses they advertise to peers, **overriding** any automatically detected addresses. This is particularly useful when running behind a **load balancer or NAT**, where the external address needs to be manually set.

Use the following flags to configure how your node builds its announced addresses:&#x20;

`--p2p.public-ip`&#x20;

e.g., `--p2p.public-ip 203.0.113.1`&#x20;

`--p2p.dns-url`&#x20;

e.g., `--p2p.dns-url attester.example.com`&#x20;

The node will automatically generate multiaddresses in the following format:&#x20;

```bash
othentic-cli node attester \
/ip4/127.0.0.1/tcp/9876/p2p/<BOOTSTRAP_NODE_ID> \
--avs-webapi localhost \
--avs-webapi-port 8080 \
--json-rpc \
--p2p.public-ip 203.0.113.1 \
--p2p.dns-url attester.example.com
```

***

To manually specify announced addresses, use:

1. Get **Peer ID** using following command

```bash
othentic-cli node get-id --node-type attester
```

2. Add the **Peer ID** from above step in the below option&#x20;

```bash
othentic-cli node attester \
  /ip4/127.0.0.1/tcp/9876/p2p/<BOOTSTRAP_NODE_ID> \
  --avs-webapi localhost \
  --avs-webapi-port 8080 \
  --json-rpc \
  --announced-addresses "/dnsaddr/my-node.example.com/tcp/9876/p2p/{Peer ID},/ip4/203.0.113.1/tcp/9876/p2p/{Peer ID}"
```

</details>

Here is an [example](https://github.com/Othentic-Labs/simple-price-oracle-avs-example/blob/main/docker-compose.prod.yml#L36) docker file to run an Attester node.

### Next Steps :

Refer to the AVS-specific documentation for detailed instructions on running an Operator.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.othentic.xyz/main/user-guide/operator-management/run-an-attester-node.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
