Files
k 54884f3e24 KOL feeds: fix dead/blocked sources, drop stale feeds (29→25)
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>
2026-06-09 22:55:16 +08:00

99 lines
5.7 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ── 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 (0100).
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=