"""Supernova — a cinematic galaxy-themed SMM reseller panel. Customers deposit Bitcoin (BTCPay) into the operator's wallet, then buy social media engagement (followers/likes/views) which the operator fulfils through the upstream SMM panel API. The operator pockets the markup. """ import os import json import time import sqlite3 import hashlib import secrets import hmac from functools import wraps import requests from flask import (Flask, request, session, redirect, url_for, render_template, jsonify, abort, flash) from panel_client import PanelClient # -------------------------------------------------------------------------- # CONFIG # -------------------------------------------------------------------------- SMM_API_KEY = os.environ.get("SMM_API_KEY", "7f8a4e57d3568202aa18efe91b48c9c8") MARKUP_PCT = float(os.environ.get("MARKUP_PCT", "100")) # 100% = 2x wholesale # BTCPay Server (Greenfield) BTCPAY_URL = os.environ.get("BTCPAY_URL", "https://10.30.20.140") BTCPAY_API_KEY = os.environ.get("BTCPAY_API_KEY", "") BTCPAY_STORE_ID = os.environ.get("BTCPAY_STORE_ID", "") BTCPAY_WEBHOOK_SECRET = os.environ.get("BTCPAY_WEBHOOK_SECRET", "") BTCPAY_PUBLIC = os.environ.get("BTCPAY_PUBLIC", "https://btcpay.thetempleofdoom.com") SITE_URL = os.environ.get("SITE_URL", "https://supernova.thetempleofdoom.com") DB_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "supernova.db") SERVICE_CACHE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "services.json") app = Flask(__name__) app.secret_key = os.environ.get("SECRET_KEY", secrets.token_hex(32)) panel = PanelClient(SMM_API_KEY) # -------------------------------------------------------------------------- # DB # -------------------------------------------------------------------------- def db(): conn = sqlite3.connect(DB_PATH) conn.row_factory = sqlite3.Row return conn def init_db(): c = db() c.executescript(""" CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, email TEXT UNIQUE NOT NULL, password_hash TEXT NOT NULL, balance REAL NOT NULL DEFAULT 0, created_at INTEGER NOT NULL ); CREATE TABLE IF NOT EXISTS orders ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER NOT NULL, service_id INTEGER NOT NULL, service_name TEXT NOT NULL, link TEXT NOT NULL, quantity INTEGER NOT NULL, cost REAL NOT NULL, panel_order_id INTEGER, status TEXT NOT NULL DEFAULT 'pending', created_at INTEGER NOT NULL ); CREATE TABLE IF NOT EXISTS deposits ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER NOT NULL, amount REAL NOT NULL, invoice_id TEXT, status TEXT NOT NULL DEFAULT 'pending', created_at INTEGER NOT NULL ); """) c.commit() c.close() # -------------------------------------------------------------------------- # Auth # -------------------------------------------------------------------------- def hash_password(pw, salt=None): salt = salt or secrets.token_hex(16) dk = hashlib.pbkdf2_hmac("sha256", pw.encode(), salt.encode(), 200_000) return f"{salt}${dk.hex()}" def verify_password(pw, stored): salt, _ = stored.split("$", 1) return hmac.compare_digest(hash_password(pw, salt), stored) def current_user(): uid = session.get("uid") if not uid: return None c = db() u = c.execute("SELECT * FROM users WHERE id=?", (uid,)).fetchone() c.close() return u def login_required(f): @wraps(f) def wrap(*a, **kw): if not current_user(): return redirect(url_for("login", next=request.path)) return f(*a, **kw) return wrap # -------------------------------------------------------------------------- # Service cache (avoid hitting the panel API every page load) # -------------------------------------------------------------------------- def get_services(force=False): if not force and os.path.exists(SERVICE_CACHE): if time.time() - os.path.getmtime(SERVICE_CACHE) < 900: # 15 min TTL with open(SERVICE_CACHE) as f: return json.load(f) svcs = panel.services() with open(SERVICE_CACHE, "w") as f: json.dump(svcs, f) return svcs def wholesale_cost(rate, quantity): return float(rate) * quantity / 1000.0 def retail_price(rate, quantity): return wholesale_cost(rate, quantity) * (1 + MARKUP_PCT / 100.0) # -------------------------------------------------------------------------- # BTCPay # -------------------------------------------------------------------------- def btcpay_headers(): return {"Authorization": f"token {BTCPAY_API_KEY}", "Content-Type": "application/json"} def create_invoice(amount_usd, order_id, buyer_email): # price in USD; BTCPay converts to BTC at its rate payload = { "amount": str(round(amount_usd, 2)), "currency": "USD", "checkout": {"redirectURL": SITE_URL + "/dashboard"}, "metadata": {"orderId": str(order_id), "buyerEmail": buyer_email}, } r = requests.post(f"{BTCPAY_URL}/api/v1/stores/{BTCPAY_STORE_ID}/invoices", headers=btcpay_headers(), json=payload, timeout=20, verify=False) r.raise_for_status() inv = r.json() # rewrite checkoutLink from LAN IP to public host (customer-facing) link = inv.get("checkoutLink", "") if link and link.startswith(BTCPAY_URL): inv["checkoutLink"] = BTCPAY_PUBLIC + link[len(BTCPAY_URL):] return inv def get_invoice(invoice_id): r = requests.get(f"{BTCPAY_URL}/api/v1/stores/{BTCPAY_STORE_ID}/invoices/{invoice_id}", headers=btcpay_headers(), timeout=20, verify=False) r.raise_for_status() return r.json() # -------------------------------------------------------------------------- # Routes # -------------------------------------------------------------------------- @app.route("/") def index(): return render_template("index.html", user=current_user()) @app.route("/robots.txt") def robots(): body = ("User-agent: *\n" "Allow: /\n" "Sitemap: https://supernova.thetempleofdoom.com/sitemap.xml\n") return body, 200, {"Content-Type": "text/plain"} @app.route("/sitemap.xml") def sitemap(): pages = [ ("/", "1.0", "weekly"), ("/services", "0.9", "daily"), ("/signup", "0.5", "monthly"), ("/login", "0.3", "monthly"), ] urls = "".join( f"https://supernova.thetempleofdoom.com{p}" f"{freq}{pri}" for p, pri, freq in pages ) xml = ('\n' '' f"{urls}") return xml, 200, {"Content-Type": "application/xml"} @app.route("/bg-demo") def bg_demo(): theme = request.args.get("theme", "cosmos") themes = ["starfield", "cosmos", "blackhole", "geometric", "nebula", "particles", "waves", "grid"] return render_template("bg-demo.html", user=current_user(), theme=theme, themes=themes) @app.route("/signup", methods=["GET", "POST"]) def signup(): if request.method == "POST": email = request.form.get("email", "").strip().lower() pw = request.form.get("password", "") if len(pw) < 8: flash("Password must be at least 8 characters.", "error") return redirect(url_for("signup")) c = db() try: c.execute("INSERT INTO users (email, password_hash, created_at) VALUES (?,?,?)", (email, hash_password(pw), int(time.time()))) c.commit() except sqlite3.IntegrityError: c.close() flash("That email is already registered.", "error") return redirect(url_for("signup")) uid = c.execute("SELECT id FROM users WHERE email=?", (email,)).fetchone()["id"] c.close() session["uid"] = uid return redirect(url_for("dashboard")) return render_template("auth.html", mode="signup", user=None) @app.route("/login", methods=["GET", "POST"]) def login(): if request.method == "POST": email = request.form.get("email", "").strip().lower() pw = request.form.get("password", "") c = db() u = c.execute("SELECT * FROM users WHERE email=?", (email,)).fetchone() c.close() if u and verify_password(pw, u["password_hash"]): session["uid"] = u["id"] nxt = request.args.get("next") or url_for("dashboard") return redirect(nxt) flash("Invalid email or password.", "error") return render_template("auth.html", mode="login", user=None) @app.route("/logout") def logout(): session.clear() return redirect(url_for("index")) @app.route("/services") def services(): svcs = get_services() # group by category cats = {} for s in svcs: cats.setdefault(s["category"], []).append(s) return render_template("services.html", user=current_user(), cats=cats) @app.route("/order/", methods=["GET", "POST"]) @login_required def order(service_id): svcs = {s["service"]: s for s in get_services()} s = svcs.get(service_id) if not s: abort(404) if request.method == "POST": link = request.form.get("link", "").strip() quantity = int(request.form.get("quantity", 0)) cost = retail_price(s["rate"], quantity) if not link or quantity < s["min"]: flash(f"Enter a valid link and quantity (min {s['min']}).", "error") return redirect(url_for("order", service_id=service_id)) u = current_user() if u["balance"] < cost: flash("Insufficient balance — deposit more BTC first.", "error") return redirect(url_for("deposit")) # charge + place upstream order try: res = panel.place_order(service_id, link, quantity) panel_oid = res.get("order") except Exception as e: flash(f"Upstream order failed: {e}", "error") return redirect(url_for("order", service_id=service_id)) c = db() c.execute("UPDATE users SET balance = balance - ? WHERE id=?", (cost, u["id"])) c.execute("""INSERT INTO orders (user_id, service_id, service_name, link, quantity, cost, panel_order_id, status, created_at) VALUES (?,?,?,?,?,?,?,?,?)""", (u["id"], service_id, s["name"], link, quantity, cost, panel_oid, "pending", int(time.time()))) c.commit() c.close() flash(f"Order placed! ${cost:.2f} — it'll start delivering shortly.", "success") return redirect(url_for("orders") + "?launched=1") return render_template("order.html", user=current_user(), s=s, markup=MARKUP_PCT) @app.route("/orders") @login_required def orders(): u = current_user() c = db() rows = c.execute("SELECT * FROM orders WHERE user_id=? ORDER BY id DESC LIMIT 100", (u["id"],)).fetchall() c.close() return render_template("orders.html", user=u, orders=rows) @app.route("/dashboard") @login_required def dashboard(): u = current_user() c = db() orders = c.execute("SELECT * FROM orders WHERE user_id=? ORDER BY id DESC LIMIT 10", (u["id"],)).fetchall() deposits = c.execute("SELECT * FROM deposits WHERE user_id=? ORDER BY id DESC LIMIT 10", (u["id"],)).fetchall() c.close() return render_template("dashboard.html", user=u, orders=orders, deposits=deposits) @app.route("/deposit", methods=["GET", "POST"]) @login_required def deposit(): u = current_user() if request.method == "POST": amount = float(request.form.get("amount", 0)) if amount <= 0: flash("Enter a valid amount.", "error") return redirect(url_for("deposit")) c = db() cur = c.execute("""INSERT INTO deposits (user_id, amount, status, created_at) VALUES (?,?,'pending',?)""", (u["id"], amount, int(time.time()))) c.commit() dep_id = cur.lastrowid c.close() inv = create_invoice(amount, dep_id, u["email"]) c = db() c.execute("UPDATE deposits SET invoice_id=? WHERE id=?", (inv["id"], dep_id)) c.commit() c.close() return redirect(inv["checkoutLink"]) return render_template("deposit.html", user=u) @app.route("/webhook/btcpay", methods=["POST"]) def btcpay_webhook(): # verify signature sig = request.headers.get("BTCPay-Sig", "") body = request.get_data() expected = "sha256=" + hmac.new(BTCPAY_WEBHOOK_SECRET.encode(), body, hashlib.sha256).hexdigest() if BTCPAY_WEBHOOK_SECRET and not hmac.compare_digest(sig, expected): return "bad signature", 401 data = request.get_json(silent=True) or {} inv_id = data.get("invoiceId") if not inv_id: return "ok", 200 # re-fetch invoice to confirm status (don't trust the webhook blindly) try: inv = get_invoice(inv_id) except Exception: return "ok", 200 if inv.get("status") != "Settled": return "ok", 200 dep_id = (inv.get("metadata") or {}).get("orderId") amount = float(inv.get("amount", 0)) c = db() dep = c.execute("SELECT * FROM deposits WHERE id=?", (dep_id,)).fetchone() if dep and dep["status"] != "credited": c.execute("UPDATE deposits SET status='credited' WHERE id=?", (dep_id,)) c.execute("UPDATE users SET balance = balance + ? WHERE id=?", (amount, dep["user_id"])) c.commit() c.close() return "ok", 200 @app.route("/api/quote//") def api_quote(service_id, quantity): svcs = {s["service"]: s for s in get_services()} s = svcs.get(service_id) if not s: return jsonify({"error": "unknown service"}), 404 return jsonify({ "quantity": quantity, "wholesale": round(wholesale_cost(s["rate"], quantity), 4), "retail": round(retail_price(s["rate"], quantity), 2), "rate": s["rate"], "min": s["min"], "max": s["max"], }) @app.route("/api/orders-status") @login_required def api_orders_status(): """Live delivery status for the dashboard ticker.""" u = current_user() c = db() rows = c.execute("SELECT * FROM orders WHERE user_id=? ORDER BY id DESC LIMIT 8", (u["id"],)).fetchall() c.close() out = [] for o in rows: status = o["status"] remains = 0 delivered = o["quantity"] if o["panel_order_id"]: try: st = panel.order_status(o["panel_order_id"]) status = (st.get("status") or o["status"]).lower().replace(" ", "") remains = int(st.get("remains") or 0) delivered = max(0, o["quantity"] - remains) except Exception: pass out.append({ "id": o["id"], "name": o["service_name"], "quantity": o["quantity"], "delivered": delivered, "status": status, }) return jsonify({"orders": out}) if __name__ == "__main__": init_db() app.run(host="0.0.0.0", port=5000)