From 10a0545773e4f04259955de0faad8070143b84ea Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 29 Sep 2020 16:38:44 +0200 Subject: [PATCH] add import zkey --- src/connection.cpp | 88 +++++++++++++++++++++++-- src/connection.h | 5 ++ src/controller.h | 10 ++- src/liteinterface.cpp | 27 ++++++++ src/liteinterface.h | 2 +- src/mainwindow.cpp | 148 +++++++++++++++++++++++------------------- src/mainwindow.ui | 6 ++ 7 files changed, 211 insertions(+), 75 deletions(-) diff --git a/src/connection.cpp b/src/connection.cpp index def0751..bac34f3 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -65,6 +65,82 @@ void ConnectionLoader::loadConnection() d->exec(); } +void ConnectionLoader::loadProgress() +{ + QTimer::singleShot(1, [=]() { this->ShowProgress(); }); + if (!Settings::getInstance()->isHeadless()) + d->exec(); +} + +void ConnectionLoader::ShowProgress() +{ + + auto config = std::shared_ptr(new ConnectionConfig()); + config->dangerous = false; + config->server = Settings::getInstance()->getSettings().server; + auto connection = makeConnection(config); + auto me = this; + + // After the lib is initialized, try to do get info + connection->doRPC("info", "", [=](auto reply) { + // If success, set the connection + main->logger->write("Connection is online."); + connection->setInfo(reply); + main->logger->write("getting Connection reply"); + isSyncing = new QAtomicInteger(); + isSyncing->store(true); + main->logger->write("isSyncing"); + + // Do a sync at startup + syncTimer = new QTimer(main); + main->logger->write("Beginning sync"); + connection->doRPCWithDefaultErrorHandling("sync", "", [=](auto) { + isSyncing->store(false); + // Cancel the timer + syncTimer->deleteLater(); + // When sync is done, set the connection + this->doRPCSetConnection(connection); + }); + + // While it is syncing, we'll show the status updates while it is alive. + QObject::connect(syncTimer, &QTimer::timeout, [=]() { + // Check the sync status + if (isSyncing != nullptr && isSyncing->load()) { + // Get the sync status + + try { + connection->doRPC("syncstatus", "", [=](json reply) { + if (isSyncing != nullptr && reply.find("synced_blocks") != reply.end()) + + { + qint64 synced = reply["synced_blocks"].get(); + qint64 total = reply["total_blocks"].get(); + me->showInformation( + "Synced " + QString::number(synced) + " / " + QString::number(total) + ); + } + }, + [=](QString err) { + qDebug() << "Sync error" << err; + }); + }catch (...) + { + main->logger->write("catch sync progress reply"); + + } + + } + }); + + syncTimer->setInterval(1* 1000); + syncTimer->start(); + main->logger->write("Start sync timer"); + + }, [=](QString err) { + showError(err); + }); +} + void ConnectionLoader::doAutoConnect() { qDebug() << "Doing autoconnect"; @@ -109,14 +185,14 @@ void ConnectionLoader::doAutoConnect() connection->setInfo(reply); main->logger->write("getting Connection reply"); isSyncing = new QAtomicInteger(); - isSyncing->storeRelaxed(true); + isSyncing->store(true); main->logger->write("isSyncing"); // Do a sync at startup syncTimer = new QTimer(main); main->logger->write("Beginning sync"); connection->doRPCWithDefaultErrorHandling("sync", "", [=](auto) { - isSyncing->storeRelaxed(false); + isSyncing->store(false); // Cancel the timer syncTimer->deleteLater(); // When sync is done, set the connection @@ -126,7 +202,7 @@ void ConnectionLoader::doAutoConnect() // While it is syncing, we'll show the status updates while it is alive. QObject::connect(syncTimer, &QTimer::timeout, [=]() { // Check the sync status - if (isSyncing != nullptr && isSyncing->loadRelaxed()) { + if (isSyncing != nullptr && isSyncing->load()) { // Get the sync status try { @@ -255,7 +331,6 @@ void Executor::run() emit responseReady(parsed); } - void Callback::processRPCCallback(json resp) { this->cb(resp); @@ -284,7 +359,10 @@ void Connection::doRPC(const QString cmd, const QString args, const std::functio // Ignoring RPC because shutdown in progress return; - //qDebug() << "Doing RPC: " << cmd; + qDebug() << "Doing RPC: " << cmd; + qDebug() << "Args :"<< args; + + // Create a runner. auto runner = new Executor(cmd, args); diff --git a/src/connection.h b/src/connection.h index 32eb230..b851a1f 100644 --- a/src/connection.h +++ b/src/connection.h @@ -24,6 +24,7 @@ public: ~ConnectionLoader(); void loadConnection(); + void loadProgress(); private: std::shared_ptr autoDetecthushConf(); @@ -32,6 +33,7 @@ private: Connection* makeConnection(std::shared_ptr config); void doAutoConnect(); + void ShowProgress(); void createOrRestore(bool dangerous, QString server); @@ -83,6 +85,7 @@ public: Executor(QString cmd, QString args) { this->cmd = cmd; this->args = args; + }; ~Executor() = default; @@ -118,7 +121,9 @@ public: void doRPC(const QString cmd, const QString args, const std::function& cb, const std::function& errCb); + void doRPCWithDefaultErrorHandling(const QString cmd, const QString args, const std::function& cb); + void doRPCIgnoreError(const QString cmd, const QString args, const std::function& cb) ; void showTxError(const QString& error); diff --git a/src/controller.h b/src/controller.h index a3333c2..a0e2d3d 100644 --- a/src/controller.h +++ b/src/controller.h @@ -154,9 +154,13 @@ public: }); } - - // void importZPrivKey(QString addr, bool rescan, const std::function& cb) { zrpc->importZPrivKey(addr, rescan, cb); } - // void importTPrivKey(QString addr, bool rescan, const std::function& cb) { zrpc->importTPrivKey(addr, rescan, cb); } + void importZPrivKey(QString addr,const std::function& cb) { + unlockIfEncrypted([=] () { + zrpc->importZPrivKey(addr,cb); + }, [=](){}); + } + void importZPrivKey(QString addr, const std::function& cb,const std::function& err) { zrpc->importZPrivKey(addr, cb, ""); } + // void importTPrivKey(QString addr,bool rescan, const std::function& cb) { zrpc->importTPrivKey(addr,rescan, cb); } QString getDefaultSaplingAddress(); QString getDefaultTAddress(); diff --git a/src/liteinterface.cpp b/src/liteinterface.cpp index 3d7a4a1..87ae1fc 100644 --- a/src/liteinterface.cpp +++ b/src/liteinterface.cpp @@ -27,6 +27,33 @@ void LiteInterface::fetchAddresses(const std::function& cb) { conn->doRPCWithDefaultErrorHandling("addresses", "", cb); } +void LiteInterface::importZPrivKey(QString addr, const std::function& cb) { + if (conn == nullptr) + return; + + // QString params = addr % QString(" "); + // params.append(birthday); + qDebug()<doRPCWithDefaultErrorHandling("import", addr, cb); + // conn->doRPC("import", params, cb, err); + + +} + +/*void LiteInterface::importTPrivKey(QString addr, bool rescan, const std::function& cb) { + if (conn == nullptr) + return; + + + + // conn->doRPCWithDefaultErrorHandling("import", addr, cb); + + // conn->doRPC("import", addr, 0, cb); +}*/ + void LiteInterface::fetchUnspent(const std::function& cb) { if (conn == nullptr) diff --git a/src/liteinterface.h b/src/liteinterface.h index b8309bd..b749081 100644 --- a/src/liteinterface.h +++ b/src/liteinterface.h @@ -70,7 +70,7 @@ public: void unlockWallet(QString password, const std::function& cb); void removeWalletEncryption(QString password, const std::function& cb); - //void importZPrivKey(QString addr, bool rescan, const std::function& cb); + void importZPrivKey(QString addr, const std::function& cb); //void importTPrivKey(QString addr, bool rescan, const std::function& cb); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index a9f28fc..433d040 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -280,6 +280,8 @@ MainWindow::MainWindow(QWidget *parent) : dialog.exec(); }); +// Import Privkey + QObject::connect(ui->actionImport_Privatkey, &QAction::triggered, this, &MainWindow::importPrivKey); // Address Book QObject::connect(ui->action_Address_Book, &QAction::triggered, this, &MainWindow::addressBook); @@ -930,30 +932,39 @@ void MainWindow::donate() { ui->tabWidget->setCurrentIndex(1); } -// void MainWindow::doImport(QList* keys) { -// if (rpc->getConnection() == nullptr) { -// // No connection, just return -// return; -// } + void MainWindow::doImport(QList* keys) { + if (rpc->getConnection() == nullptr) { + // No connection, just return + return; + } -// if (keys->isEmpty()) { -// delete keys; -// ui->statusBar->showMessage(tr("Private key import rescan finished")); -// return; -// } + if (keys->isEmpty()) { + delete keys; + ui->statusBar->showMessage(tr("Private key import rescan finished")); + return; + } -// // Pop the first key -// QString key = keys->first(); -// keys->pop_front(); -// bool rescan = keys->isEmpty(); + // Pop the first key + + QString key = keys->first(); + QString key1 = key + QString(" ") + QString("0"); + keys->pop_front(); + bool rescan = keys->isEmpty(); + -// if (key.startsWith("SK") || -// key.startsWith("secret")) { // Z key -// rpc->importZPrivKey(key, rescan, [=] (auto) { this->doImport(keys); }); -// } else { -// rpc->importTPrivKey(key, rescan, [=] (auto) { this->doImport(keys); }); -// } -// } + if (key.startsWith("SK") || + key.startsWith("secret")) { // Z key + + rpc->importZPrivKey(key, [=] (auto) { this->doImport(keys); }); + + // Then reload the connection. The ConnectionLoader deletes itself. + + + + } else { + rpc->importTPrivKey(key, rescan, [=] (auto) { this->doImport(keys); }); + } + } // Callback invoked when the RPC has finished loading all the balances, and the UI @@ -1041,51 +1052,56 @@ void MainWindow::payhushURI(QString uri, QString myAddr) { } } - -// void MainWindow::importPrivKey() { -// QDialog d(this); -// Ui_PrivKey pui; -// pui.setupUi(&d); -// Settings::saveRestore(&d); - -// pui.buttonBox->button(QDialogButtonBox::Save)->setVisible(false); -// pui.helpLbl->setText(QString() % -// tr("Please paste your private keys (z-Addr or t-Addr) here, one per line") % ".\n" % -// tr("The keys will be imported into your connected hushd node")); - -// if (d.exec() == QDialog::Accepted && !pui.privKeyTxt->toPlainText().trimmed().isEmpty()) { -// auto rawkeys = pui.privKeyTxt->toPlainText().trimmed().split("\n"); - -// QList keysTmp; -// // Filter out all the empty keys. -// std::copy_if(rawkeys.begin(), rawkeys.end(), std::back_inserter(keysTmp), [=] (auto key) { -// return !key.startsWith("#") && !key.trimmed().isEmpty(); -// }); - -// auto keys = new QList(); -// std::transform(keysTmp.begin(), keysTmp.end(), std::back_inserter(*keys), [=](auto key) { -// return key.trimmed().split(" ")[0]; -// }); - -// // Special case. -// // Sometimes, when importing from a paperwallet or such, the key is split by newlines, and might have -// // been pasted like that. So check to see if the whole thing is one big private key -// if (Settings::getInstance()->isValidSaplingPrivateKey(keys->join(""))) { -// auto multiline = keys; -// keys = new QList(); -// keys->append(multiline->join("")); -// delete multiline; -// } - -// // Start the import. The function takes ownership of keys -// QTimer::singleShot(1, [=]() {doImport(keys);}); - -// // Show the dialog that keys will be imported. -// QMessageBox::information(this, -// "Imported", tr("The keys were imported. It may take several minutes to rescan the blockchain. Until then, functionality may be limited"), -// QMessageBox::Ok); -// } -// } + void MainWindow::importPrivKey() { + QDialog d(this); + Ui_PrivKey pui; + pui.setupUi(&d); + Settings::saveRestore(&d); + + pui.buttonBox->button(QDialogButtonBox::Save)->setVisible(true); + pui.helpLbl->setText(QString() % + tr("Please paste your private key(z-Addr) here, one per import") % ".\n" % + tr("Caution: These key will be NOT inlcude in your Seed. Please send them direct to a Seed zaddr") % ".\n" % + tr("The import of your Privatkey will take some time.") + ); + + if (d.exec() == QDialog::Accepted && !pui.privKeyTxt->toPlainText().trimmed().isEmpty()) { + auto rawkeys = pui.privKeyTxt->toPlainText().trimmed().split("\n"); + + QList keysTmp; + // Filter out all the empty keys. + std::copy_if(rawkeys.begin(), rawkeys.end(), std::back_inserter(keysTmp), [=] (auto key) { + return !key.startsWith("#") && !key.trimmed().isEmpty(); + }); + + auto keys = new QList(); + std::transform(keysTmp.begin(), keysTmp.end(), std::back_inserter(*keys), [=](auto key) { + return key.trimmed().split(" ")[0]; + }); + + // Special case. + // Sometimes, when importing from a paperwallet or such, the key is split by newlines, and might have + // been pasted like that. So check to see if the whole thing is one big private key + if (Settings::getInstance()->isValidSaplingPrivateKey(keys->join(""))) { + auto multiline = keys; + keys = new QList(); + keys->append(multiline->join("")); + delete multiline; + } + + // Start the import. The function takes ownership of keys + QTimer::singleShot(1, [=]() {doImport(keys);}); + + auto cl = new ConnectionLoader(this, rpc); + QTimer::singleShot(1, [=]() { cl->loadProgress(); }); + + + // Show the dialog that keys will be imported. + // QMessageBox::information(this, + // "Imported", tr("The keys were imported. It may take several minutes to rescan the blockchain. Until then, functionality may be limited"), + // QMessageBox::Ok); + } + } /** * Export transaction history into a CSV file diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 17386a2..74543b6 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1894,6 +1894,7 @@ + @@ -2005,6 +2006,11 @@ Rescan + + + Import Privatkey + +