Browse Source

Add export all keys menu

recurring
Aditya Kulkarni 6 years ago
parent
commit
8e363649f6
  1. 57
      src/mainwindow.cpp
  2. 1
      src/mainwindow.h
  3. 6
      src/mainwindow.ui
  4. 1
      src/precompiled.h
  5. 2
      src/privkey.ui
  6. 82
      src/rpc.cpp
  7. 2
      src/rpc.h

57
src/mainwindow.cpp

@ -40,8 +40,12 @@ MainWindow::MainWindow(QWidget *parent) :
QDesktopServices::openUrl(QUrl("https://github.com/adityapk00/zec-qt-wallet/releases"));
});
// Import Private Key
QObject::connect(ui->actionImport_Private_Key, &QAction::triggered, this, &MainWindow::importPrivKey);
// Export All Private Keys
QObject::connect(ui->actionExport_All_Private_Keys, &QAction::triggered, this, &MainWindow::exportAllKeys);
// Set up about action
QObject::connect(ui->actionAbout, &QAction::triggered, [=] () {
QDialog aboutDialog(this);
@ -436,6 +440,7 @@ void MainWindow::importPrivKey() {
Ui_PrivKey pui;
pui.setupUi(&d);
pui.buttonBox->button(QDialogButtonBox::Save)->setVisible(false);
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");
@ -462,6 +467,54 @@ void MainWindow::importPrivKey() {
}
}
void MainWindow::exportAllKeys() {
QDialog d(this);
Ui_PrivKey pui;
pui.setupUi(&d);
auto ps = this->geometry();
QMargins margin = QMargins() + 50;
d.setGeometry(ps.marginsRemoved(margin));
pui.privKeyTxt->setPlainText("Loading...");
pui.privKeyTxt->setReadOnly(true);
pui.privKeyTxt->setLineWrapMode(QPlainTextEdit::LineWrapMode::NoWrap);
pui.helpLbl->setText("These are all the private keys for all the addresses in your wallet");
// 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-all-privatekeys.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();
});
// Call the API
rpc->getAllPrivKeys([=] (auto privKeys) {
QString allKeysTxt;
for (auto keypair : privKeys) {
allKeysTxt = allKeysTxt % keypair.second % " # addr=" % keypair.first % "\n";
}
pui.privKeyTxt->setPlainText(allKeysTxt);
pui.buttonBox->button(QDialogButtonBox::Save)->setEnabled(true);
});
d.exec();
}
void MainWindow::setupBalancesTab() {
ui->unconfirmedWarning->setVisible(false);
@ -486,13 +539,14 @@ void MainWindow::setupBalancesTab() {
auto fnCB = [=] (const json& reply) {
auto privKey = QString::fromStdString(reply.get<json::string_t>());
QDialog d(this);
Ui_PrivKey pui;
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::Save)->setVisible(false);
pui.buttonBox->button(QDialogButtonBox::Ok)->setVisible(false);
d.exec();
@ -542,6 +596,7 @@ void MainWindow::setupBalancesTab() {
void MainWindow::setupTransactionsTab() {
// Set up context menu on transactions tab
ui->transactionsTable->setContextMenuPolicy(Qt::CustomContextMenu);
QObject::connect(ui->transactionsTable, &QTableView::customContextMenuRequested, [=] (QPoint pos) {
QModelIndex index = ui->transactionsTable->indexAt(pos);
if (index.row() < 0) return;

1
src/mainwindow.h

@ -82,6 +82,7 @@ private:
void donate();
void importPrivKey();
void exportAllKeys();
void doImport(QList<QString>* keys);
void restoreSavedStates();

6
src/mainwindow.ui

@ -726,6 +726,7 @@
<string>&amp;File</string>
</property>
<addaction name="actionImport_Private_Key"/>
<addaction name="actionExport_All_Private_Keys"/>
<addaction name="actionTurnstile_Migration"/>
<addaction name="actionSettings"/>
<addaction name="separator"/>
@ -781,6 +782,11 @@
<string>&amp;Import Private Key</string>
</property>
</action>
<action name="actionExport_All_Private_Keys">
<property name="text">
<string>Export All Private Keys</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>

1
src/precompiled.h

@ -32,6 +32,7 @@
#include <QLabel>
#include <QDialog>
#include <QInputDialog>
#include <QFileDialog>
#include <QDebug>
#include <QUrl>
#include <QDesktopServices>

2
src/privkey.ui

@ -27,7 +27,7 @@
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close|QDialogButtonBox::Ok</set>
<set>QDialogButtonBox::Close|QDialogButtonBox::Ok|QDialogButtonBox::Save</set>
</property>
</widget>
</item>

82
src/rpc.cpp

@ -202,6 +202,88 @@ void RPC::sendZTransaction(json params, const std::function<void(json)>& cb) {
conn->doRPCWithDefaultErrorHandling(payload, cb);
}
/**
* Method to get all the private keys for both z and t addresses. It will make 2 batch calls,
* combine the result, and call the callback with a single list containing both the t-addr and z-addr
* private keys
*/
void RPC::getAllPrivKeys(const std::function<void(QList<QPair<QString, QString>>)> cb) {
// A special function that will call the callback when two lists have been added
auto holder = new QPair<int, QList<QPair<QString, QString>>>();
holder->first = 0; // This is the number of times the callback has been called, initalized to 0
auto fnCombineTwoLists = [=] (QList<QPair<QString, QString>> list) {
// Increment the callback counter
holder->first++;
// Add all
std::copy(list.begin(), list.end(), std::back_inserter(holder->second));
// And if the caller has been called twice, do the parent callback with the
// collected list
if (holder->first == 2) {
// Sort so z addresses are on top
std::sort(holder->second.begin(), holder->second.end(),
[=] (auto a, auto b) { return a.first > b.first; });
cb(holder->second);
delete holder;
}
};
// A utility fn to do the batch calling
auto fnDoBatchGetPrivKeys = [=](json getAddressPayload, std::string privKeyDumpMethodName) {
conn->doRPCWithDefaultErrorHandling(getAddressPayload, [=] (json resp) {
QList<QString> addrs;
for (auto addr : resp.get<json::array_t>()) {
addrs.push_back(QString::fromStdString(addr.get<json::string_t>()));
}
// Then, do a batch request to get all the private keys
conn->doBatchRPC<QString>(
addrs,
[=] (auto addr) {
json payload = {
{"jsonrpc", "1.0"},
{"id", "someid"},
{"method", privKeyDumpMethodName},
{"params", { addr.toStdString() }},
};
return payload;
},
[=] (QMap<QString, json>* privkeys) {
QList<QPair<QString, QString>> allTKeys;
for (QString addr: privkeys->keys()) {
allTKeys.push_back(
QPair<QString, QString>(
addr,
QString::fromStdString(privkeys->value(addr).get<json::string_t>())));
}
fnCombineTwoLists(allTKeys);
}
);
});
};
// First get all the T and Z addresses.
json payloadT = {
{"jsonrpc", "1.0"},
{"id", "someid"},
{"method", "getaddressesbyaccount"},
{"params", {""} }
};
json payloadZ = {
{"jsonrpc", "1.0"},
{"id", "someid"},
{"method", "z_listaddresses"}
};
fnDoBatchGetPrivKeys(payloadT, "dumpprivkey");
fnDoBatchGetPrivKeys(payloadZ, "z_exportkey");
}
// Build the RPC JSON Parameters for this tx (with the dev fee included if applicable)

2
src/rpc.h

@ -56,6 +56,8 @@ public:
void importZPrivKey(QString addr, bool rescan, const std::function<void(json)>& cb);
void importTPrivKey(QString addr, bool rescan, const std::function<void(json)>& cb);
void getAllPrivKeys(const std::function<void(QList<QPair<QString, QString>>)>);
Turnstile* getTurnstile() { return turnstile; }
Connection* getConnection() { return conn; }

Loading…
Cancel
Save