diff options
| author | Patrick Lodder <[email protected]> | 2021-05-24 14:36:10 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-05-24 14:36:10 +0200 |
| commit | fb56f75e9c8c48bb6c8600abe600c1813576ef49 (patch) | |
| tree | 4006f4d38b76df9d9f5c49e3563c730478889db5 /src | |
| parent | Merge pull request #1976 from langerhans/1.14.4-travis-pgsql (diff) | |
| parent | Add GUI to import private keys (diff) | |
| download | discoin-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.include | 5 | ||||
| -rw-r--r-- | src/qt/bitcoingui.cpp | 6 | ||||
| -rw-r--r-- | src/qt/bitcoingui.h | 1 | ||||
| -rw-r--r-- | src/qt/forms/importkeysdialog.ui | 208 | ||||
| -rw-r--r-- | src/qt/importkeysdialog.cpp | 164 | ||||
| -rw-r--r-- | src/qt/importkeysdialog.h | 50 | ||||
| -rw-r--r-- | src/qt/walletframe.cpp | 7 | ||||
| -rw-r--r-- | src/qt/walletframe.h | 2 | ||||
| -rw-r--r-- | src/qt/walletview.cpp | 18 | ||||
| -rw-r--r-- | src/qt/walletview.h | 7 |
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>&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>&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>&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>&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(); |