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.
 
 
 
 
 
 

806 lines
31 KiB

// Copyright 2019-2024 The Hush developers
// Released under the GPLv3
#include "firsttimewizard.h"
#include "ui_newseed.h"
#include "ui_restoreseed.h"
#include "ui_verifyseed.h"
#include "ui_newwallet.h"
#include "mainwindow.h"
#include "DataStore/DataStore.h"
#include "../lib/silentdragonlitelib.h"
#ifdef Q_OS_WIN
auto dirwalletfirst = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite/silentdragonlite-wallet.dat");
auto dirwalletencfirst = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite/silentdragonlite-wallet-enc.dat");
auto dirwalletbackupfirst = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite/silentdragonlite-wallet.datBackup");
#endif
#ifdef Q_OS_MACOS
auto dirwalletfirst = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite/silentdragonlite-wallet.dat");
auto dirwalletencfirst = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite/silentdragonlite-wallet-enc.dat");
auto dirwalletbackupfirst = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite/silentdragonlite-wallet.datBackup");
#endif
#ifdef Q_OS_LINUX
auto dirwalletfirst = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".silentdragonlite/silentdragonlite-wallet.dat");
auto dirwalletencfirst = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat");
auto dirwalletbackupfirst = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".silentdragonlite/silentdragonlite-wallet.datBackup");
#endif
void FirstTimeWizard::slot_change_theme(const QString& theme_name) {
Settings::getInstance()->set_theme_name(theme_name);
// Include css
QString saved_theme_name;
try
{
saved_theme_name = Settings::getInstance()->get_theme_name();
}
catch (...)
{
saved_theme_name = "Dark";
}
QFile qFile(":/css/res/css/" + saved_theme_name +".css");
if (qFile.open(QFile::ReadOnly))
{
QString styleSheet = QLatin1String(qFile.readAll());
this->setStyleSheet(""); // resets styles, makes app restart unnecessary
this->setStyleSheet(styleSheet);
}
}
FirstTimeWizard::FirstTimeWizard(bool dangerous, QString server){
qDebug() << __func__ << ": dangerous=" << dangerous << " server=" << server;
// Set window flags and disable close button - force user to use Wizard's cancel button to prevent funk
this->setWindowFlags(this->windowFlags() | Qt::CustomizeWindowHint);
this->setWindowFlags(this->windowFlags() & ~Qt::WindowCloseButtonHint);
// Include css
QString theme_name;
try
{
theme_name = Settings::getInstance()->get_theme_name();
}
catch (...)
{
theme_name = "Dark";
}
this->slot_change_theme(theme_name);
setWindowTitle(tr("New wallet wizard"));
this->dangerous = dangerous;
this->server = server;
//backup addresslabels.dat if there is one, to restore it later
auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
QString addressbook = dir.filePath("addresslabels.dat.enc");
QFile file(addressbook);
if (file.exists()) {
file.rename(dir.filePath("addresslabels.dat.enc-backup"));
qDebug() << __func__ << ": backed up old addresslabels";
}
// Create the pages
setPage(Page_NewOrRestore, new NewOrRestorePage(this));
setPage(Page_New, new NewSeedPage(this));
setPage(Page_Restore,new RestoreSeedPage(this));
}
int FirstTimeWizard::nextId() const {
switch (currentId()) {
case Page_NewOrRestore:
if (field("intro.new").toBool()) {
return Page_New;
} else {
return Page_Restore;
}
case Page_New:
case Page_Restore:
default:
return -1;
}
}
QString FirstTimeWizard::getSeed()
{
return _seed;
}
void FirstTimeWizard::setSeed(QString seed)
{
_seed = seed;
}
QString FirstTimeWizard::getBirthday()
{
return _birthday;
}
void FirstTimeWizard::setBirthday(QString birthday)
{
_birthday = birthday;
}
void FirstTimeWizard::initializePage() {
qDebug() << "FirstTimeWizard:" <<__func__;
}
void NewOrRestorePage::initializePage() {
qDebug() << "NewOrRestorePage:" <<__func__;
}
NewOrRestorePage::NewOrRestorePage(FirstTimeWizard *parent) : QWizardPage(parent) {
qDebug() << __func__;
setTitle(tr("Create or Restore wallet."));
QWidget* pageWidget = new QWidget();
Ui_CreateWalletForm form;
form.setupUi(pageWidget);
QGraphicsScene* scene = new QGraphicsScene();
form.Logo->setScene(scene);
QPixmap pixmap(":/icons/res/dark-01.png");
scene->addPixmap(pixmap);
form.Logo->show();
setButtonText(QWizard::CommitButton, tr("Next"));
// Remove back button
parent->setOption(QWizard::NoBackButtonOnStartPage);
parent->setOption(QWizard::NoBackButtonOnLastPage);
form.txtPassword->setEnabled(false);
form.txtConfirmPassword->setEnabled(false);
QObject::connect(form.TOS, &QRadioButton::clicked, [=](bool checked) {
qDebug() << __func__ << ": TOS radio button clicked";
if (checked) {
form.txtPassword->setEnabled(true);
form.txtConfirmPassword->setEnabled(true);
}else{
qDebug() << __func__ << ": disabling next/commit buttons";
parent->button(QWizard::CommitButton)->setEnabled(false);
parent->button(QWizard::NextButton)->setEnabled(false);
}
});
auto fnPasswordEdited = [=](const QString&) {
// Enable the Finish button if the passwords match.
QString passphraseBlank = form.txtPassword->text();
QString passphrase = QString("HUSH3") + passphraseBlank + QString("SDL");
if (!form.txtPassword->text().isEmpty() &&
form.txtPassword->text() == form.txtConfirmPassword->text() && passphraseBlank.size() >= 16 ){
form.lblPasswordMatch->setText("");
form.radioRestoreWallet->setEnabled(true);
form.radioNewWallet->setEnabled(true);
parent->button(QWizard::NextButton)->setEnabled(false);
int length = passphrase.length();
//qDebug() << __func__ << ": passphrase length=" << length;
char *sequence = NULL;
sequence = new char[length+1];
strncpy(sequence, passphrase.toUtf8(), length +1);
QString passphraseHash = blake3_PW(sequence);
char *sequence1 = NULL;
sequence1 = new char[length+1];
strncpy(sequence1, passphraseHash.toUtf8(), length+1);
#define MESSAGE ((const unsigned char *) sequence)
#define MESSAGE_LEN length
#define hash ((const unsigned char *) sequence1)
#define PASSWORD sequence
#define KEY_LEN crypto_box_SEEDBYTES
unsigned char key[KEY_LEN];
if (crypto_pwhash(key, sizeof key, PASSWORD, strlen(PASSWORD), hash,
crypto_pwhash_OPSLIMIT_SENSITIVE, crypto_pwhash_MEMLIMIT_SENSITIVE,
crypto_pwhash_ALG_DEFAULT) != 0) {
/* out of memory */
qDebug() << __func__ << ": crypto_pwhash failed! Possibly out of memory";
exit(1);
}
QString passphraseHash1 = QByteArray(reinterpret_cast<const char*>(key), KEY_LEN).toHex();
DataStore::getChatDataStore()->setPassword(passphraseHash1);
// Exclusive buttons
QObject::connect(form.radioNewWallet, &QRadioButton::clicked, [=](bool checked) {
if (checked) {
qDebug() << __func__ << ": new wallet radio button clicked";
form.radioRestoreWallet->setChecked(false);
parent->button(QWizard::CommitButton)->setEnabled(true);
}
});
QObject::connect(form.radioRestoreWallet, &QRadioButton::clicked, [=](bool checked) {
if (checked) {
qDebug() << __func__ << ": restore wallet radio button clicked";
form.radioNewWallet->setChecked(false);
parent->button(QWizard::CommitButton)->setEnabled(true);
}
});
} else {
qDebug() << __func__ << ": passphrases do not match";
form.lblPasswordMatch->setText(tr("Passphrase don't match or You have entered too few letters (16 minimum)"));
parent->button(QWizard::CommitButton)->setEnabled(false);
form.radioRestoreWallet->setEnabled(false);
form.radioNewWallet->setEnabled(false);
}
};
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(pageWidget);
setLayout(layout);
QObject::connect(form.txtConfirmPassword, &QLineEdit::textChanged, fnPasswordEdited);
QObject::connect(form.txtPassword, &QLineEdit::textChanged, fnPasswordEdited);
registerField("intro.new", form.radioNewWallet);
registerField("intro.restore", form.radioRestoreWallet);
// A trailing * means these are REQUIRED fields and "Next" button will be disabled
// until they are filled
registerField("TOS*", form.TOS);
registerField("txtPassword*", form.txtPassword);
registerField("txtConfirmPassword*", form.txtPassword);
form.radioRestoreWallet->setEnabled(false);
form.radioNewWallet->setEnabled(false);
qDebug() << __func__ << ": disabling next/commit buttons";
setCommitPage(true);
parent->button(QWizard::CommitButton)->setEnabled(false);
parent->button(QWizard::NextButton)->setEnabled(false);
// Connect cancelEvent
disconnect(parent->button(QWizard::CancelButton ), SIGNAL( clicked() ), parent, SLOT( reject() ) );
connect(parent->button(QWizard::CancelButton ), SIGNAL( clicked() ), parent, SLOT( cancelEvent() ) );
}
NewSeedPage::NewSeedPage(FirstTimeWizard *parent) : QWizardPage(parent) {
qDebug() << __func__;
this->parent = parent;
setTitle(tr("Your new wallet"));
QWidget* pageWidget = new QWidget();
form.setupUi(pageWidget);
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(pageWidget);
setLayout(layout);
}
void NewSeedPage::initializePage() {
// Call the library to create a new wallet.
qDebug() << __func__;
QString reply = "";
try {
char* resp = litelib_initialize_new(parent->dangerous,parent->server.toStdString().c_str());
reply = litelib_process_response(resp);
} catch (const std::exception& e) {
qDebug() << __func__ << ": caught an exception, ignoring: " << e.what();
}
qDebug() << __func__ << ": reply=" << reply;
if (reply.isEmpty()) {
qDebug() << "Lite server " << parent->server << " is down, getting a random one";
parent->server = Settings::getRandomServer();
qDebug() << __func__ << ": new server is " << parent->server;
// retry with the new server
// we use litelib_initialize_existing because the call to litelib_initialize_new above
// has already created a wallet on disk
char* resp = litelib_initialize_existing(parent->dangerous,parent->server.toStdString().c_str());
reply = litelib_process_response(resp);
}
auto parsed = json::parse(reply.toStdString().c_str(), nullptr, false);
if (parsed.is_discarded() || parsed.is_null() || parsed.find("seed") == parsed.end()) {
form.txtSeed->setPlainText(tr("Error creating a wallet") + "\n" + reply);
} else {
QString birthday = QString::number(parsed["birthday"].get<json::number_unsigned_t>());
QString seed = QString::fromStdString(parsed["seed"].get<json::string_t>());
form.txtSeed->setPlainText(seed);
parent->setSeed(seed);
parent->setBirthday(birthday);
form.birthday->setPlainText(birthday);
qDebug() << __func__ << ": page initialized with birthday=" << birthday;
}
}
void FirstTimeWizard::cancelEvent() {
qDebug() << __func__;
if( QMessageBox::question( this, tr(( "Quit Setup" )), tr(( "Setup is not complete yet. Are you sure you want to quit setup and close the app?" )), QMessageBox::Yes, QMessageBox::No ) == QMessageBox::Yes ) {
qDebug() << __func__ << ": wizard canceled";
// Allow cancel
reject();
// Close the app
qApp->exit();
}
}
// Will be called just before closing. Make sure we can save the seed in the wallet
// before we allow the page to be closed
bool NewSeedPage::validatePage() {
qDebug() << __func__;
Ui_verifyseed verifyseed;
QDialog dialog(this);
verifyseed.setupUi(&dialog);
Settings::saveRestore(&dialog);
form.birthday->setVisible(false);
form.txtSeed->setVisible(false);
QString seed = parent->getSeed();
QString birthday = parent->getBirthday();
QString word1 = seed.split(" ").at(13);
verifyseed.word1->setText(word1);
QString word2 = seed.split(" ").at(23);
verifyseed.word2->setText(word2);
QString word3 = seed.split(" ").at(11);
verifyseed.word3->setText(word3);
QString word4 = seed.split(" ").at(15);
verifyseed.word4->setText(word4);
QString word5 = seed.split(" ").at(20);
verifyseed.word5->setText(word5);
QString word6 = seed.split(" ").at(12);
verifyseed.word6->setText(word6);
QString word7 = seed.split(" ").at(16);
verifyseed.word7->setText(word7);
QString word8 = seed.split(" ").at(19);
verifyseed.word8->setText(word8);
QString word9 = seed.split(" ").at(21);
verifyseed.word9->setText(word9);
QString word10 = seed.split(" ").at(17);
verifyseed.word10->setText(word10);
QString word11 = seed.split(" ").at(14);
verifyseed.word11->setText(word11);
QString word12 = seed.split(" ").at(2);
verifyseed.word12->setText(word12);
QString word13 = seed.split(" ").at(5);
verifyseed.word13->setText(word13);
QString word14 = seed.split(" ").at(0);
verifyseed.word14->setText(word14);
QString word15 = seed.split(" ").at(10);
verifyseed.word15->setText(word15);
QString word16 = seed.split(" ").at(3);
verifyseed.word16->setText(word16);
QString word17 = seed.split(" ").at(6);
verifyseed.word17->setText(word17);
QString word18 = seed.split(" ").at(9);
verifyseed.word18->setText(word18);
QString word19 = seed.split(" ").at(22);
verifyseed.word19->setText(word19);
QString word20 = seed.split(" ").at(7);
verifyseed.word20->setText(word20);
QString word21 = seed.split(" ").at(4);
verifyseed.word21->setText(word21);
QString word22 = seed.split(" ").at(8);
verifyseed.word22->setText(word22);
QString word23 = seed.split(" ").at(18);
verifyseed.word23->setText(word23);
QString word24 = seed.split(" ").at(1);
verifyseed.word24->setText(word24);
QObject::connect(verifyseed.word1, &QPushButton::clicked, [&] () {
verifyseed.verify->insertPlainText(word1 + " ");
verifyseed.word1->setStyleSheet("background-color: rgb(182,182,182);");
QFont button = verifyseed.word1->font();
button.setStrikeOut(true);
verifyseed.word1->setFont(button);
verifyseed.word1->setEnabled(false);
});
QObject::connect(verifyseed.word2, &QPushButton::clicked, [&] () {
verifyseed.verify->insertPlainText(word2);
verifyseed.word2->setStyleSheet("background-color: rgb(182,182,182);");
QFont button = verifyseed.word2->font();
button.setStrikeOut(true);
verifyseed.word2->setFont(button);
verifyseed.word2->setEnabled(false);
});
QObject::connect(verifyseed.word3, &QPushButton::clicked, [&] () {
verifyseed.verify->insertPlainText(word3 + " ");
verifyseed.word3->setStyleSheet("background-color: rgb(182,182,182);");
QFont button = verifyseed.word3->font();
button.setStrikeOut(true);
verifyseed.word3->setFont(button);
verifyseed.word3->setEnabled(false);
});
QObject::connect(verifyseed.word4, &QPushButton::clicked, [&] () {
verifyseed.verify->insertPlainText(word4 + " ");
verifyseed.word4->setStyleSheet("background-color: rgb(182,182,182);");
QFont button = verifyseed.word4->font();
button.setStrikeOut(true);
verifyseed.word4->setFont(button);
verifyseed.word4->setEnabled(false);
});
QObject::connect(verifyseed.word5, &QPushButton::clicked, [&] () {
verifyseed.verify->insertPlainText(word5 + " ");
verifyseed.word5->setStyleSheet("background-color: rgb(182,182,182);");
QFont button = verifyseed.word5->font();
button.setStrikeOut(true);
verifyseed.word5->setFont(button);
verifyseed.word5->setEnabled(false);
});
QObject::connect(verifyseed.word6, &QPushButton::clicked, [&] () {
verifyseed.verify->insertPlainText(word6 + " ");
verifyseed.word6->setStyleSheet("background-color: rgb(182,182,182);");
QFont button = verifyseed.word6->font();
button.setStrikeOut(true);
verifyseed.word6->setFont(button);
verifyseed.word6->setEnabled(false);
});
QObject::connect(verifyseed.word7, &QPushButton::clicked, [&] () {
verifyseed.verify->insertPlainText(word7 + " ");
verifyseed.word7->setStyleSheet("background-color: rgb(182,182,182);");
QFont button = verifyseed.word7->font();
button.setStrikeOut(true);
verifyseed.word7->setFont(button);
verifyseed.word7->setEnabled(false);
});
QObject::connect(verifyseed.word8, &QPushButton::clicked, [&] () {
verifyseed.verify->insertPlainText(word8 + " ");
verifyseed.word8->setStyleSheet("background-color: rgb(182,182,182);");
QFont button = verifyseed.word8->font();
button.setStrikeOut(true);
verifyseed.word8->setFont(button);
verifyseed.word8->setEnabled(false);
});
QObject::connect(verifyseed.word9, &QPushButton::clicked, [&] () {
verifyseed.verify->insertPlainText(word9 + " ");
verifyseed.word9->setStyleSheet("background-color: rgb(182,182,182);");
QFont button = verifyseed.word9->font();
button.setStrikeOut(true);
verifyseed.word9->setFont(button);
verifyseed.word9->setEnabled(false);
});
QObject::connect(verifyseed.word10, &QPushButton::clicked, [&] () {
verifyseed.verify->insertPlainText(word10 + " ");
verifyseed.word10->setStyleSheet("background-color: rgb(182,182,182);");
QFont button = verifyseed.word10->font();
button.setStrikeOut(true);
verifyseed.word10->setFont(button);
verifyseed.word10->setEnabled(false);
});
QObject::connect(verifyseed.word11, &QPushButton::clicked, [&] () {
verifyseed.verify->insertPlainText(word11 + " ");
verifyseed.word11->setStyleSheet("background-color: rgb(182,182,182);");
QFont button = verifyseed.word11->font();
button.setStrikeOut(true);
verifyseed.word11->setFont(button);
verifyseed.word11->setEnabled(false);
});
QObject::connect(verifyseed.word12, &QPushButton::clicked, [&] () {
verifyseed.verify->insertPlainText(word12 + " ");
verifyseed.word12->setStyleSheet("background-color: rgb(182,182,182);");
QFont button = verifyseed.word12->font();
button.setStrikeOut(true);
verifyseed.word12->setFont(button);
verifyseed.word12->setEnabled(false);
});
QObject::connect(verifyseed.word13, &QPushButton::clicked, [&] () {
verifyseed.verify->insertPlainText(word13 + " ");
verifyseed.word13->setStyleSheet("background-color: rgb(182,182,182);");
QFont button = verifyseed.word13->font();
button.setStrikeOut(true);
verifyseed.word13->setFont(button);
verifyseed.word13->setEnabled(false);
});
QObject::connect(verifyseed.word14, &QPushButton::clicked, [&] () {
verifyseed.verify->insertPlainText(word14 + " ");
verifyseed.word14->setStyleSheet("background-color: rgb(182,182,182);");
QFont button = verifyseed.word14->font();
button.setStrikeOut(true);
verifyseed.word14->setFont(button);
verifyseed.word14->setEnabled(false);
});
QObject::connect(verifyseed.word15, &QPushButton::clicked, [&] () {
verifyseed.verify->insertPlainText(word15 + " ");
verifyseed.word15->setStyleSheet("background-color: rgb(182,182,182);");
QFont button = verifyseed.word15->font();
button.setStrikeOut(true);
verifyseed.word15->setFont(button);
verifyseed.word15->setEnabled(false);
});
QObject::connect(verifyseed.word16, &QPushButton::clicked, [&] () {
verifyseed.verify->insertPlainText(word16 + " ");
verifyseed.word16->setStyleSheet("background-color: rgb(182,182,182);");
QFont button = verifyseed.word16->font();
button.setStrikeOut(true);
verifyseed.word16->setFont(button);
verifyseed.word16->setEnabled(false);
});
QObject::connect(verifyseed.word17, &QPushButton::clicked, [&] () {
verifyseed.verify->insertPlainText(word17 + " ");
verifyseed.word17->setStyleSheet("background-color: rgb(182,182,182);");
QFont button = verifyseed.word17->font();
button.setStrikeOut(true);
verifyseed.word17->setFont(button);
verifyseed.word17->setEnabled(false);
});
QObject::connect(verifyseed.word18, &QPushButton::clicked, [&] () {
verifyseed.verify->insertPlainText(word18 + " ");
verifyseed.word18->setStyleSheet("background-color: rgb(182,182,182);");
QFont button = verifyseed.word18->font();
button.setStrikeOut(true);
verifyseed.word18->setFont(button);
verifyseed.word18->setEnabled(false);
});
QObject::connect(verifyseed.word19, &QPushButton::clicked, [&] () {
verifyseed.verify->insertPlainText(word19 + " ");
verifyseed.word19->setStyleSheet("background-color: rgb(182,182,182);");
QFont button = verifyseed.word19->font();
button.setStrikeOut(true);
verifyseed.word19->setFont(button);
verifyseed.word19->setEnabled(false);
});
QObject::connect(verifyseed.word20, &QPushButton::clicked, [&] () {
verifyseed.verify->insertPlainText(word20 + " ");
verifyseed.word20->setStyleSheet("background-color: rgb(182,182,182);");
QFont button = verifyseed.word20->font();
button.setStrikeOut(true);
verifyseed.word20->setFont(button);
verifyseed.word20->setEnabled(false);
});
QObject::connect(verifyseed.word21, &QPushButton::clicked, [&] () {
verifyseed.verify->insertPlainText(word21 + " ");
verifyseed.word21->setStyleSheet("background-color: rgb(182,182,182);");
QFont button = verifyseed.word21->font();
button.setStrikeOut(true);
verifyseed.word21->setFont(button);
verifyseed.word21->setEnabled(false);
});
QObject::connect(verifyseed.word22, &QPushButton::clicked, [&] () {
verifyseed.verify->insertPlainText(word22 + " ");
verifyseed.word22->setStyleSheet("background-color: rgb(182,182,182);");
QFont button = verifyseed.word22->font();
button.setStrikeOut(true);
verifyseed.word22->setFont(button);
verifyseed.word22->setEnabled(false);
});
QObject::connect(verifyseed.word23, &QPushButton::clicked, [&] () {
verifyseed.verify->insertPlainText(word23 + " ");
verifyseed.word23->setStyleSheet("background-color: rgb(182,182,182);");
QFont button = verifyseed.word23->font();
button.setStrikeOut(true);
verifyseed.word23->setFont(button);
verifyseed.word23->setEnabled(false);
});
QObject::connect(verifyseed.word24, &QPushButton::clicked, [&] () {
verifyseed.verify->insertPlainText(word24 + " ");
verifyseed.word24->setStyleSheet("background-color: rgb(182,182,182);");
QFont button = verifyseed.word24->font();
button.setStrikeOut(true);
verifyseed.word24->setFont(button);
verifyseed.word24->setEnabled(false);
});
dialog.exec();
QString reply = "";
if ((verifyseed.verify->toPlainText() == seed) && (verifyseed.verifyBirthday->toPlainText() == birthday)) {
try {
char* resp = litelib_execute("save", "");
reply = litelib_process_response(resp);
} catch (const std::exception& e) {
qDebug() << __func__ << ": caught an exception, ignoring: " << e.what();
}
qDebug() << __func__ << ": reply=" << reply;
// TODO: this is duplicated code that should be refactored
// into a dedicated function
if (reply.isEmpty()) {
qDebug() << "Lite server " << parent->server << " is down, getting a random one";
parent->server = Settings::getRandomServer();
qDebug() << __func__ << ": new server is " << parent->server;
// make a new connection to the new server
char* resp = litelib_initialize_new(parent->dangerous,parent->server.toStdString().c_str());
reply = litelib_process_response(resp);
// retry with the new server
try {
resp = litelib_execute("save", "");
reply = litelib_process_response(resp);
} catch (const std::exception& e) {
qDebug() << __func__ << ": caught an exception with new server, something is fucky: " << e.what();
}
}
qDebug() << __func__ << ": reply=" << reply;
auto parsed = json::parse(reply.toStdString().c_str(), nullptr, false);
if (parsed.is_discarded() || parsed.is_null() || parsed.find("result") == parsed.end()) {
QMessageBox::warning(this, tr("Failed to save wallet"),
tr("Couldn't save the wallet") + "\n" + "server=" + parent->server + "\n" + reply,
QMessageBox::Ok);
return false;
} else {
return true;
}
}else{
qDebug()<<"Wrong Seed";
QFile file(dirwalletencfirst);
QFile file1(dirwalletfirst);
file.remove();
file1.remove();
QMessageBox::warning(this, tr("Wrong Seed"), tr("Please try again") + "\n" , QMessageBox::Ok);
form.birthday->setVisible(true);
form.txtSeed->setVisible(true);
return false;
this->validatePage();
}
return false;
}
RestoreSeedPage::RestoreSeedPage(FirstTimeWizard *parent) : QWizardPage(parent) {
this->parent = parent;
setTitle(tr("Restore wallet from seed"));
QWidget* pageWidget = new QWidget();
form.setupUi(pageWidget);
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(pageWidget);
setLayout(layout);
}
bool RestoreSeedPage::validatePage() {
// 1. Validate that we do have 24 words
QString seed = form.txtSeed->toPlainText().replace(QRegExp("[ \n\r\t]+"), " "); //TODO: use .simplified()
auto seedLength = seed.trimmed().split(" ").length();
qDebug() << __func__ << ": seed length=" << seedLength;
if (seedLength != 24) {
QMessageBox::warning(this, tr("Failed to restore wallet"),
tr("SilentDragonLite needs 24 words to restore wallet"),
QMessageBox::Ok);
return false;
}
// 2. Validate birthday
QString birthday_str = form.txtBirthday->text();
bool ok;
// simplified() Returns a string that has whitespace removed from the start and the end, and that has each sequence of internal whitespace replaced with a single space.
qint64 birthday = birthday_str.simplified().toUInt(&ok);
if (!ok) {
qDebug() << __func__ << ": Failed to parse wallet birthday=" << birthday_str;
QMessageBox::warning(this, tr("Failed to parse wallet birthday"),
tr("Couldn't understand wallet birthday. This should be a block height from where to rescan the wallet. You can leave the default if you don't know what it should be."),
QMessageBox::Ok);
return false;
}
// 3. Initialize wallet with number
QString number_str = form.number->text();
qint64 number = number_str.toUInt();
qDebug() << __func__ << ": Initializing wallet with number: " << number;
QString reply = "";
try {
char *resp = litelib_initialize_new_from_phrase(parent->dangerous, parent->server.toStdString().c_str(),
seed.toStdString().c_str(), birthday, number);
if (resp != nullptr) {
reply = litelib_process_response(resp);
} else {
qDebug() << __func__ << ": Null response from litelib_initialize_new_from_phrase";
}
} catch (const std::exception &e) {
qDebug() << __func__ << ": caught an exception, ignoring: " << e.what();
}
qDebug() << __func__ << ": reply=" << reply;
if (reply.toUpper().trimmed() != "OK") {
qDebug() << "Lite server " << parent->server << " is down, getting a random one";
parent->server = Settings::getRandomServer();
qDebug() << __func__ << ": new server is " << parent->server;
char *resp = litelib_initialize_new_from_phrase(parent->dangerous, parent->server.toStdString().c_str(),
seed.toStdString().c_str(), birthday, number);
if (resp != nullptr) {
reply = litelib_process_response(resp);
} else {
qDebug() << __func__ << ": Null response on retry from litelib_initialize_new_from_phrase";
}
}
// 4. Finally attempt to save the wallet
{
QString reply = "";
try {
char* resp = litelib_execute("save", "");
reply = litelib_process_response(resp);
} catch (const std::exception& e) {
qDebug() << __func__ << ": caught an exception, ignoring: " << e.what();
}
// TODO: this is duplicated code that should be refactored
// into a dedicated function
if (reply.isEmpty()) {
qDebug() << "Lite server " << parent->server << " is down, getting a random one";
parent->server = Settings::getRandomServer();
qDebug() << __func__ << ": new server is " << parent->server;
// make a new connection to the new server
char* resp = litelib_initialize_new_from_phrase(parent->dangerous, parent->server.toStdString().c_str(),
seed.toStdString().c_str(), birthday, number);
reply = litelib_process_response(resp);
// retry with the new server
try {
resp = litelib_execute("save", "");
reply = litelib_process_response(resp);
} catch (const std::exception& e) {
qDebug() << __func__ << ": caught an exception with new server, something is fucky: " << e.what();
}
}
qDebug() << __func__ << ": reply=" << reply;
auto parsed = json::parse(reply.toStdString().c_str(), nullptr, false);
if (parsed.is_discarded() || parsed.is_null() || parsed.find("result") == parsed.end()) {
qDebug() << __func__ << ": Failed to save wallet, reply=" << reply;
QMessageBox::warning(this, tr("Failed to save wallet"),
tr("Couldn't save the wallet") + "\n" + "server=" + parent->server + "\n" + reply,
QMessageBox::Ok);
return false;
} else {
return true;
}
}
}