rmi-backend/app/telegram_bot/config.py
opencode c762564d40 style(rmi-backend): complete lint cleanup — 1175→0 ruff errors
- Fix 71 invalid-syntax files (class-body newline-broken assignments)
- Add from/None chain to 307 B904 raise-without-from sites
- Add B008 ignore to ruff.toml (already in pyproject.toml)
- Noqa F401 on __init__.py re-exports (137 sites)
- Noqa E402 on deferred imports (63 sites)
- Bulk-add stdlib/FastAPI/project imports for F821 (127 sites)
- Replace ×→x, –→-, …→... in docstrings (4093 chars)
- Manual refactor of 5 SIM103/SIM116 patterns

Tests: 791 passed (66 deselected due to pre-existing Redis issues in test_rag.py)
Co-authored-by: opencode <opencode@rugmunch.io>
2026-07-06 15:43:20 +02:00

454 lines
18 KiB
Python
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.

#!/usr/bin/env python3
"""
CryptoRugMunch Bot - Configuration
===================================
Tiers, channels, API endpoints, DEX ref links, and constants.
"""
import os
# ══════════════════════════════════════════════
# BOT
# ══════════════════════════════════════════════
BOT_TOKEN = os.getenv("RUGMUNCH_BOT_TOKEN", "")
OWNER_IDS = {int(x.strip()) for x in os.getenv("TELEGRAM_ALLOWED_USERS", "7075336557").split(",") if x.strip()}
BOT_USERNAME = "RugMunchBot"
# ══════════════════════════════════════════════
# BRANDING & SOCIAL
# ══════════════════════════════════════════════
WEBSITE_URL = "https://rugmunch.io"
WEB_APP_URL = f"{WEBSITE_URL}/scanner"
TWITTER_URL = "https://x.com/RugMunch"
TELEGRAM_CHANNEL = "https://t.me/RugMunchAlerts"
TELEGRAM_GROUP = "https://t.me/RugMunchChat"
SUPPORT_EMAIL = "biz@rugmunch.io"
ENTERPRISE_CONTACT = "biz@rugmunch.io"
SOCIAL_LINKS = {
"website": {"emoji": "🌐", "name": "RugMunch.io", "url": WEBSITE_URL},
"twitter": {"emoji": "𝕏", "name": "Twitter/X", "url": TWITTER_URL}, # noqa: RUF001
"channel": {"emoji": "📢", "name": "Alerts Channel", "url": TELEGRAM_CHANNEL},
"group": {"emoji": "💬", "name": "Community Chat", "url": TELEGRAM_GROUP},
}
# Bot profile (set via BotFather API on startup)
BOT_DESCRIPTION = (
"🛡️ RugMunch Intelligence - The Bloomberg Terminal of Shitcoins\n\n"
"Scan any token across 77+ chains for honeypots, rug pulls, bundles, "
"fake volume, and dev wallet history. AI-powered risk scoring with "
"real-time alerts.\n\n"
"🔍 Multi-chain token scanning\n"
"👛 Wallet forensics & smart money tracking\n"
"📊 Technical analysis & trending tokens\n"
"🚨 Real-time scam detection & alerts\n"
"📚 Free crypto scam education\n\n"
"🌐 rugmunch.io"
)
BOT_SHORT_DESCRIPTION = "🛡️ Crypto scam detection & token intelligence across 77+ chains. Free tier available."
# ══════════════════════════════════════════════
# API ENDPOINTS
# ══════════════════════════════════════════════
BACKEND_URL = os.getenv("RMI_BACKEND_URL", "http://localhost:8000")
DATABUS_URL = f"{BACKEND_URL}/api/v1/databus"
RAG_URL = f"{BACKEND_URL}/api/v1/rag"
# External APIs
DEXSCREENER = "https://api.dexscreener.com/latest/dex"
COINGECKO = "https://api.coingecko.com/api/v3"
DEFILLAMA = "https://api.llama.fi"
GOPLUS = "https://api.gopluslabs.com/api/v1"
HONEYPOT = "https://api.honeypot.is/v2"
BUBBLE_MAPS = "https://api.bubblemaps.io"
DEXTOOLS = "https://public-api.dextools.io/trial/v2"
# ══════════════════════════════════════════════
# SUBSCRIPTION TIERS (Weekly Allotments)
# ══════════════════════════════════════════════
# Weekly model: resets every Monday 00:00 UTC.
# Prevents day-one dump abuse and smooths API load.
TIERS = {
"free": {
"name": "Free",
"emoji": "🆓",
"scans_per_week": 25,
"ai_msgs_per_week": 15,
"price_monthly": 0,
"features": [
"25 scans/week",
"15 AI questions/week",
"Basic risk score",
"Contract safety check",
"Liquidity overview",
"Top 10 holders",
"Community access",
],
},
"scout": {
"name": "Scout",
"emoji": "🔍",
"scans_per_week": 150,
"ai_msgs_per_week": 75,
"price_monthly": 29.99,
"price_stars": 1500,
"features": [
"150 scans/week",
"75 AI questions/week",
"Advanced risk scoring",
"Bundle detection",
"Fake volume detection",
"Dev wallet finder",
"Holder trend analysis",
"Smart money alerts",
"Watchlist (10 tokens)",
"Export reports",
],
},
"hunter": {
"name": "Hunter",
"emoji": "🎯",
"scans_per_week": 400,
"ai_msgs_per_week": 250,
"price_monthly": 49.99,
"price_stars": 2500,
"features": [
"400 scans/week",
"250 AI questions/week",
"Everything in Scout, plus:",
"Full wallet forensics",
"First buyer analysis",
"Exchange flow tracking",
"Fresh wallet detection",
"Shill detection",
"Social sentiment scan",
"Watchlist (50 tokens)",
"Real-time alerts",
"TA chart generation",
],
},
"pro": {
"name": "Pro",
"emoji": "👑",
"scans_per_week": 1000,
"ai_msgs_per_week": 500,
"price_monthly": 99.99,
"price_stars": 5000,
"features": [
"1,000 scans/week",
"500 AI questions/week",
"Everything in Hunter, plus:",
"Smart money watch (live)",
"Cross-chain tracking",
"Custom alert rules",
"API access",
"Priority support",
"Early feature access",
"Unlimited watchlists",
"Multi-wallet tracking",
"White-label reports",
],
},
}
# ══════════════════════════════════════════════
# USER REFERRAL LINKS (Add your own!)
# ══════════════════════════════════════════════
# These are shown in scan reports and on the website.
USER_REF_LINKS = {
# "binance": {"name": "Binance", "url": "https://www.binance.com/en/register?ref=YOUR_CODE", "emoji": "🟡"},
# "bybit": {"name": "Bybit", "url": "https://www.bybit.com/invite?ref=YOUR_CODE", "emoji": "🟠"},
# "okx": {"name": "OKX", "url": "https://www.okx.com/join/YOUR_CODE", "emoji": "⚫"},
# "coinbase": {"name": "Coinbase", "url": "https://coinbase.com/join/YOUR_CODE", "emoji": "🔵"},
# "kucoin": {"name": "KuCoin", "url": "https://www.kucoin.com/r/YOUR_CODE", "emoji": "🟢"},
# "gate": {"name": "Gate.io", "url": "https://www.gate.io/ref/YOUR_CODE", "emoji": "🔷"},
# "mexc": {"name": "MEXC", "url": "https://www.mexc.com/register?inviteCode=YOUR_CODE", "emoji": "🔶"},
# "bitget": {"name": "Bitget", "url": "https://www.bitget.com/referral?clacCode=YOUR_CODE", "emoji": "🌊"},
}
# ══════════════════════════════════════════════
# TOP-UP PACKS (Buy extra when you run out)
# ══════════════════════════════════════════════
# One-time purchases via Telegram Stars. No expiry -
# top-up balance carries over forever until used.
TOP_UP_PACKS = {
"scans_10": {
"name": "10 Extra Scans",
"emoji": "🔬",
"type": "scans",
"amount": 10,
"stars": 75,
},
"scans_50": {
"name": "50 Extra Scans",
"emoji": "🔬",
"type": "scans",
"amount": 50,
"stars": 300,
},
"scans_100": {
"name": "100 Extra Scans",
"emoji": "🔬",
"type": "scans",
"amount": 100,
"stars": 500,
},
"ai_10": {
"name": "10 Extra AI Messages",
"emoji": "🤖",
"type": "ai_msgs",
"amount": 10,
"stars": 100,
},
"ai_50": {
"name": "50 Extra AI Messages",
"emoji": "🤖",
"type": "ai_msgs",
"amount": 50,
"stars": 400,
},
"ai_100": {
"name": "100 Extra AI Messages",
"emoji": "🤖",
"type": "ai_msgs",
"amount": 100,
"stars": 700,
},
}
# ══════════════════════════════════════════════
# SCAN PACKS (One-time deep analysis purchases)
# ══════════════════════════════════════════════
SCAN_PACKS = {
"deep_scan": {
"name": "🔬 Deep Token Scan",
"description": "Complete forensic analysis of ONE token",
"includes": [
"Price history",
"Holder bubble map",
"Wallet clusters",
"Scam indicators",
"AI prediction",
"Dev history",
],
"stars": 250,
},
"wallet_forensic": {
"name": "🕵️ Wallet Forensic Report",
"description": "Full wallet investigation - P&L, connections, history",
"includes": [
"Transaction history",
"Counterparty analysis",
"P&L breakdown",
"Bundle links",
"Scam DB check",
],
"stars": 400,
},
"bundle_investigation": {
"name": "🕸️ Bundle Investigation",
"description": "Full cluster analysis - find every connected wallet",
"includes": [
"Funding source map",
"Timing correlation",
"Wash trade detection",
"Holder overlap",
"Exit strategy clues",
],
"stars": 500,
},
}
# ══════════════════════════════════════════════
# DEX REFERRAL LINKS
# ══════════════════════════════════════════════
# These generate revenue when users trade through our links.
# Format: {platform: {url_template, chains, emoji, description}}
DEX_REF_LINKS = {
"jupiter": {
"name": "Jupiter",
"emoji": "🪐",
"url": "https://jup.ag/swap/SOL-{token}?ref=rugmunch",
"chains": ["solana"],
"description": "Best Solana DEX aggregator",
},
"photon": {
"name": "Photon",
"emoji": "",
"url": "https://photon-sol.tinyastro.io/en/lp/{token}?handle=rugmunch",
"chains": ["solana", "ethereum", "base"],
"description": "Fast Solana trading terminal",
},
"bullx": {
"name": "BullX",
"emoji": "🐂",
"url": "https://neo.bullx.io/terminal?chain={chain}&address={token}&ref=rugmunch",
"chains": ["solana", "ethereum", "base", "bsc", "arbitrum"],
"description": "Multi-chain trading bot",
},
"gmgn": {
"name": "GMGN.ai",
"emoji": "📊",
"url": "https://gmgn.ai/sol/token/{token}?ref=rugmunch",
"chains": ["solana", "ethereum", "base"],
"description": "Smart money tracking + trading",
},
"birdeye": {
"name": "Birdeye",
"emoji": "🦅",
"url": "https://birdeye.so/token/{token}?ref=rugmunch",
"chains": ["solana", "ethereum", "base", "bsc", "arbitrum"],
"description": "Token analytics & charts",
},
"oneinch": {
"name": "1inch",
"emoji": "🦄",
"url": "https://app.1inch.io/#/{chain_id}/simple/swap/ETH/{token}?ref=rugmunch",
"chains": ["ethereum", "base", "arbitrum", "bsc", "polygon", "avalanche"],
"description": "Best EVM DEX aggregator",
},
"pancakeswap": {
"name": "PancakeSwap",
"emoji": "🥞",
"url": "https://pancakeswap.finance/swap?inputCurrency=BNB&outputCurrency={token}&ref=rugmunch",
"chains": ["bsc", "ethereum", "arbitrum", "base"],
"description": "BSC's #1 DEX",
},
}
# Chain ID mapping for 1inch
CHAIN_IDS = {
"ethereum": 1,
"bsc": 56,
"polygon": 137,
"arbitrum": 42161,
"avalanche": 43114,
"optimism": 10,
"base": 8453,
"fantom": 250,
}
# ══════════════════════════════════════════════
# CHANNELS
# ══════════════════════════════════════════════
CHANNELS = {
"main": "-1002056885429",
"news": "-1003982391578",
"alerts": "-1003818352164",
"alpha": "-1003762675055",
"scans": "-1003937506770",
}
# ══════════════════════════════════════════════
# RISK VISUALIZATION
# ══════════════════════════════════════════════
RISK_COLORS = {
"critical": "🔴",
"high": "🟠",
"medium": "🟡",
"low": "🟢",
"safe": "",
"unknown": "",
}
def risk_bar(score: float, length: int = 10) -> str:
"""Generate a visual risk bar (0-100 scale)."""
filled = int((score / 100) * length)
if score >= 80:
return "🔴" * filled + "" * (length - filled) + f" {score}% DANGER"
elif score >= 60:
return "🟠" * filled + "" * (length - filled) + f" {score}% RISKY"
elif score >= 40:
return "🟡" * filled + "" * (length - filled) + f" {score}% CAUTION"
elif score >= 20:
return "🟢" * filled + "" * (length - filled) + f" {score}% LOW"
else:
return "" * filled + "" * (length - filled) + f" {score}% SAFE"
def threat_indicator(label: str, found: bool) -> str:
return f"{'🔴' if found else ''} {label}"
# ══════════════════════════════════════════════
# FORMATTING HELPERS
# ══════════════════════════════════════════════
def fmt_number(n) -> str:
"""Format large numbers: 1.2M, 450K, etc."""
if n is None:
return "N/A"
try:
n = float(n)
except (ValueError, TypeError):
return str(n)
if n >= 1e9:
return f"${n / 1e9:.2f}B"
elif n >= 1e6:
return f"${n / 1e6:.2f}M"
elif n >= 1e3:
return f"${n / 1e3:.1f}K"
elif n >= 1:
return f"${n:.4f}"
elif n >= 0.01:
return f"${n:.6f}"
else:
return f"${n:.10f}"
def fmt_pct(n) -> str:
if n is None:
return "N/A"
try:
return f"{float(n):.2f}%"
except (ValueError, TypeError):
return str(n)
def fmt_chain(chain: str) -> str:
"""Return chain emoji + name."""
emojis = {
"solana": "",
"ethereum": "",
"bsc": "🔶",
"polygon": "🟣",
"arbitrum": "🔵",
"optimism": "🔴",
"base": "🔷",
"avalanche": "🔺",
"fantom": "👻",
"tron": "🔻",
"bitcoin": "",
}
return f"{emojis.get(chain.lower(), '⛓️')} {chain.capitalize()}"
# ══════════════════════════════════════════════
# SCAM SCHOOL TOPICS
# ══════════════════════════════════════════════
SCAM_SCHOOL_TOPICS = {
"honeypot": {
"title": "🍯 Honeypot Tokens",
"content": "A honeypot lets you buy but prevents you from selling. The contract has hidden code that only allows whitelisted addresses to sell.\n\n🔍 *How to spot:*\n• Can buy but can't sell\n• Only 1-2 sellers ever\n• Contract has sell restrictions\n• Honeypot.is flags it\n\n🛡️ *Protection:* Always test with a small amount first, and use /scan before buying.",
},
"rugpull": {
"title": "🏃 Rug Pulls",
"content": "Developers drain all liquidity from a token, making it worthless. Can happen via:\n\n• Removing LP tokens\n• Minting infinite tokens\n• Hidden sell functions\n• Blacklisting buyers\n\n🔍 *How to spot:*\n• Unlocked liquidity\n• Unrenounced contract\n• Dev holds >20% supply\n• New wallet, no history\n\n🛡️ *Protection:* Check /scan for LP lock status and dev wallet analysis.",
},
"bundling": {
"title": "📦 Bundle Scams",
"content": "Devs use multiple wallets to create fake organic activity. They buy from 10-50 wallets funded from the same source.\n\n🔍 *How to spot:*\n• Multiple wallets funded from same CEX/bridge\n• Identical buy amounts\n• Same-timestamp transactions\n• Wallets only hold this one token\n\n🛡️ *Protection:* Use /scan bundle detection to trace funding sources.",
},
"wash_trading": {
"title": "🔄 Wash Trading",
"content": "Artificially inflating volume by buying and selling between own wallets.\n\n🔍 *How to spot:*\n• High volume, low unique traders\n• Same wallets trading back and forth\n• Round number trade amounts\n• Volume doesn't match market cap\n\n🛡️ *Protection:* /scan checks volume authenticity.",
},
"fresh_wallets": {
"title": "🆕 Fresh Wallet Red Flags",
"content": "When most holders are brand new wallets (created <7 days ago), it often means the dev created fake holders.\n\n🔍 *How to spot:*\n• >50% wallets <7 days old\n• Wallets only hold 1 token\n• No transaction history before buying\n• Similar naming patterns\n\n🛡️ *Protection:* /scan shows wallet age distribution.",
},
"exchange_flow": {
"title": "🏦 Exchange Flow Analysis",
"content": "Tracking when large holders move tokens to exchanges signals potential dumps.\n\n🔍 *How to spot:*\n• Top holders sending to CEX wallets\n• Increasing exchange deposits\n• Unusual transfer patterns\n• Pre-scheduled dumps\n\n🛡️ *Protection:* Hunter+ tiers get real-time exchange flow alerts.",
},
}