aboutsummaryrefslogtreecommitdiff
path: root/src/qt/importkeysdialog.cpp
diff options
context:
space:
mode:
authorchromatic <[email protected]>2021-04-21 16:35:06 -0700
committerchromatic <[email protected]>2021-05-23 19:37:09 -0700
commit0565a85c7cd8df3ea3cfee2a5a9f252b870408ad (patch)
tree4006f4d38b76df9d9f5c49e3563c730478889db5 /src/qt/importkeysdialog.cpp
parentMerge pull request #1976 from langerhans/1.14.4-travis-pgsql (diff)
downloaddiscoin-0565a85c7cd8df3ea3cfee2a5a9f252b870408ad.tar.xz
discoin-0565a85c7cd8df3ea3cfee2a5a9f252b870408ad.zip
Add GUI to import private keys
Addresses GH #1808. There are several possible future improvements: * add a new icon for key import * reduce duplication of code between the RPC private key importer and the GUI private key importer * improving error messages for various error states
Diffstat (limited to 'src/qt/importkeysdialog.cpp')
-rw-r--r--src/qt/importkeysdialog.cpp164
1 files changed, 164 insertions, 0 deletions
diff --git a/src/qt/importkeysdialog.cpp b/src/qt/importkeysdialog.cpp
new file mode 100644
index 000000000..743a61d8b
--- /dev/null
+++ b/src/qt/importkeysdialog.cpp
@@ -0,0 +1,164 @@
+// Copyright (c) 2021 The Dogecoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include "importkeysdialog.h"
+#include "ui_importkeysdialog.h"
+
+#include "base58.h"
+#include "guiutil.h"
+#include "platformstyle.h"
+#include "validation.h"
+#include "wallet/wallet.h"
+#include "walletmodel.h"
+#include "util.h"
+
+#include <QThread>
+#include <QDebug>
+
+/* Object for executing key import commands in a separate thread.
+*/
+class ImportKeyExecutor : public QObject
+{
+ Q_OBJECT
+
+public Q_SLOTS:
+ void rescan(CWallet*, CBlockIndex*);
+
+Q_SIGNALS:
+ void rescanWallet(CWallet*, CBlockIndex*);
+};
+
+#include "importkeysdialog.moc"
+
+void ImportKeyExecutor::rescan(CWallet* pwallet, CBlockIndex* genesisBlock)
+{
+ qWarning() << "started import key thread";
+ pwallet->UpdateTimeFirstKey(1);
+ pwallet->ScanForWalletTransactions(genesisBlock, true);
+ qWarning() << "quitting import key thread";
+ QObject::thread()->quit();
+}
+
+ImportKeysDialog::ImportKeysDialog(const PlatformStyle *_platformStyle, QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::ImportKeysDialog),
+ platformStyle(_platformStyle)
+{
+ ui->setupUi(this);
+
+ /* Main elements init */
+ if (fPruneMode) {
+ ui->rescanCheckBox->setEnabled(false);
+ }
+}
+
+ImportKeysDialog::~ImportKeysDialog()
+{
+ thread.wait();
+ delete ui;
+}
+
+void ImportKeysDialog::on_okButton_clicked()
+{
+ if (importKey()) {
+ resetDialogValues();
+ accept();
+ };
+}
+
+void ImportKeysDialog::on_cancelButton_clicked()
+{
+ reject();
+}
+
+void ImportKeysDialog::on_resetButton_clicked()
+{
+ resetDialogValues();
+}
+
+bool ImportKeysDialog::importKey()
+{
+ const QString privateKey = ui->privateKey->text();
+ const QString privateKeyLabel = ui->privateKeyLabel->text();
+ const bool rescan = ui->rescanCheckBox->isChecked();
+
+ resetDialogValues();
+
+ CBitcoinSecret vchSecret;
+ bool fGood = vchSecret.SetString(privateKey.toStdString());
+ if (!fGood) {
+ vchSecret.SetString("");
+ ui->privateKeyImportTextMessage->setText(tr("Invalid private key; please check and try again!"));
+ return false;
+ }
+
+ CKey key = vchSecret.GetKey();
+ if (!key.IsValid()) {
+ vchSecret.SetString("");
+ ui->privateKeyImportTextMessage->setText(tr("Invalid private key; please check and try again!"));
+ return false;
+ }
+
+ CPubKey pubkey = key.GetPubKey();
+ assert(key.VerifyPubKey(pubkey));
+ CKeyID vchAddress = pubkey.GetID();
+
+ pwalletMain->MarkDirty();
+ pwalletMain->SetAddressBook(vchAddress, privateKeyLabel.toStdString(), "receive");
+
+ if (pwalletMain->HaveKey(vchAddress)) {
+ vchSecret.SetString("");
+ ui->privateKeyImportTextMessage->setText(
+ tr("Invalid address generated from private key; please check and try again!"
+ ));
+ return false;
+ }
+
+ pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = 1;
+
+ if (!pwalletMain->AddKeyPubKey(key, pubkey)) {
+ vchSecret.SetString("");
+ ui->privateKeyImportTextMessage->setText(tr("Failed to add private key."));
+ return false;
+ }
+
+ pwalletMain->UpdateTimeFirstKey(1);
+
+ if (rescan) {
+ ImportKeyExecutor *executor = new ImportKeyExecutor();
+ executor->moveToThread(&thread);
+ connect(this, SIGNAL(rescanWallet(CWallet*, CBlockIndex*)), executor, SLOT(rescan(CWallet*, CBlockIndex*)));
+
+ // On stopExecutor signal
+ // - quit the Qt event loop in the execution thread
+ connect(this, SIGNAL(stopExecutor()), &thread, SLOT(quit()));
+ // - queue executor for deletion (in execution thread)
+ connect(&thread, SIGNAL(finished()), executor, SLOT(deleteLater()), Qt::DirectConnection);
+
+ // Default implementation of QThread::run() simply spins up an event loop in the thread,
+ // which is what we want.
+ thread.start();
+ ui->privateKeyImportTextMessage->setText(tr("Rescanning..."));
+ Q_EMIT rescanWallet(pwalletMain, chainActive.Genesis());
+ }
+
+ vchSecret.SetString("");
+ return true;
+}
+
+void ImportKeysDialog::resetDialogValues()
+{
+ ui->privateKey->clear();
+ ui->privateKeyLabel->clear();
+ ui->rescanCheckBox->setCheckState(Qt::Unchecked);
+}
+
+void ImportKeysDialog::setOkButtonState(bool fState)
+{
+ ui->okButton->setEnabled(fState);
+}