Skip to content

Configuration reference

After this page you can configure any part of a self-hosted stack and know what happens when a variable is left empty. This page mirrors .env.example in the repo root; if they disagree, .env.example wins and this page has a bug.

Every variable is optional unless marked REQUIRED. The stack runs end-to-end on the zero-key fallbacks: polling adapter, mock Telegram, Stripe test mode.

Variable Default Meaning
WIRETAP_PROVIDER polling Which adapter the ingester uses: polling | yellowstone | helius. See Providers
WIRETAP_RPC_URL http://127.0.0.1:8899 RPC endpoint for the polling adapter. Any Solana JSON-RPC endpoint works (devnet: https://api.devnet.solana.com)
WIRETAP_PROGRAMS (empty) Comma-separated program IDs to track — the CLI registers these for you
WIRETAP_RPC_BUDGET_RPS 8 Polling budget: max JSON-RPC requests/second the adapter will spend
WIRETAP_POLL_INTERVAL_MS 2000 How often (ms) the ingester polls each tracked program — raise (e.g. 10000) to cut RPC/credit usage
WIRETAP_COLD_START_MAX_SIGS 300 Max signatures hydrated per poll cycle (bounds the cold-start backfill + each resume chunk)
WIRETAP_MAINNET_RPC (falls back to public) RPC for the daily leaderboard block sampler (getBlock); a paid/Helius URL is recommended since the free endpoint restricts getBlock
YELLOWSTONE_ENDPOINT (empty) Yellowstone gRPC endpoint (paid providers: Triton, Helius, Shyft…)
YELLOWSTONE_X_TOKEN (empty) Yellowstone auth token
HELIUS_API_KEY (empty) Helius enhanced WebSocket key
Variable Default Meaning
CLICKHOUSE_URL http://127.0.0.1:8123 ClickHouse HTTP endpoint
CLICKHOUSE_DB wiretap Database name (migrations create it)
CLICKHOUSE_USER default ClickHouse user
CLICKHOUSE_PASSWORD (empty) ClickHouse password
WIRETAP_DB_PATH ./wiretap.sqlite SQLite metadata store: accounts, API keys, program registry, subscription state
Variable Default Meaning
API_PORT 8790 API listen port
API_SESSION_SECRET (generated in dev) Signs session cookies + deep-link tokens. REQUIRED in hosted mode; dev default is generated at first boot and stored next to the SQLite db
TELEGRAM_OIDC_CLIENT_ID (empty) “Log in with Telegram” — the PRIMARY web sign-in (Telegram OpenID Connect). Client ID is the bot’s numeric id (the part before the colon in the bot token). Both this and the secret empty ⇒ /auth/telegram returns “not configured” and GitHub/dev-login stay available
TELEGRAM_OIDC_CLIENT_SECRET (empty) Client Secret issued by @BotFather → Bot Settings → Web Login (register the allowed URLs there: your site + <api-base>/auth/telegram/callback). A web Telegram login resolves to the same account as that user’s bot /start
GITHUB_OAUTH_CLIENT_ID (empty) GitHub OAuth — the secondary account-lite login
GITHUB_OAUTH_CLIENT_SECRET (empty)
WIRETAP_DEV 1 1 enables the dev-login + /v1/dev/bootstrap bypass (zero-config self-host). Set 0 on a public deploy and configure GitHub OAuth above, or anyone can mint an account
WIRETAP_WHY_RPC (falls back to public) RPC for the free public /why live-lookup fallback (decode any pasted signature)
Variable Default Meaning
TELEGRAM_BOT_TOKEN (empty) Empty ⇒ mock transport: bot logic runs fully, messages are logged/captured instead of sent. Real token in ~5 minutes
Variable Default Meaning
STRIPE_SECRET_KEY (empty) Empty or test key ⇒ test mode; the flat subscription plans and 14-day trial all work with test keys
STRIPE_WEBHOOK_SECRET (empty) Webhook signature verification
STRIPE_METER_EVENT_NAME wiretap_events Legacy usage-meter event name; unused under flat per-program billing (billing is subscription-based, not metered)
Variable Default Meaning
MCP_HTTP_PORT 8791 HTTP transport port for the MCP server

All optional. Every surface is a strict no-op when its key is empty (the default), so the stack runs clean with analytics off. A slow, failing, or absent PostHog never blocks a page render, an API request, or a bot reply. There are two distinct keys:

Variable Default Meaning
PUBLIC_POSTHOG_KEY (empty) Public client key (phc_…) — safe to ship to the browser. Baked into the web + docs static bundles at build time (Astro inlines PUBLIC_*), wired as a compose build arg on the web service. Enables pageview + autocapture (visits, users, funnels). Empty ⇒ PostHog is never loaded in the browser. Do-Not-Track is respected. No cookie-consent banner is shown yet (a deferred legal decision)
PUBLIC_POSTHOG_HOST https://us.i.posthog.com Host for the browser bundle
POSTHOG_API_KEY (empty) Server capture key — used by the api + bot services (posthog-node). Stays server-side; never sent to a browser. Server events: account_created, program_watched, api_key_minted, why_lookup, command_used, alert_sent. Empty ⇒ strict no-op. For this project, set it to the same phc_ key as PUBLIC_POSTHOG_KEY (a phc_ ingest key works for capture)
POSTHOG_HOST https://us.i.posthog.com Host for the server SDK

The operator sets all of these to the WireTap PostHog project’s phc_ key/host. In compose, PUBLIC_POSTHOG_KEY is a build arg (baked at image build) while POSTHOG_API_KEY is a runtime env on the api + bot services — set both in .env before docker compose … build.