Add export all keys menu
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -82,6 +82,7 @@ private:
|
||||
|
||||
void donate();
|
||||
void importPrivKey();
|
||||
void exportAllKeys();
|
||||
void doImport(QList<QString>* keys);
|
||||
|
||||
void restoreSavedStates();
|
||||
|
||||
@@ -726,6 +726,7 @@
|
||||
<string>&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>&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>
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <QLabel>
|
||||
#include <QDialog>
|
||||
#include <QInputDialog>
|
||||
#include <QFileDialog>
|
||||
#include <QDebug>
|
||||
#include <QUrl>
|
||||
#include <QDesktopServices>
|
||||
|
||||
@@ -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
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)
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user