-
Notifications
You must be signed in to change notification settings - Fork 268
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UI external signer support (e.g. hardware wallet) #4
Changes from all commits
6cdbc83
eef8d64
450cb40
62ac119
3f845ea
24815c6
1c4b456
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -170,6 +170,16 @@ class NodeImpl : public Node | |
} | ||
return false; | ||
} | ||
#ifdef ENABLE_EXTERNAL_SIGNER | ||
std::vector<ExternalSigner> externalSigners() override | ||
{ | ||
std::vector<ExternalSigner> signers = {}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit, drop |
||
const std::string command = gArgs.GetArg("-signer", ""); | ||
if (command == "") return signers; | ||
ExternalSigner::Enumerate(command, signers, Params().NetworkIDString()); | ||
return signers; | ||
} | ||
#endif | ||
int64_t getTotalBytesRecv() override { return m_context->connman ? m_context->connman->GetTotalBytesRecv() : 0; } | ||
int64_t getTotalBytesSent() override { return m_context->connman ? m_context->connman->GetTotalBytesSent() : 0; } | ||
size_t getMempoolSize() override { return m_context->mempool ? m_context->mempool->size() : 0; } | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ | |
#include <config/bitcoin-config.h> | ||
#endif | ||
|
||
#include <external_signer.h> | ||
#include <qt/createwalletdialog.h> | ||
#include <qt/forms/ui_createwalletdialog.h> | ||
|
||
|
@@ -27,14 +28,39 @@ CreateWalletDialog::CreateWalletDialog(QWidget* parent) : | |
}); | ||
|
||
connect(ui->encrypt_wallet_checkbox, &QCheckBox::toggled, [this](bool checked) { | ||
// Disable the disable_privkeys_checkbox when isEncryptWalletChecked is | ||
// Disable the disable_privkeys_checkbox and external_signer_checkbox when isEncryptWalletChecked is | ||
// set to true, enable it when isEncryptWalletChecked is false. | ||
ui->disable_privkeys_checkbox->setEnabled(!checked); | ||
ui->external_signer_checkbox->setEnabled(!checked); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should take into account May I suggest adding a private slot There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding a fix in bitcoin/bitcoin#21935. I agree this whole toggling code needs a refactor. |
||
|
||
// When the disable_privkeys_checkbox is disabled, uncheck it. | ||
if (!ui->disable_privkeys_checkbox->isEnabled()) { | ||
ui->disable_privkeys_checkbox->setChecked(false); | ||
} | ||
|
||
// When the external_signer_checkbox box is disabled, uncheck it. | ||
if (!ui->external_signer_checkbox->isEnabled()) { | ||
ui->external_signer_checkbox->setChecked(false); | ||
} | ||
|
||
}); | ||
|
||
connect(ui->external_signer_checkbox, &QCheckBox::toggled, [this](bool checked) { | ||
ui->encrypt_wallet_checkbox->setEnabled(!checked); | ||
ui->blank_wallet_checkbox->setEnabled(!checked); | ||
ui->disable_privkeys_checkbox->setEnabled(!checked); | ||
ui->descriptor_checkbox->setEnabled(!checked); | ||
|
||
// The external signer checkbox is only enabled when a device is detected. | ||
// In that case it is checked by default. Toggling it restores the other | ||
// options to their default. | ||
ui->descriptor_checkbox->setChecked(checked); | ||
ui->encrypt_wallet_checkbox->setChecked(false); | ||
ui->disable_privkeys_checkbox->setChecked(checked); | ||
// The blank check box is ambiguous. This flag is always true for a | ||
// watch-only wallet, even though we immedidately fetch keys from the | ||
// external signer. | ||
ui->blank_wallet_checkbox->setChecked(checked); | ||
}); | ||
|
||
connect(ui->disable_privkeys_checkbox, &QCheckBox::toggled, [this](bool checked) { | ||
|
@@ -63,18 +89,51 @@ CreateWalletDialog::CreateWalletDialog(QWidget* parent) : | |
ui->descriptor_checkbox->setToolTip(tr("Compiled without sqlite support (required for descriptor wallets)")); | ||
ui->descriptor_checkbox->setEnabled(false); | ||
ui->descriptor_checkbox->setChecked(false); | ||
ui->external_signer_checkbox->setEnabled(false); | ||
ui->external_signer_checkbox->setChecked(false); | ||
#endif | ||
|
||
#ifndef USE_BDB | ||
ui->descriptor_checkbox->setEnabled(false); | ||
ui->descriptor_checkbox->setChecked(true); | ||
#endif | ||
|
||
#ifndef ENABLE_EXTERNAL_SIGNER | ||
//: "External signing" means using devices such as hardware wallets. | ||
ui->external_signer_checkbox->setToolTip(tr("Compiled without external signing support (required for external signing)")); | ||
Sjors marked this conversation as resolved.
Show resolved
Hide resolved
|
||
ui->external_signer_checkbox->setEnabled(false); | ||
ui->external_signer_checkbox->setChecked(false); | ||
#endif | ||
|
||
} | ||
|
||
CreateWalletDialog::~CreateWalletDialog() | ||
{ | ||
delete ui; | ||
} | ||
|
||
#ifdef ENABLE_EXTERNAL_SIGNER | ||
void CreateWalletDialog::setSigners(std::vector<ExternalSigner>& signers) | ||
{ | ||
if (!signers.empty()) { | ||
ui->external_signer_checkbox->setEnabled(true); | ||
ui->external_signer_checkbox->setChecked(true); | ||
ui->encrypt_wallet_checkbox->setEnabled(false); | ||
ui->encrypt_wallet_checkbox->setChecked(false); | ||
// The order matters, because connect() is called when toggling a checkbox: | ||
ui->blank_wallet_checkbox->setEnabled(false); | ||
ui->blank_wallet_checkbox->setChecked(false); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: to be consistent with |
||
ui->disable_privkeys_checkbox->setEnabled(false); | ||
ui->disable_privkeys_checkbox->setChecked(true); | ||
const std::string label = signers[0].m_name; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could add comment "TODO show available signers in combobox, for now use 1st signer name"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @promag it is just the name of the wallet so I don't think it would be worth adding a combobox tbh. That might be confusing because it wouldn't actually change between signers, it would just change the name. |
||
ui->wallet_name_line_edit->setText(QString::fromStdString(label)); | ||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); | ||
} else { | ||
ui->external_signer_checkbox->setEnabled(false); | ||
} | ||
} | ||
#endif | ||
|
||
QString CreateWalletDialog::walletName() const | ||
{ | ||
return ui->wallet_name_line_edit->text(); | ||
|
@@ -99,3 +158,8 @@ bool CreateWalletDialog::isDescriptorWalletChecked() const | |
{ | ||
return ui->descriptor_checkbox->isChecked(); | ||
} | ||
|
||
bool CreateWalletDialog::isExternalSignerChecked() const | ||
{ | ||
return ui->external_signer_checkbox->isChecked(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,10 @@ | |
|
||
class WalletModel; | ||
|
||
#ifdef ENABLE_EXTERNAL_SIGNER | ||
class ExternalSigner; | ||
#endif | ||
|
||
namespace Ui { | ||
class CreateWalletDialog; | ||
} | ||
|
@@ -23,11 +27,16 @@ class CreateWalletDialog : public QDialog | |
explicit CreateWalletDialog(QWidget* parent); | ||
virtual ~CreateWalletDialog(); | ||
|
||
#ifdef ENABLE_EXTERNAL_SIGNER | ||
void setSigners(std::vector<ExternalSigner>& signers); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm adding that to: bitcoin/bitcoin#21935 |
||
#endif | ||
|
||
QString walletName() const; | ||
bool isEncryptWalletChecked() const; | ||
bool isDisablePrivateKeysChecked() const; | ||
bool isMakeBlankWalletChecked() const; | ||
bool isDescriptorWalletChecked() const; | ||
bool isExternalSignerChecked() const; | ||
|
||
private: | ||
Ui::CreateWalletDialog *ui; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -199,6 +199,7 @@ void OptionsDialog::setModel(OptionsModel *_model) | |
connect(ui->prune, &QCheckBox::clicked, this, &OptionsDialog::togglePruneWarning); | ||
connect(ui->pruneSize, qOverload<int>(&QSpinBox::valueChanged), this, &OptionsDialog::showRestartWarning); | ||
connect(ui->databaseCache, qOverload<int>(&QSpinBox::valueChanged), this, &OptionsDialog::showRestartWarning); | ||
connect(ui->externalSignerPath, &QLineEdit::textChanged, [this]{ showRestartWarning(); }); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note to other reviewers. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should disable |
||
connect(ui->threadsScriptVerif, qOverload<int>(&QSpinBox::valueChanged), this, &OptionsDialog::showRestartWarning); | ||
/* Wallet */ | ||
connect(ui->spendZeroConfChange, &QCheckBox::clicked, this, &OptionsDialog::showRestartWarning); | ||
|
@@ -233,6 +234,7 @@ void OptionsDialog::setMapper() | |
/* Wallet */ | ||
mapper->addMapping(ui->spendZeroConfChange, OptionsModel::SpendZeroConfChange); | ||
mapper->addMapping(ui->coinControlFeatures, OptionsModel::CoinControlFeatures); | ||
mapper->addMapping(ui->externalSignerPath, OptionsModel::ExternalSignerPath); | ||
|
||
/* Network */ | ||
mapper->addMapping(ui->mapPortUpnp, OptionsModel::MapPortUPnP); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -89,6 +89,12 @@ void ReceiveRequestDialog::setInfo(const SendCoinsRecipient &_info) | |
ui->wallet_tag->hide(); | ||
ui->wallet_content->hide(); | ||
} | ||
|
||
ui->btnVerify->setVisible(this->model->wallet().hasExternalSigner()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit, drop |
||
|
||
connect(ui->btnVerify, &QPushButton::clicked, [this] { | ||
model->displayAddress(info.address.toStdString()); | ||
}); | ||
} | ||
|
||
void ReceiveRequestDialog::updateDisplayUnit() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3f845ea
Should we let this throw
runtime_error
? cc @ryanofskyThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of these ifdefs are gone in bitcoin/bitcoin#21935