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:
Diffstat (limited to 'src/gui.cpp')
-rw-r--r--src/gui.cpp145
1 files changed, 144 insertions, 1 deletions
diff --git a/src/gui.cpp b/src/gui.cpp
index e2bb5cf..df61bb1 100644
--- a/src/gui.cpp
+++ b/src/gui.cpp
@@ -51,11 +51,16 @@ static bool g_showSend = false;
51static bool g_showOptions = false; 51static bool g_showOptions = false;
52static bool g_showAbout = false; 52static bool g_showAbout = false;
53static bool g_showDiagnostics = false; 53static bool g_showDiagnostics = false;
54static bool g_showWalletSafety = false;
54static bool g_needRefresh = true; 55static bool g_needRefresh = true;
55 56
56static char g_sendAddr[128] = {}; 57static char g_sendAddr[128] = {};
57static char g_sendAmount[32] = {}; 58static char g_sendAmount[32] = {};
58static std::string g_sendStatus; 59static std::string g_sendStatus;
60static char g_backupPath[512] = {};
61static std::string g_backupStatus;
62static int64 g_lastWalletBackup = 0;
63static bool g_walletSafetyLoaded = false;
59static char g_participantPool[256] = {}; 64static char g_participantPool[256] = {};
60static char g_poolName[128] = {}; 65static char g_poolName[128] = {};
61static char g_poolFee[32] = {}; 66static char g_poolFee[32] = {};
@@ -115,8 +120,38 @@ static std::string PoolLabel(const BtfPoolAnnouncement& ann)
115 return o.str(); 120 return o.str();
116} 121}
117 122
123static std::string BackupTimeSuffix()
124{
125 return strprintf("%lld", (long long)GetTime());
126}
127
128static void SetDefaultBackupPath()
129{
130 std::string path = GetAppDir() + "/wallet-backup-" + BackupTimeSuffix() + ".dat";
131 strncpy(g_backupPath, path.c_str(), sizeof(g_backupPath)-1);
132 g_backupPath[sizeof(g_backupPath)-1] = '\0';
133}
134
135static void LoadWalletSafetyState()
136{
137 if (g_walletSafetyLoaded)
138 return;
139 CWalletDB("r").ReadSetting("nLastWalletBackup", g_lastWalletBackup);
140 SetDefaultBackupPath();
141 g_walletSafetyLoaded = true;
142}
143
144static int KeyPoolCount()
145{
146 int n = 0;
147 CRITICAL_BLOCK(cs_keyPool)
148 n = (int)mapKeyPool.size();
149 return n;
150}
151
118static void RefreshWallet() 152static void RefreshWallet()
119{ 153{
154 LoadWalletSafetyState();
120 std::vector<unsigned char> vchPubKey; 155 std::vector<unsigned char> vchPubKey;
121 if (CWalletDB("r").ReadDefaultKey(vchPubKey)) 156 if (CWalletDB("r").ReadDefaultKey(vchPubKey))
122 g_myAddress = PubKeyToAddress(vchPubKey); 157 g_myAddress = PubKeyToAddress(vchPubKey);
@@ -307,10 +342,12 @@ static void DrawMainWindow()
307 // ---- Menu bar ---- 342 // ---- Menu bar ----
308 if (ImGui::BeginMenuBar()) { 343 if (ImGui::BeginMenuBar()) {
309 if (ImGui::BeginMenu("File")) { 344 if (ImGui::BeginMenu("File")) {
345 if (ImGui::MenuItem("Backup Wallet")) g_showWalletSafety = true;
310 if (ImGui::MenuItem("Exit")) glfwSetWindowShouldClose(glfwGetCurrentContext(), true); 346 if (ImGui::MenuItem("Exit")) glfwSetWindowShouldClose(glfwGetCurrentContext(), true);
311 ImGui::EndMenu(); 347 ImGui::EndMenu();
312 } 348 }
313 if (ImGui::MenuItem("Options")) g_showOptions = true; 349 if (ImGui::MenuItem("Options")) g_showOptions = true;
350 if (ImGui::MenuItem("Wallet Safety")) g_showWalletSafety = true;
314 if (ImGui::MenuItem("Diagnostics")) g_showDiagnostics = true; 351 if (ImGui::MenuItem("Diagnostics")) g_showDiagnostics = true;
315 if (ImGui::MenuItem("About")) g_showAbout = true; 352 if (ImGui::MenuItem("About")) g_showAbout = true;
316 ImGui::EndMenuBar(); 353 ImGui::EndMenuBar();
@@ -340,6 +377,9 @@ static void DrawMainWindow()
340 if (ImGui::Button(" Send Coins ")) g_showSend = true; 377 if (ImGui::Button(" Send Coins ")) g_showSend = true;
341 ImGui::PopStyleColor(2); 378 ImGui::PopStyleColor(2);
342 379
380 ImGui::SameLine(0.0f, 8.0f);
381 if (ImGui::Button(" Backup Wallet ")) g_showWalletSafety = true;
382
343 ImGui::SameLine(0.0f, 20.0f); 383 ImGui::SameLine(0.0f, 20.0f);
344 if (fGenerateBitcoins) { 384 if (fGenerateBitcoins) {
345 ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.6f, 0.0f, 1.0f)); 385 ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.6f, 0.0f, 1.0f));
@@ -701,7 +741,7 @@ static void DrawOptionsDialog()
701 } 741 }
702 wasOpen = true; 742 wasOpen = true;
703 743
704 ImGui::SetNextWindowSize(ImVec2(500.0f, 335.0f), ImGuiCond_Always); 744 ImGui::SetNextWindowSize(ImVec2(540.0f, 385.0f), ImGuiCond_Always);
705 ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), 745 ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(),
706 ImGuiCond_Always, ImVec2(0.5f, 0.5f)); 746 ImGuiCond_Always, ImVec2(0.5f, 0.5f));
707 if (ImGui::Begin("Options", &g_showOptions, 747 if (ImGui::Begin("Options", &g_showOptions,
@@ -722,6 +762,14 @@ static void DrawOptionsDialog()
722 ImGui::RadioButton("Operator -- run a pool for other miners", &g_mineRadio, MINE_OPERATOR); 762 ImGui::RadioButton("Operator -- run a pool for other miners", &g_mineRadio, MINE_OPERATOR);
723 ImGui::RadioButton("Participant -- mine to someone's pool", &g_mineRadio, MINE_PARTICIPANT); 763 ImGui::RadioButton("Participant -- mine to someone's pool", &g_mineRadio, MINE_PARTICIPANT);
724 764
765 if (g_mineRadio != MINE_RELAY && g_lastWalletBackup == 0) {
766 ImGui::Spacing();
767 ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.75f, 0.25f, 1.0f));
768 ImGui::TextWrapped("Back up this wallet before mining. The key pool covers the next %d generated addresses, but only after you save a backup that contains those keys.", KEYPOOL_SIZE);
769 ImGui::PopStyleColor();
770 if (ImGui::SmallButton("Backup now")) g_showWalletSafety = true;
771 }
772
725 if (g_mineRadio == MINE_OPERATOR) { 773 if (g_mineRadio == MINE_OPERATOR) {
726 ImGui::Spacing(); 774 ImGui::Spacing();
727 ImGui::SeparatorText("Pool Announcement"); 775 ImGui::SeparatorText("Pool Announcement");
@@ -822,6 +870,100 @@ static void DrawOptionsDialog()
822} 870}
823 871
824// --------------------------------------------------------------------------- 872// ---------------------------------------------------------------------------
873// Wallet safety dialog
874// ---------------------------------------------------------------------------
875static void DrawWalletSafetyDialog()
876{
877 if (!g_showWalletSafety) return;
878 LoadWalletSafetyState();
879
880 ImGui::SetNextWindowSize(ImVec2(650.0f, 390.0f), ImGuiCond_Always);
881 ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(),
882 ImGuiCond_Always, ImVec2(0.5f, 0.5f));
883 if (ImGui::Begin("Wallet Safety", &g_showWalletSafety,
884 ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse))
885 {
886 ImGui::SeparatorText("Backup");
887 if (g_lastWalletBackup > 0)
888 ImGui::Text("Last GUI backup: %s", DateTimeStr(g_lastWalletBackup).c_str());
889 else
890 ImGui::TextColored(ImVec4(1.0f, 0.75f, 0.25f, 1.0f),
891 "Last GUI backup: never");
892
893 ImGui::TextDisabled("Data directory:");
894 ImGui::SameLine();
895 ImGui::TextWrapped("%s", GetAppDir().c_str());
896
897 ImGui::Spacing();
898 ImGui::Text("Backup file:");
899 ImGui::SetNextItemWidth(-1.0f);
900 ImGui::InputText("##backup-path", g_backupPath, sizeof(g_backupPath));
901
902 if (ImGui::Button("Use new default name", ImVec2(170.0f, 0.0f)))
903 SetDefaultBackupPath();
904 ImGui::SameLine();
905 if (ImGui::Button("Copy data dir", ImVec2(120.0f, 0.0f)))
906 ImGui::SetClipboardText(GetAppDir().c_str());
907
908 ImGui::Spacing();
909 if (ImGui::Button("Write Backup", ImVec2(150.0f, 0.0f)))
910 {
911 std::string path = g_backupPath;
912 if (path.empty())
913 {
914 g_backupStatus = "Choose a backup file first.";
915 }
916 else if (FileExists(path.c_str()))
917 {
918 g_backupStatus = "Refusing to overwrite an existing file. Use a new name.";
919 }
920 else
921 {
922 TopUpKeyPool();
923 if (BackupWallet(path))
924 {
925 g_lastWalletBackup = GetTime();
926 CWalletDB().WriteSetting("nLastWalletBackup", g_lastWalletBackup);
927 g_backupStatus = "Backup written: " + path;
928 SetDefaultBackupPath();
929 }
930 else
931 {
932 g_backupStatus = "Backup failed. See debug.log for the detailed error.";
933 }
934 }
935 }
936
937 if (!g_backupStatus.empty())
938 {
939 ImVec4 col = g_backupStatus.find("Backup written") == 0
940 ? ImVec4(0.35f, 1.0f, 0.45f, 1.0f)
941 : ImVec4(1.0f, 0.45f, 0.35f, 1.0f);
942 ImGui::PushStyleColor(ImGuiCol_Text, col);
943 ImGui::TextWrapped("%s", g_backupStatus.c_str());
944 ImGui::PopStyleColor();
945 }
946
947 ImGui::Spacing();
948 ImGui::SeparatorText("Key Pool");
949 int nPool = KeyPoolCount();
950 ImGui::Text("Pre-generated keys ready: %d / %d", nPool, KEYPOOL_SIZE);
951 ImGui::ProgressBar(KEYPOOL_SIZE > 0 ? (float)nPool / (float)KEYPOOL_SIZE : 0.0f,
952 ImVec2(-1.0f, 0.0f));
953 ImGui::TextWrapped(
954 "A backup contains the keys that already exist. The key pool keeps "
955 "future mining rewards and receive addresses inside the next backup "
956 "window, but it is not a seed phrase. Back up again after heavy use.");
957
958 ImGui::Spacing();
959 ImGui::Separator();
960 if (ImGui::Button("Close", ImVec2(90.0f, 0.0f)))
961 g_showWalletSafety = false;
962 }
963 ImGui::End();
964}
965
966// ---------------------------------------------------------------------------
825// About dialog 967// About dialog
826// --------------------------------------------------------------------------- 968// ---------------------------------------------------------------------------
827// What the node knows about itself, in the words it writes to the log. Same 969// What the node knows about itself, in the words it writes to the log. Same
@@ -965,6 +1107,7 @@ int RunGUI(int argc, char* argv[])
965 DrawMainWindow(); 1107 DrawMainWindow();
966 DrawSendDialog(); 1108 DrawSendDialog();
967 DrawOptionsDialog(); 1109 DrawOptionsDialog();
1110 DrawWalletSafetyDialog();
968 DrawDiagnosticsDialog(); 1111 DrawDiagnosticsDialog();
969 DrawAboutDialog(); 1112 DrawAboutDialog();
970 DrawStatusBar(); 1113 DrawStatusBar();