Hush lite wallet https://faq.hush.is/sdl
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

502 lines
17 KiB

5 years ago
#include "liteinterface.h"
LiteInterface::LiteInterface() {
}
LiteInterface::~LiteInterface() {
delete conn;
}
void LiteInterface::setConnection(Connection* c) {
if (conn) {
delete conn;
}
conn = c;
}
bool LiteInterface::haveConnection() {
return conn != nullptr;
}
5 years ago
void LiteInterface::fetchAddresses(const std::function<void(json)>& cb) {
5 years ago
if (conn == nullptr)
return;
5 years ago
conn->doRPCWithDefaultErrorHandling("addresses", "", cb);
5 years ago
}
void LiteInterface::fetchUnspent(const std::function<void(json)>& cb) {
5 years ago
if (conn == nullptr)
return;
conn->doRPCWithDefaultErrorHandling("notes", "", cb);
5 years ago
// json payload = {
// {"jsonrpc", "1.0"},
// {"id", "someid"},
// {"method", "listunspent"},
5 years ago
// {"params", {0}} // Get UTXOs with 0 confirmations as well.
// };
// conn->doRPCWithDefaultErrorHandling(payload, cb);
}
void LiteInterface::createNewZaddr(bool sapling, const std::function<void(json)>& cb) {
if (conn == nullptr)
return;
// json payload = {
// {"jsonrpc", "1.0"},
// {"id", "someid"},
// {"method", "z_getnewaddress"},
// {"params", { sapling ? "sapling" : "sprout" }},
// };
// conn->doRPCWithDefaultErrorHandling(payload, cb);
}
void LiteInterface::createNewTaddr(const std::function<void(json)>& cb) {
if (conn == nullptr)
return;
// json payload = {
// {"jsonrpc", "1.0"},
// {"id", "someid"},
// {"method", "getnewaddress"},
// };
// conn->doRPCWithDefaultErrorHandling(payload, cb);
}
void LiteInterface::fetchZPrivKey(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);
}
void LiteInterface::importZPrivKey(QString addr, bool rescan, const std::function<void(json)>& cb) {
if (conn == nullptr)
return;
// json payload = {
// {"jsonrpc", "1.0"},
// {"id", "someid"},
// {"method", "z_importkey"},
// {"params", { addr.toStdString(), (rescan? "yes" : "no") }},
// };
// conn->doRPCWithDefaultErrorHandling(payload, cb);
}
void LiteInterface::importTPrivKey(QString addr, bool rescan, const std::function<void(json)>& cb) {
if (conn == nullptr)
return;
// json payload = {
// {"jsonrpc", "1.0"},
// {"id", "someid"},
// {"method", "importprivkey"},
// {"params", { addr.toStdString(), (rescan? "yes" : "no") }},
// };
// conn->doRPCWithDefaultErrorHandling(payload, cb);
}
void LiteInterface::validateAddress(QString address, const std::function<void(json)>& cb) {
if (conn == nullptr)
return;
// QString method = Settings::isZAddress(address) ? "z_validateaddress" : "validateaddress";
// json payload = {
// {"jsonrpc", "1.0"},
// {"id", "someid"},
// {"method", method.toStdString() },
// {"params", { address.toStdString() } },
// };
// conn->doRPCWithDefaultErrorHandling(payload, cb);
}
void LiteInterface::fetchBalance(const std::function<void(json)>& cb) {
if (conn == nullptr)
return;
5 years ago
conn->doRPCWithDefaultErrorHandling("balance", "", cb);
5 years ago
}
void LiteInterface::fetchTransactions(const std::function<void(json)>& cb) {
if (conn == nullptr)
return;
// json payload = {
// {"jsonrpc", "1.0"},
// {"id", "someid"},
// {"method", "listtransactions"}
// };
// conn->doRPCWithDefaultErrorHandling(payload, cb);
}
void LiteInterface::sendZTransaction(json params, const std::function<void(json)>& cb,
const std::function<void(QString)>& err) {
if (conn == nullptr)
return;
// json payload = {
// {"jsonrpc", "1.0"},
// {"id", "someid"},
// {"method", "z_sendmany"},
// {"params", params}
// };
// conn->doRPC(payload, cb, [=] (auto reply, auto parsed) {
// if (!parsed.is_discarded() && !parsed["error"]["message"].is_null()) {
// err(QString::fromStdString(parsed["error"]["message"]));
// } else {
// err(reply->errorString());
// }
// });
}
void LiteInterface::fetchInfo(const std::function<void(json)>& cb,
const std::function<void(QString)>& err) {
5 years ago
if (conn == nullptr)
return;
5 years ago
conn->doRPC("info", "", cb, err);
5 years ago
}
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) {
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");
}
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;
// }
// );
// }
// );
}