Off-chain API server for stellar-router providing transaction simulation and real-time status tracking via WebSocket.
Allows developers to preview transaction outcomes before execution.
Request:
POST /simulate
{
"target": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4",
"function": "transfer",
"route_details": {
"name": "swap_route",
"version": 1,
"expected_outputs": ["1000000"]
}
}Response:
{
"success": true,
"estimated_fees": {
"base_fee": 100,
"resource_fee": 1000,
"total_fee": 1100,
"surge_multiplier": 100,
"high_load": false
},
"expected_outputs": ["1000000"],
"route_breakdown": {
"route_name": "swap_route",
"version": 1,
"target_contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4",
"function": "transfer"
},
"message": "Simulation successful"
}Real-time transaction status updates via WebSocket.
Subscribe to transaction:
{
"action": "subscribe",
"tx_id": "tx_12345"
}Status events:
{
"msg_type": "status_update",
"data": {
"tx_id": "tx_12345",
"status": "PENDING",
"timestamp": "2026-04-28T02:38:56Z",
"message": "Transaction queued"
}
}Supported statuses:
PENDING- Transaction is pendingSUBMITTED- Transaction submitted to networkCONFIRMED- Transaction confirmed on-chainFAILED- Transaction failed
Unsubscribe from transaction:
{
"action": "unsubscribe",
"tx_id": "tx_12345"
}- Rust 1.78+
- Soroban RPC endpoint URL
- Router execution contract ID
export LISTEN_ADDR="127.0.0.1:8080"
export SOROBAN_RPC_URL="https://soroban-testnet.stellar.org"
export ROUTER_EXECUTION_CONTRACT_ID="CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4"
export ROUTER_API_MAX_REQUESTS="60"
export ROUTER_API_RATE_WINDOW_SECS="60"ROUTER_API_MAX_REQUESTS and ROUTER_API_RATE_WINDOW_SECS control the token-bucket limiter for protected API routes. Requests are limited by X-API-Key when present, otherwise by remote IP address.
The heuristic fee-estimation model is tunable without code changes. Each variable falls back to the default shown below when unset, unparseable, or not strictly positive:
| Variable | Default | Description |
|---|---|---|
ROUTER_BASE_FEE |
100 |
Flat base fee, in stroops. |
ROUTER_RESOURCE_FEE_FLOOR |
100 |
Lower bound for the derived resource fee. |
ROUTER_RESOURCE_FEE_DIVISOR |
1000 |
Divisor scaling amount into a resource fee. |
ROUTER_SURGE_LOAD_THRESHOLD_BPS |
8000 |
Network load (bps) at/above which surge pricing applies. |
ROUTER_SURGE_MULTIPLIER |
200 |
Multiplier (percent) applied under surge. |
ROUTER_NORMAL_MULTIPLIER |
100 |
Multiplier (percent) applied under normal load. |
cargo run --release -p router-api-serverdocker build -t router-api-server -f Dockerfile.api .
docker run -p 8080:8080 \
-e SOROBAN_RPC_URL="https://soroban-testnet.stellar.org" \
-e ROUTER_EXECUTION_CONTRACT_ID="CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4" \
router-api-server| Endpoint | Method | Description |
|---|---|---|
/health |
GET | Health check |
/simulate |
POST | Simulate transaction |
/routes |
GET | List registered route names |
/routes/:name |
GET | Fetch route details |
/ws |
GET | WebSocket connection for status tracking |
The WebSocket client should implement automatic reconnection with exponential backoff:
- Initial connection attempt
- On disconnect, wait 1 second before retry
- Double wait time on each subsequent failure (max 30 seconds)
- Re-subscribe to previous transaction IDs after reconnection
400 Bad Request- Missing or invalid parameters500 Internal Server Error- RPC or contract call failure
- Invalid JSON in message
- Unknown action type
- Connection timeout (server-side: 5 minutes of inactivity)
Run tests:
cargo test -p router-api-serverBuild release:
cargo build --release -p router-api-server