Files
trumpsignal-backend/.env.example
T
k fd2e61dc48 feat(x): viral live-prediction X auto-poster for Trump signals
When Trump posts an actionable buy/short signal, instantly tweet the call
(entry/direction, hard time window, "ratio me" hook), then post a result
follow-up X_FOLLOWUP_MINUTES later reporting the realised 15-min move plus
a recent hit-rate brag with the site link.

- New app/services/x_poster.py: OAuth 1.0a signed (stdlib hmac, no new dep,
  httpx reused). Fire-and-forget, fully degradable — no-op unless X creds +
  x_enabled. Dry-run logs tweet text. In-memory UTC-daily cap. 280-char hard
  cap on all templates (no Premium).
- Gated to source=truth buy/short above x_min_confidence; scanner signals
  excluded (don't fit the "Trump just posted" format).
- Hooked next to notify_signal in /signals/ingest + both Trump pollers
  (dedup via unique external_id → single tweet per post).
- config.py + .env.example: X_API_KEY/SECRET, X_ACCESS_TOKEN/SECRET,
  X_ENABLED, X_MIN_CONFIDENCE, X_DAILY_CAP, X_FOLLOWUP_MINUTES, X_LINK_URL.

72 tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 23:34:20 +08:00

93 lines
5.3 KiB
Bash
Raw 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=