aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Chow <achow101-github@achow101.com>2019-05-24 17:14:16 -0400
committerAndrew Chow <achow101-github@achow101.com>2019-09-05 20:36:57 -0400
commit9b41cbb28f603f4f71f5854d6ae2527932bba3cb (patch)
tree2b88b292c10566b75c0df9128ffc8ad913e2635e
parent78863e290006e61060622dbdbecc5b58c0fefa05 (diff)
downloadbitcoin-9b41cbb28f603f4f71f5854d6ae2527932bba3cb.tar.xz
Expose wallet creation to the GUI via WalletController
Co-authored-by: João Barbosa <joao.paulo.barbosa@gmail.com>
-rw-r--r--src/dummywallet.cpp7
-rw-r--r--src/interfaces/node.cpp9
-rw-r--r--src/interfaces/node.h5
-rw-r--r--src/qt/createwalletdialog.cpp2
-rw-r--r--src/qt/guiconstants.h2
-rw-r--r--src/qt/walletcontroller.cpp92
-rw-r--r--src/qt/walletcontroller.h31
7 files changed, 146 insertions, 2 deletions
diff --git a/src/dummywallet.cpp b/src/dummywallet.cpp
index eeec6dec25..126e3479f3 100644
--- a/src/dummywallet.cpp
+++ b/src/dummywallet.cpp
@@ -5,8 +5,10 @@
#include <stdio.h>
#include <util/system.h>
#include <walletinitinterface.h>
+#include <support/allocators/secure.h>
class CWallet;
+enum class WalletCreationStatus;
namespace interfaces {
class Chain;
@@ -74,6 +76,11 @@ std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string&
throw std::logic_error("Wallet function called in non-wallet build.");
}
+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)
+{
+ throw std::logic_error("Wallet function called in non-wallet build.");
+}
+
namespace interfaces {
class Wallet;
diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp
index fc49817502..ccafc3ac8c 100644
--- a/src/interfaces/node.cpp
+++ b/src/interfaces/node.cpp
@@ -24,6 +24,7 @@
#include <primitives/block.h>
#include <rpc/server.h>
#include <shutdown.h>
+#include <support/allocators/secure.h>
#include <sync.h>
#include <txmempool.h>
#include <ui_interface.h>
@@ -43,6 +44,7 @@ fs::path GetWalletDir();
std::vector<fs::path> ListWalletDir();
std::vector<std::shared_ptr<CWallet>> GetWallets();
std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string& name, std::string& error, std::string& warning);
+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);
namespace interfaces {
@@ -258,6 +260,13 @@ public:
{
return MakeWallet(LoadWallet(*m_interfaces.chain, name, error, warning));
}
+ 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
+ {
+ std::shared_ptr<CWallet> wallet;
+ WalletCreationStatus status = CreateWallet(*m_interfaces.chain, passphrase, wallet_creation_flags, name, error, warning, wallet);
+ result = MakeWallet(wallet);
+ return status;
+ }
std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) override
{
return MakeHandler(::uiInterface.InitMessage_connect(fn));
diff --git a/src/interfaces/node.h b/src/interfaces/node.h
index b93b52c5cc..e8c3d0b721 100644
--- a/src/interfaces/node.h
+++ b/src/interfaces/node.h
@@ -9,6 +9,7 @@
#include <amount.h> // For CAmount
#include <net.h> // For CConnman::NumConnections
#include <netaddress.h> // For Network
+#include <support/allocators/secure.h> // For SecureString
#include <functional>
#include <memory>
@@ -27,6 +28,7 @@ class RPCTimerInterface;
class UniValue;
class proxyType;
struct CNodeStateStats;
+enum class WalletCreationStatus;
namespace interfaces {
class Handler;
@@ -200,6 +202,9 @@ public:
//! with handleLoadWallet.
virtual std::unique_ptr<Wallet> loadWallet(const std::string& name, std::string& error, std::string& warning) = 0;
+ //! Create a wallet from file
+ 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;
+
//! Register handler for init messages.
using InitMessageFn = std::function<void(const std::string& message)>;
virtual std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) = 0;
diff --git a/src/qt/createwalletdialog.cpp b/src/qt/createwalletdialog.cpp
index 449dcc70a0..10262c37c3 100644
--- a/src/qt/createwalletdialog.cpp
+++ b/src/qt/createwalletdialog.cpp
@@ -16,7 +16,7 @@ CreateWalletDialog::CreateWalletDialog(QWidget* parent) :
ui(new Ui::CreateWalletDialog)
{
ui->setupUi(this);
- ui->buttonBox->button(QDialogButtonBox::Ok)->setText("Create");
+ ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Create"));
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
ui->wallet_name_line_edit->setFocus(Qt::ActiveWindowFocusReason);
diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h
index d8f5594983..dcdb247977 100644
--- a/src/qt/guiconstants.h
+++ b/src/qt/guiconstants.h
@@ -5,6 +5,8 @@
#ifndef BITCOIN_QT_GUICONSTANTS_H
#define BITCOIN_QT_GUICONSTANTS_H
+#include <cstdint>
+
/* Milliseconds between model updates */
static const int MODEL_UPDATE_DELAY = 250;
diff --git a/src/qt/walletcontroller.cpp b/src/qt/walletcontroller.cpp
index 88ccc8c2d6..1a4f51c066 100644
--- a/src/qt/walletcontroller.cpp
+++ b/src/qt/walletcontroller.cpp
@@ -2,9 +2,14 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <qt/askpassphrasedialog.h>
+#include <qt/createwalletdialog.h>
+#include <qt/guiconstants.h>
#include <qt/guiutil.h>
#include <qt/walletcontroller.h>
+#include <wallet/wallet.h>
+
#include <interfaces/handler.h>
#include <interfaces/node.h>
@@ -162,6 +167,93 @@ void WalletControllerActivity::showProgressDialog(const QString& label_text)
GUIUtil::PolishProgressDialog(m_progress_dialog);
}
+CreateWalletActivity::CreateWalletActivity(WalletController* wallet_controller, QWidget* parent_widget)
+ : WalletControllerActivity(wallet_controller, parent_widget)
+{
+ m_passphrase.reserve(MAX_PASSPHRASE_SIZE);
+}
+
+CreateWalletActivity::~CreateWalletActivity()
+{
+ delete m_create_wallet_dialog;
+ delete m_passphrase_dialog;
+}
+
+void CreateWalletActivity::askPasshprase()
+{
+ m_passphrase_dialog = new AskPassphraseDialog(AskPassphraseDialog::Encrypt, m_parent_widget, &m_passphrase);
+ m_passphrase_dialog->show();
+
+ connect(m_passphrase_dialog, &QObject::destroyed, [this] {
+ m_passphrase_dialog = nullptr;
+ });
+ connect(m_passphrase_dialog, &QDialog::accepted, [this] {
+ createWallet();
+ });
+ connect(m_passphrase_dialog, &QDialog::rejected, [this] {
+ Q_EMIT finished();
+ });
+}
+
+void CreateWalletActivity::createWallet()
+{
+ showProgressDialog(tr("Creating Wallet <b>%1</b>...").arg(m_create_wallet_dialog->walletName().toHtmlEscaped()));
+
+ std::string name = m_create_wallet_dialog->walletName().toStdString();
+ uint64_t flags = 0;
+ if (m_create_wallet_dialog->disablePrivateKeys()) {
+ flags |= WALLET_FLAG_DISABLE_PRIVATE_KEYS;
+ }
+ if (m_create_wallet_dialog->blank()) {
+ flags |= WALLET_FLAG_BLANK_WALLET;
+ }
+
+ QTimer::singleShot(500, worker(), [this, name, flags] {
+ std::unique_ptr<interfaces::Wallet> wallet;
+ WalletCreationStatus status = node().createWallet(m_passphrase, flags, name, m_error_message, m_warning_message, wallet);
+
+ if (status == WalletCreationStatus::SUCCESS) m_wallet_model = m_wallet_controller->getOrCreateWallet(std::move(wallet));
+
+ QTimer::singleShot(500, this, &CreateWalletActivity::finish);
+ });
+}
+
+void CreateWalletActivity::finish()
+{
+ m_progress_dialog->hide();
+
+ if (!m_error_message.empty()) {
+ QMessageBox::critical(m_parent_widget, tr("Create wallet failed"), QString::fromStdString(m_error_message));
+ } else if (!m_warning_message.empty()) {
+ QMessageBox::warning(m_parent_widget, tr("Create wallet warning"), QString::fromStdString(m_warning_message));
+ }
+
+ if (m_wallet_model) Q_EMIT created(m_wallet_model);
+
+ Q_EMIT finished();
+}
+
+void CreateWalletActivity::create()
+{
+ m_create_wallet_dialog = new CreateWalletDialog(m_parent_widget);
+ m_create_wallet_dialog->setWindowModality(Qt::ApplicationModal);
+ m_create_wallet_dialog->show();
+
+ connect(m_create_wallet_dialog, &QObject::destroyed, [this] {
+ m_create_wallet_dialog = nullptr;
+ });
+ connect(m_create_wallet_dialog, &QDialog::rejected, [this] {
+ Q_EMIT finished();
+ });
+ connect(m_create_wallet_dialog, &QDialog::accepted, [this] {
+ if (m_create_wallet_dialog->encrypt()) {
+ askPasshprase();
+ } else {
+ createWallet();
+ }
+ });
+}
+
OpenWalletActivity::OpenWalletActivity(WalletController* wallet_controller, QWidget* parent_widget)
: WalletControllerActivity(wallet_controller, parent_widget)
{
diff --git a/src/qt/walletcontroller.h b/src/qt/walletcontroller.h
index dada9cfa63..4e1a772f3a 100644
--- a/src/qt/walletcontroller.h
+++ b/src/qt/walletcontroller.h
@@ -6,6 +6,7 @@
#define BITCOIN_QT_WALLETCONTROLLER_H
#include <qt/walletmodel.h>
+#include <support/allocators/secure.h>
#include <sync.h>
#include <map>
@@ -16,8 +17,9 @@
#include <QMessageBox>
#include <QMutex>
#include <QProgressDialog>
-#include <QString>
#include <QThread>
+#include <QTimer>
+#include <QString>
class OptionsModel;
class PlatformStyle;
@@ -27,6 +29,9 @@ class Handler;
class Node;
} // namespace interfaces
+class AskPassphraseDialog;
+class CreateWalletActivity;
+class CreateWalletDialog;
class OpenWalletActivity;
class WalletControllerActivity;
@@ -98,6 +103,30 @@ protected:
std::string m_warning_message;
};
+
+class CreateWalletActivity : public WalletControllerActivity
+{
+ Q_OBJECT
+
+public:
+ CreateWalletActivity(WalletController* wallet_controller, QWidget* parent_widget);
+ virtual ~CreateWalletActivity();
+
+ void create();
+
+Q_SIGNALS:
+ void created(WalletModel* wallet_model);
+
+private:
+ void askPasshprase();
+ void createWallet();
+ void finish();
+
+ SecureString m_passphrase;
+ CreateWalletDialog* m_create_wallet_dialog{nullptr};
+ AskPassphraseDialog* m_passphrase_dialog{nullptr};
+};
+
class OpenWalletActivity : public WalletControllerActivity
{
Q_OBJECT