Skip to content

Commit 77c3aeb

Browse files
qt: Improve wallet creation UI flow
- Add collapsible advanced options toggle in CreateWalletDialog - Add mnemonic verification dialog after wallet creation - Implement getMnemonic() interface method for retrieving mnemonic phrases - Add proper error handling for wallet lock state restoration - Add styling for both light and dark themes - Show verification dialog for HD wallets after creation - Skip verification for blank wallets and wallets with disabled private keys
1 parent f3219ee commit 77c3aeb

12 files changed

+1085
-2
lines changed

src/Makefile.qt.include

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ QT_FORMS_UI = \
2727
qt/forms/intro.ui \
2828
qt/forms/modaloverlay.ui \
2929
qt/forms/masternodelist.ui \
30+
qt/forms/mnemonicverificationdialog.ui \
3031
qt/forms/qrdialog.ui \
3132
qt/forms/openuridialog.ui \
3233
qt/forms/optionsdialog.ui \
@@ -66,6 +67,7 @@ QT_MOC_CPP = \
6667
qt/moc_macnotificationhandler.cpp \
6768
qt/moc_modaloverlay.cpp \
6869
qt/moc_masternodelist.cpp \
70+
qt/moc_mnemonicverificationdialog.cpp \
6971
qt/moc_notificator.cpp \
7072
qt/moc_openuridialog.cpp \
7173
qt/moc_optionsdialog.cpp \
@@ -144,6 +146,7 @@ BITCOIN_QT_H = \
144146
qt/macos_appnap.h \
145147
qt/modaloverlay.h \
146148
qt/masternodelist.h \
149+
qt/mnemonicverificationdialog.h \
147150
qt/networkstyle.h \
148151
qt/notificator.h \
149152
qt/openuridialog.h \
@@ -257,6 +260,7 @@ BITCOIN_QT_WALLET_CPP = \
257260
qt/governancelist.cpp \
258261
qt/proposalwizard.cpp \
259262
qt/masternodelist.cpp \
263+
qt/mnemonicverificationdialog.cpp \
260264
qt/openuridialog.cpp \
261265
qt/overviewpage.cpp \
262266
qt/paymentserver.cpp \

src/interfaces/wallet.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,9 @@ class Wallet
297297
//! Return whether is a legacy wallet
298298
virtual bool isLegacy() = 0;
299299

300+
//! Get mnemonic phrase from wallet.
301+
virtual bool getMnemonic(SecureString& mnemonic_out, SecureString& mnemonic_passphrase_out) = 0;
302+
300303
//! Register handler for unload message.
301304
using UnloadFn = std::function<void()>;
302305
virtual std::unique_ptr<Handler> handleUnload(UnloadFn fn) = 0;

src/qt/createwalletdialog.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <qt/guiutil.h>
1313

1414
#include <QPushButton>
15+
#include <QToolButton>
1516

1617
CreateWalletDialog::CreateWalletDialog(QWidget* parent) :
1718
QDialog(parent, GUIUtil::dialog_flags),
@@ -22,6 +23,17 @@ CreateWalletDialog::CreateWalletDialog(QWidget* parent) :
2223
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
2324
ui->wallet_name_line_edit->setFocus(Qt::ActiveWindowFocusReason);
2425

26+
// Hide advanced options by default and provide a compact toggle control.
27+
ui->groupBox->setVisible(false);
28+
ui->groupBox->setTitle(QString());
29+
ui->advanced_toggle_button->setChecked(false);
30+
ui->advanced_toggle_button->setArrowType(Qt::RightArrow);
31+
ui->advanced_toggle_button->setFocusPolicy(Qt::NoFocus);
32+
connect(ui->advanced_toggle_button, &QToolButton::toggled, this, [this](bool checked) {
33+
ui->groupBox->setVisible(checked);
34+
ui->advanced_toggle_button->setArrowType(checked ? Qt::DownArrow : Qt::RightArrow);
35+
});
36+
2537
connect(ui->wallet_name_line_edit, &QLineEdit::textEdited, [this](const QString& text) {
2638
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!text.isEmpty());
2739
});

src/qt/forms/createwalletdialog.ui

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
<bool>true</bool>
1818
</property>
1919
<layout class="QVBoxLayout" name="verticalLayout">
20+
<property name="spacing">
21+
<number>8</number>
22+
</property>
2023
<item>
2124
<layout class="QHBoxLayout" name="horizontalLayout">
2225
<item>
@@ -71,11 +74,54 @@
7174
</spacer>
7275
</item>
7376
<item>
77+
<widget class="QToolButton" name="advanced_toggle_button">
78+
<property name="text">
79+
<string>Advanced Options</string>
80+
</property>
81+
<property name="toolButtonStyle">
82+
<enum>Qt::ToolButtonTextBesideIcon</enum>
83+
</property>
84+
<property name="autoRaise">
85+
<bool>true</bool>
86+
</property>
87+
<property name="focusPolicy">
88+
<enum>Qt::NoFocus</enum>
89+
</property>
90+
<property name="checkable">
91+
<bool>true</bool>
92+
</property>
93+
<property name="checked">
94+
<bool>false</bool>
95+
</property>
96+
<property name="arrowType">
97+
<enum>Qt::RightArrow</enum>
98+
</property>
99+
</widget>
100+
</item>
101+
<item>
74102
<widget class="QGroupBox" name="groupBox">
75103
<property name="title">
76-
<string>Advanced Options</string>
104+
<string/>
105+
</property>
106+
<property name="visible">
107+
<bool>false</bool>
77108
</property>
78109
<layout class="QVBoxLayout" name="verticalLayout_groupbox">
110+
<property name="topMargin">
111+
<number>0</number>
112+
</property>
113+
<property name="leftMargin">
114+
<number>8</number>
115+
</property>
116+
<property name="rightMargin">
117+
<number>8</number>
118+
</property>
119+
<property name="bottomMargin">
120+
<number>8</number>
121+
</property>
122+
<property name="spacing">
123+
<number>4</number>
124+
</property>
79125
<item>
80126
<widget class="QCheckBox" name="disable_privkeys_checkbox">
81127
<property name="enabled">
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ui version="4.0">
3+
<class>MnemonicVerificationDialog</class>
4+
<widget class="QDialog" name="MnemonicVerificationDialog">
5+
<property name="windowTitle">
6+
<string>Save Your Mnemonic</string>
7+
</property>
8+
<layout class="QVBoxLayout" name="verticalLayout">
9+
<item>
10+
<widget class="QStackedWidget" name="stackedWidget">
11+
<property name="currentIndex">
12+
<number>0</number>
13+
</property>
14+
<widget class="QWidget" name="step1Page">
15+
<layout class="QVBoxLayout" name="verticalLayout_step1">
16+
<item>
17+
<widget class="QLabel" name="warningLabel">
18+
<property name="text">
19+
<string>WARNING: If you lose your mnemonic seed phrase, you will lose access to your wallet forever.</string>
20+
</property>
21+
<property name="textFormat">
22+
<enum>Qt::RichText</enum>
23+
</property>
24+
<property name="wordWrap">
25+
<bool>true</bool>
26+
</property>
27+
</widget>
28+
</item>
29+
<item>
30+
<widget class="QLabel" name="instructionLabel">
31+
<property name="text">
32+
<string>Please write down these words in order. You will need them to restore your wallet.</string>
33+
</property>
34+
<property name="wordWrap">
35+
<bool>true</bool>
36+
</property>
37+
</widget>
38+
</item>
39+
<item>
40+
<widget class="QScrollArea" name="mnemonicScroll">
41+
<property name="frameShape">
42+
<enum>QFrame::NoFrame</enum>
43+
</property>
44+
<property name="widgetResizable">
45+
<bool>true</bool>
46+
</property>
47+
<widget class="QWidget" name="mnemonicGridWidget">
48+
<layout class="QGridLayout" name="mnemonicGridLayout"/>
49+
</widget>
50+
</widget>
51+
</item>
52+
<item>
53+
<layout class="QHBoxLayout" name="horizontalLayout_buttons">
54+
<item>
55+
<widget class="QPushButton" name="showMnemonicButton">
56+
<property name="text">
57+
<string>Show</string>
58+
</property>
59+
</widget>
60+
</item>
61+
<item>
62+
<widget class="QPushButton" name="hideMnemonicButton">
63+
<property name="text">
64+
<string>Hide</string>
65+
</property>
66+
</widget>
67+
</item>
68+
<item>
69+
<spacer name="horizontalSpacer_1">
70+
<property name="orientation">
71+
<enum>Qt::Horizontal</enum>
72+
</property>
73+
<property name="sizeHint" stdset="0">
74+
<size>
75+
<width>20</width>
76+
<height>20</height>
77+
</size>
78+
</property>
79+
</spacer>
80+
</item>
81+
<item>
82+
<widget class="QCheckBox" name="writtenDownCheckbox">
83+
<property name="text">
84+
<string>I have written down my mnemonic</string>
85+
</property>
86+
</widget>
87+
</item>
88+
</layout>
89+
</item>
90+
</layout>
91+
</widget>
92+
<widget class="QWidget" name="step2Page">
93+
<layout class="QVBoxLayout" name="verticalLayout_step2">
94+
<item>
95+
<widget class="QLabel" name="verificationLabel">
96+
<property name="text">
97+
<string>To verify you've saved your mnemonic, please enter the following words:</string>
98+
</property>
99+
<property name="wordWrap">
100+
<bool>true</bool>
101+
</property>
102+
</widget>
103+
</item>
104+
<item>
105+
<layout class="QFormLayout" name="formLayout">
106+
<item row="0" column="0">
107+
<widget class="QLabel" name="word1Label">
108+
<property name="text">
109+
<string>Word #1:</string>
110+
</property>
111+
</widget>
112+
</item>
113+
<item row="0" column="1">
114+
<layout class="QHBoxLayout" name="horizontalLayout_word1">
115+
<item>
116+
<widget class="QLineEdit" name="word1Edit"/>
117+
</item>
118+
<item>
119+
<widget class="QLabel" name="word1Status"/>
120+
</item>
121+
</layout>
122+
</item>
123+
<item row="1" column="0">
124+
<widget class="QLabel" name="word2Label">
125+
<property name="text">
126+
<string>Word #2:</string>
127+
</property>
128+
</widget>
129+
</item>
130+
<item row="1" column="1">
131+
<layout class="QHBoxLayout" name="horizontalLayout_word2">
132+
<item>
133+
<widget class="QLineEdit" name="word2Edit"/>
134+
</item>
135+
<item>
136+
<widget class="QLabel" name="word2Status"/>
137+
</item>
138+
</layout>
139+
</item>
140+
<item row="2" column="0">
141+
<widget class="QLabel" name="word3Label">
142+
<property name="text">
143+
<string>Word #3:</string>
144+
</property>
145+
</widget>
146+
</item>
147+
<item row="2" column="1">
148+
<layout class="QHBoxLayout" name="horizontalLayout_word3">
149+
<item>
150+
<widget class="QLineEdit" name="word3Edit"/>
151+
</item>
152+
<item>
153+
<widget class="QLabel" name="word3Status"/>
154+
</item>
155+
</layout>
156+
</item>
157+
</layout>
158+
</item>
159+
<item>
160+
<layout class="QHBoxLayout" name="horizontalLayout_actions">
161+
<item>
162+
<widget class="QPushButton" name="showMnemonicAgainButton">
163+
<property name="text">
164+
<string>Back</string>
165+
</property>
166+
</widget>
167+
</item>
168+
<item>
169+
<spacer name="horizontalSpacer_2">
170+
<property name="orientation">
171+
<enum>Qt::Horizontal</enum>
172+
</property>
173+
</spacer>
174+
</item>
175+
</layout>
176+
</item>
177+
</layout>
178+
</widget>
179+
</widget>
180+
</item>
181+
<item>
182+
<widget class="QDialogButtonBox" name="buttonBox">
183+
<property name="standardButtons">
184+
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
185+
</property>
186+
</widget>
187+
</item>
188+
</layout>
189+
</widget>
190+
<resources/>
191+
<connections>
192+
<connection>
193+
<sender>buttonBox</sender>
194+
<signal>accepted()</signal>
195+
<receiver>MnemonicVerificationDialog</receiver>
196+
<slot>accept()</slot>
197+
</connection>
198+
<connection>
199+
<sender>buttonBox</sender>
200+
<signal>rejected()</signal>
201+
<receiver>MnemonicVerificationDialog</receiver>
202+
<slot>reject()</slot>
203+
</connection>
204+
</connections>
205+
</ui>
206+

0 commit comments

Comments
 (0)