# SHiNE ESP32 Subserver UI Spec ## Назначение Этот документ описывает актуальный UI-прототип сабсервера `SHiNE` для платы `Waveshare ESP32-S3-Touch-AMOLED-2.16`. Документ является источником истины для Arduino-скетча: - если меняется этот документ, должен меняться и скетч; - если меняется скетч, должен обновляться и этот документ; - экраны, кнопки, поля, статусы, переходы и тексты не должны расходиться. ## Текущий объём реализации Текущая реализация является интерактивным прототипом экрана устройства, пригодным для ручной проверки на железе. Что уже входит в прототип: - локальный UI на тач-экране; - хранение настроек и секретов во внутренней памяти `ESP32` через `NVS`; - русский текст в логике интерфейса; в текущей временной сборке отображение на экране идёт через ASCII-транслитерацию, потому что `U8g2`-шрифты на устройстве временно не рисуются; - экран пополнения с реальным `solana:` URI и рисованием QR-кода; - реальное подключение к `Wi-Fi` по сохранённым `SSID/паролю`; - реальная проверка доступности `API`, `RPC` и `WS`-адресов; - реальное чтение баланса кошелька из `Solana RPC`; - проверка обязательных условий перед регистрацией; - живая on-chain регистрация серверного `user_pda` в `shine_users` через `device key` устройства; - прототип входящих запросов с подтверждением и отклонением; - PIN-блокировка (в текущей временной сборке вход по PIN отключён, устройство открывает `HOME` сразу после старта); - базовые настройки, статус и главный экран; - сохранение `PDA` и `tx signature` после успешной регистрации. Что пока считается именно прототипом, а не финальной интеграцией: - приём реальных входящих запросов на вход/подпись пока не подключён к живой сети; - входящие запросы пока демонстрационные, чтобы можно было проверить UX и логику подтверждения. ## Основная идея устройства Устройство работает как отдельный сабсервер: - хранит секрет на самом устройстве; - позволяет ввести логин, секрет и имя сабсервера; - показывает адрес кошелька устройства; - позволяет пополнить баланс перед регистрацией; - после выполнения условий даёт зарегистрировать устройство как сабсервер; - после регистрации может принимать входящие запросы на вход и на подпись. `SD`-карта не нужна для постоянного хранения секрета в этом прототипе. Основное сохранение идёт во внутреннюю flash-память через `NVS`. ## Данные, которые хранятся на устройстве Прототип хранит: - `PIN`; - `Wi-Fi SSID`; - `Wi-Fi password`; - `login`; - `session/subserver name`; - `master secret`; - `wallet address`; - `user pda address`; - `registration signature`; - `balance`; - `server api url`; - `server rpc url`; - `server ws url`; - флаги: `wifiReady`, `serversReady`, `secretReady`, `registered`, `online`. ## Правила готовности к регистрации Кнопка регистрации доступна только если одновременно выполнены условия: 1. настроен и подтверждён `Wi-Fi`; 2. заполнены и подтверждены серверные адреса; 3. задан логин; 4. сгенерирован или введён секрет; 5. баланс кошелька не меньше `0.20 SOL`; 6. устройство ещё не зарегистрировано. Если хотя бы одно условие не выполнено, главный экран показывает, чего именно не хватает. ## Экранная модель В прототипе используются следующие экраны: 1. `LOCK` 2. `HOME` 3. `STATUS` 4. `CONNECTION` 5. `WIFI_EDIT` 6. `SERVERS` 7. `ACCOUNT` 8. `WALLET` 9. `WALLET_QR` 10. `REQUESTS` 11. `REQUEST_DETAIL` 12. `SETTINGS` 13. `PIN_EDIT` 14. `TEXT_INPUT` 15. `CONFIRM` ## Общие правила интерфейса - Верхняя строка всегда показывает краткий статус устройства: `PIN`, `Wi-Fi`, `сервер`, `регистрация`. - Основной язык прототипа: русский. - Для вывода текста в текущей временной сборке используется стандартный шрифт `Arduino_GFX`. - Русские строки на экране временно показываются в ASCII-транслитерации. - Кнопки крупные, с тач-ориентированным размером. - Опасные действия подтверждаются отдельным диалогом. - После изменения данных конфигурация сразу сохраняется в `NVS`. ## Экран LOCK Назначение: - экран блокировки предусмотрен в UI, но в текущей временной сборке после запуска пропускается; - вход по PIN временно отключён для отладки остальных экранов. Отображается: - заголовок `SHiNE Device`; - статус `Устройство заблокировано`; - поле ввода PIN в виде маски; - кнопки цифровой клавиатуры; - кнопки `Стереть` и `Открыть`. Поведение: - если PIN введён верно, открывается `HOME`; - если PIN неверный, показывается ошибка `Неверный PIN`; - в текущей временной сборке этот экран не показывается автоматически при старте. ## Экран HOME Это основной экран устройства. Показывает: - крупный статус регистрации; - имя логина; - имя сабсервера; - короткий статус Wi-Fi; - короткий статус сервера; - короткий статус баланса. Нижние кнопки: - `Статус` - `Подключение` - `Аккаунт` - `Кошелёк` - `Запросы` - `Настройки` Дополнительная большая кнопка: - `Зарегистрировать` Если регистрация уже сделана: - вместо призыва к регистрации показывается статус `Сабсервер активен`. ## Экран STATUS Показывает сводку: - логин; - сабсервер; - есть ли секрет; - зарегистрировано ли устройство; - подключён ли Wi-Fi; - доступны ли серверы; - хватает ли баланса; - находится ли устройство онлайн; - краткий отпечаток `PDA` или `tx`. Кнопки: - `Назад` - `Обновить статус` `Обновить статус` в прототипе не делает сеть, а просто перерисовывает текущие вычисленные состояния. ## Экран CONNECTION Показывает: - `Wi-Fi`: готов / не готов; - `Серверы`: готовы / не готовы; - `Онлайн`: да / нет. Кнопки: - `Wi-Fi` - `Серверы` - `Подключить` - `Отключить` - `Назад` Поведение: - `Подключить` переводит устройство в `online=true`, если `Wi-Fi` реально подключён и серверы реально проверены; - `Отключить` переводит устройство в `online=false`. ## Экран WIFI_EDIT Поля: - `SSID` - `Пароль` Кнопки: - `Изменить SSID` - `Изменить пароль` - `Проверить` - `Сбросить` - `Назад` Поведение: - `Проверить` делает реальную попытку подключения к `Wi-Fi`; - `Сбросить` очищает обе строки и ставит `wifiReady=false`. ## Экран SERVERS Поля: - `API URL` - `RPC URL` - `WS URL` Кнопки: - `Изменить API` - `Изменить RPC` - `Изменить WS` - `Проверить` - `Тестовые` - `Назад` Поведение: - `Тестовые` подставляет дефолтные тестовые значения; - `Проверить` делает реальные сетевые проверки: - `API URL` должен отвечать по `HTTP/HTTPS`; - `RPC URL` должен отвечать на `Solana JSON-RPC`; - `WS URL` должен принимать `TCP/TLS`-соединение. ## Экран ACCOUNT Показывает: - логин; - имя сабсервера; - статус секрета; - короткий отпечаток секрета; - статус регистрации; - короткий отпечаток `PDA` или `tx`. Кнопки: - `Изменить логин` - `Секрет` - `Имя сабсервера` - `Сгенерировать` - `Очистить` - `Назад` Поведение: - `Сгенерировать` создаёт новый `master secret` и пересчитывает из него `device`-кошелёк; - `Очистить` удаляет секрет, адрес кошелька, `PDA`, `tx`, регистрацию и онлайн-статус; - логин приводится к нижнему регистру и trim. ## Экран WALLET Показывает: - адрес кошелька устройства; - баланс в `SOL`; - минимально рекомендуемую сумму для регистрации; - статус `Хватает / Не хватает`. Кнопки: - `QR и URI` - `+0.10 SOL` - `+0.25 SOL` - `-0.10 SOL` - `Проверить` - `Назад` Поведение: - кнопки пополнения/уменьшения нужны для теста сценариев; - `Проверить` читает реальный баланс из `Solana RPC`; - адрес кошелька должен совпадать с `device key`, вычисленным из сохранённого `master secret`; - отрицательный баланс не допускается. ## Экран WALLET_QR Показывает: - QR-код для строки вида: `solana:?amount=0.20&label=SHiNE%20Register`; - адрес кошелька; - сумму; - текст URI. Кнопки: - `Назад` QR должен быть сканируемым, а не декоративным. ## Экран REQUESTS Показывает список демонстрационных запросов: - `Вход в сессию` - `Подпись сообщения` Для каждого запроса: - тип; - источник; - короткий статус. Кнопки: - `Открыть запрос 1` - `Открыть запрос 2` - `Назад` ## Экран REQUEST_DETAIL Показывает детали выбранного запроса: - тип запроса; - кто запросил; - время; - описание; - отпечаток/идентификатор. Кнопки: - `Разрешить` - `Отклонить` - `Назад` Поведение: - после разрешения или отклонения запрос помечается обработанным; - экран списка отражает новый статус. ## Экран SETTINGS Показывает: - текущий PIN; - базовые флаги безопасности; - технические действия прототипа. Кнопки: - `Сменить PIN` - `Сбросить онлайн` - `Полный сброс` - `Назад` `Полный сброс` очищает весь локальный конфиг и возвращает устройство к стартовому состоянию. ## Экран PIN_EDIT Используется для ввода нового PIN. Правила: - допустимы только цифры; - длина PIN: 4..8 символов; - после сохранения новый PIN немедленно пишется в `NVS`. ## Экран TEXT_INPUT Это общий экран редактирования текстовых полей. Используется для: - `SSID` - `Пароль Wi-Fi` - `Логин` - `Имя сабсервера` - `API URL` - `RPC URL` - `WS URL` Состав экрана: - заголовок поля; - текущее значение; - программная клавиатура; - кнопки `Стереть`, `OK`, `Отмена`. ## Экран CONFIRM Это модальный экран подтверждения. Используется для: - регистрации; - очистки секрета; - полного сброса. Кнопки: - `Подтвердить` - `Отмена` ## Сценарий первой настройки Ожидаемый путь пользователя: 1. открыть устройство сразу после старта; экран PIN временно не требуется; 2. открыть `Подключение -> Wi-Fi`; 3. ввести `SSID` и пароль, нажать `Проверить`; 4. открыть `Подключение -> Серверы`; 5. проверить или задать серверные адреса; 6. открыть `Аккаунт`; 7. ввести логин; 8. задать имя сабсервера; 9. сгенерировать секрет; 10. открыть `Кошелёк`; 11. при необходимости пополнить баланс; 12. вернуться на `HOME`; 13. нажать `Зарегистрировать`; 14. после подтверждения увидеть статус `Сабсервер активен`. Примечание: - устройство реально отправляет `create_user_pda` в `shine_users`, а после подтверждения сохраняет `PDA` и `tx signature`. ## Сценарий входящего запроса 1. открыть `Запросы`; 2. выбрать один из запросов; 3. прочитать детали; 4. нажать `Разрешить` или `Отклонить`; 5. убедиться, что статус запроса изменился. ## Временный режим текста В текущей диагностической версии: - строковые литералы в коде остаются русскими и в `UTF-8`; - перед выводом на экран они временно транслитерируются в ASCII; - рендер выполняется стандартным шрифтом `Arduino_GFX`; - это обходной режим, пока `U8g2`-шрифты на устройстве не начнут рисоваться стабильно. ## Критерии ручной проверки Минимально нужно проверить: 1. устройство загружается и сразу открывает `HOME`; экран блокировки временно отключён; 2. текст отображается читаемо хотя бы в ASCII-транслитерации; 3. ввод по экранной клавиатуре работает; 4. после перезагрузки сохранённые поля остаются в памяти; 5. секрет и адрес кошелька сохраняются на устройстве; 6. экран `QR и URI` рисует читаемый QR-код; 7. регистрация блокируется, пока условия не выполнены; 8. после выполнения условий регистрация становится доступной; 9. список запросов и экран подтверждения работают; 10. полный сброс действительно очищает сохранённое состояние.