merge latest update
This commit is contained in:
BIN
Silentdragonlite
BIN
Silentdragonlite
Binary file not shown.
37
Silentdragonlite_resource.rc
Normal file
37
Silentdragonlite_resource.rc
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
IDI_ICON1 ICON DISCARDABLE "/home/denio/SilentDragonLite/res/icon.ico"
|
||||||
|
|
||||||
|
VS_VERSION_INFO VERSIONINFO
|
||||||
|
FILEVERSION 0,0,0,0
|
||||||
|
PRODUCTVERSION 0,0,0,0
|
||||||
|
FILEFLAGSMASK 0x3fL
|
||||||
|
#ifdef _DEBUG
|
||||||
|
FILEFLAGS VS_FF_DEBUG
|
||||||
|
#else
|
||||||
|
FILEFLAGS 0x0L
|
||||||
|
#endif
|
||||||
|
FILEOS VOS__WINDOWS32
|
||||||
|
FILETYPE VFT_APP
|
||||||
|
FILESUBTYPE 0x0L
|
||||||
|
BEGIN
|
||||||
|
BLOCK "StringFileInfo"
|
||||||
|
BEGIN
|
||||||
|
BLOCK "040904b0"
|
||||||
|
BEGIN
|
||||||
|
VALUE "CompanyName", "\0"
|
||||||
|
VALUE "FileDescription", "\0"
|
||||||
|
VALUE "FileVersion", "0.0.0.0\0"
|
||||||
|
VALUE "LegalCopyright", "\0"
|
||||||
|
VALUE "OriginalFilename", "Silentdragonlite.exe\0"
|
||||||
|
VALUE "ProductName", "Silentdragonlite\0"
|
||||||
|
VALUE "ProductVersion", "0.0.0.0\0"
|
||||||
|
END
|
||||||
|
END
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
BEGIN
|
||||||
|
VALUE "Translation", 0x0409, 1200
|
||||||
|
END
|
||||||
|
END
|
||||||
|
/* End of Version info */
|
||||||
|
|
||||||
@@ -174,7 +174,7 @@ void Executor::run() {
|
|||||||
|
|
||||||
QString reply = litelib_process_response(resp);
|
QString reply = litelib_process_response(resp);
|
||||||
|
|
||||||
qDebug() << "RPC Reply=" << reply;
|
//qDebug() << "RPC Reply=" << reply;
|
||||||
auto parsed = json::parse(reply.toStdString().c_str(), nullptr, false);
|
auto parsed = json::parse(reply.toStdString().c_str(), nullptr, false);
|
||||||
if (parsed.is_discarded() || parsed.is_null()) {
|
if (parsed.is_discarded() || parsed.is_null()) {
|
||||||
emit handleError(reply);
|
emit handleError(reply);
|
||||||
@@ -213,7 +213,7 @@ void Connection::doRPC(const QString cmd, const QString args, const std::functio
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "Doing RPC: " << cmd;
|
//qDebug() << "Doing RPC: " << cmd;
|
||||||
|
|
||||||
// Create a runner.
|
// Create a runner.
|
||||||
auto runner = new Executor(cmd, args);
|
auto runner = new Executor(cmd, args);
|
||||||
|
|||||||
@@ -473,6 +473,9 @@ void Controller::unlockIfEncrypted(std::function<void(void)> cb, std::function<v
|
|||||||
zrpc->unlockWallet(password, [=](json reply) {
|
zrpc->unlockWallet(password, [=](json reply) {
|
||||||
if (isJsonSuccess(reply)) {
|
if (isJsonSuccess(reply)) {
|
||||||
cb();
|
cb();
|
||||||
|
|
||||||
|
// Refresh the wallet so the encryption status is now in sync.
|
||||||
|
refresh(true);
|
||||||
} else {
|
} else {
|
||||||
QMessageBox::critical(main, main->tr("Wallet Decryption Failed"),
|
QMessageBox::critical(main, main->tr("Wallet Decryption Failed"),
|
||||||
QString::fromStdString(reply["error"].get<json::string_t>()),
|
QString::fromStdString(reply["error"].get<json::string_t>()),
|
||||||
@@ -539,7 +542,7 @@ void Controller::checkForUpdate(bool silent) {
|
|||||||
if (!zrpc->haveConnection())
|
if (!zrpc->haveConnection())
|
||||||
return noConnection();
|
return noConnection();
|
||||||
|
|
||||||
QUrl cmcURL("https://api.github.com/repos/MyHush/SilentDragonLite/releases");
|
QUrl cmcURL("https://api.github.com/repos/DenioD/SilentDragonLite/releases");
|
||||||
|
|
||||||
QNetworkRequest req;
|
QNetworkRequest req;
|
||||||
req.setUrl(cmcURL);
|
req.setUrl(cmcURL);
|
||||||
@@ -587,7 +590,7 @@ void Controller::checkForUpdate(bool silent) {
|
|||||||
.arg(currentVersion.toString()),
|
.arg(currentVersion.toString()),
|
||||||
QMessageBox::Yes, QMessageBox::Cancel);
|
QMessageBox::Yes, QMessageBox::Cancel);
|
||||||
if (ans == QMessageBox::Yes) {
|
if (ans == QMessageBox::Yes) {
|
||||||
QDesktopServices::openUrl(QUrl("https://github.com/MyHush/SilentDragonLite/releases"));
|
QDesktopServices::openUrl(QUrl("https://github.com/DenioD/SilentDragonLite/releases"));
|
||||||
} else {
|
} else {
|
||||||
// If the user selects cancel, don't bother them again for this version
|
// If the user selects cancel, don't bother them again for this version
|
||||||
s.setValue("update/lastversion", maxVersion.toString());
|
s.setValue("update/lastversion", maxVersion.toString());
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ public:
|
|||||||
cb({ {"error", "Failed to unlock wallet"} });
|
cb({ {"error", "Failed to unlock wallet"} });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void fetchAllPrivKeys(const std::function<void(json)> cb) {
|
void fetchAllPrivKeys(const std::function<void(json)> cb) {
|
||||||
unlockIfEncrypted([=] () {
|
unlockIfEncrypted([=] () {
|
||||||
zrpc->fetchAllPrivKeys(cb);
|
zrpc->fetchAllPrivKeys(cb);
|
||||||
@@ -89,6 +90,15 @@ public:
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fetchSeed(const std::function<void(json)> cb) {
|
||||||
|
unlockIfEncrypted([=] () {
|
||||||
|
zrpc->fetchSeed(cb);
|
||||||
|
},
|
||||||
|
[=]() {
|
||||||
|
cb({ {"error", "Failed to unlock wallet"} });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// void importZPrivKey(QString addr, bool rescan, const std::function<void(json)>& cb) { zrpc->importZPrivKey(addr, rescan, 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); }
|
// void importTPrivKey(QString addr, bool rescan, const std::function<void(json)>& cb) { zrpc->importTPrivKey(addr, rescan, cb); }
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,13 @@ void LiteInterface::fetchPrivKey(QString addr, const std::function<void(json)>&
|
|||||||
conn->doRPCWithDefaultErrorHandling("export", addr, cb);
|
conn->doRPCWithDefaultErrorHandling("export", addr, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LiteInterface::fetchSeed(const std::function<void(json)>& cb) {
|
||||||
|
if (conn == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
conn->doRPCWithDefaultErrorHandling("seed", "", cb);
|
||||||
|
}
|
||||||
|
|
||||||
void LiteInterface::fetchBalance(const std::function<void(json)>& cb) {
|
void LiteInterface::fetchBalance(const std::function<void(json)>& cb) {
|
||||||
if (conn == nullptr)
|
if (conn == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ public:
|
|||||||
|
|
||||||
void fetchPrivKey(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 fetchAllPrivKeys(const std::function<void(json)>);
|
||||||
|
void fetchSeed(const std::function<void(json)>&);
|
||||||
|
|
||||||
void saveWallet(const std::function<void(json)>& cb);
|
void saveWallet(const std::function<void(json)>& cb);
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||||||
|
|
||||||
// File a bug
|
// File a bug
|
||||||
QObject::connect(ui->actionFile_a_bug, &QAction::triggered, [=]() {
|
QObject::connect(ui->actionFile_a_bug, &QAction::triggered, [=]() {
|
||||||
QDesktopServices::openUrl(QUrl("https://github.com/MyHush/silentdragonlite/issues/new"));
|
QDesktopServices::openUrl(QUrl("https://github.com/DenioD/SilentDragonLite/issues/new"));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set up check for updates action
|
// Set up check for updates action
|
||||||
@@ -95,7 +95,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||||||
QObject::connect(ui->actionExport_All_Private_Keys, &QAction::triggered, this, &MainWindow::exportAllKeys);
|
QObject::connect(ui->actionExport_All_Private_Keys, &QAction::triggered, this, &MainWindow::exportAllKeys);
|
||||||
|
|
||||||
// Backup wallet.dat
|
// Backup wallet.dat
|
||||||
QObject::connect(ui->actionBackup_wallet_dat, &QAction::triggered, this, &MainWindow::backupWalletDat);
|
QObject::connect(ui->actionExport_Seed, &QAction::triggered, this, &MainWindow::exportSeed);
|
||||||
|
|
||||||
// Export transactions
|
// Export transactions
|
||||||
QObject::connect(ui->actionExport_transactions, &QAction::triggered, this, &MainWindow::exportTransactions);
|
QObject::connect(ui->actionExport_transactions, &QAction::triggered, this, &MainWindow::exportTransactions);
|
||||||
@@ -279,6 +279,9 @@ void MainWindow::encryptWallet() {
|
|||||||
fnShowError(tr("Wallet Encryption Failed"), reply);
|
fnShowError(tr("Wallet Encryption Failed"), reply);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// And then refresh the UI
|
||||||
|
rpc->refresh(true);
|
||||||
} else {
|
} else {
|
||||||
fnShowError(tr("Wallet Encryption Failed"), res);
|
fnShowError(tr("Wallet Encryption Failed"), res);
|
||||||
}
|
}
|
||||||
@@ -297,8 +300,22 @@ void MainWindow::removeWalletEncryption() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ok;
|
||||||
QString password = QInputDialog::getText(this, tr("Wallet Password"),
|
QString password = QInputDialog::getText(this, tr("Wallet Password"),
|
||||||
tr("Please enter your wallet password"), QLineEdit::Password);
|
tr("Please enter your wallet password"), QLineEdit::Password, "", &ok);
|
||||||
|
|
||||||
|
// If cancel was pressed, just return
|
||||||
|
if (!ok) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (password.isEmpty()) {
|
||||||
|
QMessageBox::critical(this, tr("Wallet Decryption Failed"),
|
||||||
|
tr("Please enter a password to decrypt your wallet!"),
|
||||||
|
QMessageBox::Ok
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
rpc->removeWalletEncryption(password, [=] (json res) {
|
rpc->removeWalletEncryption(password, [=] (json res) {
|
||||||
if (isJsonSuccess(res)) {
|
if (isJsonSuccess(res)) {
|
||||||
@@ -316,6 +333,9 @@ void MainWindow::removeWalletEncryption() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// And then refresh the UI
|
||||||
|
rpc->refresh(true);
|
||||||
} else {
|
} else {
|
||||||
QMessageBox::critical(this, tr("Wallet Decryption Failed"),
|
QMessageBox::critical(this, tr("Wallet Decryption Failed"),
|
||||||
QString::fromStdString(res["error"].get<json::string_t>()),
|
QString::fromStdString(res["error"].get<json::string_t>()),
|
||||||
@@ -641,44 +661,71 @@ void MainWindow::exportTransactions() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Backup the wallet.dat file. This is kind of a hack, since it has to read from the filesystem rather than an RPC call
|
* Export the seed phrase.
|
||||||
* This might fail for various reasons - Remote hushd, non-standard locations, custom params passed to hushd, many others
|
|
||||||
*/
|
*/
|
||||||
void MainWindow::backupWalletDat() {
|
void MainWindow::exportSeed() {
|
||||||
if (!rpc->getConnection())
|
if (!rpc->getConnection())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
QDialog d(this);
|
||||||
|
Ui_PrivKey pui;
|
||||||
|
pui.setupUi(&d);
|
||||||
|
|
||||||
|
// Make the window big by default
|
||||||
|
auto ps = this->geometry();
|
||||||
|
QMargins margin = QMargins() + 50;
|
||||||
|
d.setGeometry(ps.marginsRemoved(margin));
|
||||||
|
|
||||||
|
Settings::saveRestore(&d);
|
||||||
|
|
||||||
|
pui.privKeyTxt->setPlainText(tr("This might take several minutes. Loading..."));
|
||||||
|
pui.privKeyTxt->setReadOnly(true);
|
||||||
|
pui.privKeyTxt->setLineWrapMode(QPlainTextEdit::LineWrapMode::NoWrap);
|
||||||
|
|
||||||
|
pui.helpLbl->setText(tr("This is your wallet seed. Please back it up carefully and safely."));
|
||||||
|
|
||||||
|
// 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-seed.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();
|
||||||
|
});
|
||||||
|
|
||||||
|
rpc->fetchSeed([=](json reply) {
|
||||||
|
if (isJsonError(reply)) {
|
||||||
|
pui.privKeyTxt->setPlainText(tr("Error loading wallet seed: ") + QString::fromStdString(reply["error"]));
|
||||||
|
pui.buttonBox->button(QDialogButtonBox::Save)->setEnabled(false);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pui.privKeyTxt->setPlainText(QString::fromStdString(reply.dump()));
|
||||||
|
pui.buttonBox->button(QDialogButtonBox::Save)->setEnabled(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
d.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
// QDir hushdir(rpc->getConnection()->config->hushDir);
|
|
||||||
// QString backupDefaultName = "hush-wallet-backup-" + QDateTime::currentDateTime().toString("yyyyMMdd") + ".dat";
|
|
||||||
|
|
||||||
// if (Settings::getInstance()->isTestnet()) {
|
|
||||||
// hushdir.cd("testnet3");
|
|
||||||
// backupDefaultName = "testnet-" + backupDefaultName;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// QFile wallet(hushdir.filePath("wallet.dat"));
|
|
||||||
// if (!wallet.exists()) {
|
|
||||||
// QMessageBox::critical(this, tr("No wallet.dat"), tr("Couldn't find the wallet.dat on this computer") + "\n" +
|
|
||||||
// tr("You need to back it up from the machine hushd is running on"), QMessageBox::Ok);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// QUrl backupName = QFileDialog::getSaveFileUrl(this, tr("Backup wallet.dat"), backupDefaultName, "Data file (*.dat)");
|
|
||||||
// if (backupName.isEmpty())
|
|
||||||
// return;
|
|
||||||
|
|
||||||
// if (!wallet.copy(backupName.toLocalFile())) {
|
|
||||||
// QMessageBox::critical(this, tr("Couldn't backup"), tr("Couldn't backup the wallet.dat file.") +
|
|
||||||
// tr("You need to back it up manually."), QMessageBox::Ok);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
void MainWindow::exportAllKeys() {
|
void MainWindow::exportAllKeys() {
|
||||||
exportKeys("");
|
exportKeys("");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::exportKeys(QString addr) {
|
void MainWindow::exportKeys(QString addr) {
|
||||||
|
if (!rpc->getConnection())
|
||||||
|
return;
|
||||||
|
|
||||||
bool allKeys = addr.isEmpty() ? true : false;
|
bool allKeys = addr.isEmpty() ? true : false;
|
||||||
|
|
||||||
QDialog d(this);
|
QDialog d(this);
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ private:
|
|||||||
void importPrivKey();
|
void importPrivKey();
|
||||||
void exportAllKeys();
|
void exportAllKeys();
|
||||||
void exportKeys(QString addr = "");
|
void exportKeys(QString addr = "");
|
||||||
void backupWalletDat();
|
void exportSeed();
|
||||||
void exportTransactions();
|
void exportTransactions();
|
||||||
|
|
||||||
void doImport(QList<QString>* keys);
|
void doImport(QList<QString>* keys);
|
||||||
|
|||||||
@@ -1099,7 +1099,7 @@
|
|||||||
<addaction name="actionPay_URI"/>
|
<addaction name="actionPay_URI"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionExport_All_Private_Keys"/>
|
<addaction name="actionExport_All_Private_Keys"/>
|
||||||
<addaction name="actionBackup_wallet_dat"/>
|
<addaction name="actionExport_Seed"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionExport_transactions"/>
|
<addaction name="actionExport_transactions"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
@@ -1190,9 +1190,9 @@
|
|||||||
<string>Ctrl+B</string>
|
<string>Ctrl+B</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionBackup_wallet_dat">
|
<action name="actionExport_Seed">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Backup wallet.dat</string>
|
<string>&Export seed phrase</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionExport_transactions">
|
<action name="actionExport_transactions">
|
||||||
|
|||||||
@@ -616,6 +616,7 @@ void MainWindow::sendButton() {
|
|||||||
Tx tx = createTxFromSendPage();
|
Tx tx = createTxFromSendPage();
|
||||||
|
|
||||||
QString error = doSendTxValidations(tx);
|
QString error = doSendTxValidations(tx);
|
||||||
|
|
||||||
if (!error.isEmpty()) {
|
if (!error.isEmpty()) {
|
||||||
// Something went wrong, so show an error and exit
|
// Something went wrong, so show an error and exit
|
||||||
QMessageBox msg(QMessageBox::Critical, tr("Transaction Error"), error,
|
QMessageBox msg(QMessageBox::Critical, tr("Transaction Error"), error,
|
||||||
@@ -709,6 +710,9 @@ void MainWindow::sendButton() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString MainWindow::doSendTxValidations(Tx tx) {
|
QString MainWindow::doSendTxValidations(Tx tx) {
|
||||||
|
// Check to see if we have enough verified funds to send the Tx.
|
||||||
|
|
||||||
|
CAmount total;
|
||||||
for (auto toAddr : tx.toAddrs) {
|
for (auto toAddr : tx.toAddrs) {
|
||||||
if (!Settings::isValidAddress(toAddr.addr)) {
|
if (!Settings::isValidAddress(toAddr.addr)) {
|
||||||
QString addr = (toAddr.addr.length() > 100 ? toAddr.addr.left(100) + "..." : toAddr.addr);
|
QString addr = (toAddr.addr.length() > 100 ? toAddr.addr.left(100) + "..." : toAddr.addr);
|
||||||
@@ -720,6 +724,16 @@ QString MainWindow::doSendTxValidations(Tx tx) {
|
|||||||
if (toAddr.amount.toqint64() < 0) {
|
if (toAddr.amount.toqint64() < 0) {
|
||||||
return QString(tr("Amount for address '%1' is invalid!").arg(toAddr.addr));
|
return QString(tr("Amount for address '%1' is invalid!").arg(toAddr.addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
total = total + toAddr.amount;
|
||||||
|
}
|
||||||
|
total = total + tx.fee;
|
||||||
|
|
||||||
|
auto available = rpc->getModel()->getAvailableBalance();
|
||||||
|
|
||||||
|
if (available < total) {
|
||||||
|
return tr("Not enough available funds to send this transaction\n\nHave: %1\nNeed: %2\n\nNote: Funds need 5 confirmations before they can be spent")
|
||||||
|
.arg(available.toDecimalhushString(), total.toDecimalhushString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
|
|||||||
@@ -127,4 +127,10 @@ inline bool isJsonSuccess(const json& res) {
|
|||||||
QString::fromStdString(res["result"].get<json::string_t>()) == "success";
|
QString::fromStdString(res["result"].get<json::string_t>()) == "success";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool isJsonError(const json& res) {
|
||||||
|
return res.find("result") != res.end() &&
|
||||||
|
QString::fromStdString(res["result"].get<json::string_t>()) == "error";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // SETTINGS_H
|
#endif // SETTINGS_H
|
||||||
|
|||||||
Reference in New Issue
Block a user