Skip to content

Commit 9b41cbb

Browse files
achow101promag
andcommitted
Expose wallet creation to the GUI via WalletController
Co-authored-by: João Barbosa <[email protected]>
1 parent 78863e2 commit 9b41cbb

File tree

7 files changed

+146
-2
lines changed

7 files changed

+146
-2
lines changed

src/dummywallet.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
#include <stdio.h>
66
#include <util/system.h>
77
#include <walletinitinterface.h>
8+
#include <support/allocators/secure.h>
89

910
class CWallet;
11+
enum class WalletCreationStatus;
1012

1113
namespace interfaces {
1214
class Chain;
@@ -74,6 +76,11 @@ std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string&
7476
throw std::logic_error("Wallet function called in non-wallet build.");
7577
}
7678

79+
WalletCreationStatus CreateWallet(interfaces::Chain& chain, const SecureString& passphrase, uint64_t wallet_creation_flags, const std::string& name, std::string& error, std::string& warning, std::shared_ptr<CWallet>& result)
80+
{
81+
throw std::logic_error("Wallet function called in non-wallet build.");
82+
}
83+
7784
namespace interfaces {
7885

7986
class Wallet;

src/interfaces/node.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <primitives/block.h>
2525
#include <rpc/server.h>
2626
#include <shutdown.h>
27+
#include <support/allocators/secure.h>
2728
#include <sync.h>
2829
#include <txmempool.h>
2930
#include <ui_interface.h>
@@ -43,6 +44,7 @@ fs::path GetWalletDir();
4344
std::vector<fs::path> ListWalletDir();
4445
std::vector<std::shared_ptr<CWallet>> GetWallets();
4546
std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string& name, std::string& error, std::string& warning);
47+
WalletCreationStatus CreateWallet(interfaces::Chain& chain, const SecureString& passphrase, uint64_t wallet_creation_flags, const std::string& name, std::string& error, std::string& warning, std::shared_ptr<CWallet>& result);
4648

4749
namespace interfaces {
4850

@@ -258,6 +260,13 @@ class NodeImpl : public Node
258260
{
259261
return MakeWallet(LoadWallet(*m_interfaces.chain, name, error, warning));
260262
}
263+
WalletCreationStatus createWallet(const SecureString& passphrase, uint64_t wallet_creation_flags, const std::string& name, std::string& error, std::string& warning, std::unique_ptr<Wallet>& result) override
264+
{
265+
std::shared_ptr<CWallet> wallet;
266+
WalletCreationStatus status = CreateWallet(*m_interfaces.chain, passphrase, wallet_creation_flags, name, error, warning, wallet);
267+
result = MakeWallet(wallet);
268+
return status;
269+
}
261270
std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) override
262271
{
263272
return MakeHandler(::uiInterface.InitMessage_connect(fn));

src/interfaces/node.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <amount.h> // For CAmount
1010
#include <net.h> // For CConnman::NumConnections
1111
#include <netaddress.h> // For Network
12+
#include <support/allocators/secure.h> // For SecureString
1213

1314
#include <functional>
1415
#include <memory>
@@ -27,6 +28,7 @@ class RPCTimerInterface;
2728
class UniValue;
2829
class proxyType;
2930
struct CNodeStateStats;
31+
enum class WalletCreationStatus;
3032

3133
namespace interfaces {
3234
class Handler;
@@ -200,6 +202,9 @@ class Node
200202
//! with handleLoadWallet.
201203
virtual std::unique_ptr<Wallet> loadWallet(const std::string& name, std::string& error, std::string& warning) = 0;
202204

205+
//! Create a wallet from file
206+
virtual WalletCreationStatus createWallet(const SecureString& passphrase, uint64_t wallet_creation_flags, const std::string& name, std::string& error, std::string& warning, std::unique_ptr<Wallet>& result) = 0;
207+
203208
//! Register handler for init messages.
204209
using InitMessageFn = std::function<void(const std::string& message)>;
205210
virtual std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) = 0;

src/qt/createwalletdialog.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ CreateWalletDialog::CreateWalletDialog(QWidget* parent) :
1616
ui(new Ui::CreateWalletDialog)
1717
{
1818
ui->setupUi(this);
19-
ui->buttonBox->button(QDialogButtonBox::Ok)->setText("Create");
19+
ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Create"));
2020
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
2121
ui->wallet_name_line_edit->setFocus(Qt::ActiveWindowFocusReason);
2222

src/qt/guiconstants.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#ifndef BITCOIN_QT_GUICONSTANTS_H
66
#define BITCOIN_QT_GUICONSTANTS_H
77

8+
#include <cstdint>
9+
810
/* Milliseconds between model updates */
911
static const int MODEL_UPDATE_DELAY = 250;
1012

src/qt/walletcontroller.cpp

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@
22
// Distributed under the MIT software license, see the accompanying
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

5+
#include <qt/askpassphrasedialog.h>
6+
#include <qt/createwalletdialog.h>
7+
#include <qt/guiconstants.h>
58
#include <qt/guiutil.h>
69
#include <qt/walletcontroller.h>
710

11+
#include <wallet/wallet.h>
12+
813
#include <interfaces/handler.h>
914
#include <interfaces/node.h>
1015

@@ -162,6 +167,93 @@ void WalletControllerActivity::showProgressDialog(const QString& label_text)
162167
GUIUtil::PolishProgressDialog(m_progress_dialog);
163168
}
164169

170+
CreateWalletActivity::CreateWalletActivity(WalletController* wallet_controller, QWidget* parent_widget)
171+
: WalletControllerActivity(wallet_controller, parent_widget)
172+
{
173+
m_passphrase.reserve(MAX_PASSPHRASE_SIZE);
174+
}
175+
176+
CreateWalletActivity::~CreateWalletActivity()
177+
{
178+
delete m_create_wallet_dialog;
179+
delete m_passphrase_dialog;
180+
}
181+
182+
void CreateWalletActivity::askPasshprase()
183+
{
184+
m_passphrase_dialog = new AskPassphraseDialog(AskPassphraseDialog::Encrypt, m_parent_widget, &m_passphrase);
185+
m_passphrase_dialog->show();
186+
187+
connect(m_passphrase_dialog, &QObject::destroyed, [this] {
188+
m_passphrase_dialog = nullptr;
189+
});
190+
connect(m_passphrase_dialog, &QDialog::accepted, [this] {
191+
createWallet();
192+
});
193+
connect(m_passphrase_dialog, &QDialog::rejected, [this] {
194+
Q_EMIT finished();
195+
});
196+
}
197+
198+
void CreateWalletActivity::createWallet()
199+
{
200+
showProgressDialog(tr("Creating Wallet <b>%1</b>...").arg(m_create_wallet_dialog->walletName().toHtmlEscaped()));
201+
202+
std::string name = m_create_wallet_dialog->walletName().toStdString();
203+
uint64_t flags = 0;
204+
if (m_create_wallet_dialog->disablePrivateKeys()) {
205+
flags |= WALLET_FLAG_DISABLE_PRIVATE_KEYS;
206+
}
207+
if (m_create_wallet_dialog->blank()) {
208+
flags |= WALLET_FLAG_BLANK_WALLET;
209+
}
210+
211+
QTimer::singleShot(500, worker(), [this, name, flags] {
212+
std::unique_ptr<interfaces::Wallet> wallet;
213+
WalletCreationStatus status = node().createWallet(m_passphrase, flags, name, m_error_message, m_warning_message, wallet);
214+
215+
if (status == WalletCreationStatus::SUCCESS) m_wallet_model = m_wallet_controller->getOrCreateWallet(std::move(wallet));
216+
217+
QTimer::singleShot(500, this, &CreateWalletActivity::finish);
218+
});
219+
}
220+
221+
void CreateWalletActivity::finish()
222+
{
223+
m_progress_dialog->hide();
224+
225+
if (!m_error_message.empty()) {
226+
QMessageBox::critical(m_parent_widget, tr("Create wallet failed"), QString::fromStdString(m_error_message));
227+
} else if (!m_warning_message.empty()) {
228+
QMessageBox::warning(m_parent_widget, tr("Create wallet warning"), QString::fromStdString(m_warning_message));
229+
}
230+
231+
if (m_wallet_model) Q_EMIT created(m_wallet_model);
232+
233+
Q_EMIT finished();
234+
}
235+
236+
void CreateWalletActivity::create()
237+
{
238+
m_create_wallet_dialog = new CreateWalletDialog(m_parent_widget);
239+
m_create_wallet_dialog->setWindowModality(Qt::ApplicationModal);
240+
m_create_wallet_dialog->show();
241+
242+
connect(m_create_wallet_dialog, &QObject::destroyed, [this] {
243+
m_create_wallet_dialog = nullptr;
244+
});
245+
connect(m_create_wallet_dialog, &QDialog::rejected, [this] {
246+
Q_EMIT finished();
247+
});
248+
connect(m_create_wallet_dialog, &QDialog::accepted, [this] {
249+
if (m_create_wallet_dialog->encrypt()) {
250+
askPasshprase();
251+
} else {
252+
createWallet();
253+
}
254+
});
255+
}
256+
165257
OpenWalletActivity::OpenWalletActivity(WalletController* wallet_controller, QWidget* parent_widget)
166258
: WalletControllerActivity(wallet_controller, parent_widget)
167259
{

src/qt/walletcontroller.h

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define BITCOIN_QT_WALLETCONTROLLER_H
77

88
#include <qt/walletmodel.h>
9+
#include <support/allocators/secure.h>
910
#include <sync.h>
1011

1112
#include <map>
@@ -16,8 +17,9 @@
1617
#include <QMessageBox>
1718
#include <QMutex>
1819
#include <QProgressDialog>
19-
#include <QString>
2020
#include <QThread>
21+
#include <QTimer>
22+
#include <QString>
2123

2224
class OptionsModel;
2325
class PlatformStyle;
@@ -27,6 +29,9 @@ class Handler;
2729
class Node;
2830
} // namespace interfaces
2931

32+
class AskPassphraseDialog;
33+
class CreateWalletActivity;
34+
class CreateWalletDialog;
3035
class OpenWalletActivity;
3136
class WalletControllerActivity;
3237

@@ -98,6 +103,30 @@ class WalletControllerActivity : public QObject
98103
std::string m_warning_message;
99104
};
100105

106+
107+
class CreateWalletActivity : public WalletControllerActivity
108+
{
109+
Q_OBJECT
110+
111+
public:
112+
CreateWalletActivity(WalletController* wallet_controller, QWidget* parent_widget);
113+
virtual ~CreateWalletActivity();
114+
115+
void create();
116+
117+
Q_SIGNALS:
118+
void created(WalletModel* wallet_model);
119+
120+
private:
121+
void askPasshprase();
122+
void createWallet();
123+
void finish();
124+
125+
SecureString m_passphrase;
126+
CreateWalletDialog* m_create_wallet_dialog{nullptr};
127+
AskPassphraseDialog* m_passphrase_dialog{nullptr};
128+
};
129+
101130
class OpenWalletActivity : public WalletControllerActivity
102131
{
103132
Q_OBJECT

0 commit comments

Comments
 (0)