SHA256
homeserver: рендейм subserver→homeserver, документ деривации ключей, запрет пустого пароля
Основное (наша работа в этой сессии): - Переименование «subserver» → «homeserver» по всему проекту: основной ESP32-скетч (папка shine_subserver_ui → shine_homeserver_ui, .ino, flash-скрипт, режим burn.sh homeserver-ui), скетч lvgl_nav_minimal_test (ключ homeserver.key:<имя>), spec-доки reference/*, формат PDA (терминология session_type=100 «Homeserver пользователя»), константа SESSION_TYPE_HOMESERVER в JS и Rust (значение 100 не менялось, формат не затронут), pending/future доки, AGENTS.md, DAO-док. Сохранены отдельный lvgl_subserver_touch_test и историческая пометка о рендейме в DERIVATION.md. - Новый источник истины по деривации ключей: Dev_Docs/Keys/DERIVATION.md (Argon2id-секрет из пароля, формула Ed25519(SHA-256(base64(secret)|suffix)), суффиксы root/bch/dev/homeserver.key, Solana-ключ = dev.key). Уточнены роли root (главный/master) и dev (пополняемый кошелёк) в Dev_Docs/Keys/README.md. - UI: убран легаси-путь пустого пароля (derivePasswordSeed и др.), deriveMasterSecretFromPassword бросает ошибку на пустом пароле, register-view блокирует пустой пароль; экран пополнения переведён на канонический device-адрес из preGeneratedKeyBundle (удалён расходящийся deriveWalletFromPassword). Включены также параллельные правки Solana-аудита №3 (были в рабочем дереве, переплетены в lib.rs): - shine_users: defense-in-depth «строгий список аккаунтов» (require!(it.next().is_none())) в init/update economy config и create/update user PDA, плюс описание в doc/programs/shine_users.md; - Dev_Docs/audit/Solana-audit-3-by-Claude-12июня2026.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
cf6a2830c8
commit
42dcf6970d
@@ -2,7 +2,7 @@
|
||||
|
||||
Набор отдельных диагностических скетчей для `Waveshare ESP32-S3-Touch-AMOLED-2.16`.
|
||||
|
||||
Скетчи в этой папке нужны для быстрой проверки конкретных гипотез без влияния на основной `shine_subserver_ui`.
|
||||
Скетчи в этой папке нужны для быстрой проверки конкретных гипотез без влияния на основной `shine_homeserver_ui`.
|
||||
|
||||
## Список
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
- `lvgl_interaction_test/` - расширенный тест `LVGL` с 9 кнопками, touch-вводом и статусом нажатия
|
||||
- `lvgl_touch_debug_test/` - диагностика touch: сырые координаты, точка касания и одна большая кнопка `LVGL`
|
||||
- `lvgl_official_based_test/` - минимальный наш экран поверх максимально близкой к официальному `05_LVGL_Widgets` инициализации
|
||||
- `lvgl_subserver_touch_test/` - гибридный тест: `LVGL`-экран с инициализацией дисплея и чтением touch из `shine_subserver_ui`; подтверждён на реальном устройстве
|
||||
- `lvgl_subserver_touch_test/` - гибридный тест: `LVGL`-экран с инициализацией дисплея и чтением touch из `shine_homeserver_ui`; подтверждён на реальном устройстве
|
||||
- `lvgl_russian_font_test/` - тест кастомного кириллического `LVGL`-шрифта с русскими кнопками, длинными строками и рабочим touch
|
||||
- `lvgl_nav_minimal_test/` - новый минимальный навигационный каркас сабсервера на рабочем `LVGL + subserver touch`, расширенный настройкой Wi-Fi и сохранением в NVS
|
||||
|
||||
|
||||
+67
-67
@@ -48,7 +48,7 @@
|
||||
#define TEXT_EDIT_PANEL_Y 112
|
||||
#define TEXT_EDIT_PANEL_W 460
|
||||
#define TEXT_EDIT_PANEL_H 330
|
||||
#define TEST_VERSION "SHiNE subserver (v.0.18)"
|
||||
#define TEST_VERSION "SHiNE homeserver (v.0.18)"
|
||||
|
||||
static const char *kShineUsersProgramId = "FZS1YctoeEhCkZ5VTjsysUFAXR8CqxYztcLboXcg2Rpm";
|
||||
static const char *kShineUsersUserPdaSeedPrefix = "user_login=";
|
||||
@@ -60,7 +60,7 @@ static const uint8_t kBlockTypeServerProfile = 30;
|
||||
static const uint8_t kBlockTypeAccessServers = 40;
|
||||
static const uint8_t kBlockTypeSessions = 50;
|
||||
static const uint8_t kBlockTypeTrustedState = 70;
|
||||
static const uint8_t kSessionTypeSubserver = 100;
|
||||
static const uint8_t kSessionTypeHomeserver = 100;
|
||||
|
||||
enum Screen {
|
||||
SCREEN_HOME,
|
||||
@@ -68,7 +68,7 @@ enum Screen {
|
||||
SCREEN_WIFI,
|
||||
SCREEN_SERVER,
|
||||
SCREEN_ACCOUNT,
|
||||
SCREEN_ACCOUNT_SUBSERVER,
|
||||
SCREEN_ACCOUNT_HOMESERVER,
|
||||
SCREEN_ACCOUNT_SECRET,
|
||||
SCREEN_SECRET_SHOW,
|
||||
SCREEN_SECRET_GENERATE_INFO,
|
||||
@@ -99,10 +99,10 @@ enum ActionId {
|
||||
ACTION_SERVER_EDIT_SOLANA,
|
||||
ACTION_SERVER_EDIT_SHINE,
|
||||
ACTION_ACCOUNT_EDIT_LOGIN,
|
||||
ACTION_ACCOUNT_EDIT_SUBSERVER,
|
||||
ACTION_ACCOUNT_EDIT_HOMESERVER,
|
||||
ACTION_ACCOUNT_EDIT_SECRET,
|
||||
ACTION_ACCOUNT_SUBSERVER_USE_DEFAULT,
|
||||
ACTION_ACCOUNT_SUBSERVER_EDIT_MANUAL,
|
||||
ACTION_ACCOUNT_HOMESERVER_USE_DEFAULT,
|
||||
ACTION_ACCOUNT_HOMESERVER_EDIT_MANUAL,
|
||||
ACTION_SECRET_SHOW,
|
||||
ACTION_SECRET_MANUAL,
|
||||
ACTION_SECRET_GENERATE,
|
||||
@@ -129,7 +129,7 @@ enum EditContext {
|
||||
EDIT_CONTEXT_SOLANA_RPC,
|
||||
EDIT_CONTEXT_SHINE_SERVER,
|
||||
EDIT_CONTEXT_LOGIN,
|
||||
EDIT_CONTEXT_SUBSERVER,
|
||||
EDIT_CONTEXT_HOMESERVER,
|
||||
EDIT_CONTEXT_SECRET_MANUAL,
|
||||
EDIT_CONTEXT_SECRET_GENERATE_PASSWORD,
|
||||
};
|
||||
@@ -216,7 +216,7 @@ static String gSolanaRpcUrl = "https://api.devnet.solana.com";
|
||||
static String gShineServerUrl = "https://shineup.me";
|
||||
static String gServerStatusMessage = "Edit RPC or shine host";
|
||||
static String gLoginValue;
|
||||
static String gSubserverValue = "subserver1";
|
||||
static String gHomeserverValue = "homeserver1";
|
||||
static bool gSecretConfigured = false;
|
||||
static String gSecretBase58;
|
||||
static uint8_t gSecretBytes[32] = {};
|
||||
@@ -257,8 +257,8 @@ static String gBlockchainPubB58;
|
||||
static String gBlockchainPrivB58;
|
||||
static String gDevicePubB58;
|
||||
static String gDevicePrivB58;
|
||||
static String gSubserverPubB58;
|
||||
static String gSubserverPrivB58;
|
||||
static String gHomeserverPubB58;
|
||||
static String gHomeserverPrivB58;
|
||||
|
||||
static EditContext gEditContext = EDIT_CONTEXT_NONE;
|
||||
static Screen gEditReturnScreen = SCREEN_HOME;
|
||||
@@ -305,7 +305,7 @@ static void restoreTextareaFromEditValue();
|
||||
static void refreshDerivedKeys();
|
||||
static void clearDerivedKeys();
|
||||
static String loginDisplayValue();
|
||||
static String subserverDisplayValue();
|
||||
static String homeserverDisplayValue();
|
||||
static String homeSecretStatus();
|
||||
static String secretButtonValue();
|
||||
static void clearSecretValue();
|
||||
@@ -687,13 +687,13 @@ static bool parseUrlHostPortPath(const String &url, String &hostOut, uint16_t &p
|
||||
return hostOut.length() > 0 && portOut > 0;
|
||||
}
|
||||
|
||||
static String subserverKeySuffix() {
|
||||
String name = gSubserverValue;
|
||||
static String homeserverKeySuffix() {
|
||||
String name = gHomeserverValue;
|
||||
name.trim();
|
||||
if (name.isEmpty()) {
|
||||
name = "subserver1";
|
||||
name = "homeserver1";
|
||||
}
|
||||
return String("subserver.key:") + name;
|
||||
return String("homeserver.key:") + name;
|
||||
}
|
||||
|
||||
static void deriveKeyPairFromSecretSuffix(const uint8_t *secret32, const String &suffix, String &pubB58, String &privB58) {
|
||||
@@ -718,8 +718,8 @@ static void clearDerivedKeys() {
|
||||
gBlockchainPrivB58 = "";
|
||||
gDevicePubB58 = "";
|
||||
gDevicePrivB58 = "";
|
||||
gSubserverPubB58 = "";
|
||||
gSubserverPrivB58 = "";
|
||||
gHomeserverPubB58 = "";
|
||||
gHomeserverPrivB58 = "";
|
||||
}
|
||||
|
||||
static void refreshDerivedKeys() {
|
||||
@@ -730,7 +730,7 @@ static void refreshDerivedKeys() {
|
||||
deriveKeyPairFromSecretSuffix(gSecretBytes, "root.key", gRootPubB58, gRootPrivB58);
|
||||
deriveKeyPairFromSecretSuffix(gSecretBytes, "bch.key", gBlockchainPubB58, gBlockchainPrivB58);
|
||||
deriveKeyPairFromSecretSuffix(gSecretBytes, "dev.key", gDevicePubB58, gDevicePrivB58);
|
||||
deriveKeyPairFromSecretSuffix(gSecretBytes, subserverKeySuffix(), gSubserverPubB58, gSubserverPrivB58);
|
||||
deriveKeyPairFromSecretSuffix(gSecretBytes, homeserverKeySuffix(), gHomeserverPubB58, gHomeserverPrivB58);
|
||||
}
|
||||
|
||||
static bool deriveKeypairFromSeed32(const uint8_t seed32[32], uint8_t pub32[32], uint8_t sec64[64]) {
|
||||
@@ -1302,20 +1302,20 @@ static void refreshAccountPdaStatus() {
|
||||
mismatch = "blockchain key mismatch";
|
||||
} else if (memcmp(devicePub, pdaState.deviceKey32, 32) != 0) {
|
||||
mismatch = "device key mismatch";
|
||||
} else if (gSubserverValue.isEmpty()) {
|
||||
mismatch = "subserver not set";
|
||||
} else if (gHomeserverValue.isEmpty()) {
|
||||
mismatch = "homeserver not set";
|
||||
} else {
|
||||
bool foundSession = false;
|
||||
bool sessionMismatch = false;
|
||||
for (const auto &session : pdaState.sessions) {
|
||||
if (session.sessionType == kSessionTypeSubserver && session.sessionName == gSubserverValue) {
|
||||
if (session.sessionType == kSessionTypeHomeserver && session.sessionName == gHomeserverValue) {
|
||||
foundSession = true;
|
||||
if (gSubserverPubB58.isEmpty()) {
|
||||
if (gHomeserverPubB58.isEmpty()) {
|
||||
sessionMismatch = true;
|
||||
} else {
|
||||
uint8_t subserverPub[32] = {};
|
||||
if (!base58ToFixed32(gSubserverPubB58, subserverPub)
|
||||
|| memcmp(subserverPub, session.sessionPubKey32, 32) != 0) {
|
||||
uint8_t homeserverPub[32] = {};
|
||||
if (!base58ToFixed32(gHomeserverPubB58, homeserverPub)
|
||||
|| memcmp(homeserverPub, session.sessionPubKey32, 32) != 0) {
|
||||
sessionMismatch = true;
|
||||
}
|
||||
}
|
||||
@@ -1323,9 +1323,9 @@ static void refreshAccountPdaStatus() {
|
||||
}
|
||||
}
|
||||
if (!foundSession) {
|
||||
mismatch = "subserver not in PDA";
|
||||
mismatch = "homeserver not in PDA";
|
||||
} else if (sessionMismatch) {
|
||||
mismatch = "subserver key mismatch";
|
||||
mismatch = "homeserver key mismatch";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1565,7 +1565,7 @@ static bool ensureShineSessionAuthenticated(String &errorOut) {
|
||||
errorOut = "Wi-Fi disconnected";
|
||||
return false;
|
||||
}
|
||||
if (gLoginValue.isEmpty() || !gSecretConfigured || gSubserverValue.isEmpty()) {
|
||||
if (gLoginValue.isEmpty() || !gSecretConfigured || gHomeserverValue.isEmpty()) {
|
||||
errorOut = "account not configured";
|
||||
return false;
|
||||
}
|
||||
@@ -1605,7 +1605,7 @@ static bool ensureShineSessionAuthenticated(String &errorOut) {
|
||||
uint8_t subPub[32] = {};
|
||||
uint8_t subSec[64] = {};
|
||||
if (!deriveSeedKeypairFromBase58(gDevicePrivB58, deviceSeed, devicePub, deviceSec)
|
||||
|| !deriveSeedKeypairFromBase58(gSubserverPrivB58, subSeed, subPub, subSec)) {
|
||||
|| !deriveSeedKeypairFromBase58(gHomeserverPrivB58, subSeed, subPub, subSec)) {
|
||||
errorOut = "local key derive failed";
|
||||
return false;
|
||||
}
|
||||
@@ -1634,7 +1634,7 @@ static bool ensureShineSessionAuthenticated(String &errorOut) {
|
||||
+ "\",\"sessionKey\":\"" + jsonEscape(sessionKey)
|
||||
+ "\",\"timeMs\":" + String((unsigned long long)timeMs)
|
||||
+ ",\"signatureB64\":\"" + jsonEscape(bytesToBase64String(signature, 64))
|
||||
+ "\",\"clientInfo\":\"ESP32 subserver\"}";
|
||||
+ "\",\"clientInfo\":\"ESP32 homeserver\"}";
|
||||
String loginResp;
|
||||
if (shineWsRequest(gShineWs, "SessionLogin", loginReq, loginResp)) {
|
||||
if (jsonInt64Field(loginResp, "status", statusCode) && statusCode == 200) {
|
||||
@@ -1691,7 +1691,7 @@ static bool ensureShineSessionAuthenticated(String &errorOut) {
|
||||
+ ",\"authNonce\":\"" + jsonEscape(authNonce)
|
||||
+ "\",\"deviceKey\":\"" + jsonEscape(bytesToBase64String(devicePub, 32))
|
||||
+ "\",\"signatureB64\":\"" + jsonEscape(bytesToBase64String(signature, 64))
|
||||
+ "\",\"clientInfo\":\"ESP32 subserver\"}";
|
||||
+ "\",\"clientInfo\":\"ESP32 homeserver\"}";
|
||||
String createResp;
|
||||
if (!shineWsRequest(gShineWs, "CreateAuthSession", createReq, createResp)) {
|
||||
errorOut = "CreateAuthSession failed";
|
||||
@@ -1710,7 +1710,7 @@ static bool ensureShineSessionAuthenticated(String &errorOut) {
|
||||
|
||||
static void manageShineConnection() {
|
||||
String serverLabel = gShineServerUrl.isEmpty() ? "not set" : gShineServerUrl;
|
||||
if (gLoginValue.isEmpty() || !gSecretConfigured || gSubserverValue.isEmpty()) {
|
||||
if (gLoginValue.isEmpty() || !gSecretConfigured || gHomeserverValue.isEmpty()) {
|
||||
gShineStatusLine = String("SHiNE: ") + serverLabel + " account not configured";
|
||||
clearShineSessionState(false);
|
||||
return;
|
||||
@@ -1802,7 +1802,7 @@ static void loadPrefs() {
|
||||
gSolanaRpcUrl = gPrefs.getString("solana_rpc", "https://api.devnet.solana.com");
|
||||
gShineServerUrl = gPrefs.getString("shine_server", "https://shineup.me");
|
||||
gLoginValue = gPrefs.getString("login", "");
|
||||
gSubserverValue = gPrefs.getString("subserver", "subserver1");
|
||||
gHomeserverValue = gPrefs.getString("homeserver", "homeserver1");
|
||||
gSecretConfigured = gPrefs.getBool("secret_set", false);
|
||||
gSecretBase58 = gPrefs.getString("secret_b58", "");
|
||||
if (gSecretConfigured && gPrefs.getBytesLength("secret_bytes") == 32) {
|
||||
@@ -1850,7 +1850,7 @@ static void saveServerPrefs() {
|
||||
|
||||
static void saveAccountPrefs() {
|
||||
gPrefs.putString("login", gLoginValue);
|
||||
gPrefs.putString("subserver", gSubserverValue);
|
||||
gPrefs.putString("homeserver", gHomeserverValue);
|
||||
gPrefs.putBool("secret_set", gSecretConfigured);
|
||||
gPrefs.putString("secret_b58", gSecretBase58);
|
||||
if (gSecretConfigured) {
|
||||
@@ -1925,8 +1925,8 @@ static String loginDisplayValue() {
|
||||
return gLoginValue.isEmpty() ? "login not set" : gLoginValue;
|
||||
}
|
||||
|
||||
static String subserverDisplayValue() {
|
||||
return gSubserverValue.isEmpty() ? "subserver not set" : gSubserverValue;
|
||||
static String homeserverDisplayValue() {
|
||||
return gHomeserverValue.isEmpty() ? "homeserver not set" : gHomeserverValue;
|
||||
}
|
||||
|
||||
static String homeSecretStatus() {
|
||||
@@ -2234,13 +2234,13 @@ static void applyEditorValue() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (gEditContext == EDIT_CONTEXT_SUBSERVER) {
|
||||
if (gEditContext == EDIT_CONTEXT_HOMESERVER) {
|
||||
value.trim();
|
||||
gSubserverValue = value;
|
||||
gHomeserverValue = value;
|
||||
refreshDerivedKeys();
|
||||
saveAccountPrefs();
|
||||
markAccountStateDirty();
|
||||
gAccountStatusMessage = gSubserverValue.isEmpty() ? "Subserver cleared" : "Subserver saved";
|
||||
gAccountStatusMessage = gHomeserverValue.isEmpty() ? "Homeserver cleared" : "Homeserver saved";
|
||||
showScreen(SCREEN_ACCOUNT);
|
||||
return;
|
||||
}
|
||||
@@ -2465,8 +2465,8 @@ static void actionButtonCb(lv_event_t *event) {
|
||||
gLoginValue,
|
||||
false);
|
||||
break;
|
||||
case ACTION_ACCOUNT_EDIT_SUBSERVER:
|
||||
showScreen(SCREEN_ACCOUNT_SUBSERVER);
|
||||
case ACTION_ACCOUNT_EDIT_HOMESERVER:
|
||||
showScreen(SCREEN_ACCOUNT_HOMESERVER);
|
||||
break;
|
||||
case ACTION_ACCOUNT_EDIT_SECRET:
|
||||
showScreen(SCREEN_ACCOUNT_SECRET);
|
||||
@@ -2506,20 +2506,20 @@ static void actionButtonCb(lv_event_t *event) {
|
||||
case ACTION_SECRET_GENERATE_CANCEL_NO:
|
||||
showScreen(SCREEN_SECRET_GENERATE_RUNNING);
|
||||
break;
|
||||
case ACTION_ACCOUNT_SUBSERVER_USE_DEFAULT:
|
||||
gSubserverValue = "subserver1";
|
||||
case ACTION_ACCOUNT_HOMESERVER_USE_DEFAULT:
|
||||
gHomeserverValue = "homeserver1";
|
||||
refreshDerivedKeys();
|
||||
saveAccountPrefs();
|
||||
markAccountStateDirty();
|
||||
gAccountStatusMessage = "Subserver set to subserver1";
|
||||
gAccountStatusMessage = "Homeserver set to homeserver1";
|
||||
showScreen(SCREEN_ACCOUNT);
|
||||
break;
|
||||
case ACTION_ACCOUNT_SUBSERVER_EDIT_MANUAL:
|
||||
openEditor(EDIT_CONTEXT_SUBSERVER,
|
||||
case ACTION_ACCOUNT_HOMESERVER_EDIT_MANUAL:
|
||||
openEditor(EDIT_CONTEXT_HOMESERVER,
|
||||
SCREEN_ACCOUNT,
|
||||
"EDIT SUBSERVER",
|
||||
"EDIT HOMESERVER",
|
||||
"",
|
||||
gSubserverValue,
|
||||
gHomeserverValue,
|
||||
false);
|
||||
break;
|
||||
case ACTION_BACK_SECRET_MENU:
|
||||
@@ -2616,17 +2616,17 @@ static void makeVersionTag() {
|
||||
static void drawHome() {
|
||||
setRootStyle();
|
||||
|
||||
lv_obj_t *subserver = lv_label_create(gRoot);
|
||||
lv_label_set_text(subserver, subserverDisplayValue().c_str());
|
||||
lv_obj_set_style_text_font(subserver, &lv_font_montserrat_18, 0);
|
||||
lv_obj_set_style_text_color(subserver, lv_color_hex(0xFFFFFF), 0);
|
||||
lv_obj_align(subserver, LV_ALIGN_TOP_LEFT, 24, 18);
|
||||
lv_obj_t *homeserver = lv_label_create(gRoot);
|
||||
lv_label_set_text(homeserver, homeserverDisplayValue().c_str());
|
||||
lv_obj_set_style_text_font(homeserver, &lv_font_montserrat_18, 0);
|
||||
lv_obj_set_style_text_color(homeserver, lv_color_hex(0xFFFFFF), 0);
|
||||
lv_obj_align(homeserver, LV_ALIGN_TOP_LEFT, 24, 18);
|
||||
|
||||
lv_obj_t *login = lv_label_create(gRoot);
|
||||
lv_label_set_text(login, loginDisplayValue().c_str());
|
||||
lv_obj_set_style_text_font(login, &lv_font_montserrat_22, 0);
|
||||
lv_obj_set_style_text_color(login, lv_color_hex(0xD5DEE7), 0);
|
||||
lv_obj_align_to(login, subserver, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 6);
|
||||
lv_obj_align_to(login, homeserver, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 6);
|
||||
|
||||
lv_obj_t *accountDot = lv_obj_create(gRoot);
|
||||
lv_obj_set_size(accountDot, 14, 14);
|
||||
@@ -2793,23 +2793,23 @@ static void drawAccountScreen() {
|
||||
showMessageAt(gAccountStatusMessage, 56);
|
||||
|
||||
String loginButton = String("Login (") + (gLoginValue.isEmpty() ? "not set" : gLoginValue) + ")";
|
||||
String subserverButton = String("Subserver (") + (gSubserverValue.isEmpty() ? "not set" : gSubserverValue) + ")";
|
||||
String homeserverButton = String("Homeserver (") + (gHomeserverValue.isEmpty() ? "not set" : gHomeserverValue) + ")";
|
||||
String secretButton = String("Secret (") + secretButtonValue() + ")";
|
||||
|
||||
makeButton(loginButton.c_str(), 22, 118, 436, 84, 0x355C7D, ACTION_ACCOUNT_EDIT_LOGIN, &lv_font_montserrat_20);
|
||||
makeButton(subserverButton.c_str(), 22, 222, 436, 84, 0x355C7D, ACTION_ACCOUNT_EDIT_SUBSERVER, &lv_font_montserrat_20);
|
||||
makeButton(homeserverButton.c_str(), 22, 222, 436, 84, 0x355C7D, ACTION_ACCOUNT_EDIT_HOMESERVER, &lv_font_montserrat_20);
|
||||
makeButton(secretButton.c_str(), 22, 326, 436, 84, 0x355C7D, ACTION_ACCOUNT_EDIT_SECRET, &lv_font_montserrat_20);
|
||||
makeBody("Swipe right to return to Settings.", 420, 420);
|
||||
makeVersionTag();
|
||||
}
|
||||
|
||||
static void drawAccountSubserverScreen() {
|
||||
static void drawAccountHomeserverScreen() {
|
||||
setRootStyle();
|
||||
makeTitle("SUBSERVER", 18, &lv_font_montserrat_24);
|
||||
showMessageAt(String("Current: ") + subserverDisplayValue(), 56);
|
||||
makeBody("If you only use one subserver, keep the default name subserver1.", 98, 420);
|
||||
makeButton("USE SUBSERVER1", 22, 202, 436, 84, 0x2A9D8F, ACTION_ACCOUNT_SUBSERVER_USE_DEFAULT, &lv_font_montserrat_22);
|
||||
makeButton("EDIT MANUALLY", 22, 306, 436, 84, 0x355C7D, ACTION_ACCOUNT_SUBSERVER_EDIT_MANUAL, &lv_font_montserrat_22);
|
||||
makeTitle("HOMESERVER", 18, &lv_font_montserrat_24);
|
||||
showMessageAt(String("Current: ") + homeserverDisplayValue(), 56);
|
||||
makeBody("If you only use one homeserver, keep the default name homeserver1.", 98, 420);
|
||||
makeButton("USE HOMESERVER1", 22, 202, 436, 84, 0x2A9D8F, ACTION_ACCOUNT_HOMESERVER_USE_DEFAULT, &lv_font_montserrat_22);
|
||||
makeButton("EDIT MANUALLY", 22, 306, 436, 84, 0x355C7D, ACTION_ACCOUNT_HOMESERVER_EDIT_MANUAL, &lv_font_montserrat_22);
|
||||
makeButton("BACK", 140, 402, 200, 54, 0x5A6570, ACTION_BACK_ACCOUNT, &lv_font_montserrat_20);
|
||||
makeVersionTag();
|
||||
}
|
||||
@@ -2876,8 +2876,8 @@ static void drawSecretShowScreen() {
|
||||
addKeyBlock("Blockchain key priv (base58)", "sha256(base64(secret)|bch.key)", gBlockchainPrivB58);
|
||||
addKeyBlock("Device key (base58)", "pub from sha256(base64(secret)|dev.key)", gDevicePubB58);
|
||||
addKeyBlock("Device key priv (base58)", "sha256(base64(secret)|dev.key)", gDevicePrivB58);
|
||||
addKeyBlock("Subserver key (base58)", String("pub from sha256(base64(secret)|") + subserverKeySuffix() + ")", gSubserverPubB58);
|
||||
addKeyBlock("Subserver key priv (base58)", String("sha256(base64(secret)|") + subserverKeySuffix() + ")", gSubserverPrivB58);
|
||||
addKeyBlock("Homeserver key (base58)", String("pub from sha256(base64(secret)|") + homeserverKeySuffix() + ")", gHomeserverPubB58);
|
||||
addKeyBlock("Homeserver key priv (base58)", String("sha256(base64(secret)|") + homeserverKeySuffix() + ")", gHomeserverPrivB58);
|
||||
} else {
|
||||
showMessageAt("Secret not set", 96);
|
||||
}
|
||||
@@ -3084,8 +3084,8 @@ static void rebuildScreen() {
|
||||
case SCREEN_ACCOUNT:
|
||||
drawAccountScreen();
|
||||
break;
|
||||
case SCREEN_ACCOUNT_SUBSERVER:
|
||||
drawAccountSubserverScreen();
|
||||
case SCREEN_ACCOUNT_HOMESERVER:
|
||||
drawAccountHomeserverScreen();
|
||||
break;
|
||||
case SCREEN_ACCOUNT_SECRET:
|
||||
drawAccountSecretScreen();
|
||||
@@ -3219,7 +3219,7 @@ static void handleSwipe(SwipeDirection swipe) {
|
||||
case SCREEN_ACCOUNT:
|
||||
handleAccountSwipe(swipe);
|
||||
break;
|
||||
case SCREEN_ACCOUNT_SUBSERVER:
|
||||
case SCREEN_ACCOUNT_HOMESERVER:
|
||||
case SCREEN_ACCOUNT_SECRET:
|
||||
handleAccountSubscreenSwipe(swipe);
|
||||
break;
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@
|
||||
#include <Arduino_GFX_Library.h>
|
||||
#include <TouchDrvCSTXXX.hpp>
|
||||
|
||||
// Подтверждено на устройстве: LVGL-рендер работает вместе с touch-путём из shine_subserver_ui.
|
||||
// Подтверждено на устройстве: LVGL-рендер работает вместе с touch-путём из shine_homeserver_ui.
|
||||
|
||||
#define PIN_LCD_CS 12
|
||||
#define PIN_LCD_SCLK 38
|
||||
@@ -146,7 +146,7 @@ static void createUi() {
|
||||
lv_obj_align(gVersionLabel, LV_ALIGN_TOP_MID, 0, 12);
|
||||
|
||||
lv_obj_t *subtitle = lv_label_create(screen);
|
||||
lv_label_set_text(subtitle, "Touch path comes from shine_subserver_ui. Tap buttons and watch status.");
|
||||
lv_label_set_text(subtitle, "Touch path comes from shine_homeserver_ui. Tap buttons and watch status.");
|
||||
lv_obj_set_width(subtitle, 436);
|
||||
lv_label_set_long_mode(subtitle, LV_LABEL_LONG_WRAP);
|
||||
lv_obj_set_style_text_font(subtitle, &lv_font_montserrat_14, 0);
|
||||
|
||||
Reference in New Issue
Block a user