From 54c3971bed4400f014c9b4d4ee9e186502f64d00 Mon Sep 17 00:00:00 2001 From: Aditya Kulkarni Date: Thu, 31 Oct 2019 10:58:54 -0700 Subject: [PATCH] Export seed menu item --- lib/Cargo.lock | 6 ++-- src/controller.h | 10 ++++++ src/liteinterface.cpp | 7 ++++ src/liteinterface.h | 1 + src/mainwindow.cpp | 77 +++++++++++++++++++++++++++++-------------- src/mainwindow.h | 2 +- src/mainwindow.ui | 6 ++-- src/settings.h | 6 ++++ 8 files changed, 83 insertions(+), 32 deletions(-) diff --git a/lib/Cargo.lock b/lib/Cargo.lock index 6f0ae92..f4d311b 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -1051,7 +1051,7 @@ version = "0.1.0" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", - "zecwalletlitelib 0.1.0 (git+https://github.com/adityapk00/zecwallet-light-cli?rev=50d331b0cfe1b3c4b81e33fd6febb4b24264627a)", + "zecwalletlitelib 0.1.0 (git+https://github.com/adityapk00/zecwallet-light-cli?rev=3e1c61a4b0589be1ff7590cf4ddf025a9160c631)", ] [[package]] @@ -2266,7 +2266,7 @@ dependencies = [ [[package]] name = "zecwalletlitelib" version = "0.1.0" -source = "git+https://github.com/adityapk00/zecwallet-light-cli?rev=50d331b0cfe1b3c4b81e33fd6febb4b24264627a#50d331b0cfe1b3c4b81e33fd6febb4b24264627a" +source = "git+https://github.com/adityapk00/zecwallet-light-cli?rev=3e1c61a4b0589be1ff7590cf4ddf025a9160c631#3e1c61a4b0589be1ff7590cf4ddf025a9160c631" dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bellman 0.1.0 (git+https://github.com/adityapk00/librustzcash.git?rev=188537ea025fcb7fbdfc11266f307a084a5451e4)", @@ -2562,4 +2562,4 @@ dependencies = [ "checksum zcash_client_backend 0.0.0 (git+https://github.com/adityapk00/librustzcash.git?rev=188537ea025fcb7fbdfc11266f307a084a5451e4)" = "" "checksum zcash_primitives 0.0.0 (git+https://github.com/adityapk00/librustzcash.git?rev=188537ea025fcb7fbdfc11266f307a084a5451e4)" = "" "checksum zcash_proofs 0.0.0 (git+https://github.com/adityapk00/librustzcash.git?rev=188537ea025fcb7fbdfc11266f307a084a5451e4)" = "" -"checksum zecwalletlitelib 0.1.0 (git+https://github.com/adityapk00/zecwallet-light-cli?rev=50d331b0cfe1b3c4b81e33fd6febb4b24264627a)" = "" +"checksum zecwalletlitelib 0.1.0 (git+https://github.com/adityapk00/zecwallet-light-cli?rev=3e1c61a4b0589be1ff7590cf4ddf025a9160c631)" = "" diff --git a/src/controller.h b/src/controller.h index c2eb326..1394fad 100644 --- a/src/controller.h +++ b/src/controller.h @@ -81,6 +81,7 @@ public: cb({ {"error", "Failed to unlock wallet"} }); }); } + void fetchAllPrivKeys(const std::function cb) { unlockIfEncrypted([=] () { zrpc->fetchAllPrivKeys(cb); @@ -90,6 +91,15 @@ public: }); } + void fetchSeed(const std::function cb) { + unlockIfEncrypted([=] () { + zrpc->fetchSeed(cb); + }, + [=]() { + cb({ {"error", "Failed to unlock wallet"} }); + }); + } + // 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); } diff --git a/src/liteinterface.cpp b/src/liteinterface.cpp index 88628a9..30f1a0b 100644 --- a/src/liteinterface.cpp +++ b/src/liteinterface.cpp @@ -56,6 +56,13 @@ void LiteInterface::fetchPrivKey(QString addr, const std::function& conn->doRPCWithDefaultErrorHandling("export", addr, cb); } +void LiteInterface::fetchSeed(const std::function& cb) { + if (conn == nullptr) + return; + + conn->doRPCWithDefaultErrorHandling("seed", "", cb); +} + void LiteInterface::fetchBalance(const std::function& cb) { if (conn == nullptr) return; diff --git a/src/liteinterface.h b/src/liteinterface.h index da04641..203967f 100644 --- a/src/liteinterface.h +++ b/src/liteinterface.h @@ -52,6 +52,7 @@ public: void fetchPrivKey(QString addr, const std::function& cb); void fetchAllPrivKeys(const std::function); + void fetchSeed(const std::function&); void saveWallet(const std::function& cb); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 02eb930..8384e49 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -91,7 +91,7 @@ MainWindow::MainWindow(QWidget *parent) : QObject::connect(ui->actionExport_All_Private_Keys, &QAction::triggered, this, &MainWindow::exportAllKeys); // Backup wallet.dat - QObject::connect(ui->actionBackup_wallet_dat, &QAction::triggered, this, &MainWindow::backupWalletDat); + QObject::connect(ui->actionExport_Seed, &QAction::triggered, this, &MainWindow::exportSeed); // Export transactions QObject::connect(ui->actionExport_transactions, &QAction::triggered, this, &MainWindow::exportTransactions); @@ -648,36 +648,60 @@ void MainWindow::exportTransactions() { } /** - * Backup the wallet.dat file. This is kind of a hack, since it has to read from the filesystem rather than an RPC call - * This might fail for various reasons - Remote zcashd, non-standard locations, custom params passed to zcashd, many others + * Export the seed phrase. */ -void MainWindow::backupWalletDat() { +void MainWindow::exportSeed() { if (!rpc->getConnection()) return; - // QDir zcashdir(rpc->getConnection()->config->zcashDir); - // QString backupDefaultName = "zcash-wallet-backup-" + QDateTime::currentDateTime().toString("yyyyMMdd") + ".dat"; - - // if (Settings::getInstance()->isTestnet()) { - // zcashdir.cd("testnet3"); - // backupDefaultName = "testnet-" + backupDefaultName; - // } + QDialog d(this); + Ui_PrivKey pui; + pui.setupUi(&d); - // QFile wallet(zcashdir.filePath("wallet.dat")); - // if (!wallet.exists()) { - // QMessageBox::critical(this, tr("No wallet.dat"), tr("Couldn't find the wallet.dat on this computer") + "\n" + - // tr("You need to back it up from the machine zcashd is running on"), QMessageBox::Ok); - // return; - // } + // Make the window big by default + auto ps = this->geometry(); + QMargins margin = QMargins() + 50; + d.setGeometry(ps.marginsRemoved(margin)); + + Settings::saveRestore(&d); + + pui.privKeyTxt->setPlainText(tr("This might take several minutes. Loading...")); + pui.privKeyTxt->setReadOnly(true); + pui.privKeyTxt->setLineWrapMode(QPlainTextEdit::LineWrapMode::NoWrap); + + pui.helpLbl->setText(tr("This is your wallet seed. Please back it up carefully and safely.")); + + // Disable the save button until it finishes loading + pui.buttonBox->button(QDialogButtonBox::Save)->setEnabled(false); + pui.buttonBox->button(QDialogButtonBox::Ok)->setVisible(false); + + // Wire up save button + QObject::connect(pui.buttonBox->button(QDialogButtonBox::Save), &QPushButton::clicked, [=] () { + QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), + "zcash-seed.txt"); + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly)) { + QMessageBox::information(this, tr("Unable to open file"), file.errorString()); + return; + } + QTextStream out(&file); + out << pui.privKeyTxt->toPlainText(); + }); + + rpc->fetchSeed([=](json reply) { + if (isJsonError(reply)) { + pui.privKeyTxt->setPlainText(tr("Error loading wallet seed: ") + QString::fromStdString(reply["error"])); + pui.buttonBox->button(QDialogButtonBox::Save)->setEnabled(false); + + return; + } + + pui.privKeyTxt->setPlainText(QString::fromStdString(reply.dump())); + pui.buttonBox->button(QDialogButtonBox::Save)->setEnabled(true); + }); + - // QUrl backupName = QFileDialog::getSaveFileUrl(this, tr("Backup wallet.dat"), backupDefaultName, "Data file (*.dat)"); - // if (backupName.isEmpty()) - // return; - - // if (!wallet.copy(backupName.toLocalFile())) { - // QMessageBox::critical(this, tr("Couldn't backup"), tr("Couldn't backup the wallet.dat file.") + - // tr("You need to back it up manually."), QMessageBox::Ok); - // } + d.exec(); } void MainWindow::exportAllKeys() { @@ -685,6 +709,9 @@ void MainWindow::exportAllKeys() { } void MainWindow::exportKeys(QString addr) { + if (!rpc->getConnection()) + return; + bool allKeys = addr.isEmpty() ? true : false; QDialog d(this); diff --git a/src/mainwindow.h b/src/mainwindow.h index f1f0426..6d3393d 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -120,7 +120,7 @@ private: void importPrivKey(); void exportAllKeys(); void exportKeys(QString addr = ""); - void backupWalletDat(); + void exportSeed(); void exportTransactions(); void doImport(QList* keys); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 690f3d9..b66cf15 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1099,7 +1099,7 @@ - + @@ -1178,9 +1178,9 @@ Ctrl+B - + - &Backup wallet.dat + &Export seed phrase diff --git a/src/settings.h b/src/settings.h index 94a1e8c..d60619d 100644 --- a/src/settings.h +++ b/src/settings.h @@ -127,4 +127,10 @@ inline bool isJsonSuccess(const json& res) { QString::fromStdString(res["result"].get()) == "success"; } +inline bool isJsonError(const json& res) { + return res.find("result") != res.end() && + QString::fromStdString(res["result"].get()) == "error"; +} + + #endif // SETTINGS_H