From 7fa7c3d6da91b1bbffd4576067d57e4963c5b8eb Mon Sep 17 00:00:00 2001 From: DanS Date: Sat, 3 Oct 2026 19:52:10 -0500 Subject: [PATCH] fix(lite): drop the 15 s startup overlay and a TLS connection per refresh - The refresh-model mapper marks the encryption state known when the backend reports it. The wallet tabs wait for that, so every Lite launch sat behind the loading overlay until the 15 s "assume unencrypted" fallback. - Each 2 s refresh skips the backend's `info` (a fresh TLS connection and GetLightdInfo, only a fallback for the chat tip, which the explicit height call already provides) and the gateway's `height` (replaced by that explicit call, which runs after the sync commands so it sees the newest block). Co-Authored-By: Claude Opus 5.5 --- src/wallet/lite_wallet_controller.cpp | 10 +++++++++- tests/test_phase4.cpp | 9 +++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/wallet/lite_wallet_controller.cpp b/src/wallet/lite_wallet_controller.cpp index 2818cf6..f5fa3e9 100644 --- a/src/wallet/lite_wallet_controller.cpp +++ b/src/wallet/lite_wallet_controller.cpp @@ -239,9 +239,12 @@ void applyLiteRefreshModelToWalletState(const LiteWalletAppRefreshModel& model, } if (model.hasEncryptionStatus) { - // Reflect backend encryption state so isLocked()/isEncrypted() gate the UI correctly. + // Reflect backend encryption state so isLocked()/isEncrypted() gate the UI correctly, and mark + // it known: the wallet tabs wait for that, and without it lite always sat behind the loading + // overlay until its 15 s "assume unencrypted" fallback. state.encrypted = model.encrypted; state.locked = model.locked; + state.encryption_state_known = true; } } @@ -744,6 +747,11 @@ std::optional LiteWalletController::refreshModel() // Synced: full refresh (balance/addresses/transactions are fast now). LiteWalletRefreshRequest request; + // Skip `info` (a fresh TLS connection + GetLightdInfo every cycle, and only a fallback for the chat + // tip, which the height below already provides) and the gateway's `height` (the explicit call after + // the refresh replaces it, and runs after the syncing commands so it sees the newest block). + request.includeInfo = false; + request.includeHeight = false; if (syncResult.ok) { request.haveSyncStatus = true; request.syncStatus = syncResult.syncStatus; diff --git a/tests/test_phase4.cpp b/tests/test_phase4.cpp index 03a720c..b0be774 100644 --- a/tests/test_phase4.cpp +++ b/tests/test_phase4.cpp @@ -6840,6 +6840,15 @@ void testLiteWalletControllerEncryption() applyLiteRefreshModelToWalletState(model, state); EXPECT_TRUE(state.isEncrypted()); EXPECT_TRUE(state.isLocked()); + // ...and marks it known: the wallet tabs wait for that (lite used to sit behind the loading + // overlay until the 15 s "assume unencrypted" fallback). + EXPECT_TRUE(state.encryption_state_known); + + LiteWalletAppRefreshModel syncOnly; + syncOnly.hasSyncStatus = true; + dragonx::WalletState untouched; + applyLiteRefreshModelToWalletState(syncOnly, untouched); + EXPECT_FALSE(untouched.encryption_state_known); } }