diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 75b04e4..e693c7b 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1,5 +1,6 @@ #include "mainwindow.h" #include "ui_mainwindow.h" +#include "ui_privkey.h" #include "ui_about.h" #include "ui_settings.h" #include "ui_turnstile.h" @@ -38,7 +39,7 @@ MainWindow::MainWindow(QWidget *parent) : QDesktopServices::openUrl(QUrl("https://github.com/adityapk00/zec-qt-wallet/releases")); }); - QObject::connect(ui->actionImport_Private_Keys, &QAction::triggered, this, &MainWindow::importPrivKeys); + QObject::connect(ui->actionImport_Private_Key, &QAction::triggered, this, &MainWindow::importPrivKey); // Set up about action QObject::connect(ui->actionAbout, &QAction::triggered, [=] () { @@ -384,26 +385,31 @@ void MainWindow::donate() { ui->tabWidget->setCurrentIndex(1); } -void MainWindow::importPrivKeys() { - bool ok; - QString text = QInputDialog::getMultiLineText( - this, "Import Private Keys", - QString() + - "Please paste your private keys (z-Addr or t-Addr) here, one per line.\n" + - "The keys will be imported into your connected zcashd node", - "", &ok); - if (ok && !text.isEmpty()) { - auto keys = text.split("\n"); + +void MainWindow::importPrivKey() { + QDialog d(this); + Ui_PrivKey pui; + pui.setupUi(&d); + + pui.helpLbl->setText(QString() % + "Please paste your private keys (z-Addr or t-Addr) here, one per line.\n" % + "The keys will be imported into your connected zcashd node"); + if (d.exec() == QDialog::Accepted && !pui.privKeyTxt->toPlainText().trimmed().isEmpty()) { + auto keys = pui.privKeyTxt->toPlainText().trimmed().split("\n"); for (int i=0; i < keys.length(); i++) { auto key = keys[i].trimmed(); if (key.startsWith("S") || key.startsWith("secret")) { // Z key - + rpc->importZPrivKey(key, [=] (auto) {} ); } else { // T Key - + rpc->importTPrivKey(key, [=] (auto) {} ); } } } + + QMessageBox::information(this, + "Imported", "The keys were imported. It may be a while to rescan the blockchain with the new keys.", + QMessageBox::Ok); } void MainWindow::setupBalancesTab() { @@ -420,12 +426,34 @@ void MainWindow::setupBalancesTab() { QMenu menu(this); - menu.addAction("Copy Address", [=] () { + menu.addAction("Copy address", [=] () { QClipboard *clipboard = QGuiApplication::clipboard(); clipboard->setText(addr); ui->statusBar->showMessage("Copied to clipboard", 3 * 1000); }); + menu.addAction("Get private key", [=] () { + auto fnCB = [=] (const json& reply) { + auto privKey = QString::fromStdString(reply.get()); + QDialog d(this); + Ui_PrivKey pui; + pui.setupUi(&d); + + pui.helpLbl->setText("Private Key:"); + pui.privKeyTxt->setPlainText(privKey); + pui.privKeyTxt->setReadOnly(true); + pui.privKeyTxt->selectAll(); + pui.buttonBox->button(QDialogButtonBox::Ok)->setVisible(false); + + d.exec(); + }; + + if (Settings::getInstance()->isZAddress(addr)) + rpc->getZPrivKey(addr, fnCB); + else + rpc->getTPrivKey(addr, fnCB); + }); + menu.addAction("Send from " % addr.left(40) % (addr.size() > 40 ? "..." : ""), [=]() { // Find the inputs combo for (int i = 0; i < ui->inputsCombo->count(); i++) { diff --git a/src/mainwindow.h b/src/mainwindow.h index 2cf57c0..256a6bc 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -79,7 +79,7 @@ private: QString doSendTxValidations(Tx tx); void donate(); - void importPrivKeys(); + void importPrivKey(); RPC* rpc; diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 111fe9c..81e3a5f 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -725,7 +725,7 @@ File - + @@ -763,14 +763,6 @@ Donate - - - Import Private Keys - - - false - - Check github.com for Updates @@ -781,6 +773,11 @@ Sapling Turnstile + + + Import Private Key + + diff --git a/src/privkey.ui b/src/privkey.ui new file mode 100644 index 0000000..320e8bf --- /dev/null +++ b/src/privkey.ui @@ -0,0 +1,78 @@ + + + PrivKey + + + + 0 + 0 + 461 + 389 + + + + Private Key + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close|QDialogButtonBox::Ok + + + + + + + TextLabel + + + + + + + + + buttonBox + accepted() + PrivKey + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + PrivKey + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/rpc.cpp b/src/rpc.cpp index 03e7b94..c483fe2 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp @@ -162,6 +162,51 @@ void RPC::newTaddr(const std::function& cb) { doRPC(payload, cb); } +void RPC::getZPrivKey(QString addr, const std::function& cb) { + json payload = { + {"jsonrpc", "1.0"}, + {"id", "someid"}, + {"method", "z_exportkey"}, + {"params", { addr.toStdString() }}, + }; + + doRPC(payload, cb); +} + +void RPC::getTPrivKey(QString addr, const std::function& cb) { + json payload = { + {"jsonrpc", "1.0"}, + {"id", "someid"}, + {"method", "dumpprivkey"}, + {"params", { addr.toStdString() }}, + }; + + doRPC(payload, cb); +} + +void RPC::importZPrivKey(QString addr, const std::function& cb) { + json payload = { + {"jsonrpc", "1.0"}, + {"id", "someid"}, + {"method", "z_importkey"}, + {"params", { addr.toStdString() }}, + }; + + doRPC(payload, cb); +} + + +void RPC::importTPrivKey(QString addr, const std::function& cb) { + json payload = { + {"jsonrpc", "1.0"}, + {"id", "someid"}, + {"method", "importprivkey"}, + {"params", { addr.toStdString() }}, + }; + + doRPC(payload, cb); +} + void RPC::getBalance(const std::function& cb) { json payload = { diff --git a/src/rpc.h b/src/rpc.h index bbabb75..ae7ed82 100644 --- a/src/rpc.h +++ b/src/rpc.h @@ -50,6 +50,12 @@ public: void newZaddr(bool sapling, const std::function& cb); void newTaddr(const std::function& cb); + + void getZPrivKey(QString addr, const std::function& cb); + void getTPrivKey(QString addr, const std::function& cb); + void importZPrivKey(QString addr, const std::function& cb); + void importTPrivKey(QString addr, const std::function& cb); + Turnstile* getTurnstile() { return turnstile; } // Batch method. Note: Because of the template, it has to be in the header file. diff --git a/src/ui_mainwindow.h b/src/ui_mainwindow.h index 88ffa57..155e99d 100644 --- a/src/ui_mainwindow.h +++ b/src/ui_mainwindow.h @@ -45,9 +45,9 @@ public: QAction *actionAbout; QAction *actionSettings; QAction *actionDonate; - QAction *actionImport_Private_Keys; QAction *actionCheck_for_Updates; QAction *actionTurnstile_Migration; + QAction *actionImport_Private_Key; QWidget *centralWidget; QGridLayout *gridLayout_3; QTabWidget *tabWidget; @@ -155,13 +155,12 @@ public: actionSettings->setObjectName(QStringLiteral("actionSettings")); actionDonate = new QAction(MainWindow); actionDonate->setObjectName(QStringLiteral("actionDonate")); - actionImport_Private_Keys = new QAction(MainWindow); - actionImport_Private_Keys->setObjectName(QStringLiteral("actionImport_Private_Keys")); - actionImport_Private_Keys->setVisible(false); actionCheck_for_Updates = new QAction(MainWindow); actionCheck_for_Updates->setObjectName(QStringLiteral("actionCheck_for_Updates")); actionTurnstile_Migration = new QAction(MainWindow); actionTurnstile_Migration->setObjectName(QStringLiteral("actionTurnstile_Migration")); + actionImport_Private_Key = new QAction(MainWindow); + actionImport_Private_Key->setObjectName(QStringLiteral("actionImport_Private_Key")); centralWidget = new QWidget(MainWindow); centralWidget->setObjectName(QStringLiteral("centralWidget")); gridLayout_3 = new QGridLayout(centralWidget); @@ -670,7 +669,7 @@ public: menuBar->addAction(menuBalance->menuAction()); menuBar->addAction(menuHelp->menuAction()); - menuBalance->addAction(actionImport_Private_Keys); + menuBalance->addAction(actionImport_Private_Key); menuBalance->addAction(actionTurnstile_Migration); menuBalance->addAction(actionSettings); menuBalance->addSeparator(); @@ -694,9 +693,9 @@ public: actionAbout->setText(QApplication::translate("MainWindow", "About", nullptr)); actionSettings->setText(QApplication::translate("MainWindow", "Settings", nullptr)); actionDonate->setText(QApplication::translate("MainWindow", "Donate", nullptr)); - actionImport_Private_Keys->setText(QApplication::translate("MainWindow", "Import Private Keys", nullptr)); actionCheck_for_Updates->setText(QApplication::translate("MainWindow", "Check github.com for Updates", nullptr)); actionTurnstile_Migration->setText(QApplication::translate("MainWindow", "Sapling Turnstile", nullptr)); + actionImport_Private_Key->setText(QApplication::translate("MainWindow", "Import Private Key", nullptr)); groupBox->setTitle(QApplication::translate("MainWindow", "Summary", nullptr)); label->setText(QApplication::translate("MainWindow", "Shielded", nullptr)); balSheilded->setText(QString()); diff --git a/src/ui_privkey.h b/src/ui_privkey.h new file mode 100644 index 0000000..825c5e0 --- /dev/null +++ b/src/ui_privkey.h @@ -0,0 +1,77 @@ +/******************************************************************************** +** Form generated from reading UI file 'privkey.ui' +** +** Created by: Qt User Interface Compiler version 5.11.2 +** +** WARNING! All changes made in this file will be lost when recompiling UI file! +********************************************************************************/ + +#ifndef UI_PRIVKEY_H +#define UI_PRIVKEY_H + +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Ui_PrivKey +{ +public: + QGridLayout *gridLayout; + QPlainTextEdit *privKeyTxt; + QDialogButtonBox *buttonBox; + QLabel *helpLbl; + + void setupUi(QDialog *PrivKey) + { + if (PrivKey->objectName().isEmpty()) + PrivKey->setObjectName(QStringLiteral("PrivKey")); + PrivKey->resize(461, 389); + gridLayout = new QGridLayout(PrivKey); + gridLayout->setObjectName(QStringLiteral("gridLayout")); + privKeyTxt = new QPlainTextEdit(PrivKey); + privKeyTxt->setObjectName(QStringLiteral("privKeyTxt")); + + gridLayout->addWidget(privKeyTxt, 1, 0, 1, 1); + + buttonBox = new QDialogButtonBox(PrivKey); + buttonBox->setObjectName(QStringLiteral("buttonBox")); + buttonBox->setOrientation(Qt::Horizontal); + buttonBox->setStandardButtons(QDialogButtonBox::Close|QDialogButtonBox::Ok); + + gridLayout->addWidget(buttonBox, 2, 0, 1, 1); + + helpLbl = new QLabel(PrivKey); + helpLbl->setObjectName(QStringLiteral("helpLbl")); + + gridLayout->addWidget(helpLbl, 0, 0, 1, 1); + + + retranslateUi(PrivKey); + QObject::connect(buttonBox, SIGNAL(accepted()), PrivKey, SLOT(accept())); + QObject::connect(buttonBox, SIGNAL(rejected()), PrivKey, SLOT(reject())); + + QMetaObject::connectSlotsByName(PrivKey); + } // setupUi + + void retranslateUi(QDialog *PrivKey) + { + PrivKey->setWindowTitle(QApplication::translate("PrivKey", "Private Key", nullptr)); + privKeyTxt->setPlainText(QString()); + helpLbl->setText(QApplication::translate("PrivKey", "TextLabel", nullptr)); + } // retranslateUi + +}; + +namespace Ui { + class PrivKey: public Ui_PrivKey {}; +} // namespace Ui + +QT_END_NAMESPACE + +#endif // UI_PRIVKEY_H diff --git a/zec-qt-wallet.pro b/zec-qt-wallet.pro index 8c50d62..ebda8db 100644 --- a/zec-qt-wallet.pro +++ b/zec-qt-wallet.pro @@ -75,7 +75,8 @@ FORMS += \ src/about.ui \ src/confirm.ui \ src/turnstile.ui \ - src/turnstileprogress.ui + src/turnstileprogress.ui \ + src/privkey.ui src/memodialog.ui # Default rules for deployment.