aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPatrick Lodder <[email protected]>2021-05-24 14:36:10 +0200
committerGitHub <[email protected]>2021-05-24 14:36:10 +0200
commitfb56f75e9c8c48bb6c8600abe600c1813576ef49 (patch)
tree4006f4d38b76df9d9f5c49e3563c730478889db5 /src
parentMerge pull request #1976 from langerhans/1.14.4-travis-pgsql (diff)
parentAdd GUI to import private keys (diff)
downloaddiscoin-fb56f75e9c8c48bb6c8600abe600c1813576ef49.tar.xz
discoin-fb56f75e9c8c48bb6c8600abe600c1813576ef49.zip
Merge pull request #1856 from chromatic/add-wif-import
Add a WIF import dialog to the QT wallet.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.qt.include5
-rw-r--r--src/qt/bitcoingui.cpp6
-rw-r--r--src/qt/bitcoingui.h1
-rw-r--r--src/qt/forms/importkeysdialog.ui208
-rw-r--r--src/qt/importkeysdialog.cpp164
-rw-r--r--src/qt/importkeysdialog.h50
-rw-r--r--src/qt/walletframe.cpp7
-rw-r--r--src/qt/walletframe.h2
-rw-r--r--src/qt/walletview.cpp18
-rw-r--r--src/qt/walletview.h7
10 files changed, 468 insertions, 0 deletions
diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include
index 723e29dc5..3997ae0ec 100644
--- a/src/Makefile.qt.include
+++ b/src/Makefile.qt.include
@@ -101,6 +101,7 @@ QT_FORMS_UI = \
qt/forms/editaddressdialog.ui \
qt/forms/helpmessagedialog.ui \
qt/forms/intro.ui \
+ qt/forms/importkeysdialog.ui \
qt/forms/modaloverlay.ui \
qt/forms/openuridialog.ui \
qt/forms/optionsdialog.ui \
@@ -130,6 +131,7 @@ QT_MOC_CPP = \
qt/moc_editaddressdialog.cpp \
qt/moc_guiutil.cpp \
qt/moc_intro.cpp \
+ qt/moc_importkeysdialog.cpp \
qt/moc_macdockiconhandler.cpp \
qt/moc_macnotificationhandler.cpp \
qt/moc_modaloverlay.cpp \
@@ -169,6 +171,7 @@ BITCOIN_MM = \
QT_MOC = \
qt/bitcoin.moc \
qt/bitcoinamountfield.moc \
+ qt/importkeysdialog.moc \
qt/intro.moc \
qt/overviewpage.moc \
qt/rpcconsole.moc
@@ -199,6 +202,7 @@ BITCOIN_QT_H = \
qt/guiconstants.h \
qt/guiutil.h \
qt/intro.h \
+ qt/importkeysdialog.h \
qt/macdockiconhandler.h \
qt/macnotificationhandler.h \
qt/modaloverlay.h \
@@ -331,6 +335,7 @@ BITCOIN_QT_WALLET_CPP = \
qt/coincontroldialog.cpp \
qt/coincontroltreewidget.cpp \
qt/editaddressdialog.cpp \
+ qt/importkeysdialog.cpp \
qt/openuridialog.cpp \
qt/overviewpage.cpp \
qt/paymentrequestplus.cpp \
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 71c1fd355..f7e58abee 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -102,6 +102,7 @@ BitcoinGUI::BitcoinGUI(const PlatformStyle *_platformStyle, const NetworkStyle *
sendCoinsMenuAction(0),
usedSendingAddressesAction(0),
usedReceivingAddressesAction(0),
+ importPrivateKeyAction(0),
signMessageAction(0),
verifyMessageAction(0),
aboutAction(0),
@@ -392,6 +393,9 @@ void BitcoinGUI::createActions()
openAction = new QAction(platformStyle->TextColorIcon(":/icons/open"), tr("Open &URI..."), this);
openAction->setStatusTip(tr("Open a dogecoin: URI or payment request"));
+ importPrivateKeyAction = new QAction(platformStyle->TextColorIcon(":/icons/address-book"), tr("&Import Private Key..."), this);
+ importPrivateKeyAction->setStatusTip(tr("Import a Dogecoin private key"));
+
showHelpMessageAction = new QAction(platformStyle->TextColorIcon(":/icons/info"), tr("&Command-line options"), this);
showHelpMessageAction->setMenuRole(QAction::NoRole);
showHelpMessageAction->setStatusTip(tr("Show the %1 help message to get a list with possible Dogecoin command-line options").arg(tr(PACKAGE_NAME)));
@@ -418,6 +422,7 @@ void BitcoinGUI::createActions()
connect(usedReceivingAddressesAction, SIGNAL(triggered()), walletFrame, SLOT(usedReceivingAddresses()));
connect(openAction, SIGNAL(triggered()), this, SLOT(openClicked()));
connect(paperWalletAction, SIGNAL(triggered()), walletFrame, SLOT(printPaperWallets()));
+ connect(importPrivateKeyAction, SIGNAL(triggered()), walletFrame, SLOT(importPrivateKey()));
}
#endif // ENABLE_WALLET
@@ -445,6 +450,7 @@ void BitcoinGUI::createMenuBar()
file->addAction(verifyMessageAction);
file->addAction(paperWalletAction);
file->addSeparator();
+ file->addAction(importPrivateKeyAction);
file->addAction(usedSendingAddressesAction);
file->addAction(usedReceivingAddressesAction);
file->addSeparator();
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index 6b0cc65c5..8d250af03 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -99,6 +99,7 @@ private:
QAction *sendCoinsMenuAction;
QAction *usedSendingAddressesAction;
QAction *usedReceivingAddressesAction;
+ QAction *importPrivateKeyAction;
QAction *signMessageAction;
QAction *verifyMessageAction;
QAction *paperWalletAction;
diff --git a/src/qt/forms/importkeysdialog.ui b/src/qt/forms/importkeysdialog.ui
new file mode 100644
index 000000000..0d4aa47a3
--- /dev/null
+++ b/src/qt/forms/importkeysdialog.ui
@@ -0,0 +1,208 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ImportKeysDialog</class>
+ <widget class="QDialog" name="ImportKeysDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>560</width>
+ <height>200</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Import Private Key</string>
+ </property>
+ <property name="modal">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QWidget" name="tabImportPrivateKey">
+ <attribute name="title">
+ <string>&amp;Import Private Key</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_Display">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_1_ImportPrivateKey">
+ <item>
+ <widget class="QLabel" name="privateKeyWidgetLabel">
+ <property name="text">
+ <string>Private Key:</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="privateKey">
+ <property name="toolTip">
+ <string>Private key to import into your wallet</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2_ImportPrivateKey">
+ <item>
+ <widget class="QLabel" name="privateKeyLabelWidgetLabel">
+ <property name="toolTip">
+ <string>Label for this private key in your wallet</string>
+ </property>
+ <property name="text">
+ <string>Label (optional):</string>
+ </property>
+ <property name="buddy">
+ <cstring>privateKeyLabel</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="privateKeyLabel">
+ <property name="toolTip">
+ <string>Label for this private key in your wallet</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="rescanCheckBox">
+ <property name="toolTip">
+ <string extracomment="Rescan the blockchain on import (disabled when running in pruned mode)."/>
+ </property>
+ <property name="text">
+ <string>Rescan</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="privateKeyImportTextMessage">
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_ImportPrivateKey">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="frame">
+ <layout class="QVBoxLayout" name="verticalLayout_Bottom">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_Bottom"/>
+ </item>
+ <item>
+ <widget class="QLabel" name="overriddenByCommandLineLabel">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_Buttons">
+ <item>
+ <widget class="QPushButton" name="resetButton">
+ <property name="toolTip">
+ <string>Reset all key management options to default.</string>
+ </property>
+ <property name="text">
+ <string>&amp;Reset</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_1">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>48</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="statusLabel">
+ <property name="minimumSize">
+ <size>
+ <width>200</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="okButton">
+ <property name="text">
+ <string>&amp;Import</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelButton">
+ <property name="text">
+ <string>&amp;Cancel</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
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);
+}
diff --git a/src/qt/importkeysdialog.h b/src/qt/importkeysdialog.h
new file mode 100644
index 000000000..115e0bd0b
--- /dev/null
+++ b/src/qt/importkeysdialog.h
@@ -0,0 +1,50 @@
+// 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.
+
+#ifndef BITCOIN_QT_OPTIONSDIALOG_H
+#define BITCOIN_QT_OPTIONSDIALOG_H
+class CWallet;
+class CBlockIndex;
+
+#include <QDialog>
+#include <QThread>
+
+class ImportKeysDialog;
+class PlatformStyle;
+
+namespace Ui {
+class ImportKeysDialog;
+}
+
+/** Preferences dialog. */
+class ImportKeysDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit ImportKeysDialog(const PlatformStyle *_platformStyle, QWidget *parent = 0);
+ ~ImportKeysDialog();
+
+Q_SIGNALS:
+ void stopExecutor();
+ void rescanWallet(CWallet*, CBlockIndex*);
+
+private:
+ Ui::ImportKeysDialog *ui;
+ const PlatformStyle *platformStyle;
+ QThread thread;
+
+private Q_SLOTS:
+ /* set OK button state (enabled / disabled) */
+ void setOkButtonState(bool fState);
+ void on_resetButton_clicked();
+ void on_okButton_clicked();
+ void on_cancelButton_clicked();
+ void resetDialogValues();
+
+ /* import a private key */
+ bool importKey();
+};
+
+#endif // BITCOIN_QT_OPTIONSDIALOG_H
diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp
index b2bb7d554..ccf4830e2 100644
--- a/src/qt/walletframe.cpp
+++ b/src/qt/walletframe.cpp
@@ -186,6 +186,13 @@ void WalletFrame::printPaperWallets()
walletView->printPaperWallets();
}
+void WalletFrame::importPrivateKey()
+{
+ WalletView *walletView = currentWalletView();
+ if (walletView)
+ walletView->importPrivateKey();
+}
+
void WalletFrame::usedSendingAddresses()
{
WalletView *walletView = currentWalletView();
diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h
index a04a5b340..8a9ca2ef4 100644
--- a/src/qt/walletframe.h
+++ b/src/qt/walletframe.h
@@ -85,6 +85,8 @@ public Q_SLOTS:
/** Ask for passphrase to unlock wallet temporarily */
void unlockWallet();
+ /** import a private key */
+ void importPrivateKey();
void printPaperWallets();
/** Show used sending addresses */
diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp
index e7a1753ef..7474b7dc3 100644
--- a/src/qt/walletview.cpp
+++ b/src/qt/walletview.cpp
@@ -9,6 +9,7 @@
#include "bitcoingui.h"
#include "clientmodel.h"
#include "guiutil.h"
+#include "importkeysdialog.h"
#include "optionsmodel.h"
#include "overviewpage.h"
#include "platformstyle.h"
@@ -65,6 +66,8 @@ WalletView::WalletView(const PlatformStyle *_platformStyle, QWidget *parent):
addWidget(receiveCoinsPage);
addWidget(sendCoinsPage);
+ importKeysDialog = new ImportKeysDialog(platformStyle);
+
// Clicking on a transaction on the overview pre-selects the transaction on the transaction history page
connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), transactionView, SLOT(focusTransaction(QModelIndex)));
connect(overviewPage, SIGNAL(outOfSyncWarningClicked()), this, SLOT(requestedSyncWarningInfo()));
@@ -217,6 +220,11 @@ void WalletView::gotoVerifyMessageTab(QString addr)
signVerifyMessageDialog->setAddress_VM(addr);
}
+void WalletView::gotoImportKeysDialog()
+{
+ setCurrentWidget(importKeysDialog);
+}
+
bool WalletView::handlePaymentRequest(const SendCoinsRecipient& recipient)
{
return sendCoinsPage->handlePaymentRequest(recipient);
@@ -302,6 +310,16 @@ void WalletView::usedReceivingAddresses()
usedReceivingAddressesPage->activateWindow();
}
+void WalletView::importPrivateKey()
+{
+ if(!walletModel)
+ return;
+
+ importKeysDialog->show();
+ importKeysDialog->raise();
+ importKeysDialog->activateWindow();
+}
+
void WalletView::showProgress(const QString &title, int nProgress)
{
if (nProgress == 0)
diff --git a/src/qt/walletview.h b/src/qt/walletview.h
index 67d163fa0..bd581e124 100644
--- a/src/qt/walletview.h
+++ b/src/qt/walletview.h
@@ -19,6 +19,7 @@ class SendCoinsRecipient;
class TransactionView;
class WalletModel;
class AddressBookPage;
+class ImportKeysDialog;
QT_BEGIN_NAMESPACE
class QModelIndex;
@@ -64,6 +65,7 @@ private:
SendCoinsDialog *sendCoinsPage;
AddressBookPage *usedSendingAddressesPage;
AddressBookPage *usedReceivingAddressesPage;
+ ImportKeysDialog *importKeysDialog;
TransactionView *transactionView;
@@ -75,6 +77,8 @@ public Q_SLOTS:
void gotoOverviewPage();
/** Switch to history (transactions) page */
void gotoHistoryPage();
+ /** Switch to import keys dialog */
+ void gotoImportKeysDialog();
/** Switch to receive coins page */
void gotoReceiveCoinsPage();
/** Switch to send coins page */
@@ -106,6 +110,9 @@ public Q_SLOTS:
/** Show used receiving addresses */
void usedReceivingAddresses();
+ /** Import a private key */
+ void importPrivateKey();
+
/** Re-emit encryption status signal */
void updateEncryptionStatus();