> For the complete documentation index, see [llms.txt](/llms.txt)

# Configure environment

**Time:** \~5 minutes.

<!-- -->

<!-- -->

<!-- -->

## 1. Create the directory

```bash
mkdir -p aztec-sequencer/data && cd aztec-sequencer
```

## 2. Copy your keystore into the project

Copy only the node keystore files (`key1.json`, `key2.json`, ...) into the directory the node loads. Do **not** copy the `*_staker_output.json` files.

```bash
mkdir -p ./keys
cp ~/.aztec/keystore/key*.json ./keys
rm -f ./keys/*_staker_output.json
```

Keep staker output files out of `KEY_STORE_DIRECTORY`

The node loads every `.json` file in `KEY_STORE_DIRECTORY` and expects each one to be a node keystore. The `key*_staker_output.json` files generated by `aztec validator-keys new --staker-output` are a different format (used for registration, not for running the node), so leaving one in this directory makes the node fail to start. The `rm` above removes them after the copy.

## 3. Create the `.env` file

```bash
# ── Aztec Sequencer Configuration ──

# Data & Keys
DATA_DIRECTORY=./data
KEY_STORE_DIRECTORY=./keys
LOG_LEVEL=info

# Ethereum L1 endpoints
ETHEREUM_HOSTS={{ETH_RPC}}
L1_CONSENSUS_HOST_URLS={{CONSENSUS_RPC}}
ETHEREUM_DEBUG_HOSTS={{DEBUG_RPC}}

# P2P networking
P2P_IP={{P2P_IP}}
P2P_PORT=40400

# Aztec ports
AZTEC_PORT=8080
AZTEC_ADMIN_PORT=8880
```

Don't know your external IP?

Run `curl ipv4.icanhazip.com`.

Never expose port 8880

Port 8880 is the **admin port**: it reads and changes node configuration. It requires an API key by default, and it must still never be exposed. It is intentionally not mapped in the Docker Compose file in the next step.

## After delegation: set coinbase to the Split contract

When a delegator stakes to your provider, the protocol creates a **Splits-V2 Split contract** that holds the commission/delegator distribution rules for that delegation. In the default flow, you update the corresponding attester's keystore so its `coinbase` points at that Split. Without this step, rewards still accumulate but the Split can't disperse them according to your agreed commission. For the opt-in alternative, see [EOA coinbase with the payout script](#alternative-eoa-coinbase-with-the-payout-script) below.

This is a **per-delegation, manual** task. The protocol does not notify you when a new delegation arrives.

**The procedure for each new delegation:**

1. Open the [staking dashboard](https://stake.aztec.network) and find your provider page.

2. Expand the **Sequencer Registered (x)** dropdown. The table shows each of your active attester addresses paired with its Split contract address.

3. Edit the keystore for that attester. Set `coinbase` to the Split contract address. Example:

   ```json
   {
     "schemaVersion": 1,
     "validators": [{
       "attester": { "eth": "0x...", "bls": "0x..." },
       "publisher": ["0x..."],
       "coinbase": "0x<SPLIT_CONTRACT_ADDRESS>",
       "feeRecipient": "0x000...000"
     }]
   }
   ```

4. Tell the running node to reload the keystore from disk. This applies the new coinbase without a restart:

   ```bash
   docker exec -it aztec-sequencer curl -X POST http://localhost:8880 \
     -H 'Content-Type: application/json' \
     -H 'x-api-key: [ADMIN_API_KEY]' \
     -d '{"jsonrpc":"2.0","method":"aztecAdmin_reloadKeystore","params":[],"id":1}'
   ```

   The admin API requires an API key by default. The node generates one at first startup and prints it once to the logs; it is reused across restarts because you set `DATA_DIRECTORY`. Pass it with the `x-api-key` header (or `Authorization: Bearer [ADMIN_API_KEY]`). See [admin API key authentication](/operate/operators/reference/changelog/v4.md#admin-api-key-authentication) for the key lifecycle and the opt-out flag.

   `aztecAdmin_reloadKeystore` re-reads the keystore directory and applies each validator's attester key, coinbase, and fee recipient. It does not reload L1 publisher signers, prover keys, or HA signer database connections; those still require a restart. A new validator must reuse a publisher key that was already configured at startup, or the reload is rejected. See the [node API reference](/operate/operators/reference/node_api_reference.md#admin-api).

   Restarting the node also loads the new keystore, if you prefer:

   ```bash
   docker compose restart aztec-sequencer
   ```

Monitor delegations actively

The system does not push notifications. Set up a daily (or hourly during active recruiting) check on the dashboard, and update keystores promptly when new delegations arrive. Maintain a local mapping of attester → Split address so you don't lose track.

### Alternative: EOA coinbase with the payout script

Instead of pointing each delegated attester's coinbase at its Split contract, a provider can set the coinbase to an address they control and handle delegator payouts with the [aztec-staking-payout](https://github.com/AztecProtocol/aztec-staking-payout) script:

* Run the script on a regular cadence (weekly, for example). It calculates each delegator's share at the commission rate you publish.
* It produces a Multicall3 batch of ERC20 transfers ready to sign, plus auditable JSON artifacts that delegators can verify against onchain data.

This is fully opt-in and nothing changes at the protocol level: existing Split contracts keep working, and providers who stay on the Split flow take no action. The difference is the trust model, which moves offchain. Delegators rely on you running the script at the commission and cadence you published, so publish both and keep to them. Background and discussion: [Operator commission adjustments](https://forum.aztec.network/t/operator-commission-adjustments/8588) on the forum.

If you hit empty queue, no delegations can activate. See [Updates, alerts, rewards](/operate/operators/provider/day-2-essentials.md) for the queue-monitoring snippet.

What does each variable do?

* **`DATA_DIRECTORY`** is where the node stores blockchain data. The directory grows over time.
* **`KEY_STORE_DIRECTORY`** is the path to your validator keystore (the `key1.json` file).
* **`ETHEREUM_HOSTS`** is your L1 execution client. The node reads rollup contract state and submits proofs here.
* **`L1_CONSENSUS_HOST_URLS`** is your L1 consensus client (Beacon API). Needed for blob data access.
* **`ETHEREUM_DEBUG_HOSTS`** is a trace-capable endpoint (`debug_traceTransaction`). It is optional: if you leave it unset, the node uses `ETHEREUM_HOSTS` for trace calls, so set it separately only if your trace-capable endpoint differs from your main execution endpoint. Whichever endpoint the node traces with must serve trace methods: the node refuses to start otherwise, unless you set `ETHEREUM_ALLOW_NO_DEBUG_HOSTS=true`.
* **`P2P_IP`** is your server's public IP so other nodes can connect to you.
* **`P2P_PORT 40400`** is the port for peer-to-peer communication, both TCP and UDP. It must be forwarded through your firewall.
