Configuration
dispatch-service (config.toml)
[server]
host = "0.0.0.0"
port = 7700
[indexer]
# Your on-chain provider address (holds the GRT provision).
service_provider_address = "0x..."
# 32-byte hex ECDSA private key of your operator key.
# Signs response attestations and on-chain collect() transactions.
# Use a dedicated hot key — NOT your wallet or staking key.
operator_private_key = "0x..."
[tap]
# RPCDataService contract address.
data_service_address = "0xA983b18B8291F0c317Ba4Fe0dc0f7cc9373AF078"
# Ethereum addresses authorised to send TAP receipts to this service.
# Derived from the gateway's signer_private_key. Leave empty to accept all.
authorized_senders = ["0x..."]
# EIP-712 domain — must match the deployed GraphTallyCollector. Do not change.
eip712_domain_name = "GraphTallyCollector"
eip712_chain_id = 42161
eip712_verifying_contract = "0x8f69F5C07477Ac46FBc491B1E6D91E2bb0111A9e"
# Internal URL of your dispatch-gateway (for RAV aggregation).
aggregator_url = "http://dispatch-gateway:8080"
# How often to aggregate receipts into RAVs (default: 60s).
# aggregation_interval_secs = 60
# Maximum unconfirmed GRT wei per consumer before rejecting requests (default: 0.1 GRT).
# credit_threshold = 100_000_000_000_000_000
# Arbitrum One RPC for on-chain escrow balance pre-checks (cached 30s per consumer).
# Falls back to [collector].arbitrum_rpc_url. Omit both to disable escrow checks.
# escrow_check_rpc_url = "https://arb1.arbitrum.io/rpc"
# PaymentsEscrow contract — defaults to the live Horizon deployment, no need to change.
# payments_escrow_address = "0xf6Fcc27aAf1fcD8B254498c9794451d82afC673E"
[chains]
# Chain IDs this node is registered to serve.
supported = [1, 42161]
[chains.backends]
# Internal RPC URL of your Ethereum node for each chain.
"1" = "http://eth-node:8545"
"42161" = "http://arbitrum-node:8545"
[database]
url = "postgres://dispatch:dispatch@postgres:5432/dispatch"
[collector]
# Arbitrum One RPC for sending on-chain collect() transactions.
arbitrum_rpc_url = "https://arb1.arbitrum.io/rpc"
collect_interval_secs = 3600 # collect GRT every hour
# min_collect_value = 0 # skip collect if accumulated value is below this (GRT wei)
dispatch-gateway (gateway.toml)
[gateway]
host = "0.0.0.0"
port = 8080
region = "eu-west" # optional — used for geographic routing bonus
[tap]
# 32-byte hex ECDSA private key — gateway signs TAP receipts with this.
# Its derived Ethereum address must be in each provider's authorized_senders list.
signer_private_key = "0x..."
# RPCDataService contract address.
data_service_address = "0xA983b18B8291F0c317Ba4Fe0dc0f7cc9373AF078"
# GRT wei per compute unit. Default ≈ $40/M requests at $0.09/GRT.
base_price_per_cu = 4000000000000
# EIP-712 domain — must match the deployed GraphTallyCollector. Do not change.
eip712_domain_name = "GraphTallyCollector"
eip712_chain_id = 42161
eip712_verifying_contract = "0x8f69F5C07477Ac46FBc491B1E6D91E2bb0111A9e"
[qos]
probe_interval_secs = 10 # synthetic eth_blockNumber probe period
concurrent_k = 3 # dispatch to top-k providers, return first valid response
region_bonus = 0.15 # score boost for providers in the same region
[discovery]
# The Graph subgraph URL for dynamic provider discovery.
subgraph_url = "https://api.studio.thegraph.com/query/1747796/rpc-network/v0.2.0"
interval_secs = 60
# Optional: static providers used at startup and as fallback.
[[providers]]
address = "0x..."
endpoint = "https://rpc.your-indexer.com"
chains = [1, 42161]
region = "eu-west"
capabilities = ["standard", "archive"]
Environment variables
dispatch-service:
DISPATCH_CONFIG=/etc/dispatch/config.toml # path to config file (default: config.toml)
RUST_LOG=info # log level: error, warn, info, debug, trace
dispatch-gateway:
DISPATCH_GATEWAY_CONFIG=/etc/dispatch/gateway.toml
RUST_LOG=info