For the complete documentation index optimized for AI agents, see llms.txt or llms-full.txt. A markdown version of this page is available by appending.mdto the URL or sendingAccept: text/markdown.
Configuration Reference
For AI agents: the documentation index is at llms.txt (full corpus: llms-full.txt). A markdown source for this page is /a4-server/reference.md.
This page documents the principal configuration options available in
a4-server. The server consumes generated Rust spec() values, not deployment
URLs or hosted release manifests.
Server Builder API
Section titled “Server Builder API”The server is configured using a fluent builder pattern:
use a4_server::Server;
Server::builder() .spec(my_spec()) // Generated live or program-only specification .websocket() // Enable WebSocket server .bind("[::]:8877".parse()?) .yellowstone(config) // Optional: manual Yellowstone config .health_monitoring() // Enable health monitoring .http_health() // Configure the shared HTTP listener .reconnection() // Enable auto-reconnection .start() .await?;The generated spec carries exact ProgramSpec identities and local account readers. For OSS code-first use, release fingerprints are derived automatically from each ProgramSpec and the generated decoder-engine contract. Hosted Program Releases, deployments, and endpoint bindings are separate control-plane concepts and are not required here.
Runtime Capability Plan
Section titled “Runtime Capability Plan”Live, Program Read, chain-read, and transaction surfaces are independent. The
fluent helpers update a RuntimePlan:
| Builder method | Capabilities enabled |
|---|---|
.websocket() | WebSocket transport and live projection runtime |
.program_reads() | Health plus typed, release-checked program HTTP reads |
.chain_reads() | Generic Solana chain-read HTTP routes |
.stack_queries() | Stack-scoped query HTTP routes |
.transactions_config(config) | Fixed transaction routes when config.enabled is true |
.http() | Convenience set: health, program reads, chain reads, and stack queries |
Transaction routes are never enabled by .http(). To enforce an exact
capability set after configuring listeners, replace the inferred plan:
use a4_server::RuntimePlan;
let plan = RuntimePlan { health: true, chain_reads: false, program_reads: true, stack_queries: false, transactions: false, websocket: false, live_runtime: false,};
Server::builder() .spec(my_program::spec()) .http_bind("0.0.0.0:8081".parse()?) .runtime_plan(plan) .start() .await?;This program-only configuration does not require Yellowstone. A composed client may point each LiveSpec alias and each Program Read binding at different services, then supply independent chain and transaction transports.
Environment Variables
Section titled “Environment Variables”These environment variables are read by the generated runtime and server code:
| Variable | Required | Default | Description |
|---|---|---|---|
YELLOWSTONE_ENDPOINT | For live runtime | — | Yellowstone gRPC endpoint URL |
YELLOWSTONE_X_TOKEN | Provider-specific | — | Authentication token for the endpoint |
ARETE_READ_RPC_URL | For RPC-backed reads | — | Upstream used by Program Read and chain-read routes |
ARETE_TRANSACTION_RPC_URL | For transaction routes | — | Independent transaction inspect/send upstream |
ARETE_TRANSACTIONS_ENABLED | No | false | Explicitly enables fixed transaction routes |
ARETE_SNAPSHOT_ENABLED | No | false | Enables state snapshots for restart recovery |
ARETE_SNAPSHOT_URL | For snapshots | — | Snapshot store location (file://... or local path) |
RUST_LOG | No | info | Log level filter (e.g., debug, info,a4_server=debug) |
The full set of ARETE_SNAPSHOT_* variables is documented in
State Snapshots & Restore.
WebSocket Configuration
Section titled “WebSocket Configuration”Basic Usage
Section titled “Basic Usage”// Enable with defaults (binds to [::]:8877)Server::builder() .websocket() .start() .await?;
// Or specify a custom bind addressServer::builder() .websocket() .bind("[::]:9000".parse()?) .start() .await?;WebSocketConfig
Section titled “WebSocketConfig”For full control, use websocket_config():
use a4_server::WebSocketConfig;
let ws_config = WebSocketConfig { bind_address: "[::]:8877".parse()?,};
Server::builder() .websocket_config(ws_config) .start() .await?;| Field | Type | Default | Description |
|---|---|---|---|
bind_address | SocketAddr | [::]:8877 | Address and port for the WebSocket server |
Yellowstone Configuration
Section titled “Yellowstone Configuration”The Yellowstone gRPC connection is typically configured via environment variables. However, you can also configure it programmatically:
use a4_server::YellowstoneConfig;
let yellowstone = YellowstoneConfig::new("https://your-endpoint.com") .with_token("your-secret-token");
Server::builder() .yellowstone(yellowstone) .start() .await?;YellowstoneConfig
Section titled “YellowstoneConfig”| Field | Type | Default | Description |
|---|---|---|---|
endpoint | String | — | Yellowstone gRPC endpoint URL |
x_token | Option<String> | None | Authentication token |
Builder Methods
Section titled “Builder Methods”| Method | Description |
|---|---|
YellowstoneConfig::new(endpoint) | Create with endpoint |
.with_token(token) | Set authentication token |
Health Monitoring
Section titled “Health Monitoring”Health monitoring tracks stream connectivity and detects issues like stale connections.
Basic Usage
Section titled “Basic Usage”// Enable with defaultsServer::builder() .health_monitoring() .start() .await?;HealthConfig
Section titled “HealthConfig”use a4_server::HealthConfig;use std::time::Duration;
let health = HealthConfig::new() .with_heartbeat_interval(Duration::from_secs(30)) .with_health_check_timeout(Duration::from_secs(10));
Server::builder() .health_config(health) .start() .await?;| Field | Type | Default | Description |
|---|---|---|---|
heartbeat_interval | Duration | 30s | How often to check stream health |
health_check_timeout | Duration | 10s | Timeout for health check operations |
Builder Methods
Section titled “Builder Methods”| Method | Description |
|---|---|
HealthConfig::new() | Create with defaults |
.with_heartbeat_interval(duration) | Set heartbeat interval |
.with_health_check_timeout(duration) | Set health check timeout |
Shared HTTP Server and Health Routes
Section titled “Shared HTTP Server and Health Routes”The shared HTTP listener exposes health routes and whichever read/transaction
capabilities are selected in RuntimePlan. For compatibility,
http_health()/http_health_config() are aliases for http()/http_config();
by themselves they infer health, Program Read, chain-read, and stack-query
capabilities.
Basic Usage
Section titled “Basic Usage”// Configure the listener with the full HTTP convenience capability set.// It binds to [::]:8081.Server::builder() .http_health() .start() .await?;
// Or specify a custom bind addressServer::builder() .http_health() .health_bind("0.0.0.0:8081".parse()?) .start() .await?;For health-only HTTP alongside a live WebSocket, replace the inferred plan after configuring the listener:
use a4_server::RuntimePlan;
Server::builder() .spec(spec) .websocket() .http_health() .health_bind("0.0.0.0:8081".parse()?) .runtime_plan(RuntimePlan { health: true, websocket: true, live_runtime: true, ..RuntimePlan::default() }) .start() .await?;HttpHealthConfig
Section titled “HttpHealthConfig”use a4_server::HttpHealthConfig;
let http_health = HttpHealthConfig::new("0.0.0.0:9090".parse()?);
Server::builder() .http_health_config(http_health) .start() .await?;| Field | Type | Default | Description |
|---|---|---|---|
bind_address | SocketAddr | [::]:8081 | Address and port for the HTTP health server |
Health Endpoints
Section titled “Health Endpoints”| Endpoint | Method | Description |
|---|---|---|
/health or /healthz | GET | Liveness check — returns 200 OK if server is running |
/ready or /readiness | GET | Readiness check — returns 200 OK if stream is healthy, 503 otherwise |
/status | GET | Detailed JSON status with health state and error count |
Example /status Response
Section titled “Example /status Response”{ "healthy": true, "status": "Connected", "error_count": 0}Reconnection Configuration
Section titled “Reconnection Configuration”Controls automatic reconnection behavior when the Yellowstone gRPC connection drops.
Basic Usage
Section titled “Basic Usage”// Enable with defaultsServer::builder() .reconnection() .start() .await?;ReconnectionConfig
Section titled “ReconnectionConfig”use a4_server::ReconnectionConfig;use std::time::Duration;
let reconnect = ReconnectionConfig::new() .with_initial_delay(Duration::from_millis(100)) .with_max_delay(Duration::from_secs(60)) .with_max_attempts(10) .with_backoff_multiplier(2.0) .with_http2_keep_alive_interval(Duration::from_secs(30));
Server::builder() .reconnection_config(reconnect) .start() .await?;| Field | Type | Default | Description |
|---|---|---|---|
initial_delay | Duration | 100ms | Delay before first reconnection attempt |
max_delay | Duration | 60s | Maximum delay between attempts (caps exponential backoff) |
max_attempts | Option<u32> | None (infinite) | Maximum reconnection attempts before giving up |
backoff_multiplier | f64 | 2.0 | Multiplier for exponential backoff |
http2_keep_alive_interval | Option<Duration> | 30s | HTTP/2 keep-alive to prevent silent disconnects |
Builder Methods
Section titled “Builder Methods”| Method | Description |
|---|---|
ReconnectionConfig::new() | Create with defaults |
.with_initial_delay(duration) | Set initial reconnection delay |
.with_max_delay(duration) | Set maximum backoff delay |
.with_max_attempts(n) | Limit reconnection attempts |
.with_backoff_multiplier(m) | Set exponential backoff multiplier |
.with_http2_keep_alive_interval(duration) | Set HTTP/2 keep-alive interval |
Feature Flags
Section titled “Feature Flags”Enable optional features in your Cargo.toml:
[dependencies]a4-server = { version = "0.20.1", features = ["otel"] }| Feature | Default | Description |
|---|---|---|
otel | No | OpenTelemetry integration for metrics and distributed tracing |
Using OpenTelemetry Metrics
Section titled “Using OpenTelemetry Metrics”When the otel feature is enabled:
use a4_server::Metrics;
let metrics = Metrics::new();
Server::builder() .metrics(metrics) .start() .await?;Complete Example
Section titled “Complete Example”Here’s a production-ready configuration combining all options:
use a4_server::{ Server, HealthConfig, HttpHealthConfig, ReconnectionConfig};use std::time::Duration;
#[tokio::main]async fn main() -> anyhow::Result<()> { // TLS provider for gRPC rustls::crypto::ring::default_provider() .install_default() .expect("Failed to install rustls crypto provider");
// Load environment variables dotenvy::dotenv().ok();
// Initialize logging tracing_subscriber::fmt() .with_env_filter( tracing_subscriber::EnvFilter::try_from_default_env() .unwrap_or_else(|_| "info,a4_server=debug".into()), ) .init();
let spec = my_stack::spec();
Server::builder() .spec(spec) // WebSocket on port 8877 .websocket() .bind("[::]:8877".parse()?) // Health monitoring with custom intervals .health_config( HealthConfig::new() .with_heartbeat_interval(Duration::from_secs(15)) ) // Shared HTTP listener on port 8081. The convenience helper enables // health, Program Read, chain-read, and stack-query routes. .http_health() .health_bind("0.0.0.0:8081".parse()?) // Reconnection with limited attempts .reconnection_config( ReconnectionConfig::new() .with_max_attempts(100) .with_max_delay(Duration::from_secs(30)) ) .start() .await?;
Ok(())}Operational Handoff
Section titled “Operational Handoff”Portable ProgramSpec, LiveSpec, and StackManifest hashes do not include runtime
hostnames. Building or starting a4-server also does not publish generated SDK
packages. Operators are responsible for reviewed npm/crates.io publication and
for mapping the resulting endpoint bindings through any DNS/CDN provider they
choose.