> ## Documentation Index
> Fetch the complete documentation index at: https://docs.panofx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Relay environment variables

> Configuration for the relay, its keeper and the indexer.

The relay and the indexer are two processes from one image and read the same variables. Config is checked
at start and a bad value names the variable.

## Chains

One relay serves every chain. The flat `RPC_URL`, `CHAIN_ID`, `REACTOR`, `VALIDATION`, `EXECUTOR`,
`FEE_CONTROLLER`, `KEEPER_PRIVATE_KEY` and `TOKENS` variables describe a single EVM chain and are used
when `CHAINS` is empty. `CHAINS` is a JSON array describing any number, and wins where both exist.

An EVM entry (`"kind": "evm"` may be left out):

```json theme={null}
[{"chainId":8453,"name":"Base","rpcUrls":["https://..."],"reactor":"0x..","validation":"0x..",
  "executor":"0x..","feeController":"0x..","tokens":[{"symbol":"cNGN","address":"0x..","decimals":6,"minimum":"1000"}],
  "gasFeeToken":"0x..","oracle":{"base":"cNGN","quote":"USDC"},"indexerStartBlock":"46676667"}]
```

A Solana entry. Its keeper secret is `SOLANA_KEEPER_SECRET_<chainId>`, never in `CHAINS`:

```json theme={null}
{"kind":"solana","chainId":103,"cluster":"devnet","rpcUrls":["https://..."],"program":"<base58>","treasury":"<base58>",
 "tokens":[{"symbol":"USDC","address":"<mint>","tokenProgram":"Tokenkeg..","decimals":6}, ...],"feeToken":["USDC","USDT"],
 "pairs":[["cNGN","USDC"],["cNGN","USDT"]],"oracle":{"base":"cNGN","quote":["USDC","USDT"]},
 "feeBps":5,"computeUnitLimit":200000,"computeUnitPrice":"10000","indexerStartSlot":"497711080"}
```

`feeToken` and `oracle.quote` also take one symbol. Without `pairs`, every pair of tokens with a fee token
is a corridor. A token's `minimum` is the corridor's smallest sell amount in whole tokens.

## Relay

| Variable                                 | Default             | Meaning                                                   |
| ---------------------------------------- | ------------------- | --------------------------------------------------------- |
| `HOST`, `PORT`                           | `127.0.0.1`, `8080` |                                                           |
| `LOG_LEVEL`                              | `info`              |                                                           |
| `DATABASE_URL`                           | required            | Postgres                                                  |
| `RPC_FALLBACK_URLS`                      |                     | Comma-separated, tried in order when the primary errors   |
| `CHAIN_NAME`                             |                     | Display name for the single chain                         |
| `PERMIT2`                                | canonical           |                                                           |
| `RFQ_WINDOW_MS`                          | `1500`              | How long resolvers have to reply                          |
| `QUOTE_TTL_MS`                           | `20000`             | How long a quote stays open                               |
| `MIN_OFFER_TTL_MS`                       | `10000`             | Offers with a shorter deadline are rejected               |
| `HEARTBEAT_INTERVAL_MS`, `NODE_STALE_MS` | `10000`, `35000`    |                                                           |
| `GAS_FEE_TOKEN`                          | buy token           | The token the gas fee is charged in                       |
| `GAS_FEE_FIXED`                          | `0`                 | Fallback gas fee in base units when no price is available |
| `GAS_UNITS`                              | `450000`            | Gas one settlement is expected to use                     |
| `GAS_MARGIN_BPS`                         | `2500`              | Headroom over the estimate (1.25x)                        |
| `GAS_MIN_USD`, `GAS_MAX_USD`             | `0.03`, `0.5`       | Floor and ceiling of the gas line                         |
| `KEEPER_LEASE_TTL_MS`                    | `15000`             | The Postgres lease the keeper leader holds, per chain     |
| `STATIC_DIR`                             |                     | Static files served at `/` (the M0 swap page)             |
| `TRUST_PROXY`                            | `true`              | Read the client IP from `X-Forwarded-For`                 |

## Abuse controls and registry

| Variable                        | Default | Meaning                                                          |
| ------------------------------- | ------- | ---------------------------------------------------------------- |
| `REQUIRE_TAKER_PROOF`           | `false` | Require a [taker proof](/integrators/taker-proof) on every quote |
| `REQUIRE_REGISTRATION`          | `false` | Admit only registered resolvers                                  |
| `MAX_OUTSTANDING_RFQS`          | `4`     | In-flight RFQs per taker                                         |
| `RESOLVER_RFQ_PER_SEC`          | `100`   | RFQs per second to any one resolver; burst is twice              |
| `RATE_LIMIT_QUOTES_PER_MIN`     | `120`   | Per IP; 0 disables                                               |
| `RATE_LIMIT_EXECUTIONS_PER_MIN` | `30`    |                                                                  |
| `RATE_LIMIT_REGISTER_PER_MIN`   | `10`    |                                                                  |

## Oracle

| Variable                      | Default        | Meaning                                                                                                                  |
| ----------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `ORACLE_ENABLED`              | `true`         |                                                                                                                          |
| `ORACLE_INTERVAL_MS`          | `10000`        |                                                                                                                          |
| `ORACLE_BASE`, `ORACLE_QUOTE` | `cNGN`, `USDC` | Symbols of the band. `ORACLE_QUOTE` may list several dollar tokens, comma-separated; the first prices the gas fee        |
| `ORACLE_STATIC`               |                | A fixed NGN/USD value instead of the public sources                                                                      |
| `ORACLE_STATIC_SOL_USD`       |                | A fixed SOL/USD price for the Solana gas fee                                                                             |
| `ORACLE_SOURCES`              |                | Which sources make the band. Empty means the peer-to-peer and NGN exchange books; official FX rates can be added by name |

## Limit orders

| Variable                                   | Default          | Meaning                                                                       |
| ------------------------------------------ | ---------------- | ----------------------------------------------------------------------------- |
| `LIMIT_ORDERS_ENABLED`                     | `true`           |                                                                               |
| `LIMIT_POLL_MS`                            | `5000`           | How often the keeper leader looks at the book                                 |
| `LIMIT_RECHECK_MS`                         | `15000`          | Least time between two auctions for one order; doubles after each failed fill |
| `LIMIT_MAX_PER_TICK`                       | `8`              | Auctions per poll per chain                                                   |
| `LIMIT_BAND_SLACK_BPS`                     | `150`            | An order more than this much better than the oracle mid is not auctioned      |
| `LIMIT_MIN_EXPIRY_S`, `LIMIT_MAX_EXPIRY_S` | `300`, `2592000` | 5 minutes to 30 days                                                          |
| `LIMIT_MAX_OPEN_PER_TAKER`                 | `20`             |                                                                               |
| `LIMIT_GAS_HEADROOM`                       | `3`              | The gas cap an order signs, as a multiple of today's fee                      |

## Remote console

| Variable                     | Default | Meaning                                                                          |
| ---------------------------- | ------- | -------------------------------------------------------------------------------- |
| `REMOTE_ENABLED`             | `true`  |                                                                                  |
| `REMOTE_MAX_DEVICES`         | `8`     | Device sockets per channel                                                       |
| `REMOTE_DEVICE_CONNS_PER_IP` | `20`    |                                                                                  |
| `REMOTE_ALLOWED_ORIGINS`     |         | Comma-separated origins that may open a device socket; empty allows every origin |

## Indexer

| Variable                | Default           | Meaning                                                      |
| ----------------------- | ----------------- | ------------------------------------------------------------ |
| `HOST`, `PORT`          | `0.0.0.0`, `8090` | `/health` reports lag in blocks or slots                     |
| `DATABASE_URL`          | required          |                                                              |
| `CHAINS`                |                   | The same value the relay reads                               |
| `INDEXER_START_BLOCK`   | `0`               | First block scanned on an empty database (single-chain form) |
| `INDEXER_CONFIRMATIONS` | `12`              |                                                              |
| `INDEXER_POLL_MS`       | `4000`            |                                                              |
| `INDEXER_CHUNK`         | `2000`            | Blocks per `getLogs` call                                    |
| `RELIABILITY_EVERY_MS`  | `60000`           | How often reliability and demotion are recomputed            |
