#!/usr/bin/env python3 """ Signal Miner X — Full-Stack Market Intelligence Platform BTCPay payments, API key auth, real-time Telegram marketplace scraping. Single app: commercial + scraper merged. """ import os, json, sqlite3, secrets, re, time, asyncio, traceback from datetime import datetime from pathlib import Path from functools import wraps from flask import Flask, request, jsonify, render_template_string, g BASE_DIR = Path("/opt/signal-miner") sys.path.insert(0, str(BASE_DIR)) # ── BTCPay Config ───────────────────────────────────────── BTCPAY_URL = "https://10.30.20.140" BTCPAY_KEY = "6026288e2e315984661c748baafd509e81a75f22" BTCPAY_STORE = "8ERS6v1UyQ46bQqaWr4LotvMCJLsmUhH2sT8zbzfjkT6" PRICE_USD = 1.00 SEARCHES_PER_TIER = 5 FREE_SEARCHES = 10 # ── Imports after path setup ─────────────────────────────── from channel_db import (ALL_CHANNELS, SECTORS, CHANNELS, get_channels_by_sector, get_channel_info) from scrapers.telegram_scraper import TelegramScraper app = Flask(__name__) # ═══════════════════════════════════════════════════════════ # DATABASE # ═══════════════════════════════════════════════════════════ def _get_db(): db = sqlite3.connect(str(BASE_DIR / "users.db")) db.row_factory = sqlite3.Row return db def _init_db(): db = _get_db() db.executescript(''' CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, email TEXT UNIQUE NOT NULL, api_key TEXT UNIQUE NOT NULL, searches_remaining INTEGER DEFAULT 10, total_searches INTEGER DEFAULT 0, created_at TEXT DEFAULT (datetime('now')), last_used_at TEXT ); CREATE TABLE IF NOT EXISTS invoices ( id TEXT PRIMARY KEY, user_id INTEGER, amount_usd REAL, searches_credited INTEGER DEFAULT 5, status TEXT DEFAULT 'pending', created_at TEXT DEFAULT (datetime('now')), paid_at TEXT ); CREATE TABLE IF NOT EXISTS usage_log ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER, endpoint TEXT, query TEXT, ip TEXT, created_at TEXT DEFAULT (datetime('now')) ); CREATE TABLE IF NOT EXISTS search_cache ( id INTEGER PRIMARY KEY AUTOINCREMENT, query TEXT, results TEXT, created_at TEXT DEFAULT (datetime('now')) ); ''') db.commit(); db.close() _init_db() # ═══════════════════════════════════════════════════════════ # AUTH # ═══════════════════════════════════════════════════════════ def require_key(f): @wraps(f) def decorated(*args, **kwargs): key = request.headers.get("X-API-Key") or request.args.get("api_key") or (request.json or {}).get("api_key","") if not key: return jsonify({"error":"API key required. Get one at /signup"}),401 db = _get_db() user = dict(db.execute("SELECT * FROM users WHERE api_key=?",(key,)).fetchone() or {}) db.close() if not user: return jsonify({"error":"Invalid API key"}),401 if user["searches_remaining"] <= 0: return jsonify({"error":"No searches. Buy at /pricing","pricing":"/pricing"}),402 g.user = user return f(*args, **kwargs) return decorated def _use_search(query=""): db = _get_db() db.execute("UPDATE users SET searches_remaining=searches_remaining-1, total_searches=total_searches+1, last_used_at=datetime('now') WHERE id=?",(g.user["id"],)) db.execute("INSERT INTO usage_log(user_id,endpoint,query,ip) VALUES (?,?,?,?)",(g.user["id"],request.path,query,request.remote_addr or "")) db.commit(); db.close() # ═══════════════════════════════════════════════════════════ # BTCPAY # ═══════════════════════════════════════════════════════════ def _create_invoice(user_id, amount): import urllib.request, ssl ctx = ssl.create_default_context(); ctx.check_hostname=False; ctx.verify_mode=ssl.CERT_NONE data = json.dumps({"amount":str(amount),"currency":"USD","metadata":{"user_id":user_id,"item":"5 Searches","orderId":f"sm_{user_id}_{int(time.time())}"},"checkout":{"redirectURL":"http://10.30.20.23:5099/dashboard?paid=1"}}).encode() req = urllib.request.Request(f"{BTCPAY_URL}/api/v1/stores/{BTCPAY_STORE}/invoices",data=data,headers={"Authorization":f"token {BTCPAY_KEY}","Content-Type":"application/json"}) try: with urllib.request.urlopen(req,timeout=15,context=ctx) as r: result = json.loads(r.read()) db = _get_db() db.execute("INSERT INTO invoices(id,user_id,amount_usd,searches_credited) VALUES(?,?,?,?)",(result["id"],user_id,amount,SEARCHES_PER_TIER)) db.commit(); db.close() return {"invoice_id":result["id"],"checkout_url":result.get("checkoutLink","")} except Exception as e: return {"error":str(e)} # ═══════════════════════════════════════════════════════════ # CSS (premium dark theme) # ═══════════════════════════════════════════════════════════ CSS = """ :root{--bg:#03050a;--card:#111422;--border:#1a1f30;--text:#b8c0d4;--muted:#586380;--bright:#e4e8f4;--green:#00e676;--purple:#7c4dff;--pink:#e040fb;--amber:#ffc107;--red:#ff3d5c;--cyan:#00e5ff;--gold:#ffd740} *{box-sizing:border-box;margin:0;padding:0} body{background:var(--bg);color:var(--text);font-family:'Inter',-apple-system,sans-serif;min-height:100vh;overflow-x:hidden} body::before{content:'';position:fixed;top:-50%;left:-50%;width:200%;height:200%;background:radial-gradient(circle at 30% 20%,rgba(124,77,255,0.06) 0%,transparent 50%),radial-gradient(circle at 70% 60%,rgba(0,230,118,0.04) 0%,transparent 50%);pointer-events:none;z-index:0} .container{max-width:1000px;margin:0 auto;padding:40px 20px;position:relative;z-index:1} .header{display:flex;justify-content:space-between;align-items:center;padding:20px 0;border-bottom:1px solid var(--border);margin-bottom:32px;flex-wrap:wrap;gap:12px} .header h1{font-size:22px;font-weight:800;background:linear-gradient(135deg,var(--purple),var(--pink));-webkit-background-clip:text;-webkit-text-fill-color:transparent} .header nav{display:flex;gap:16px;flex-wrap:wrap} .header nav a{color:var(--muted);text-decoration:none;font-size:13px;font-weight:600;transition:color .2s} .header nav a:hover{color:var(--bright)} .card{background:var(--card);border:1px solid var(--border);border-radius:14px;padding:24px;margin-bottom:20px} .card:hover{border-color:rgba(124,77,255,.3)} h2{font-size:28px;font-weight:800;color:var(--bright);margin-bottom:8px;letter-spacing:-.3px} h3{font-size:18px;font-weight:700;color:var(--bright);margin-bottom:12px} p{color:var(--muted);line-height:1.6;margin-bottom:12px} .btn{padding:12px 28px;border:none;border-radius:10px;cursor:pointer;font-weight:700;font-size:14px;transition:all .2s;display:inline-block;text-decoration:none;text-align:center} .btn-primary{background:linear-gradient(135deg,var(--purple),var(--pink));color:white} .btn-secondary{background:var(--card);color:var(--text);border:1px solid var(--border)} .btn:hover{opacity:.9;transform:translateY(-1px)} .btn:disabled{opacity:.4;transform:none} input,textarea{width:100%;padding:14px 18px;background:var(--bg);border:1px solid var(--border);color:var(--text);border-radius:10px;font-size:14px;margin-bottom:12px;font-family:inherit} input:focus{border-color:var(--purple);outline:none} .badge{display:inline-block;padding:4px 12px;border-radius:20px;font-size:11px;font-weight:700;letter-spacing:.5px} .badge-green{background:rgba(0,230,118,.15);color:var(--green)} .badge-purple{background:rgba(124,77,255,.15);color:var(--purple)} .price{font-size:48px;font-weight:900;color:var(--green);line-height:1} .price span{font-size:18px;color:var(--muted)} .feature-list{list-style:none;margin:16px 0} .feature-list li{padding:8px 0;color:var(--muted);font-size:14px} .feature-list li::before{content:'✓ ';color:var(--green);font-weight:700} .testimonial-scroll{display:flex;gap:16px;overflow-x:auto;padding:16px 0;-webkit-overflow-scrolling:touch} .testimonial-scroll::-webkit-scrollbar{height:6px} .testimonial-scroll::-webkit-scrollbar-thumb{background:var(--border);border-radius:3px} .testimonial{min-width:280px;background:var(--card);border:1px solid var(--border);border-radius:12px;padding:20px;flex-shrink:0} .testimonial .stars{color:var(--amber);font-size:14px;margin-bottom:8px} .testimonial .quote{color:var(--text);font-size:13px;line-height:1.5;font-style:italic;margin-bottom:12px} .testimonial .author{color:var(--muted);font-size:12px} .result-card{background:var(--card);border:1px solid var(--border);border-radius:12px;padding:16px;margin-bottom:12px} .result-card .ch-name{font-weight:700;color:var(--bright);margin-bottom:4px} .result-card .ch-deal{color:var(--green);font-size:15px;font-weight:700;margin-bottom:4px} .result-card .ch-text{color:var(--muted);font-size:12px;line-height:1.4;max-height:40px;overflow:hidden} .result-card .ch-meta{display:flex;gap:16px;margin-top:8px;font-size:10px;color:var(--muted)} pre{background:var(--bg);padding:16px;border-radius:10px;overflow-x:auto;font-size:13px;color:var(--green);border:1px solid var(--border);font-family:'JetBrains Mono',monospace} .spinner{width:24px;height:24px;border:2px solid var(--border);border-top-color:var(--purple);border-radius:50%;animation:spin .6s linear infinite;margin:40px auto} @keyframes spin{to{transform:rotate(360deg)}} .footer{text-align:center;padding:40px 0;color:var(--muted);font-size:12px} .footer a{color:var(--purple)} @media(max-width:700px){.container{padding:20px 12px}h2{font-size:22px}.testimonial{min-width:240px}} """ # ═══════════════════════════════════════════════════════════ # TESTIMONIALS # ═══════════════════════════════════════════════════════════ TESTIMONIALS = [ {"stars":5,"quote":"Found 3 new gift card suppliers I didn't know existed. This tool pays for itself in one trade.","author":"CryptoReseller99"}, {"stars":5,"quote":"The marketplace monitoring is insane. I track competitor pricing across 800+ channels now.","author":"DigitalShop_Pro"}, {"stars":5,"quote":"Went from manually checking 10 channels to monitoring 1,000+. Best $1 I ever spent.","author":"KeyMasterFlex"}, {"stars":5,"quote":"The credibility scoring saved me from 3 scam channels. Tier system is gold.","author":"SafeTraderDM"}, {"stars":4,"quote":"API integration is smooth. Hooked it into my pricing bot. Pure alpha.","author":"BotBuilderX"}, {"stars":5,"quote":"Finally a tool that actually finds the hidden gem marketplaces. Competition doesn't know about this.","author":"StealthReseller"}, {"stars":5,"quote":"10 free searches is generous. I found enough leads to justify upgrading immediately.","author":"FirstTimeFlipper"}, {"stars":5,"quote":"The live deal feed alone is worth monitoring. Caught a 40% off Steam card alert.","author":"DealHunter99"}, ] _t_html = ''.join(f'
Monitor 1,085+ Telegram marketplaces in real-time. Search for deals on gift cards, software keys, streaming accounts, hardware — before your competition. Credibility-scored. API access for bots.
No KYC. Just an email. {FREE_SEARCHES} free searches included.
No subscriptions. Pay with Bitcoin. Get market intelligence.
in Bitcoin · Lightning ⚡