Premium API

Система управления подписками с шифрованием на основе доменных хешей. Позволяет провайдерам настраивать внешний вид приложения, параметры серверов и уведомления для своих пользователей.

Обзор

Приложение при добавлении подписки извлекает домен из URL и запрашивает конфигурацию провайдера через зашифрованный API. Домен никогда не передаётся в открытом виде — используется SHA-256 хеш.


API

Endpoint

GET /api/subscription/config?h=<sha256hex>&hwid=<sha256hex>

Запрос

Параметр
Тип
Обязательный
Описание

h

string

да

SHA-256 хеш домена (64 hex-символа)

hwid

string

нет

SHA-256 хеш HWID устройства (64 hex-символа). Для проверки лимита устройств

Хеш вычисляется от домена в нижнем регистре:

SHA256("example.com") → "a379a6f6eeafb9a55e378c118034e2751e682fab9f2d30ab13d2125586ce1947"

Ответ

Сервер всегда возвращает зашифрованный ответ:

{
    "encrypted": true,
    "iv": "<base64>",
    "data": "<base64>",
    "tag": "<base64>"
}

Поля ответа (после расшифровки)

Поле
Тип
Описание

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

Включить упрощённый режим

liteBigButton

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

defaultSortOrder

string?

Сортировка серверов: none, ping, name

pingOnUpdate

boolean?

Авто-пинг всех серверов после обновления подписки

Контент

Поле
Тип
Описание

announceUrl

string?

URL для объявлений провайдера в приложении

webPageUrl

string?

Ссылка на веб-страницу провайдера

Кастомная тема (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 документа провайдера в Firestore.

Как работает

  1. Клиент отправляет hwid=SHA256(rawHwid) в запросе конфигурации

  2. Сервер проверяет, зарегистрировано ли устройство с таким hwidHash для доменов данного провайдера

  3. Если устройство уже зарегистрировано — всегда получает premium (существующие устройства не блокируются)

  4. Если устройство не зарегистрировано — сервер считает общее количество устройств провайдера:

    • Если totalDevices < maxDevices — premium выдаётся

    • Если totalDevices >= maxDevices — возвращается isPremium: false + deviceLimitExceeded: true

Поведение клиента при deviceLimitExceeded: true

  • Premium-функции отключены (как при isPremium: false)

  • Кастомная тема провайдера не применяется

  • Premium-настройки (фрагментация, fronting и т.д.) не используются

  • VPN продолжает работать в базовом режиме

  • Устройство регистрируется в Firebase (но без premium)

Тарифы

Лимит
Описание

1000

Стандартный тариф

3000

Средний тариф

6000

Максимальный тариф

null

Безлимитный (нет ограничений)


Регистрация устройства

При добавлении подписки приложение регистрирует устройство для отслеживания активных подключений и push-уведомлений.

Данные регистрации

Поле
Тип
Описание

hwid

string

Аппаратный идентификатор устройства (подробнее)

hwidHash

string

SHA-256 хеш HWID (для серверной проверки лимитов)

uid

string

Firebase anonymous UID

platform

string

"android", "ios", "linux", "windows"

appVersion

string

Версия приложения

osVersion

string

Версия ОС

locale

string

Язык устройства

subscriptionDomainHash

string

SHA-256 хеш домена подписки

fcmToken

string

Firebase Cloud Messaging токен

lastActive

timestamp

Время последней активности

Поле hwidHash добавляется при регистрации и используется сервером для проверки лимита устройств без знания исходного HWID.

Синхронизация подписки

Сервер может установить флаг subscriptionNeedsSync = true на устройстве. При обнаружении этого флага приложение:

  1. Читает поле subscriptionNewDomain из документа устройства

  2. Обновляет URL подписки на новый домен

  3. Сбрасывает флаг subscriptionNeedsSync

Это позволяет провайдеру мигрировать пользователей на новый домен при блокировке старого.


Кеширование

  • In-memory кеш: конфигурация хранится в памяти на время работы приложения

  • Disk кеш: сохраняется в SecureStorage для offline-доступа

  • Fallback: при ошибке 503 используется кешированная конфигурация

  • Очистка: конфигурация удаляется из кеша, если домен больше не является premium


Certificate Pinning

Запросы к Premium API на Android и Desktop защищены certificate pinning (SHA-256 пины TLS-сертификата). Это предотвращает MITM-атаки на канал связи с API.


Firestore индекс

Для корректной работы проверки лимитов необходим составной индекс:

  • Коллекция: devices

  • Поля: hwidHash (ASC), subscriptionDomainHash (ASC)`

Последнее обновление