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