Expose wallet creation to the GUI via WalletController
Co-authored-by: João Barbosa <joao.paulo.barbosa@gmail.com>
This commit is contained in:
parent
78863e2900
commit
9b41cbb28f
7 changed files with 146 additions and 2 deletions
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue