ESP32: добавить UI сабсервера, PIN-ввод пока не работает

This commit is contained in:
AidarKC
2026-06-08 12:25:54 +04:00
parent 885cf463a7
commit b9185e761b
10 changed files with 3043 additions and 3 deletions
@@ -0,0 +1,478 @@
# SHiNE ESP32 Subserver UI Spec
## Назначение
Этот документ описывает актуальный UI-прототип сабсервера `SHiNE` для платы `Waveshare ESP32-S3-Touch-AMOLED-2.16`.
Документ является источником истины для Arduino-скетча:
- если меняется этот документ, должен меняться и скетч;
- если меняется скетч, должен обновляться и этот документ;
- экраны, кнопки, поля, статусы, переходы и тексты не должны расходиться.
## Текущий объём реализации
Текущая реализация является интерактивным прототипом экрана устройства, пригодным для ручной проверки на железе.
Что уже входит в прототип:
- локальный UI на тач-экране;
- хранение настроек и секретов во внутренней памяти `ESP32` через `NVS`;
- русский текст на экране через `UTF-8` + кириллический шрифт `U8g2`;
- экран пополнения с реальным `solana:` URI и рисованием QR-кода;
- реальное подключение к `Wi-Fi` по сохранённым `SSID/паролю`;
- реальная проверка доступности `API`, `RPC` и `WS`-адресов;
- реальное чтение баланса кошелька из `Solana RPC`;
- проверка обязательных условий перед регистрацией;
- живая on-chain регистрация серверного `user_pda` в `shine_users` через `device key` устройства;
- прототип входящих запросов с подтверждением и отклонением;
- PIN-блокировка;
- базовые настройки, статус и главный экран;
- сохранение `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`, `сервер`, `регистрация`.
- Основной язык прототипа: русский.
- Для вывода текста используется `UTF-8`.
- Для кириллицы используется `U8g2`-шрифт с поддержкой `Cyrillic`.
- Кнопки крупные, с тач-ориентированным размером.
- Опасные действия подтверждаются отдельным диалогом.
- После изменения данных конфигурация сразу сохраняется в `NVS`.
## Экран LOCK
Назначение:
- блокировка устройства после запуска;
- вход по 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:<wallet>?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`;
- вызывать `gfx->setUTF8Print(true)`;
- использовать шрифт `U8g2` с поддержкой `Cyrillic`;
- не полагаться на стандартный `ASCII`-шрифт `Arduino_GFX` для русского текста.
Если эти условия нарушены, UI считается сломанным даже при правильной логике экранов.
## Критерии ручной проверки
Минимально нужно проверить:
1. устройство загружается и показывает экран блокировки;
2. русский текст отображается без кракозябр;
3. ввод по экранной клавиатуре работает;
4. после перезагрузки сохранённые поля остаются в памяти;
5. секрет и адрес кошелька сохраняются на устройстве;
6. экран `QR и URI` рисует читаемый QR-код;
7. регистрация блокируется, пока условия не выполнены;
8. после выполнения условий регистрация становится доступной;
9. список запросов и экран подтверждения работают;
10. полный сброс действительно очищает сохранённое состояние.