|
|
@ -10,6 +10,8 @@ |
|
|
|
#include "websockets.h" |
|
|
|
#include "Model/ChatItem.h" |
|
|
|
#include "DataStore/DataStore.h" |
|
|
|
#include <thread> |
|
|
|
|
|
|
|
|
|
|
|
ChatModel *chatModel = new ChatModel(); |
|
|
|
Chat *chat = new Chat(); |
|
|
@ -262,24 +264,39 @@ void Controller::noConnection() |
|
|
|
|
|
|
|
// Clear balances
|
|
|
|
ui->balSheilded->setText(""); |
|
|
|
ui->balUnconfirmed->setText(""); |
|
|
|
ui->balTransparent->setText(""); |
|
|
|
ui->balTotal->setText(""); |
|
|
|
|
|
|
|
ui->balSheilded->setToolTip(""); |
|
|
|
ui->balUnconfirmed->setToolTip(""); |
|
|
|
ui->balTransparent->setToolTip(""); |
|
|
|
ui->balTotal->setToolTip(""); |
|
|
|
} |
|
|
|
|
|
|
|
/// This will refresh all the balance data from hushd
|
|
|
|
void Controller::refresh(bool force) |
|
|
|
{ |
|
|
|
qDebug()<< __func__; |
|
|
|
if (!zrpc->haveConnection()) |
|
|
|
return; |
|
|
|
#include <thread> |
|
|
|
|
|
|
|
void Controller::refresh(bool force) { |
|
|
|
qDebug() << __func__; |
|
|
|
|
|
|
|
getInfoThenRefresh(force); |
|
|
|
int attempts = 0; |
|
|
|
const int max_attempts = 10; |
|
|
|
|
|
|
|
while (!zrpc->haveConnection()) { |
|
|
|
if (attempts >= max_attempts) { |
|
|
|
qDebug() << "Max retry reached"; |
|
|
|
return; |
|
|
|
} |
|
|
|
qDebug() << "Waiting for connection... try : " << attempts + 1; |
|
|
|
std::this_thread::sleep_for(std::chrono::seconds(2 * attempts)); |
|
|
|
attempts++; |
|
|
|
} |
|
|
|
|
|
|
|
getInfoThenRefresh(force); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Controller::processInfo(const json& info) |
|
|
|
{ |
|
|
|
// Testnet?
|
|
|
@ -300,9 +317,19 @@ void Controller::processInfo(const json& info) |
|
|
|
|
|
|
|
void Controller::getInfoThenRefresh(bool force) |
|
|
|
{ |
|
|
|
qDebug()<< __func__; |
|
|
|
if (!zrpc->haveConnection()) |
|
|
|
return noConnection(); |
|
|
|
qDebug()<< __func__; |
|
|
|
int attempts = 0; |
|
|
|
int max_attempts = 10; |
|
|
|
|
|
|
|
while (!zrpc->haveConnection()) { |
|
|
|
if (attempts >= max_attempts) { |
|
|
|
return noConnection(); |
|
|
|
} |
|
|
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::seconds(2 * attempts)); |
|
|
|
attempts++; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static bool prevCallSucceeded = false; |
|
|
|
|
|
|
@ -628,8 +655,19 @@ void Controller::setLag(int lag) |
|
|
|
void Controller::refreshAddresses() |
|
|
|
{ |
|
|
|
qDebug()<< __func__; |
|
|
|
if (!zrpc->haveConnection()) |
|
|
|
return noConnection(); |
|
|
|
|
|
|
|
int attempts = 0; |
|
|
|
const int max_attempts = 10; |
|
|
|
|
|
|
|
while (!zrpc->haveConnection()) { |
|
|
|
if (attempts >= max_attempts) { |
|
|
|
qDebug() << "Max try reached"; |
|
|
|
return noConnection(); |
|
|
|
} |
|
|
|
qDebug() << "Waiting for connection... try : " << attempts + 1; |
|
|
|
std::this_thread::sleep_for(std::chrono::seconds(2 * attempts)); |
|
|
|
attempts++; |
|
|
|
} |
|
|
|
|
|
|
|
auto newzaddresses = new QList<QString>(); |
|
|
|
auto newtaddresses = new QList<QString>(); |
|
|
@ -732,6 +770,7 @@ void Controller::updateUIBalances() |
|
|
|
{ |
|
|
|
CAmount balT = getModel()->getBalT(); |
|
|
|
CAmount balZ = getModel()->getBalZ(); |
|
|
|
CAmount balU = getModel()->getBalU(); |
|
|
|
CAmount balVerified = getModel()->getBalVerified(); |
|
|
|
CAmount balSpendable = getModel()->getBalSpendable(); |
|
|
|
|
|
|
@ -749,6 +788,7 @@ void Controller::updateUIBalances() |
|
|
|
// Balances table
|
|
|
|
ui->balSheilded->setText(balZ.toDecimalhushString()); |
|
|
|
ui->balVerified->setText(balVerified.toDecimalhushString()); |
|
|
|
ui->balUnconfirmed->setText(balU.toDecimalhushString()); |
|
|
|
ui->balTransparent->setText(balT.toDecimalhushString()); |
|
|
|
ui->balSpendable->setText(balSpendable.toDecimalhushString()); |
|
|
|
ui->balTotal->setText(balTotal.toDecimalhushString()); |
|
|
@ -881,18 +921,31 @@ void Controller::updateUIBalances() |
|
|
|
void Controller::refreshBalances() |
|
|
|
{ |
|
|
|
qDebug()<< __func__; |
|
|
|
if (!zrpc->haveConnection()) |
|
|
|
return noConnection(); |
|
|
|
|
|
|
|
int attempts = 0; |
|
|
|
const int max_attempts = 10; |
|
|
|
|
|
|
|
while (!zrpc->haveConnection()) { |
|
|
|
if (attempts >= max_attempts) { |
|
|
|
qDebug() << "Max try reached"; |
|
|
|
return noConnection(); |
|
|
|
} |
|
|
|
qDebug() << "Waiting for connection... try : " << attempts + 1; |
|
|
|
std::this_thread::sleep_for(std::chrono::seconds(2 * attempts)); |
|
|
|
attempts++; |
|
|
|
} |
|
|
|
|
|
|
|
// 1. Get the Balances
|
|
|
|
zrpc->fetchBalance([=] (json reply) { |
|
|
|
CAmount balT = CAmount::fromqint64(reply["tbalance"].get<json::number_unsigned_t>()); |
|
|
|
CAmount balZ = CAmount::fromqint64(reply["zbalance"].get<json::number_unsigned_t>()); |
|
|
|
CAmount balU = CAmount::fromqint64(reply["unconfirmed"].get<json::number_unsigned_t>()); |
|
|
|
CAmount balVerified = CAmount::fromqint64(reply["verified_zbalance"].get<json::number_unsigned_t>()); |
|
|
|
CAmount balSpendable = CAmount::fromqint64(reply["spendable_zbalance"].get<json::number_unsigned_t>()); |
|
|
|
|
|
|
|
model->setBalT(balT); |
|
|
|
model->setBalZ(balZ); |
|
|
|
model->setBalU(balU); |
|
|
|
model->setBalVerified(balVerified); |
|
|
|
model->setBalSpendable(balSpendable); |
|
|
|
|
|
|
@ -933,10 +986,41 @@ void Controller::refreshBalances() |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
void printJsonValue(QTextStream& out, const nlohmann::json& j, int depth = 0) { |
|
|
|
if (j.is_array()) { |
|
|
|
for (auto& elem : j) { |
|
|
|
printJsonValue(out, elem, depth + 1); |
|
|
|
} |
|
|
|
} else if (j.is_object()) { |
|
|
|
for (auto it = j.begin(); it != j.end(); ++it) { |
|
|
|
std::string key = it.key(); |
|
|
|
const nlohmann::json& value = it.value(); |
|
|
|
out << QString::fromStdString(std::string(depth * 4, ' ')) |
|
|
|
<< QString::fromStdString(key) << ": "; |
|
|
|
printJsonValue(out, value, depth + 1); |
|
|
|
} |
|
|
|
} else { |
|
|
|
out << QString::fromStdString(j.dump(4)) << "\n"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Controller::refreshTransactions() { |
|
|
|
qDebug()<< __func__; |
|
|
|
if (!zrpc->haveConnection()) |
|
|
|
return noConnection(); |
|
|
|
|
|
|
|
int attempts = 0; |
|
|
|
const int max_attempts = 10; |
|
|
|
|
|
|
|
while (!zrpc->haveConnection()) { |
|
|
|
if (attempts >= max_attempts) { |
|
|
|
qDebug() << "Max try reached"; |
|
|
|
return noConnection(); |
|
|
|
} |
|
|
|
qDebug() << "Waiting for connection... try : " << attempts + 1; |
|
|
|
std::this_thread::sleep_for(std::chrono::seconds(2 * attempts)); |
|
|
|
attempts++; |
|
|
|
} |
|
|
|
|
|
|
|
qDebug() << __func__ << ": fetchTransactions"; |
|
|
|
zrpc->fetchTransactions([=] (json reply) { |
|
|
@ -1044,7 +1128,6 @@ void Controller::refreshTransactions() { |
|
|
|
|
|
|
|
#define MESSAGEAS1 ((const unsigned char *) hashEncryptionKeyraw) ///////////
|
|
|
|
#define MESSAGEAS1_LEN length |
|
|
|
|
|
|
|
unsigned char sk[crypto_kx_SECRETKEYBYTES]; |
|
|
|
unsigned char pk[crypto_kx_PUBLICKEYBYTES]; |
|
|
|
|
|
|
@ -1058,9 +1141,7 @@ void Controller::refreshTransactions() { |
|
|
|
unsigned char server_rx[crypto_kx_SESSIONKEYBYTES], server_tx[crypto_kx_SESSIONKEYBYTES]; |
|
|
|
|
|
|
|
////////////////Get the pubkey from Bob, so we can create the share key
|
|
|
|
|
|
|
|
/////Create the shared key for sending the message
|
|
|
|
|
|
|
|
if (crypto_kx_server_session_keys(server_rx, server_tx, pk, sk, pubkeyBob) != 0) |
|
|
|
{ |
|
|
|
main->logger->write("Suspicious client public outgoing key, bail out "); |
|
|
@ -1082,15 +1163,11 @@ void Controller::refreshTransactions() { |
|
|
|
{ |
|
|
|
//////unsigned char* as message from QString
|
|
|
|
#define MESSAGE2 (const unsigned char *) encryptedMemo |
|
|
|
|
|
|
|
///////// length of the encrypted message
|
|
|
|
#define CIPHERTEXT1_LEN encryptedMemoSize1 |
|
|
|
|
|
|
|
///////Message length is smaller then the encrypted message
|
|
|
|
#define MESSAGE1_LEN encryptedMemoSize1 - crypto_secretstream_xchacha20poly1305_ABYTES |
|
|
|
|
|
|
|
//////Set the length of the decrypted message
|
|
|
|
|
|
|
|
unsigned char decrypted[MESSAGE1_LEN]; |
|
|
|
unsigned char tag[crypto_secretstream_xchacha20poly1305_TAG_FINAL]; |
|
|
|
crypto_secretstream_xchacha20poly1305_state state; |
|
|
@ -1118,7 +1195,6 @@ void Controller::refreshTransactions() { |
|
|
|
|
|
|
|
/////Now we can convert it to QString
|
|
|
|
//////////////Give us the output of the decrypted message as debug to see if it was successfully
|
|
|
|
|
|
|
|
ChatItem item = ChatItem( |
|
|
|
datetime, |
|
|
|
address, |
|
|
@ -1161,13 +1237,13 @@ void Controller::refreshTransactions() { |
|
|
|
} else { |
|
|
|
|
|
|
|
{ // Incoming Transaction
|
|
|
|
address = (it["address"].is_null() ? "" : QString::fromStdString(it["address"])); |
|
|
|
model->markAddressUsed(address); |
|
|
|
QString memo; |
|
|
|
address = (it["address"].is_null() ? "" : QString::fromStdString(it["address"])); |
|
|
|
|
|
|
|
QString memo; |
|
|
|
if (!it["memo"].is_null()) { |
|
|
|
memo = QString::fromStdString(it["memo"]); |
|
|
|
} |
|
|
|
|
|
|
|
items.push_back(TransactionItemDetail{ address, |
|
|
|
CAmount::fromqint64(it["amount"].get<json::number_integer_t>()), |
|
|
|
memo |
|
|
@ -1187,7 +1263,7 @@ void Controller::refreshTransactions() { |
|
|
|
QString contactname = ""; |
|
|
|
bool isContact = false; |
|
|
|
|
|
|
|
if (!it["memo"].is_null()) { |
|
|
|
if (!memo.isNull()) { |
|
|
|
|
|
|
|
if (memo.startsWith("{")) { |
|
|
|
try { |
|
|
@ -1257,7 +1333,8 @@ void Controller::refreshTransactions() { |
|
|
|
if (position == 1) |
|
|
|
{ |
|
|
|
chatModel->addMemo(txid, headerbytes); |
|
|
|
} else { |
|
|
|
} |
|
|
|
else { |
|
|
|
//
|
|
|
|
} |
|
|
|
|
|
|
@ -1273,7 +1350,6 @@ void Controller::refreshTransactions() { |
|
|
|
|
|
|
|
#define MESSAGEAS1 ((const unsigned char *) hashEncryptionKeyraw)///////////
|
|
|
|
#define MESSAGEAS1_LEN length |
|
|
|
|
|
|
|
unsigned char sk[crypto_kx_SECRETKEYBYTES]; |
|
|
|
unsigned char pk[crypto_kx_PUBLICKEYBYTES]; |
|
|
|
|
|
|
@ -1287,7 +1363,6 @@ void Controller::refreshTransactions() { |
|
|
|
unsigned char client_rx[crypto_kx_SESSIONKEYBYTES], client_tx[crypto_kx_SESSIONKEYBYTES]; |
|
|
|
|
|
|
|
////////////////Get the pubkey from Bob, so we can create the share key
|
|
|
|
|
|
|
|
/////Create the shared key for sending the message
|
|
|
|
if (crypto_kx_client_session_keys(client_rx, client_tx, pk, sk, pubkeyBob) != 0) |
|
|
|
{ |
|
|
@ -1304,18 +1379,13 @@ void Controller::refreshTransactions() { |
|
|
|
|
|
|
|
int encryptedMemoSize1 = ba.length(); |
|
|
|
//int headersize = ba1.length();
|
|
|
|
|
|
|
|
//////unsigned char* as message from QString
|
|
|
|
#define MESSAGE2 (const unsigned char *) encryptedMemo |
|
|
|
|
|
|
|
///////// length of the encrypted message
|
|
|
|
#define CIPHERTEXT1_LEN encryptedMemoSize1 |
|
|
|
|
|
|
|
///////Message length is smaller then the encrypted message
|
|
|
|
#define MESSAGE1_LEN encryptedMemoSize1 - crypto_secretstream_xchacha20poly1305_ABYTES |
|
|
|
|
|
|
|
//////Set the length of the decrypted message
|
|
|
|
|
|
|
|
unsigned char decrypted[MESSAGE1_LEN+1]; |
|
|
|
unsigned char tag[crypto_secretstream_xchacha20poly1305_TAG_FINAL]; |
|
|
|
crypto_secretstream_xchacha20poly1305_state state; |
|
|
@ -1343,7 +1413,6 @@ void Controller::refreshTransactions() { |
|
|
|
memodecrypt = QString::fromUtf8( decryptedMemo.data(), decryptedMemo.size()); |
|
|
|
|
|
|
|
////Give us the output of the decrypted message as debug to see if it was successfully
|
|
|
|
|
|
|
|
ChatItem item = ChatItem( |
|
|
|
datetime, |
|
|
|
address, |
|
|
@ -1367,8 +1436,6 @@ void Controller::refreshTransactions() { |
|
|
|
qDebug() << __func__ << ": ignoring txid="<< txid; |
|
|
|
} |
|
|
|
|
|
|
|
//} else if (memo.startsWith("{")) {
|
|
|
|
//qDebug() << __func__ << ": ignoring a header memo";
|
|
|
|
} else { |
|
|
|
// Add a chatitem for the initial CR
|
|
|
|
ChatItem item = ChatItem( |
|
|
@ -1553,8 +1620,19 @@ void Controller::checkForUpdate(bool silent) |
|
|
|
qDebug()<< __func__; |
|
|
|
// No checking for updates, needs testing with Gitea
|
|
|
|
return; |
|
|
|
if (!zrpc->haveConnection()) |
|
|
|
return noConnection(); |
|
|
|
|
|
|
|
int attempts = 0; |
|
|
|
const int max_attempts = 10; |
|
|
|
|
|
|
|
while (!zrpc->haveConnection()) { |
|
|
|
if (attempts >= max_attempts) { |
|
|
|
qDebug() << "Max try reached"; |
|
|
|
return noConnection(); |
|
|
|
} |
|
|
|
qDebug() << "Waiting for connection... try : " << attempts + 1; |
|
|
|
std::this_thread::sleep_for(std::chrono::seconds(2 * attempts)); |
|
|
|
attempts++; |
|
|
|
} |
|
|
|
|
|
|
|
QUrl cmcURL("https://git.hush.is/repos/MyHush/SilentDragonLite/releases"); |
|
|
|
|
|
|
@ -1642,8 +1720,19 @@ void Controller::checkForUpdate(bool silent) |
|
|
|
void Controller::refreshHUSHPrice() |
|
|
|
{ |
|
|
|
qDebug()<< __func__; |
|
|
|
if (!zrpc->haveConnection()) |
|
|
|
return; |
|
|
|
|
|
|
|
int attempts = 0; |
|
|
|
const int max_attempts = 10; |
|
|
|
|
|
|
|
while (!zrpc->haveConnection()) { |
|
|
|
if (attempts >= max_attempts) { |
|
|
|
qDebug() << "Max try reached"; |
|
|
|
return noConnection(); |
|
|
|
} |
|
|
|
qDebug() << "Waiting for connection... try : " << attempts + 1; |
|
|
|
std::this_thread::sleep_for(std::chrono::seconds(2 * attempts)); |
|
|
|
attempts++; |
|
|
|
} |
|
|
|
|
|
|
|
// TODO: use/render all this data
|
|
|
|
QUrl cmcURL("https://api.coingecko.com/api/v3/simple/price?ids=hush&vs_currencies=btc%2Cusd%2Ceur%2Ceth%2Cgbp%2Ccny%2Cjpy%2Crub%2Ccad%2Csgd%2Cchf%2Cinr%2Caud%2Cinr&include_market_cap=true&include_24hr_vol=true&include_24hr_change=true"); |
|
|
|