Premium API¶
Система управления подписками с шифрованием на основе доменных хешей. Позволяет провайдерам настраивать внешний вид приложения, параметры серверов и уведомления для своих пользователей.
Обзор¶
Приложение при добавлении подписки извлекает домен из URL и запрашивает конфигурацию провайдера через зашифрованный API. Домен никогда не передаётся в открытом виде — используется SHA-256 хеш.
API¶
Endpoint¶
Запрос¶
| Параметр | Тип | Обязательный | Описание |
|---|---|---|---|
h |
string | да | SHA-256 хеш домена (64 hex-символа) |
hwid |
string | нет | SHA-256 хеш HWID устройства (64 hex-символа). Для проверки лимита устройств |
Хеш вычисляется от домена в нижнем регистре:
Ответ¶
Сервер всегда возвращает зашифрованный ответ:
Поля ответа (после расшифровки)¶
| Поле | Тип | Описание |
|---|---|---|
success |
boolean | Успешность запроса |
domain |
string | Домен подписки |
isPremium |
boolean | Активен ли Premium у провайдера |
deviceLimitExceeded |
boolean | Лимит устройств провайдера превышен (см. Лимиты устройств) |
logoUrl |
string? | URL логотипа провайдера |
settings |
object | Настройки провайдера (см. ниже) |
theme |
object | Кастомная тема (см. ниже) |
Rate Limit¶
30 запросов в минуту на IP-адрес. При превышении — ответ 429.
Шифрование¶
Ответы API зашифрованы алгоритмом AES-256-GCM. Ключ шифрования деривируется на основе домена — только клиент, знающий оригинальный домен и комбинацию, может расшифровать ответ.
Компоненты ответа:
| Поле | Описание |
|---|---|
iv |
Initialization vector (base64, 12 байт) |
data |
Зашифрованные данные (base64) |
tag |
Authentication tag (base64, 16 байт) |
Детали деривации ключа и реализация шифрования являются внутренними и не публикуются.
Структура конфигурации¶
Настройки провайдера (settings)¶
Базовые¶
| Поле | Тип | Описание |
|---|---|---|
serverDescription |
string | Описание сервера (до 30 символов) |
alwaysHwidEnable |
boolean | Принудительная отправка HWID (пользователь не может отключить) |
expiryNotifications |
boolean | Локальные уведомления об истечении подписки |
showServerDescription |
boolean | Показывать описание серверов. По умолчанию true |
Domain fronting и фрагментация¶
| Поле | Тип | Описание |
|---|---|---|
resolveAddress |
string | IP для domain fronting |
hostHeader |
string | Host-заголовок для domain fronting |
fragmentEnabled |
boolean | TCP-фрагментация в hev-socks5-tunnel |
fragmentLength |
string | Диапазон длины фрагментов (напр. "10-30") |
fragmentInterval |
string | Диапазон интервала (напр. "20-40" мс) |
fragmentPackets |
string | Количество фрагментов (напр. "5-10") |
DNS-резолв адреса сервера (DoH)¶
| Поле | Тип | Описание |
|---|---|---|
serverAddressResolveEnable |
boolean | Предварительный резолв адреса сервера через DoH |
serverAddressResolveDnsDomain |
string | URL DoH-сервера (напр. https://common.dot.dns.yandex.net/dns-query) |
serverAddressResolveDnsIp |
string | IP DoH-сервера (используется до резолва его домена) |
Lite Mode¶
Упрощённый интерфейс с ссылками на бот, канал, поддержку и (опционально) премиум. Подробнее про иконки — icon-presets.md.
| Поле | Тип | Описание |
|---|---|---|
liteMode |
boolean | Включить упрощённый режим |
botUrl |
string? | Ссылка на Telegram-бот |
channelUrl |
string? | Ссылка на Telegram-канал |
supportUrl |
string? | Ссылка на поддержку |
botIconKey |
string? | Ключ иконки бота из пресет-набора (см. icon-presets.md) |
channelIconKey |
string? | Ключ иконки канала |
supportIconKey |
string? | Ключ иконки поддержки |
nullили неизвестный ключ → клиент использует дефолтную иконку (sendдля бота,megaphoneдля канала,helpдля поддержки).
Админ-доступ (admin HWIDs)¶
Устройства в списке adminHwids могут:
- Просматривать и редактировать конфиги серверов прямо в приложении.
- Отправлять провайдерские уведомления без модерации (auto-approve при совпадении с
targetSegment.hwid).
Подробности — admin-hwids.md.
| Поле | Тип | Описание |
|---|---|---|
adminHwids |
string[] |
Список HWID устройств с админ-правами |
Баннер подписки¶
Красный/произвольного цвета баннер внутри карточки подписки. Используется для апсейла / предупреждений об истечении / анонсов.
| Поле | Тип | Описание |
|---|---|---|
bannerEnabled |
boolean | Показывать баннер |
bannerText |
string? | Текст баннера (белым по bannerBgColor) |
bannerButtonText |
string? | Текст кнопки (если пусто — кнопка скрыта) |
bannerButtonUrl |
string? | URL кнопки |
bannerBgColor |
string? | Цвет фона баннера (hex, напр. "#E53E3E", по умолчанию красный) |
bannerButtonColor |
string? | Цвет кнопки (hex, по умолчанию зелёный) |
Принудительные настройки¶
Переопределяют выбор пользователя в настройках приложения, пока подписка активна.
| Поле | Тип | Описание |
|---|---|---|
forceConnectionStyle |
string? |
Стиль кнопки подключения: "classic" (крупная круглая кнопка) или "compact" (узкий toggle внизу) |
Ping и сортировка¶
Применяются при первом подключении подписки и переопределяют дефолтные настройки приложения.
| Поле | Тип | Описание |
|---|---|---|
defaultPingProtocol |
string? | Тип пинга: tcp, proxy_head, proxy_get, icmp |
pingTestUrl |
string? | URL для HTTP-пинга (используется при proxy_head / proxy_get) |
defaultSortOrder |
string? | Сортировка серверов: none, ping, name |
pingOnUpdate |
boolean? | Авто-пинг всех серверов после обновления подписки |
Контент¶
| Поле | Тип | Описание |
|---|---|---|
announceUrl |
string? | URL для объявлений провайдера в приложении |
webPageUrl |
string? | Ссылка на веб-страницу провайдера |
Резервные домены (fallbackHosts)¶
| Поле | Тип | Описание |
|---|---|---|
fallbackHosts |
string[] | Список запасных хостов. Если основной домен подписки не отвечает при обновлении, клиент повторяет тот же запрос, подставляя эти хосты по очереди (меняется только хост, путь/токен те же). Перебираются сверху вниз. |
Клиент кэширует
fallbackHostsна подписке, поэтому перебор работает даже когда основной домен полностью недоступен. На404/410(подписка удалена) перебор не выполняется. В премиум-панели задаётся кнопкой «Резервные» рядом с доменом.
Кастомная тема (theme)¶
Расширенная палитра, применяется только когда пользователь видит premium-подписку. Поддерживает плоские цвета и 2-4-стоповые градиенты.
Плоские цвета¶
| Поле | Тип | Описание |
|---|---|---|
enabled |
boolean | Кастомная тема включена |
darkMode |
boolean | Тёмный режим |
accent |
string | Основной акцентный цвет (hex, напр. "#FF6B6B") |
accentSecondary |
string | Вторичный акцентный цвет |
background |
string | Цвет фона |
card |
string | Цвет карточек |
surface |
string | Цвет поверхности |
textPrimary |
string | Основной цвет текста |
textSecondary |
string | Вторичный цвет текста |
Градиенты¶
Если задан, перекрывает плоские accent/accentSecondary для акцентных элементов и background для фона.
| Поле | Тип | Описание |
|---|---|---|
accentGradient.stops |
GradientStop[] | 2-4 стопа ({ color, position }), position в диапазоне 0.0..1.0 |
accentGradient.angle |
number | Угол градиента в градусах 0..360 |
backgroundGradient.enabled |
boolean | Включить градиентный фон |
backgroundGradient.stops |
GradientStop[] | 2-3 стопа |
backgroundGradient.angle |
number | Угол градиента |
Каждый стоп:
Лимиты устройств¶
Premium-провайдеры имеют тарифы с ограничением по количеству устройств. Лимит задаётся полем maxDevices провайдера.
Как работает¶
- Клиент отправляет
hwid=SHA256(rawHwid)в запросе конфигурации - Сервер проверяет, зарегистрировано ли устройство с таким
hwidHashдля доменов данного провайдера - Если устройство уже зарегистрировано — всегда получает premium (существующие устройства не блокируются)
- Если устройство не зарегистрировано — сервер считает общее количество устройств провайдера:
- Если
totalDevices < maxDevices— premium выдаётся - Если
totalDevices >= maxDevices— возвращаетсяisPremium: false+deviceLimitExceeded: true
Поведение клиента при deviceLimitExceeded: true¶
- Premium-функции отключены (как при
isPremium: false) - Кастомная тема провайдера не применяется
- Premium-настройки (фрагментация, fronting и т.д.) не используются
- VPN продолжает работать в базовом режиме
- Устройство регистрируется (но без premium)
Тарифы¶
| Лимит | Описание |
|---|---|
1000 |
Стандартный тариф |
3000 |
Средний тариф |
6000 |
Максимальный тариф |
null |
Безлимитный (нет ограничений) |
Регистрация устройства¶
При добавлении подписки приложение регистрирует устройство для отслеживания активных подключений и push-уведомлений.
Данные регистрации¶
| Поле | Тип | Описание |
|---|---|---|
hwid |
string | Аппаратный идентификатор устройства (подробнее) |
hwidHash |
string | SHA-256 хеш HWID (для серверной проверки лимитов) |
uid |
string | Анонимный UID устройства |
platform |
string | "android", "ios", "linux", "windows", "macos" |
appVersion |
string | Версия приложения |
osVersion |
string | Версия ОС |
locale |
string | Язык устройства |
subscriptionDomainHash |
string | SHA-256 хеш домена подписки |
fcmToken |
string | Push-токен для уведомлений (FCM / APNs) |
lastActive |
timestamp | Время последней активности |
Поле
hwidHashдобавляется при регистрации и используется сервером для проверки лимита устройств без знания исходного HWID.
Синхронизация подписки¶
Сервер может установить флаг subscriptionNeedsSync = true на устройстве. При обнаружении этого флага приложение:
- Читает поле
subscriptionNewDomainиз документа устройства - Обновляет URL подписки на новый домен
- Сбрасывает флаг
subscriptionNeedsSync
Это позволяет провайдеру мигрировать пользователей на новый домен при блокировке старого.
Кеширование¶
- In-memory кеш: конфигурация хранится в памяти на время работы приложения
- Disk кеш: сохраняется в SecureStorage для offline-доступа
- Fallback: при ошибке
503используется кешированная конфигурация - Очистка: конфигурация удаляется из кеша, если домен больше не является premium
Certificate Pinning¶
Запросы к Premium API на Android и Desktop защищены certificate pinning (SHA-256 пины TLS-сертификата). Это предотвращает MITM-атаки на канал связи с API.