| name | kora-operator |
| description | Kora paymaster node operator guide. Use when the user asks about: configuring kora.toml (rate limits, validation, allowed programs/tokens, fee payer policy, pricing, auth, caching, bundles, lighthouse), setting up signers.toml (memory/Turnkey/Privy/Vault, pool strategies), running Kora (kora rpc start, config validate, CLI, justfile), deploying to Docker/Railway, fee calculation (margin/fixed/free pricing), Jito bundle config, Lighthouse fee payer protection, reCAPTCHA bot protection, Prometheus monitoring, usage limits with rules, or API key/HMAC authentication setup. Not for client SDK integration (use kora-client). |
Kora Node Operator Guide
Run Kora nodes to validate, sign, and sponsor Solana transaction fees for your users.
Docs: https://launch.solana.com/docs/kora/operators
Install: cargo install kora-cli
Docker: docker pull ghcr.io/solana-foundation/kora:latest
Source: https://github.com/solana-foundation/kora
Quick Start
cargo install kora-cli
kora --config kora.toml config validate
kora --config kora.toml rpc start --signers-config signers.toml
kora --config kora.toml rpc initialize-atas --signers-config signers.toml
CLI Reference
kora --config <path>
kora --rpc-url <url>
kora config validate
kora config validate-with-rpc
kora rpc start --signers-config <path>
kora rpc start --no-load-signer
kora rpc start --port 8080
kora rpc start --logging-format json
kora rpc initialize-atas --signers-config <path>
--fee-payer-key <base58>
--compute-unit-price <num>
--compute-unit-limit <num>
--chunk-size <num>
Configuration Overview
Two config files required:
| File | Purpose |
|---|
kora.toml | Server config: validation, auth, pricing, caching, methods, bundles, lighthouse, metrics |
signers.toml | Signer pool: keys, types, selection strategy |
Minimal kora.toml
[kora]
rate_limit = 100
[validation]
max_allowed_lamports = 1000000
max_signatures = 10
price_source = "Mock"
allowed_programs = [
"11111111111111111111111111111111",
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",
"ComputeBudget111111111111111111111111111111",
]
allowed_tokens = ["<your-token-mint>"]
allowed_spl_paid_tokens = ["<your-token-mint>"]
[validation.price]
type = "margin"
margin = 0.1
Minimal signers.toml
[signer_pool]
strategy = "round_robin"
[[signers]]
name = "signer_1"
type = "memory"
private_key_env = "KORA_PRIVATE_KEY"
weight = 1
Detailed References
Key Operator Decisions
Pricing Model
| Model | Use Case | Security |
|---|
margin (default) | Charge users cost + markup | Safest - includes fee payer outflow |
fixed | Flat fee per transaction | Must disable fee payer transfers in policy |
free | Sponsor all fees | Must disable fee payer transfers in policy |
Authentication
Three optional methods, can be used simultaneously:
- API Key: Simple
x-api-key header. Set api_key in [kora.auth] or KORA_API_KEY env var.
- HMAC: Cryptographic signature with timestamp. Set
hmac_secret in [kora.auth] or KORA_HMAC_SECRET env var.
- reCAPTCHA v3: Bot protection for signing methods. Set
recaptcha_secret in [kora.auth] or KORA_RECAPTCHA_SECRET env var. Configurable recaptcha_score_threshold (default: 0.5) and protected_methods.
Fee Payer Policy
Control what actions the fee payer can perform in transactions. All default to false (restrictive). Explicitly set to true only what you need.
Critical for fixed/free pricing: ensure allow_transfer remains false (the default) on system and token programs to prevent fee payer fund drain.
Jito Bundle Support
Enable atomic multi-transaction execution via Jito:
[kora.bundle]
enabled = true
[kora.bundle.jito]
block_engine_url = "https://mainnet.block-engine.jito.wtf"
When using Jito tips paid by Kora, set allow_transfer = true in [validation.fee_payer_policy.system].
Lighthouse Fee Payer Protection
Adds balance assertion instructions to protect the fee payer from drainage attacks:
[kora.lighthouse]
enabled = true
fail_if_transaction_size_overflow = true
Only works with signTransaction/signBundle (not broadcast methods). Requires Lighthouse program in allowed_programs: L2TExMFKdjpN9kozasaurPirfHy9P8sbXoAN1qA3S95
Usage Limits
Rule-based per-user limiting with Redis backend:
[kora.usage_limit]
enabled = true
cache_url = "redis://redis:6379"
fallback_if_unavailable = false
[[kora.usage_limit.rules]]
type = "transaction"
max = 100
window_seconds = 3600
[[kora.usage_limit.rules]]
type = "instruction"
program = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
instruction = "Transfer"
max = 10
window_seconds = 3600
Requires user_id parameter in signing requests when enabled with free pricing.
Caching
Optional Redis caching for token account lookups:
[kora.cache]
enabled = true
url = "redis://localhost:6379"
default_ttl = 300
account_ttl = 60
Monitoring
Optional Prometheus metrics at /metrics:
[metrics]
enabled = true
endpoint = "/metrics"
port = 9090
Key metrics: kora_http_requests_total, kora_http_request_duration_seconds, signer_balance_lamports.
Deployment
Docker
Pre-built image available (tags: latest, beta, v<version>):
docker pull ghcr.io/solana-foundation/kora:latest
docker run -v ./kora.toml:/kora.toml -v ./signers.toml:/signers.toml \
-e RPC_URL=https://api.mainnet-beta.solana.com \
-e KORA_PRIVATE_KEY=<key> \
-p 8080:8080 \
ghcr.io/solana-foundation/kora:latest
Or build from source:
FROM rust:1.86-bookworm AS builder
RUN cargo install kora-cli
FROM debian:bookworm-slim
COPY --from=builder /usr/local/cargo/bin/kora /usr/local/bin/kora
COPY kora.toml signers.toml ./
ENV RPC_URL=https://api.mainnet-beta.solana.com
CMD ["kora", "rpc", "start", "--signers-config", "signers.toml"]
Railway
- Create project with kora.toml, signers.toml, Dockerfile
railway login && railway init && railway up
- Set env vars in dashboard:
RPC_URL, KORA_PRIVATE_KEY, RUST_LOG
- Generate public domain from settings
Docs: https://launch.solana.com/docs/kora/operators/deployment/railway
Kora Core Development
For contributors working on the Kora codebase itself:
just build
just build-lib
just build-cli
just check
just fmt
just unit-test
just integration-test