# Copy to .env (never commit it). Every *_app loads it via --env or the default ./.env. # Common NODE_ENV=development LOG_LEVEL=info CLUSTER=devnet # Solana RPC RPC_URL=https://api.devnet.solana.com RPC_FALLBACK_URL= EPOCH_PROGRAM_ID= # Yellowstone gRPC: Solami primary, RPC Fast failover SOLAMI_GRPC_URL=grpc.solami.dev:443 SOLAMI_TOKEN= RPC_FAST_GRPC_URL= RPC_FAST_TOKEN= # Postgres (local: pnpm db:up) DATABASE_URL=postgres://epoch:epoch@localhost:5432/epoch DATABASE_POOL_SIZE=10 # API API_PORT=4000 API_CORS_ORIGINS=http://localhost:3000 # Keeper / publisher wallets: paths to keypair files kept OUTSIDE the repo CRANK_KEYPAIR_PATH=~/.config/solana/epoch-crank.json PUBLISHER_KEYPAIR_PATH=~/.config/solana/epoch-publisher.json # Fee Index operator keys this publisher votes with once consensus is on (comma-separated, at most 8; unset: the # publisher key votes). One per process in production. INDEX_OPERATOR_KEYPAIR_PATHS= # Revenue-token buybacks (cranks_app BuybackJob, ADR 0006) BUYBACK_ENABLED=true # min_amount_out = fresh Meteora quote less this; the program also enforces its own floor BUYBACK_SLIPPAGE_BPS=100 BUYBACK_MAX_ATTEMPTS=3 BUYBACK_COMPUTE_UNITS=300000 # Panta: real-money Predict (USDC on Solana mainnet) and the bot that creates the Fee Index markets. # The key is server-side only (never in the app). Empty values mean "unset" (defaults in Panta.config.ts). PANTA_API_URL= PANTA_API_KEY= # Unset: on when PANTA_API_KEY is set. false = browse only. PANTA_TRADING_ENABLED= # ISO codes (e.g. US,GB) that may browse but not trade; read from the trusted proxy's geo header. PANTA_BLOCKED_COUNTRIES= # true: also refuse trades when no trusted geo header names a country (deployments without a geo-aware proxy). PANTA_GEO_FAIL_CLOSED=false # Mainnet RPC for Panta transactions (defaults to DATA_RPC_URL, then the public mainnet RPC). PANTA_RPC_URL= # panta_bot_app: keypair FILE outside the repo; public https image; Epoch's public https API base (markets resolve # from PUBLIC_API_URL/v1/index/epochs/{N}); creation fees allowed per rolling 24 h, USDC. PANTA_BOT_KEYPAIR_PATH=~/.config/solana/epoch-panta-bot.json # Unset: the API's own PNG at PUBLIC_API_URL/v1/predict/panta/market-image.png. PANTA_MARKET_IMAGE_URL= PUBLIC_API_URL= PANTA_MAX_CREATE_USDC_PER_DAY=100 # Strikes (markets) per epoch, 1-5: quantiles of the last 10 final index values (3 = p30/p50/p70). Each pays a fee. PANTA_STRIKES_PER_EPOCH=1 # Solami Track: the Fee Index live from mainnet (packages/indexer_app/README.md). Keys stay in .env only. # SOLAMI_GRPC_URL and SOLAMI_TOKEN (the gRPC x-token) are above; one Standard key works for gRPC and RPC. SOLAMI_RPC_URL= # https://rpc.solami.dev/sol?api_key= SLOT_SOURCE=auto # auto | grpc (firehose, needs gRPC PAYG) | hybrid | rpc SOLAMI_GRPC_COMPRESSION=none # none | zstd | gzip INDEXER_BACKFILL_EPOCH=false # true: start at the current epoch's first slot (gap-filled over RPC) GAP_FILL_RPS=8 GAP_FILL_CONCURRENCY=4 RPC_SLOT_STRIDE=1 # rpc mode only: sample one slot in N (demo on public RPC; no final values) LIVE_INDEX_INTERVAL_MS=2000 LIVE_STALE_AFTER_SECONDS=20 # api_app: older data is served with live: false # api_app / cranks_app mainnet reads can use Solami RPC too: DATA_RPC_URL=https://rpc.solami.dev/sol?api_key= # (keep DATA_RPC_FALLBACK_URL on another RPC for getProgramAccounts, which Solami caps per plan) # Beam over HTTP for every mainnet transaction we sign (publisher_app post_index and quotes, cranks_app sends and # treasury claims): your Solami RPC URL takes the tipped sendTransaction. unset = off. (llms.txt also names # https://beam-http.solami.dev; it did not resolve on 5 Oct 2026: `pnpm solami:check` tests it.) SOLAMI_BEAM_URL= SOLAMI_BEAM_TIP_LAMPORTS=100000 # api_app: one Solami gRPC stream (with SOLAMI_TOKEN) for the WS `slot` channel and, when EPOCH_CLUSTER=mainnet, the # program's events; slot polling and logsSubscribe stay as the fallbacks SOLAMI_API_STREAM=true SOLAMI_USAGE_STALE_SECONDS=120 # GET /v1/live/solami: older component counters are shown as stale # Revenue-token launches on Meteora (plan F13): docs/runbooks/meteora-mainnet-launch.md, docs/pages/launch.md # Uncomment what you use: an empty value is not the same as unset. # LAUNCHES_PATH=/srv/epoch/launches.json LAUNCH_CLUSTER=devnet # LAUNCH_RPC_URL=https://api.devnet.solana.com # Launch CLI (packages/meteora scripts): keypair FILES outside the repo; addresses are public keys. # EPOCH_PROGRAM_ID (above) decides the DBC fee claimer: the program's treasury PDA ["treasury", pool], no key. # LAUNCH_KEYPAIR_PATH=~/.config/solana/epoch-launch.json # EPOCH_TREASURY= # LAUNCH_OPERATOR_KEYPAIR_PATH= # LAUNCH_LEFTOVER_RECEIVER= # LAUNCH_CREATOR_KEYPAIR_PATH=~/.config/solana/validator-wallet.json # Launch page in api_app LAUNCH_TRADES_INGEST=true # Realtime trade feed: auto = Solami gRPC for a mainnet launch with SOLAMI_TOKEN, else the RPC websocket; off = polling # LAUNCH_REALTIME=auto # LAUNCH_TRADES_BACKSTOP_SECONDS=60 LAUNCH_TRADE_MAX_SOL=10 # LAUNCH_TRADE_PRIORITY_MICROLAMPORTS=100000 # Meteora's DAMM v2 data API for graduated pools (auto = mainnet only) # LAUNCH_INDEXED_DATA=auto # Launch fee claims in cranks_app. The treasury PDA's claims go through the Epoch program, sent by the crank # (CRANK_KEYPAIR_PATH, EPOCH_PROGRAM_ID; LAUNCH_CLUSTER must be EPOCH_CLUSTER). TREASURY_KEYPAIR_PATH is only for a fee # claimer that is a plain wallet. LAUNCH_CLAIMS_ENABLED=false # Graduates completed curves: Meteora's keepers skip raises under 10 SOL # LAUNCH_MIGRATE_ENABLED=true # TREASURY_KEYPAIR_PATH=~/.config/solana/epoch-treasury.json # LAUNCH_CREATOR_KEYPAIR_PATHS= # LAUNCH_CLAIM_KINDS=partnerTradingFee,partnerSurplus,partnerMigrationFee,lpFee,creatorMigrationFee,creatorSurplus,creatorTradingFee,leftover # India page (Superteam India track): SOL in ₹. Optional CoinGecko key, sent only when set (a demo key, or a paid key # with COINGECKO_API_URL=https://pro-api.coingecko.com/api/v3) COINGECKO_API_KEY= # Vote accounts to list as Indian validators besides those Stakewiz geolocates in India (comma-separated) INDIA_VALIDATOR_VOTES=