From 4eed4283d65a6043843993ba4341b87e3d32c550 Mon Sep 17 00:00:00 2001 From: DanS Date: Sat, 3 Oct 2026 19:52:10 -0500 Subject: [PATCH] fix(chat): provision the chat identity after an encrypted wallet unlocks Lite opens an encrypted wallet locked, but the model saying so arrives a moment later. The first seed export therefore failed with "locked" and disabled chat for good, so encrypted Lite wallets never got chat. - While the wallet is locked, a failure recorded before the lock was seen is cleared, so provisioning runs again after the unlock (like lockLiteWallet()). Nothing is retried while locked: that branch returns before any RPC or backend call. - Lite waits for the first model's lock state before exporting the seed. Co-Authored-By: Claude Opus 5.5 --- src/app_network.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/app_network.cpp b/src/app_network.cpp index 2820483..383a8e7 100644 --- a/src/app_network.cpp +++ b/src/app_network.cpp @@ -3326,6 +3326,11 @@ void App::maybeProvisionChatIdentity() // isLocked()==false and fall through. if (state_.isLocked()) { if (chat_identity_provisioned_ || chat_service_.hasIdentity()) resetChatSession(); + // A failure recorded before the lock was seen isn't final: lite opens an encrypted wallet + // LOCKED, but the model saying so arrives a moment later, so the first seed export fails with + // "locked" and used to disable chat for good. Re-arm for the next unlock, like lockLiteWallet(). + // Nothing is retried while locked: this returns before any RPC or backend call. + chat_identity_unavailable_ = false; return; } @@ -3338,6 +3343,7 @@ void App::maybeProvisionChatIdentity() if (supportsLiteBackend()) { // Lite: the backend's `seed` command returns the 24-word mnemonic synchronously. if (!lite_wallet_ || !lite_wallet_->walletOpen()) return; + if (!state_.encryption_state_known) return; // wait for the first model's lock state wallet::LiteSeedResult seed = lite_wallet_->exportSeed(); if (!seed.ok || seed.seedPhrase.empty()) { wallet::secureWipeLiteSecret(seed.seedPhrase);