Full-featured platform for selling VPN subscriptions
Telegram bot β’ Mini App β’ Client dashboard β’ Admin panel
Everything in one box. One script β and it works.
Quick start β’ Requirements β’ Architecture β’ Features β’ Telegram bot β’ Web panel β’ API β’ Docker Services β’ Configuration β’ Migration
Caution
To avoid any conflicts, it is strongly recommended to install this stack on a separate server!
apt install git -y
curl -fsSL https://get.docker.com | sh
cd /opt
git clone https://github.com/systemmaster1200-eng/remnawave-STEALTHNET-Bot.git
cd remnawave-STEALTHNET-Bot
bash install.shWarning
If after launch your API service crashes, the bot replies "β fetch failed", and in the logs (docker compose logs -f api) you see the error "Error: P1000: Authentication failed", and if you don't have any other important projects running on this server, you can and should delete them to free up space with the following command:
docker system prune -a --volumes
The interactive installer will configure everything in 2 minutes:
- Domain and SSL certificates (Let's Encrypt)
- PostgreSQL, JWT secrets, administrator credentials
- Remnawave API connection
- Telegram bot
- Nginx (built-in with auto-SSL or your own reverse proxy)
Estimated configurations for running all services (API, frontend, bot, Nginx, PostgreSQL) in Docker:
| Level | CPU | RAM | Disk | Purpose |
|---|---|---|---|---|
| Minimum | 1 vCPU | 1.5β2 GB | 20 GB | Testing, demo, up to ~50 active users |
| Medium | 2 vCPU | 4 GB | 40 GB SSD | Small production, up to ~500 users, stable operation |
| Recommended | 4 vCPU | 8 GB | 80 GB SSD | Production with reserve, thousands of users, fast response |
General:
- OS: Linux (Debian 13, Ubuntu 24.04 LTS or equivalent), Docker and Docker Compose v2+.
- Open ports: 80 (HTTP), 443 (HTTPS); when installed via
install.shβ only these are needed. - For medium and recommended levels, an SSD and separate DB backups are desirable.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β STEALTHNET 3.0 β
ββββββββββββββββ¬βββββββββββββββ¬βββββββββββββββ¬ββββββββββββββ€
β Telegram β Mini App β Client β Admin β
β Bot β (WebApp) β dashboard β panel β
β Grammy β React β React β React β
ββββββββββββββββ΄βββββββββββββββ΄βββββββββββββββ΄ββββββββββββββ€
β Backend API (Express) β
β JWT Auth Β· Prisma ORM Β· Webhooks β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β PostgreSQL β Remnawave API β
β (Data) β (VPN core) β
ββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββ€
β Nginx + Let's Encrypt Β· Docker Compose β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Service | Technologies | Purpose |
|---|---|---|
| backend | Node.js, Express, Prisma, PostgreSQL | REST API: auth, clients, tariffs, payments, referrals, promo, analytics |
| frontend | React 18, Vite, Tailwind CSS, shadcn/ui, Framer Motion | Admin panel + client dashboard + Telegram Mini App |
| bot | Grammy (TypeScript) | Full Telegram bot with client dashboard |
| nginx | Nginx + Certbot | Reverse proxy, SSL, static, gzip |
| postgres | PostgreSQL 16 | Data storage |
- Platega.io β payment acceptance (cards, SBP, crypto, etc.); callback URL is copied in the admin panel
- YooMoney β balance top-up and tariff payment via card (transfer form, HTTP notifications); webhook URL with a "Copy" button in settings
- YooKassa β card and SBP payments via API (RUB only); 54-FZ receipts; webhook on
payment.succeeded; webhook URL is copied in the admin panel - Balance payment β internal balance top-up and deduction
- Auto-activation β after payment, the tariff is activated instantly via webhook (Platega, YooMoney, YooKassa)
- Payment description β for all payment systems (Platega, YooMoney, YooKassa), the service name from admin settings is added to the description (General β Service Name)
- Flexible tariffs β categories, durations, traffic and device limits, binding to Remnawave squads
- Multi-currency β support for multiple currencies (USD, RUB, etc.)
- 3-level referrals β earn from invited users and their referrals
- Customizable percentages β separately for each level
- Automatic accrual β bonuses are credited to the balance with every referral payment
- Referral links β for the bot and the website
- Promo groups β free subscription via link (
/start promo_CODE), with activation limits - Promo codes β discounts (% or fixed amount) and free days
- Usage limits β total limit and limit per client, expiration date
- Activation statistics β how many times it was used, by whom, when
- Free trial β customizable duration, traffic and device limits
- One-time activation β one trial per client
- Squad binding β separate squad for trial users
- User management β creation, deletion, blocking in Remnawave
- Subscriptions β activation, extension, status check
- Nodes β monitoring, enable/disable, restart
- Squads β distribution of users across servers
- Synchronization β two-way data sync (Remnawave <-> STEALTHNET)
- Webhooks β automatic handling of Remnawave events
- Collapsible tariff categories β with multiple categories on narrow screens and in the Mini App, categories are shown as an accordion: the first is open by default, others open on click
- Compact tariff cards β in mobile view, tariffs are in one column, long thin rows (name and parameters on the left, price and "Pay" on the right)
- Unified mobile interface β bottom navigation, compact header, same style in mobile browser and Telegram WebApp
- Dashboard β key metrics in real-time
- Revenue charts β daily for 90 days
- Client base growth β registration dynamics
- Top tariffs β best-selling plans
- Referral stats β earnings by level
- Conversion β trial -> paid subscription
- Sales report β filtering by date and payment provider
- JWT authentication β access + refresh tokens
- Forced password change β on the first admin login
- Email verification β confirmation via link in email
- Client blocking β with reason specification
- SSL/TLS β automatic Let's Encrypt certificates
A full client dashboard right in Telegram:
| Command / Button | Action |
|---|---|
/start |
Registration and main menu |
/start ref_CODE |
Registration via referral link |
/start promo_CODE |
Promo group activation |
| Main Menu | Subscription status, balance, days left, traffic, device limit |
| Tariffs | View categories and tariffs, purchase |
| Top-up | Balance top-up (presets and custom amount) |
| Profile | Language and currency selection |
| Referrals | Statistics and referral link |
| Trial | Free trial activation |
| VPN | Subscription page (Mini App) |
| Promo code | Enter promo code for discount or free days |
| Support | Links to support, agreement, offer, instructions |
Bot Features:
- Custom emojis (Premium Emoji)
- Colored buttons (primary / success / danger)
- Traffic usage progress bar
- Telegram Mini App (WebApp) integration
- Customizable texts and logo
| Section | Description |
|---|---|
| Dashboard | Statistics, node status, quick actions |
| Clients | Client list, search, filters, block/unblock, password reset |
| Tariffs | Category and tariff management (CRUD) |
| Promo groups | Promo links creation and management |
| Promo codes | Discount and free days promo codes creation |
| Analytics | Revenue, clients, referrals, conversion charts |
| Sales Report | Detailed sales with filters |
| Settings | Branding (service name, logo), SMTP, Platega / YooMoney / YooKassa (webhook URLs with a "Copy" button), bot, Remnawave, referral system |
| Section | Description |
|---|---|
| Authorization | Email + password or Telegram widget |
| Registration | With email confirmation |
| Dashboard | Subscription status, balance, payment history, trial |
| Tariffs | View and purchase tariffs |
| Subscription | VPN page: apps by platform, deep links |
| Referrals | Statistics and invitation link |
| Profile | Language, currency, password change |
Frontend Technologies:
- React 18 + TypeScript + Vite
- Tailwind CSS + shadcn/ui
- Framer Motion (animations)
- Recharts (charts)
- Dark / light theme
- Responsive design (mobile + desktop)
- PWA (Service Worker)
- Telegram Mini App
POST /auth/register β Registration (email + password)
POST /auth/login β Login
POST /auth/telegram-miniapp β Telegram Mini App login
GET /auth/me β Current user
GET /subscription β Subscription status
GET /tariffs β Available tariffs
POST /payments/platega β Create payment (Platega)
POST /payments/balance β Balance payment
POST /yookassa/create-payment β Create YooKassa payment (card/SBP, RUB), redirect to payment page
GET /yoomoney/auth-url β YooMoney authorization URL (OAuth)
POST /yoomoney/request-topup β Request YooMoney wallet top-up
POST /yoomoney/create-form-payment β YooMoney form (card payment), returns paymentUrl
POST /trial β Activate trial
POST /promo/activate β Activate promo group
POST /promo-code/check β Check promo code
POST /promo-code/activate β Apply promo code
GET /referral-stats β Referral statistics
GET /dashboard/stats β Dashboard stats
GET /clients β Client list (pagination, search)
GET /clients/:id β Client details
PATCH /clients/:id β Update client
CRUD /tariff-categories β Tariff categories
CRUD /tariffs β Tariffs
CRUD /promo-groups β Promo groups
CRUD /promo-codes β Promo codes
GET /analytics β Analytics
GET /sales-report β Sales report
GET/PATCH /settings β System settings
GET /remna/* β Proxy requests to Remnawave
POST /sync/from-remna β Sync from Remnawave
POST /sync/to-remna β Sync to Remnawave
GET /config β Public configuration
GET /tariffs β Tariff list
GET /subscription-page β Subscription page config
GET /deeplink β Deep link for VPN apps
POST /webhooks/remna β Remnawave events
POST /webhooks/platega β Platega callback (auto-activation)
POST /webhooks/yoomoney β YooMoney HTTP notifications (top-up, tariff payment)
POST /webhooks/yookassa β YooKassa events (payment.succeeded β top-up/tariff activation)
docker compose ps| Container | Port | Description |
|---|---|---|
stealthnet-postgres |
5432 (int.) | PostgreSQL 16 β database |
stealthnet-api |
5000 | Backend API |
stealthnet-bot |
β | Telegram bot |
stealthnet-nginx |
80, 443 | Nginx + SSL (built-in mode) |
stealthnet-certbot |
β | SSL certificate auto-renewal |
# Update to the latest commit (latest main branch, not always stable)
git pull origin main
# Update to a specific version (more stable, release version):
git fetch --tags
git checkout v3.1.3
# Services status
docker compose ps
# Real-time logs
docker compose logs -f api
docker compose logs -f bot
docker compose logs -f nginx
# Restart API and bot
docker compose restart api bot
# Full shutdown
docker compose down
# Start (without built-in nginx)
docker compose up -d
# Start (with built-in nginx + SSL)
docker compose --profile builtin-nginx up -d
# Shutdown (with built-in nginx + SSL)
docker compose --profile builtin-nginx down
# Rebuild after code update
docker compose build api bot
docker compose up frontend # rebuild frontend
docker compose restart api bot
# Rebuild after code update (with external nginx)
chmod +x ./scripts/update-front-with-external-nginx.sh
./scripts/update-front-with-external-nginx.sh
# For cleaning old images (if disk space too small)
docker compose down
docker system prune -a
docker compose up -d --build && docker compose logs -f -tnginx/nginx.confβ is in.gitignore(file generated by install.sh for the domain). If Git still updates it on pull, run once:
git rm --cached nginx/nginx.conf && git commit -m "Stop tracking nginx.conf"- Source code (
backend/...,nginx/nginx.conf.template, etc.) should not be added to ignore. Beforegit pull, either commit changes or stash them:
git stash && git pull && git stash pop
All variables are described in .env.example:
| Variable | Required | Description |
|---|---|---|
DOMAIN |
yes | Panel domain (e.g., vpn.example.com) |
POSTGRES_DB |
yes | Database name |
POSTGRES_USER |
yes | PostgreSQL user |
POSTGRES_PASSWORD |
yes | PostgreSQL password |
JWT_SECRET |
yes | JWT token secret (min. 32 chars) |
JWT_ACCESS_EXPIRES_IN |
no | Access token lifetime (default 15m) |
JWT_REFRESH_EXPIRES_IN |
no | Refresh token lifetime (default 7d) |
INIT_ADMIN_EMAIL |
yes | First admin email |
INIT_ADMIN_PASSWORD |
yes | First admin password |
REMNA_API_URL |
yes | Remnawave panel URL |
REMNA_ADMIN_TOKEN |
yes | Remnawave API token |
BOT_TOKEN |
no | Telegram bot token |
USE_BUILTIN_NGINX |
no | true for built-in nginx |
CERTBOT_EMAIL |
no | Email for Let's Encrypt |
If external nginx was chosen during installation:
- Config example:
nginx/external.conf.example - API proxied to
http://127.0.0.1:5000 - Frontend static files:
/var/www/stealthnet/orfrontend/dist/
# Get SSL
sudo certbot --nginx -d your-domain.com
# Link config
sudo cp nginx/external.conf.example /etc/nginx/sites-available/stealthnet.conf
sudo ln -s /etc/nginx/sites-available/stealthnet.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginxremnawave-STEALTHNET-Bot/
βββ backend/ # Backend API
β βββ src/
β β βββ index.ts # Entry point
β β βββ modules/
β β β βββ auth/ # JWT authentication
β β β βββ admin/ # Admin routes and controllers
β β β βββ client/ # Client routes and controllers
β β βββ ...
β βββ prisma/
β βββ schema.prisma # Database schema
βββ bot/ # Telegram bot
β βββ src/
β β βββ index.ts # Bot logic
β β βββ api.ts # Client for Backend API
β β βββ keyboard.ts # Keyboards and buttons
β βββ ...
βββ frontend/ # React SPA
β βββ src/
β β βββ pages/ # Pages (admin + cabinet)
β β βββ components/ # Reusable components
β β βββ ...
β βββ ...
βββ nginx/ # Nginx configs
β βββ nginx.conf.template # Template for built-in nginx
β βββ nginx-initial.conf # Initial config for certbot
β βββ external.conf.example # Example for external nginx
βββ scripts/ # Helper scripts
βββ docker-compose.yml # Orchestration of all services
βββ install.sh # Interactive installer
βββ .env.example # Env variables template
βββ README.md # This file
Migrating from another panel? Migration is supported from two sources:
| Source | Script | Documentation |
|---|---|---|
| Old STEALTHNET panel (Flask) | scripts/migrate-from-old-panel.js |
Detailed instructions |
| Bedolaga Bot | scripts/migrate-from-bedolaga.js |
Detailed instructions |
# 1. Install script dependencies (once)
cd scripts && npm install && cd ..
# 2a. Migration from old Flask panel
OLD_DB_HOST=localhost OLD_DB_NAME=stealthnet_old \
NEW_DB_HOST=localhost NEW_DB_NAME=stealthnet \
node scripts/migrate-from-old-panel.js
# 2b. Migration from Bedolaga (path to backup)
node scripts/migrate-from-bedolaga.js ./backup_20260126_000000.tar.gzThe currency is determined automatically from system settings (
default_currency).
Scripts are idempotent β they can be run repeatedly without the risk of duplicates.
Full documentation, variables, FAQ β in MIGRATION.md.
Questions, suggestions, bug reports β all here:
This project is licensed under the GNU AGPL-3.0 License.
The full text of the license is in the LICENSE file. When using, modifying, and distributing the code, you must comply with the conditions of AGPL-3.0 (including source code disclosure of derivative works when used as a network service).
STEALTHNET 3.0 β sell VPN beautifully.
Built with TypeScript, React, Grammy, Prisma, Docker
