The config file
A Smart Router config is a single YAML file with two required lists — the listeners
it opens (endpoints) and the upstreams it routes to (direct-rpc) — plus a few
optional top-level keys. Everything else (node selection, failover, timeouts) is
tuned with CLI flags, not the file.
You point the router at it positionally:
Working examples live under
config/smartrouter_examples/ —
the fastest way to a real config is to copy one and edit it, or let the
wizard generate one.
A minimal config
metrics-listen-address: "0.0.0.0:7779"
endpoints:
- network-address: "0.0.0.0:3360"
chain-id: "ETH1"
api-interface: "jsonrpc"
direct-rpc:
- name: "eth-publicnode"
chain-id: "ETH1"
api-interface: "jsonrpc"
node-urls:
- url: "https://ethereum-rpc.publicnode.com"
- url: "wss://ethereum-rpc.publicnode.com"
The router pairs each endpoints[] listener with the direct-rpc[] nodes that
share its chain-id + api-interface. A listener with no matching node won't
serve; a node with no matching listener is never used.
Top-level keys
| Key | Required | What it is |
|---|---|---|
endpoints |
yes | The listeners the router opens — one per chain × API interface. |
direct-rpc |
yes | The upstream node pool. |
backup-direct-rpc |
no | Emergency-fallback nodes, only used once the primary pool is exhausted. Same shape as direct-rpc. |
cache-be |
no | Address of the cache sidecar, e.g. cache:20100. Omit to disable caching. |
metrics-listen-address |
no | Prometheus /metrics address, e.g. 0.0.0.0:7779. disabled turns metrics off. Overridden by --metrics-listen-address. |
cross-validation |
no | Per-method operator policies for cross-validation (mandate, cap, or forbid). |
Deprecated keys removed
The old static-providers / backup-providers keys are gone — use direct-rpc /
backup-direct-rpc.
endpoints[] — listeners
Each entry opens one listening socket for one chain + interface.
| Field | Required | Description |
|---|---|---|
network-address |
yes | host:port to listen on, e.g. 0.0.0.0:3360. |
chain-id |
yes | Spec chain id (ETH1, SOLANA, COSMOSHUB, …). Must resolve from --use-static-spec. |
api-interface |
yes | jsonrpc, rest, grpc, or tendermintrpc — must be supported by the chain spec. |
tls-enabled |
no | Serve this listener over TLS using a self-signed certificate. Default false. |
health-check-path |
no | HTTP path that returns 200 for liveness probes. Default /lava/health. |
endpoints:
- network-address: "0.0.0.0:3360"
chain-id: "COSMOSHUB"
api-interface: "rest"
- network-address: "0.0.0.0:3361"
chain-id: "COSMOSHUB"
api-interface: "grpc"
direct-rpc[] — upstream nodes
Each entry is one named backend serving one chain + interface, with one or more URLs.
| Field | Required | Description |
|---|---|---|
name |
yes | Human label — shows up in logs and as the Prometheus endpoint_id. |
chain-id |
yes | Chain this backend serves; must match an endpoints[] entry. |
api-interface |
yes | Interface this backend serves; must match the listener. |
node-urls |
yes | One or more URL entries (below). |
stake |
no | Optional weight (in ulava) for selection scoring. Omit (or 0) to apply the default static-node boost. |
group-label |
no | Optional provider-group id (e.g. tier-1, external) for cross-validation group-diversity policies. No effect unless a policy requires group spread. |
direct-rpc:
- name: "eth-publicnode"
chain-id: "ETH1"
api-interface: "jsonrpc"
node-urls:
- url: "https://ethereum-rpc.publicnode.com"
- url: "wss://ethereum-rpc.publicnode.com"
node-urls[] — per-URL options
| Field | Description |
|---|---|
url |
Connection URL. Schemes: http(s)://, ws(s)://, grpc(s)://. A jsonrpc backend on an ETH1-derived spec needs a paired wss:// url. |
timeout |
Per-URL request timeout, e.g. 10s. Defaults to the spec value. |
addons |
Add-ons this URL serves, e.g. ["archive", "debug"]. The router only routes matching methods here. |
methods |
Restrict this URL to a specific method list. When set, only those methods route here. |
internal-path |
Path override when proxying through a gateway. |
ip-forwarding |
Forward the client IP via X-Forwarded-For to the upstream. |
skip-verifications |
Skip chain-tracker startup checks for this URL, e.g. ["pruning", "tx-indexing"]. |
auth-config |
Per-URL authentication — see Authentication. |
grpc-config |
gRPC descriptor settings (below). |
node-urls:
- url: "https://your-eth-provider.example.com"
timeout: 10s
addons: ["bundler", "debug"]
auth-config:
auth-headers:
x-api-key: "${RPC_KEY_ETH}"
- url: "wss://your-eth-provider.example.com/websocket"
grpc-config — gRPC descriptors
Only relevant for grpc interfaces.
| Field | Default | Description |
|---|---|---|
descriptor-source |
reflection |
reflection (server reflection), file (a compiled descriptor set), or hybrid (reflection, then file). |
descriptor-set-path |
— | Path to a protobuf FileDescriptorSet. Required for file / hybrid. |
reflection-timeout |
5s |
Timeout for reflection queries. |
allow-insecure |
false |
Permit non-TLS grpc://. Dev/test only. |
Cross-validation
An optional top-level block sets per-method operator policies for cross-validation — to mandate it (with floors/caps clients can't weaken), or forbid clients from requesting it. Without this block, cross-validation is purely client-driven via the request headers.
cross-validation:
policies:
# Mandate consensus for a sensitive read, capped so clients can't fan out wider.
- chain-id: "ETH1"
api-interface: "jsonrpc"
method: "eth_getLogs"
enabled: true
agreement-threshold: { floor: 2 }
max-participants: { floor: 3, cap: 5 }
# Forbid clients from cross-validating a non-deterministic method.
- chain-id: "ETH1"
api-interface: "jsonrpc"
method: "eth_blockNumber"
forbid-caller-cv: true
| Field | Description |
|---|---|
chain-id / api-interface / method |
Which requests the policy applies to (method casing is preserved). |
enabled |
Mandate cross-validation for this method. |
max-participants / agreement-threshold / min-groups |
Bounds — each takes { floor, cap }. A client header may raise within the cap but can't drop below the floor. |
per-group-quorum |
Require each of min-groups groups to independently reach the threshold (needs min-groups > 1). |
forbid-caller-cv |
Disable cross-validation for this method even if a client sends the headers. Mutually exclusive with enabled. |
Secrets
Never commit API keys. Put them in upstream URLs or auth-config as ${VAR}
placeholders and render them at run time — see Authentication. The
rendered URL embeds the full key and is a bearer credential, so generated configs
default to the gitignored config/local/.
See also
- Authentication —
auth-config,${VAR}secrets, mTLS. - CLI reference — every runtime flag.
- Supported chains — valid
chain-id/api-interfacevalues.