54884f3e24
Feed-health pass over KOL_FEEDS: - raoulpal: stale Substack (last 2024-05) → Real Vision podcast feed - dampedspring: paywalled (0 entries) → free "Damped Spring 101" Substack - unchained: Cloudflare 403 → canonical Megaphone podcast feed - lynalden: Cloudflare 202 → FeedBurner mirror - glassnode: recovered via httpx http2=True (was 403 on HTTP/1.1) - browser User-Agent + Accept headers on feed fetch - removed dead feeds with no active replacement: placeholder, dragonfly, niccarter, eugene - pin h2==4.3.0 (required by http2=True) All 25 remaining feeds verified fetching real body content; newest post per feed ≤88d. Bundles in-flight KOL-module work already in the working tree (kol_x ingest, migration 027, tests). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
99 lines
5.7 KiB
Bash
99 lines
5.7 KiB
Bash
# ── Database ─────────────────────────────────────────────────────────────────
|
||
# Docker Compose reads SERVICE_* values and injects DATABASE_URL into the API
|
||
# container. Bare-metal/systemd reads DATABASE_URL directly.
|
||
SERVICE_USER_POSTGRES=trumpsignal
|
||
SERVICE_PASSWORD_POSTGRES=change_me_in_production
|
||
DATABASE_URL=postgresql+asyncpg://trumpsignal:change_me_in_production@localhost:5432/trumpsignal
|
||
|
||
# ── CORS / Frontend ──────────────────────────────────────────────────────────
|
||
# Your frontend origin — no trailing slash. Used as the only allowed CORS
|
||
# origin in production. Multiple origins not currently supported here; if
|
||
# you need staging + prod simultaneously, edit app/main.py allowed_origins.
|
||
FRONTEND_URL=https://yourdomain.com
|
||
|
||
# ── Encryption ───────────────────────────────────────────────────────────────
|
||
# KEK for envelope-encrypting HL API keys in DB.
|
||
# Generate: openssl rand -hex 32
|
||
# WARNING: rotating this invalidates all stored keys.
|
||
ENCRYPTION_KEY=
|
||
|
||
# ── AI provider (System 1 / Trump analysis only) ────────────────────────────
|
||
# OpenAI-compatible endpoint. DeepSeek used in dev.
|
||
AI_API_KEY=
|
||
AI_BASE_URL=https://api.deepseek.com/v1
|
||
AI_MODEL=deepseek-v4-pro # batch / reanalysis (quality)
|
||
AI_LIVE_MODEL=deepseek-v4-flash # live post analysis (latency)
|
||
# Optional: native Anthropic key takes priority over AI_API_KEY if set.
|
||
# Used for KOL analysis (long-form essays) where reasoning > latency.
|
||
ANTHROPIC_API_KEY=
|
||
|
||
# ── Signal ingest (System 2 scanners + external modules) ─────────────────────
|
||
# Shared secret for POST /api/signals/ingest. Empty = endpoint disabled
|
||
# (fail-closed). Generate: openssl rand -hex 32
|
||
INGEST_API_KEY=
|
||
|
||
# ── On-chain data providers ──────────────────────────────────────────────────
|
||
# Glassnode — used by the BTC bottom-reversal scanner (MVRV-Z + STH-SOPR).
|
||
# Free tier covers our query volume. Empty = scanner skips with a warning.
|
||
# Sign up: https://glassnode.com → Account → API
|
||
GLASSNODE_API_KEY=
|
||
|
||
# Etherscan — used by KOL A-tier on-chain poller to read ERC-20 balances for
|
||
# the wallets in `kol_wallets`. Free tier (5 req/s) is plenty for daily polls.
|
||
# Empty = KOL on-chain snapshot pipeline skips Ethereum wallets (HL perps
|
||
# still polled via Hyperliquid's free public API).
|
||
# Sign up: https://etherscan.io/register → My API Keys
|
||
ETHERSCAN_API_KEY=
|
||
|
||
# ── Telegram push alerts ─────────────────────────────────────────────────────
|
||
# Bot token from @BotFather (https://t.me/BotFather → /newbot). Free.
|
||
# Empty = Telegram alerts disabled (bot loop skipped, notify_signal is a
|
||
# no-op, /api/telegram endpoints return 503).
|
||
TELEGRAM_BOT_TOKEN=
|
||
# Bot username (no @) — used by the Settings UI to render the deep link
|
||
# t.me/<username>?start=<code>. Example: trumpalpha_bot
|
||
TELEGRAM_BOT_USERNAME=
|
||
|
||
# ── Hyperliquid (server-side fallback only — most ops use user-provided keys) ─
|
||
# These are ONLY for server-controlled signals (e.g. a dev/admin trade) — the
|
||
# user-facing bot reads each subscriber's encrypted key from the DB instead.
|
||
# Leave empty in production unless you're running a single-account demo.
|
||
HL_API_PRIVATE_KEY=
|
||
HL_ACCOUNT_ADDRESS=
|
||
HL_LEVERAGE=3
|
||
HL_MAINNET=true
|
||
|
||
# ── Runtime ──────────────────────────────────────────────────────────────────
|
||
# development | production
|
||
# development → enables /api/dev/* endpoints (paper-mode toggle, etc.) AND
|
||
# auto-runs create_all() on startup (Alembic bypass — DEV ONLY).
|
||
# production → both are off; schema strictly Alembic-managed.
|
||
ENVIRONMENT=production
|
||
|
||
# ── X (Twitter) auto-poster ───────────────────────────────────────────────────
|
||
# Viral "live prediction" tweets: when Trump posts an actionable signal, the bot
|
||
# tweets the call instantly, then posts a result follow-up X_FOLLOWUP_MINUTES later.
|
||
# OAuth 1.0a User Context. From developer.x.com → your App → "Keys and tokens".
|
||
# ⚠️ App permissions MUST be "Read and Write" — then REGENERATE the access token.
|
||
# ⚠️ Do NOT use Bearer Token / Client ID / Client Secret (those are read/OAuth2).
|
||
X_API_KEY=
|
||
X_API_SECRET=
|
||
X_ACCESS_TOKEN=
|
||
X_ACCESS_SECRET=
|
||
# Master switch. false = dry-run (logs tweet text, sends nothing) even with keys set.
|
||
X_ENABLED=false
|
||
# Only tweet when ai_confidence >= this (0–100).
|
||
X_MIN_CONFIDENCE=60
|
||
# Hard daily tweet cap (initial + follow-ups), resets at UTC midnight.
|
||
X_DAILY_CAP=40
|
||
# Minutes after the prediction tweet to post the result follow-up.
|
||
X_FOLLOWUP_MINUTES=15
|
||
# Public URL appended to the follow-up tweet (defaults to FRONTEND_URL if empty).
|
||
X_LINK_URL=
|
||
|
||
# ── X (Twitter) READ — KOL tweet ingestion (kol_x.py) ────────────────────────
|
||
# twitterapi.io managed-scraper key (x-api-key). Reads other people's tweets —
|
||
# unrelated to the OAuth poster creds above. Empty = X ingestion disabled.
|
||
# Get a pay-as-you-go key at twitterapi.io (~$0.15 / 1k tweets).
|
||
TWITTERAPI_IO_KEY=
|