Wire up private key export
This commit is contained in:
parent
70774a477d
commit
fba4c61976
|
@ -64,9 +64,8 @@ public:
|
|||
void createNewZaddr(bool sapling, const std::function<void(json)>& cb) { zrpc->createNewZaddr(sapling, cb); }
|
||||
void createNewTaddr(const std::function<void(json)>& cb) { zrpc->createNewTaddr(cb); }
|
||||
|
||||
void fetchZPrivKey(QString addr, const std::function<void(json)>& cb) { zrpc->fetchZPrivKey(addr, cb); }
|
||||
void fetchTPrivKey(QString addr, const std::function<void(json)>& cb) { zrpc->fetchTPrivKey(addr, cb); }
|
||||
void fetchAllPrivKeys(const std::function<void(QList<QPair<QString, QString>>)> cb) { zrpc->fetchAllPrivKeys(cb); }
|
||||
void fetchPrivKey(QString addr, const std::function<void(json)>& cb) { zrpc->fetchPrivKey(addr, cb); }
|
||||
void fetchAllPrivKeys(const std::function<void(json)> cb) { zrpc->fetchAllPrivKeys(cb); }
|
||||
|
||||
// void importZPrivKey(QString addr, bool rescan, const std::function<void(json)>& cb) { zrpc->importZPrivKey(addr, rescan, cb); }
|
||||
// void importTPrivKey(QString addr, bool rescan, const std::function<void(json)>& cb) { zrpc->importTPrivKey(addr, rescan, cb); }
|
||||
|
|
|
@ -33,15 +33,6 @@ void LiteInterface::fetchUnspent(const std::function<void(json)>& cb) {
|
|||
return;
|
||||
|
||||
conn->doRPCWithDefaultErrorHandling("notes", "", cb);
|
||||
|
||||
// json payload = {
|
||||
// {"jsonrpc", "1.0"},
|
||||
// {"id", "someid"},
|
||||
// {"method", "listunspent"},
|
||||
// {"params", {0}} // Get UTXOs with 0 confirmations as well.
|
||||
// };
|
||||
|
||||
// conn->doRPCWithDefaultErrorHandling(payload, cb);
|
||||
}
|
||||
|
||||
void LiteInterface::createNewZaddr(bool, const std::function<void(json)>& cb) {
|
||||
|
@ -58,32 +49,11 @@ void LiteInterface::createNewTaddr(const std::function<void(json)>& cb) {
|
|||
conn->doRPCWithDefaultErrorHandling("new", "t", cb);
|
||||
}
|
||||
|
||||
void LiteInterface::fetchZPrivKey(QString addr, const std::function<void(json)>& cb) {
|
||||
void LiteInterface::fetchPrivKey(QString addr, const std::function<void(json)>& cb) {
|
||||
if (conn == nullptr)
|
||||
return;
|
||||
|
||||
// json payload = {
|
||||
// {"jsonrpc", "1.0"},
|
||||
// {"id", "someid"},
|
||||
// {"method", "z_exportkey"},
|
||||
// {"params", { addr.toStdString() }},
|
||||
// };
|
||||
|
||||
// conn->doRPCWithDefaultErrorHandling(payload, cb);
|
||||
}
|
||||
|
||||
void LiteInterface::fetchTPrivKey(QString addr, const std::function<void(json)>& cb) {
|
||||
if (conn == nullptr)
|
||||
return;
|
||||
|
||||
// json payload = {
|
||||
// {"jsonrpc", "1.0"},
|
||||
// {"id", "someid"},
|
||||
// {"method", "dumpprivkey"},
|
||||
// {"params", { addr.toStdString() }},
|
||||
// };
|
||||
|
||||
// conn->doRPCWithDefaultErrorHandling(payload, cb);
|
||||
conn->doRPCWithDefaultErrorHandling("export", addr, cb);
|
||||
}
|
||||
|
||||
// void LiteInterface::importZPrivKey(QString addr, bool rescan, const std::function<void(json)>& cb) {
|
||||
|
@ -145,309 +115,17 @@ void LiteInterface::fetchInfo(const std::function<void(json)>& cb,
|
|||
conn->doRPC("info", "", cb, err);
|
||||
}
|
||||
|
||||
void LiteInterface::fetchBlockchainInfo(const std::function<void(json)>& cb) {
|
||||
if (conn == nullptr)
|
||||
return;
|
||||
|
||||
// json payload = {
|
||||
// {"jsonrpc", "1.0"},
|
||||
// {"id", "someid"},
|
||||
// {"method", "getblockchaininfo"}
|
||||
// };
|
||||
|
||||
// conn->doRPCIgnoreError(payload, cb);
|
||||
}
|
||||
|
||||
void LiteInterface::fetchNetSolOps(const std::function<void(qint64)> cb) {
|
||||
if (conn == nullptr)
|
||||
return;
|
||||
|
||||
// json payload = {
|
||||
// {"jsonrpc", "1.0"},
|
||||
// {"id", "someid"},
|
||||
// {"method", "getnetworksolps"}
|
||||
// };
|
||||
|
||||
// conn->doRPCIgnoreError(payload, [=](const json& reply) {
|
||||
// qint64 solrate = reply.get<json::number_unsigned_t>();
|
||||
// cb(solrate);
|
||||
// });
|
||||
}
|
||||
|
||||
void LiteInterface::fetchMigrationStatus(const std::function<void(json)>& cb) {
|
||||
if (conn == nullptr)
|
||||
return;
|
||||
|
||||
// json payload = {
|
||||
// {"jsonrpc", "1.0"},
|
||||
// {"id", "someid"},
|
||||
// {"method", "z_getmigrationstatus"},
|
||||
// };
|
||||
|
||||
// conn->doRPCWithDefaultErrorHandling(payload, cb);
|
||||
}
|
||||
|
||||
|
||||
void LiteInterface::setMigrationStatus(bool enabled) {
|
||||
if (conn == nullptr)
|
||||
return;
|
||||
|
||||
// json payload = {
|
||||
// {"jsonrpc", "1.0"},
|
||||
// {"id", "someid"},
|
||||
// {"method", "z_setmigration"},
|
||||
// {"params", {enabled}}
|
||||
// };
|
||||
|
||||
// conn->doRPCWithDefaultErrorHandling(payload, [=](json) {
|
||||
// // Ignore return value.
|
||||
// });
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 LiteInterface::fetchAllPrivKeys(const std::function<void(QList<QPair<QString, QString>>)> cb) {
|
||||
void LiteInterface::fetchAllPrivKeys(const std::function<void(json)> cb) {
|
||||
if (conn == nullptr) {
|
||||
// No connection, just return
|
||||
return;
|
||||
}
|
||||
|
||||
// // 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, initialized 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);
|
||||
// delete privkeys;
|
||||
// }
|
||||
// );
|
||||
// });
|
||||
// };
|
||||
|
||||
// // 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");
|
||||
conn->doRPCWithDefaultErrorHandling("export", "", cb);
|
||||
}
|
||||
|
||||
void LiteInterface::fetchOpStatus(const std::function<void(json)>& cb) {
|
||||
if (conn == nullptr)
|
||||
return;
|
||||
|
||||
// Make an RPC to load pending operation statues
|
||||
// json payload = {
|
||||
// {"jsonrpc", "1.0"},
|
||||
// {"id", "someid"},
|
||||
// {"method", "z_getoperationstatus"},
|
||||
// };
|
||||
|
||||
// conn->doRPCIgnoreError(payload, cb);
|
||||
}
|
||||
|
||||
void LiteInterface::fetchReceivedTTrans(QList<QString> txids, QList<TransactionItem> sentZTxs,
|
||||
const std::function<void(QList<TransactionItem>)> txdataFn) {
|
||||
if (conn == nullptr)
|
||||
return;
|
||||
|
||||
// Look up all the txids to get the confirmation count for them.
|
||||
// conn->doBatchRPC<QString>(txids,
|
||||
// [=] (QString txid) {
|
||||
// json payload = {
|
||||
// {"jsonrpc", "1.0"},
|
||||
// {"id", "senttxid"},
|
||||
// {"method", "gettransaction"},
|
||||
// {"params", {txid.toStdString()}}
|
||||
// };
|
||||
|
||||
// return payload;
|
||||
// },
|
||||
// [=] (QMap<QString, json>* txidList) {
|
||||
// auto newSentZTxs = sentZTxs;
|
||||
// // Update the original sent list with the confirmation count
|
||||
// // TODO: This whole thing is kinda inefficient. We should probably just update the file
|
||||
// // with the confirmed block number, so we don't have to keep calling gettransaction for the
|
||||
// // sent items.
|
||||
// for (TransactionItem& sentTx: newSentZTxs) {
|
||||
// auto j = txidList->value(sentTx.txid);
|
||||
// if (j.is_null())
|
||||
// continue;
|
||||
// auto error = j["confirmations"].is_null();
|
||||
// if (!error)
|
||||
// sentTx.confirmations = j["confirmations"].get<json::number_integer_t>();
|
||||
// }
|
||||
|
||||
// txdataFn(newSentZTxs);
|
||||
// delete txidList;
|
||||
// }
|
||||
// );
|
||||
}
|
||||
|
||||
|
||||
// Refresh received z txs by calling z_listreceivedbyaddress/gettransaction
|
||||
void LiteInterface::fetchReceivedZTrans(QList<QString> zaddrs, const std::function<void(QString)> usedAddrFn,
|
||||
const std::function<void(QList<TransactionItem>)> txdataFn) {
|
||||
if (conn == nullptr)
|
||||
return;
|
||||
|
||||
|
||||
// This method is complicated because z_listreceivedbyaddress only returns the txid, and
|
||||
// we have to make a follow up call to gettransaction to get details of that transaction.
|
||||
// Additionally, it has to be done in batches, because there are multiple z-Addresses,
|
||||
// and each z-Addr can have multiple received txs.
|
||||
|
||||
// 1. For each z-Addr, get list of received txs
|
||||
// conn->doBatchRPC<QString>(zaddrs,
|
||||
// [=] (QString zaddr) {
|
||||
// json payload = {
|
||||
// {"jsonrpc", "1.0"},
|
||||
// {"id", "z_lrba"},
|
||||
// {"method", "z_listreceivedbyaddress"},
|
||||
// {"params", {zaddr.toStdString(), 0}} // Accept 0 conf as well.
|
||||
// };
|
||||
|
||||
// return payload;
|
||||
// },
|
||||
// [=] (QMap<QString, json>* zaddrTxids) {
|
||||
// // Process all txids, removing duplicates. This can happen if the same address
|
||||
// // appears multiple times in a single tx's outputs.
|
||||
// QSet<QString> txids;
|
||||
// QMap<QString, QString> memos;
|
||||
// for (auto it = zaddrTxids->constBegin(); it != zaddrTxids->constEnd(); it++) {
|
||||
// auto zaddr = it.key();
|
||||
// for (auto& i : it.value().get<json::array_t>()) {
|
||||
// // Mark the address as used
|
||||
// usedAddrFn(zaddr);
|
||||
|
||||
// // Filter out change txs
|
||||
// if (! i["change"].get<json::boolean_t>()) {
|
||||
// auto txid = QString::fromStdString(i["txid"].get<json::string_t>());
|
||||
// txids.insert(txid);
|
||||
|
||||
// // Check for Memos
|
||||
// QString memoBytes = QString::fromStdString(i["memo"].get<json::string_t>());
|
||||
// if (!memoBytes.startsWith("f600")) {
|
||||
// QString memo(QByteArray::fromHex(
|
||||
// QByteArray::fromStdString(i["memo"].get<json::string_t>())));
|
||||
// if (!memo.trimmed().isEmpty())
|
||||
// memos[zaddr + txid] = memo;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// // 2. For all txids, go and get the details of that txid.
|
||||
// conn->doBatchRPC<QString>(txids.toList(),
|
||||
// [=] (QString txid) {
|
||||
// json payload = {
|
||||
// {"jsonrpc", "1.0"},
|
||||
// {"id", "gettx"},
|
||||
// {"method", "gettransaction"},
|
||||
// {"params", {txid.toStdString()}}
|
||||
// };
|
||||
|
||||
// return payload;
|
||||
// },
|
||||
// [=] (QMap<QString, json>* txidDetails) {
|
||||
// QList<TransactionItem> txdata;
|
||||
|
||||
// // Combine them both together. For every zAddr's txid, get the amount, fee, confirmations and time
|
||||
// for (auto it = zaddrTxids->constBegin(); it != zaddrTxids->constEnd(); it++) {
|
||||
// for (auto& i : it.value().get<json::array_t>()) {
|
||||
// // Filter out change txs
|
||||
// if (i["change"].get<json::boolean_t>())
|
||||
// continue;
|
||||
|
||||
// auto zaddr = it.key();
|
||||
// auto txid = QString::fromStdString(i["txid"].get<json::string_t>());
|
||||
|
||||
// // Lookup txid in the map
|
||||
// auto txidInfo = txidDetails->value(txid);
|
||||
|
||||
// qint64 timestamp;
|
||||
// if (txidInfo.find("time") != txidInfo.end()) {
|
||||
// timestamp = txidInfo["time"].get<json::number_unsigned_t>();
|
||||
// } else {
|
||||
// timestamp = txidInfo["blocktime"].get<json::number_unsigned_t>();
|
||||
// }
|
||||
|
||||
// auto amount = i["amount"].get<json::number_float_t>();
|
||||
// auto confirmations = static_cast<long>(txidInfo["confirmations"].get<json::number_integer_t>());
|
||||
|
||||
// TransactionItem tx{ QString("receive"), timestamp, zaddr, txid, amount,
|
||||
// confirmations, "", memos.value(zaddr + txid, "") };
|
||||
// txdata.push_front(tx);
|
||||
// }
|
||||
// }
|
||||
|
||||
// txdataFn(txdata);
|
||||
|
||||
// // Cleanup both responses;
|
||||
// delete zaddrTxids;
|
||||
// delete txidDetails;
|
||||
// }
|
||||
// );
|
||||
// }
|
||||
// );
|
||||
}
|
||||
|
|
|
@ -39,34 +39,22 @@ public:
|
|||
|
||||
void fetchUnspent (const std::function<void(json)>& cb);
|
||||
void fetchTransactions (const std::function<void(json)>& cb);
|
||||
void fetchAddresses (const std::function<void(json)>& cb);
|
||||
|
||||
void fetchReceivedZTrans(QList<QString> zaddrs, const std::function<void(QString)> usedAddrFn,
|
||||
const std::function<void(QList<TransactionItem>)> txdataFn);
|
||||
void fetchReceivedTTrans(QList<QString> txids, QList<TransactionItem> sentZtxs,
|
||||
const std::function<void(QList<TransactionItem>)> txdataFn);
|
||||
void fetchAddresses (const std::function<void(json)>& cb);
|
||||
|
||||
void fetchInfo(const std::function<void(json)>& cb,
|
||||
const std::function<void(QString)>& err);
|
||||
void fetchBlockchainInfo(const std::function<void(json)>& cb);
|
||||
void fetchNetSolOps(const std::function<void(qint64)> cb);
|
||||
void fetchOpStatus(const std::function<void(json)>& cb);
|
||||
|
||||
void fetchMigrationStatus(const std::function<void(json)>& cb);
|
||||
void setMigrationStatus(bool enabled);
|
||||
|
||||
|
||||
void fetchBalance(const std::function<void(json)>& cb);
|
||||
|
||||
void createNewZaddr(bool sapling, const std::function<void(json)>& cb);
|
||||
void createNewTaddr(const std::function<void(json)>& cb);
|
||||
|
||||
void fetchZPrivKey(QString addr, const std::function<void(json)>& cb);
|
||||
void fetchTPrivKey(QString addr, const std::function<void(json)>& cb);
|
||||
void fetchPrivKey(QString addr, const std::function<void(json)>& cb);
|
||||
void fetchAllPrivKeys(const std::function<void(json)>);
|
||||
|
||||
//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 fetchAllPrivKeys(const std::function<void(QList<QPair<QString, QString>>)>);
|
||||
|
||||
void sendTransaction(QString params, const std::function<void(json)>& cb, const std::function<void(QString)>& err);
|
||||
|
||||
private:
|
||||
|
|
|
@ -214,7 +214,7 @@ public:
|
|||
}
|
||||
|
||||
w = new MainWindow();
|
||||
w->setWindowTitle("ZecWallet v" + QString(APP_VERSION));
|
||||
w->setWindowTitle("Zecwallet v" + QString(APP_VERSION));
|
||||
|
||||
// If there was a payment URI on the command line, pay it
|
||||
if (parser.positionalArguments().length() > 0) {
|
||||
|
|
|
@ -695,13 +695,20 @@ void MainWindow::exportKeys(QString addr) {
|
|||
// Call the API
|
||||
auto isDialogAlive = std::make_shared<bool>(true);
|
||||
|
||||
auto fnUpdateUIWithKeys = [=](QList<QPair<QString, QString>> privKeys) {
|
||||
auto fnUpdateUIWithKeys = [=](json reply) {
|
||||
// Check to see if we are still showing.
|
||||
if (! *(isDialogAlive.get()) ) return;
|
||||
|
||||
if (reply.is_discarded() || !reply.is_array()) {
|
||||
pui.privKeyTxt->setPlainText(tr("Error loading private keys"));
|
||||
pui.buttonBox->button(QDialogButtonBox::Save)->setEnabled(false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
QString allKeysTxt;
|
||||
for (auto keypair : privKeys) {
|
||||
allKeysTxt = allKeysTxt % keypair.second % " # addr=" % keypair.first % "\n";
|
||||
for (auto i : reply.get<json::array_t>()) {
|
||||
allKeysTxt = allKeysTxt % QString::fromStdString(i["private_key"]) % " # addr=" % QString::fromStdString(i["address"]) % "\n";
|
||||
}
|
||||
|
||||
pui.privKeyTxt->setPlainText(allKeysTxt);
|
||||
|
@ -711,19 +718,8 @@ void MainWindow::exportKeys(QString addr) {
|
|||
if (allKeys) {
|
||||
rpc->fetchAllPrivKeys(fnUpdateUIWithKeys);
|
||||
}
|
||||
else {
|
||||
auto fnAddKey = [=](json key) {
|
||||
QList<QPair<QString, QString>> singleAddrKey;
|
||||
singleAddrKey.push_back(QPair<QString, QString>(addr, QString::fromStdString(key.get<json::string_t>())));
|
||||
fnUpdateUIWithKeys(singleAddrKey);
|
||||
};
|
||||
|
||||
if (Settings::getInstance()->isZAddress(addr)) {
|
||||
rpc->fetchZPrivKey(addr, fnAddKey);
|
||||
}
|
||||
else {
|
||||
rpc->fetchTPrivKey(addr, fnAddKey);
|
||||
}
|
||||
else {
|
||||
rpc->fetchPrivKey(addr, fnUpdateUIWithKeys);
|
||||
}
|
||||
|
||||
d.exec();
|
||||
|
|
Loading…
Reference in New Issue