upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/gui.cpp
diff options
context:
space:
mode:
authormtg0001 <106211915+mtg0001@users.noreply.github.com>2026-08-03 10:43:42 -0300
committerGitHub <noreply@github.com>2026-08-03 10:43:42 -0300
commit57441faffb02f4f2eea37d31b29728de25f18bef (patch)
treeedade03dddf472790e8bc7e3bc52d3e8f8eac87b /src/gui.cpp
parent5e37647023463cec4331dc48dc360ba60b22c888 (diff)
Add wallet recovery balance audit (#117)
Co-authored-by: Gilcimar Duarte <ti@gpm.infra>
Diffstat (limited to 'src/gui.cpp')
-rw-r--r--src/gui.cpp54
1 files changed, 52 insertions, 2 deletions
diff --git a/src/gui.cpp b/src/gui.cpp
index e3a8499..2335bf9 100644
--- a/src/gui.cpp
+++ b/src/gui.cpp
@@ -65,6 +65,8 @@ static std::string g_sendStatus;
65static char g_backupPath[512] = {}; 65static char g_backupPath[512] = {};
66static std::string g_backupStatus; 66static std::string g_backupStatus;
67static int64 g_lastWalletBackup = 0; 67static int64 g_lastWalletBackup = 0;
68static WalletRecoveryAudit g_recoveryAudit;
69static int64 g_recoveryAuditTime = 0;
68static bool g_walletSafetyLoaded = false; 70static bool g_walletSafetyLoaded = false;
69static char g_participantPool[256] = {}; 71static char g_participantPool[256] = {};
70static char g_poolName[128] = {}; 72static char g_poolName[128] = {};
@@ -184,6 +186,15 @@ static void LoadWalletSafetyState()
184 g_walletSafetyLoaded = true; 186 g_walletSafetyLoaded = true;
185} 187}
186 188
189static void RefreshRecoveryAudit(bool fForce=false)
190{
191 int64 nNow = GetTime();
192 if (!fForce && g_recoveryAuditTime != 0 && nNow - g_recoveryAuditTime < 5)
193 return;
194 g_recoveryAudit = GetWalletRecoveryAudit();
195 g_recoveryAuditTime = nNow;
196}
197
187static int KeyPoolCount() 198static int KeyPoolCount()
188{ 199{
189 int n = 0; 200 int n = 0;
@@ -267,7 +278,11 @@ static void RefreshWallet()
267 g_lastWalletRefresh = GetTime(); 278 g_lastWalletRefresh = GetTime();
268} 279}
269 280
270void MainFrameRepaint() { g_needRefresh = true; } 281void MainFrameRepaint()
282{
283 g_needRefresh = true;
284 g_recoveryAuditTime = 0;
285}
271 286
272// DateTimeStr moved to util.cpp: main.cpp logs block times with it, so it is 287// DateTimeStr moved to util.cpp: main.cpp logs block times with it, so it is
273// needed by builds that have no GUI at all. 288// needed by builds that have no GUI at all.
@@ -967,6 +982,7 @@ static void RestoreThread(std::string strPhrase)
967 "Check the words and their order.", nDerived); 982 "Check the words and their order.", nDerived);
968 } 983 }
969 g_restoreRunning.store(false); 984 g_restoreRunning.store(false);
985 g_recoveryAuditTime = 0;
970 g_needRefresh = true; 986 g_needRefresh = true;
971} 987}
972 988
@@ -1021,6 +1037,7 @@ static void DrawCreatePhraseDialog()
1021 if (SetHDSeedFromMnemonic(g_pendingMnemonic, strError)) 1037 if (SetHDSeedFromMnemonic(g_pendingMnemonic, strError))
1022 { 1038 {
1023 TopUpKeyPool(); 1039 TopUpKeyPool();
1040 g_recoveryAuditTime = 0;
1024 g_phraseStatus = "Recovery phrase created. New addresses come from it."; 1041 g_phraseStatus = "Recovery phrase created. New addresses come from it.";
1025 } 1042 }
1026 else 1043 else
@@ -1141,8 +1158,9 @@ static void DrawWalletSafetyDialog()
1141{ 1158{
1142 if (!g_showWalletSafety) return; 1159 if (!g_showWalletSafety) return;
1143 LoadWalletSafetyState(); 1160 LoadWalletSafetyState();
1161 RefreshRecoveryAudit();
1144 1162
1145 ImGui::SetNextWindowSize(ImVec2(650.0f, 390.0f), ImGuiCond_Always); 1163 ImGui::SetNextWindowSize(ImVec2(650.0f, 450.0f), ImGuiCond_Always);
1146 ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), 1164 ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(),
1147 ImGuiCond_Always, ImVec2(0.5f, 0.5f)); 1165 ImGuiCond_Always, ImVec2(0.5f, 0.5f));
1148 if (ImGui::Begin("Wallet Safety", &g_showWalletSafety, 1166 if (ImGui::Begin("Wallet Safety", &g_showWalletSafety,
@@ -1229,6 +1247,38 @@ static void DrawWalletSafetyDialog()
1229 ImGui::TextColored(ImVec4(1.0f, 0.75f, 0.25f, 1.0f), 1247 ImGui::TextColored(ImVec4(1.0f, 0.75f, 0.25f, 1.0f),
1230 "No recovery phrase. Only a file backup can rebuild this wallet."); 1248 "No recovery phrase. Only a file backup can rebuild this wallet.");
1231 1249
1250 ImGui::Text("Phrase-backed spendable balance: %s BTF",
1251 FmtMoney(g_recoveryAudit.nRecoverableCredit).c_str());
1252 ImGui::Text("Wallet.dat-only spendable balance: %s BTF",
1253 FmtMoney(g_recoveryAudit.nLegacyCredit).c_str());
1254 ImGui::Text("Phrase-backed immature mining rewards: %s BTF",
1255 FmtMoney(g_recoveryAudit.nRecoverableImmatureCredit).c_str());
1256 ImGui::Text("Wallet.dat-only immature mining rewards: %s BTF",
1257 FmtMoney(g_recoveryAudit.nLegacyImmatureCredit).c_str());
1258 if (!g_recoveryAudit.fDeriveComplete)
1259 {
1260 ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.75f, 0.25f, 1.0f));
1261 ImGui::TextWrapped("%s", g_recoveryAudit.strDeriveError.c_str());
1262 ImGui::PopStyleColor();
1263 }
1264 if (g_recoveryAudit.nLegacyCredit > 0 ||
1265 g_recoveryAudit.nLegacyImmatureCredit > 0)
1266 {
1267 ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.75f, 0.25f, 1.0f));
1268 ImGui::TextWrapped(
1269 "Some coins are on keys the phrase does not reproduce. "
1270 "Keep wallet.dat backups until that balance has been moved to a "
1271 "phrase-backed address.");
1272 ImGui::PopStyleColor();
1273 }
1274 else if (HaveHDSeed() &&
1275 g_recoveryAudit.nRecoverableCredit +
1276 g_recoveryAudit.nRecoverableImmatureCredit > 0)
1277 {
1278 ImGui::TextColored(ImVec4(0.55f, 1.0f, 0.6f, 1.0f),
1279 "All known wallet balance is covered by the phrase.");
1280 }
1281
1232 if (!HaveHDSeed()) 1282 if (!HaveHDSeed())
1233 { 1283 {
1234 if (ImGui::Button("Create recovery phrase", ImVec2(200.0f, 0.0f))) 1284 if (ImGui::Button("Create recovery phrase", ImVec2(200.0f, 0.0f)))