merge
This commit is contained in:
6
lib/Cargo.lock
generated
6
lib/Cargo.lock
generated
@@ -1051,7 +1051,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=a9d235e117da1fdbe3c576d0713b87cfdf97baf6)",
|
"silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=4d9c09433007e71e259b10f15c28ba1c6ac3efae)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1467,7 +1467,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "silentdragonlitelib"
|
name = "silentdragonlitelib"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=a9d235e117da1fdbe3c576d0713b87cfdf97baf6#a9d235e117da1fdbe3c576d0713b87cfdf97baf6"
|
source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=4d9c09433007e71e259b10f15c28ba1c6ac3efae#4d9c09433007e71e259b10f15c28ba1c6ac3efae"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"bellman 0.1.0 (git+https://github.com/DenioD/librustzcash.git?rev=caaee693c47c2ee9ecd1e1546b8fe3c714f342bc)",
|
"bellman 0.1.0 (git+https://github.com/DenioD/librustzcash.git?rev=caaee693c47c2ee9ecd1e1546b8fe3c714f342bc)",
|
||||||
@@ -2481,7 +2481,7 @@ dependencies = [
|
|||||||
"checksum serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2"
|
"checksum serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2"
|
||||||
"checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35"
|
"checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35"
|
||||||
"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d"
|
"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d"
|
||||||
"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=a9d235e117da1fdbe3c576d0713b87cfdf97baf6)" = "<none>"
|
"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=4d9c09433007e71e259b10f15c28ba1c6ac3efae)" = "<none>"
|
||||||
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
||||||
"checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7"
|
"checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7"
|
||||||
"checksum sodiumoxide 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585232e78a4fc18133eef9946d3080befdf68b906c51b621531c37e91787fa2b"
|
"checksum sodiumoxide 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585232e78a4fc18133eef9946d3080befdf68b906c51b621531c37e91787fa2b"
|
||||||
|
|||||||
@@ -11,4 +11,4 @@ crate-type = ["staticlib"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
libc = "0.2.58"
|
libc = "0.2.58"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "a9d235e117da1fdbe3c576d0713b87cfdf97baf6" }
|
silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "4d9c09433007e71e259b10f15c28ba1c6ac3efae" }
|
||||||
|
|||||||
@@ -5,13 +5,21 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern bool litelib_wallet_exists (const char* chain_name);
|
extern bool litelib_wallet_exists (const char* chain_name);
|
||||||
extern char * litelib_initialze_existing (bool dangerous, const char* server);
|
extern char * litelib_initialize_new (bool dangerous, const char* server);
|
||||||
extern char * litelib_execute (const char* s, const char* args);
|
extern char * litelib_initialize_new_from_phrase
|
||||||
extern void litelib_rust_free_string (char* s);
|
(bool dangerous, const char* server, const char* seed,
|
||||||
|
unsigned long long birthday);
|
||||||
|
extern char * litelib_initialize_existing (bool dangerous, const char* server);
|
||||||
|
extern char * litelib_execute (const char* s, const char* args);
|
||||||
|
extern void litelib_rust_free_string (char* s);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// This is a function implemented in connection.cpp that will process a string response from
|
||||||
|
// the litelib and turn into into a QString in a memory-safe way.
|
||||||
|
QString litelib_process_response(char* resp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
109
lib/src/lib.rs
109
lib/src/lib.rs
@@ -17,11 +17,23 @@ lazy_static! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if there is an existing wallet
|
// Check if there is an existing wallet
|
||||||
|
|
||||||
|
|
||||||
// Initialize a new lightclient and store its value
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn litelib_initialze_existing(dangerous: bool, server: *const c_char) -> *mut c_char {
|
pub extern fn litelib_wallet_exists(chain_name: *const c_char) -> bool {
|
||||||
|
let chain_name_str = unsafe {
|
||||||
|
assert!(!chain_name.is_null());
|
||||||
|
|
||||||
|
CStr::from_ptr(chain_name).to_string_lossy().into_owned()
|
||||||
|
};
|
||||||
|
|
||||||
|
let config = LightClientConfig::create_unconnected(chain_name_str, None);
|
||||||
|
|
||||||
|
println!("Wallet exists: {}", config.wallet_exists());
|
||||||
|
config.wallet_exists()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new wallet and return the seed for the newly created wallet.
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern fn litelib_initialize_new(dangerous: bool, server: *const c_char) -> *mut c_char {
|
||||||
let server_str = unsafe {
|
let server_str = unsafe {
|
||||||
assert!(!server.is_null());
|
assert!(!server.is_null());
|
||||||
|
|
||||||
@@ -38,8 +50,95 @@ pub extern fn litelib_initialze_existing(dangerous: bool, server: *const c_char)
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let lightclient = match LightClient::new(&config, latest_block_height) {
|
||||||
|
Ok(l) => l,
|
||||||
|
Err(e) => {
|
||||||
|
let e_str = CString::new(format!("Error: {}", e)).unwrap();
|
||||||
|
return e_str.into_raw();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let lightclient = match LightClient::read_from_disk(&config) {
|
let seed = match lightclient.do_seed_phrase() {
|
||||||
|
Ok(s) => s.dump(),
|
||||||
|
Err(e) => {
|
||||||
|
let e_str = CString::new(format!("Error: {}", e)).unwrap();
|
||||||
|
return e_str.into_raw();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
LIGHTCLIENT.lock().unwrap().replace(Some(lightclient));
|
||||||
|
|
||||||
|
// Return the wallet's seed
|
||||||
|
let s_str = CString::new(seed).unwrap();
|
||||||
|
return s_str.into_raw();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Restore a wallet from the seed phrase
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern fn litelib_initialize_new_from_phrase(dangerous: bool, server: *const c_char,
|
||||||
|
seed: *const c_char, birthday: u64) -> *mut c_char {
|
||||||
|
let server_str = unsafe {
|
||||||
|
assert!(!server.is_null());
|
||||||
|
|
||||||
|
CStr::from_ptr(server).to_string_lossy().into_owned()
|
||||||
|
};
|
||||||
|
|
||||||
|
let seed_str = unsafe {
|
||||||
|
assert!(!seed.is_null());
|
||||||
|
|
||||||
|
CStr::from_ptr(seed).to_string_lossy().into_owned()
|
||||||
|
};
|
||||||
|
|
||||||
|
let server = LightClientConfig::get_server_or_default(Some(server_str));
|
||||||
|
let (config, _latest_block_height) = match LightClientConfig::create(server, dangerous) {
|
||||||
|
Ok((c, h)) => (c, h),
|
||||||
|
Err(e) => {
|
||||||
|
let e_str = CString::new(format!("Error: {}", e)).unwrap();
|
||||||
|
return e_str.into_raw();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let lightclient = match LightClient::new_from_phrase(seed_str, &config, birthday) {
|
||||||
|
Ok(l) => l,
|
||||||
|
Err(e) => {
|
||||||
|
let e_str = CString::new(format!("Error: {}", e)).unwrap();
|
||||||
|
return e_str.into_raw();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let seed = match lightclient.do_seed_phrase() {
|
||||||
|
Ok(s) => s.dump(),
|
||||||
|
Err(e) => {
|
||||||
|
let e_str = CString::new(format!("Error: {}", e)).unwrap();
|
||||||
|
return e_str.into_raw();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
LIGHTCLIENT.lock().unwrap().replace(Some(lightclient));
|
||||||
|
|
||||||
|
let c_str = CString::new("OK").unwrap();
|
||||||
|
return c_str.into_raw();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize a new lightclient and store its value
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern fn litelib_initialize_existing(dangerous: bool, server: *const c_char) -> *mut c_char {
|
||||||
|
let server_str = unsafe {
|
||||||
|
assert!(!server.is_null());
|
||||||
|
|
||||||
|
CStr::from_ptr(server).to_string_lossy().into_owned()
|
||||||
|
};
|
||||||
|
|
||||||
|
let server = LightClientConfig::get_server_or_default(Some(server_str));
|
||||||
|
let (config, _latest_block_height) = match LightClientConfig::create(server, dangerous) {
|
||||||
|
Ok((c, h)) => (c, h),
|
||||||
|
Err(e) => {
|
||||||
|
let e_str = CString::new(format!("Error: {}", e)).unwrap();
|
||||||
|
return e_str.into_raw();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let lightclient = match LightClient::read_from_disk(&config) {
|
||||||
Ok(l) => l,
|
Ok(l) => l,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let e_str = CString::new(format!("Error: {}", e)).unwrap();
|
let e_str = CString::new(format!("Error: {}", e)).unwrap();
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ UI_DIR = src
|
|||||||
CONFIG += c++14
|
CONFIG += c++14
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
src/firsttimewizard.cpp \
|
||||||
src/main.cpp \
|
src/main.cpp \
|
||||||
src/mainwindow.cpp \
|
src/mainwindow.cpp \
|
||||||
src/balancestablemodel.cpp \
|
src/balancestablemodel.cpp \
|
||||||
@@ -62,6 +63,7 @@ SOURCES += \
|
|||||||
src/liteinterface.cpp
|
src/liteinterface.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
|
src/firsttimewizard.h \
|
||||||
src/mainwindow.h \
|
src/mainwindow.h \
|
||||||
src/precompiled.h \
|
src/precompiled.h \
|
||||||
src/balancestablemodel.h \
|
src/balancestablemodel.h \
|
||||||
@@ -91,7 +93,10 @@ HEADERS += \
|
|||||||
FORMS += \
|
FORMS += \
|
||||||
src/mainwindow.ui \
|
src/mainwindow.ui \
|
||||||
src/migration.ui \
|
src/migration.ui \
|
||||||
|
src/newseed.ui \
|
||||||
|
src/newwallet.ui \
|
||||||
src/recurringpayments.ui \
|
src/recurringpayments.ui \
|
||||||
|
src/restoreseed.ui \
|
||||||
src/settings.ui \
|
src/settings.ui \
|
||||||
src/about.ui \
|
src/about.ui \
|
||||||
src/confirm.ui \
|
src/confirm.ui \
|
||||||
|
|||||||
BIN
silentdragonlite
BIN
silentdragonlite
Binary file not shown.
@@ -2,9 +2,11 @@
|
|||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "ui_connection.h"
|
#include "ui_connection.h"
|
||||||
|
#include "firsttimewizard.h"
|
||||||
#include "ui_createhushconfdialog.h"
|
#include "ui_createhushconfdialog.h"
|
||||||
#include "controller.h"
|
#include "controller.h"
|
||||||
|
|
||||||
|
|
||||||
#include "../lib/silentdragonlitelib.h"
|
#include "../lib/silentdragonlitelib.h"
|
||||||
|
|
||||||
#include "precompiled.h"
|
#include "precompiled.h"
|
||||||
@@ -42,7 +44,15 @@ void ConnectionLoader::doAutoConnect() {
|
|||||||
|
|
||||||
// Initialize the library
|
// Initialize the library
|
||||||
main->logger->write(QObject::tr("Attempting to initialize"));
|
main->logger->write(QObject::tr("Attempting to initialize"));
|
||||||
litelib_initialze_existing(config->dangerous, config->server.toStdString().c_str());
|
|
||||||
|
// Check to see if there's an existing wallet
|
||||||
|
if (litelib_wallet_exists(Settings::getChainName().toStdString().c_str())) {
|
||||||
|
main->logger->write(QObject::tr("Using existing wallet."));
|
||||||
|
litelib_initialize_existing(config->dangerous, config->server.toStdString().c_str());
|
||||||
|
} else {
|
||||||
|
main->logger->write(QObject::tr("Create/restore wallet."));
|
||||||
|
createOrRestore(config->dangerous, config->server);
|
||||||
|
}
|
||||||
|
|
||||||
auto connection = makeConnection(config);
|
auto connection = makeConnection(config);
|
||||||
|
|
||||||
@@ -54,6 +64,16 @@ void ConnectionLoader::doAutoConnect() {
|
|||||||
}, [=](auto err) {});
|
}, [=](auto err) {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConnectionLoader::createOrRestore(bool dangerous, QString server) {
|
||||||
|
// Close the startup dialog, since we'll be showing the wizard
|
||||||
|
d->hide();
|
||||||
|
|
||||||
|
// Create a wizard
|
||||||
|
FirstTimeWizard wizard(dangerous, server);
|
||||||
|
|
||||||
|
wizard.exec();
|
||||||
|
}
|
||||||
|
|
||||||
void ConnectionLoader::doRPCSetConnection(Connection* conn) {
|
void ConnectionLoader::doRPCSetConnection(Connection* conn) {
|
||||||
rpc->setConnection(conn);
|
rpc->setConnection(conn);
|
||||||
|
|
||||||
@@ -94,15 +114,7 @@ void ConnectionLoader::showError(QString explanation) {
|
|||||||
d->close();
|
d->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString litelib_process_response(char* resp) {
|
||||||
|
|
||||||
/***********************************************************************************
|
|
||||||
* Connection, Executor and Callback Class
|
|
||||||
************************************************************************************/
|
|
||||||
void Executor::run() {
|
|
||||||
char* resp = litelib_execute(this->cmd.toStdString().c_str(), this->args.toStdString().c_str());
|
|
||||||
|
|
||||||
// Copy the string, since we need to return this back to rust
|
|
||||||
char* resp_copy = new char[strlen(resp) + 1];
|
char* resp_copy = new char[strlen(resp) + 1];
|
||||||
strcpy(resp_copy, resp);
|
strcpy(resp_copy, resp);
|
||||||
litelib_rust_free_string(resp);
|
litelib_rust_free_string(resp);
|
||||||
@@ -111,6 +123,17 @@ void Executor::run() {
|
|||||||
memset(resp_copy, '-', strlen(resp_copy));
|
memset(resp_copy, '-', strlen(resp_copy));
|
||||||
delete[] resp_copy;
|
delete[] resp_copy;
|
||||||
|
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************************
|
||||||
|
* Connection, Executor and Callback Class
|
||||||
|
************************************************************************************/
|
||||||
|
void Executor::run() {
|
||||||
|
char* resp = litelib_execute(this->cmd.toStdString().c_str(), this->args.toStdString().c_str());
|
||||||
|
|
||||||
|
QString reply = litelib_process_response(resp);
|
||||||
|
|
||||||
qDebug() << "Reply=" << reply;
|
qDebug() << "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()) {
|
||||||
@@ -126,8 +149,6 @@ void Executor::run() {
|
|||||||
|
|
||||||
|
|
||||||
void Callback::processRPCCallback(json resp) {
|
void Callback::processRPCCallback(json resp) {
|
||||||
const bool isGuiThread = QThread::currentThread() == QCoreApplication::instance()->thread();
|
|
||||||
qDebug() << "Doing RPC callback: isGUI=" << isGuiThread;
|
|
||||||
this->cb(resp);
|
this->cb(resp);
|
||||||
|
|
||||||
// Destroy self
|
// Destroy self
|
||||||
@@ -135,8 +156,6 @@ void Callback::processRPCCallback(json resp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Callback::processError(QString resp) {
|
void Callback::processError(QString resp) {
|
||||||
const bool isGuiThread = QThread::currentThread() == QCoreApplication::instance()->thread();
|
|
||||||
qDebug() << "Doing RPC callback: isGUI=" << isGuiThread;
|
|
||||||
this->errCb(resp);
|
this->errCb(resp);
|
||||||
|
|
||||||
// Destroy self
|
// Destroy self
|
||||||
@@ -158,9 +177,7 @@ void Connection::doRPC(const QString cmd, const QString args, const std::functio
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool isGuiThread =
|
qDebug() << "Doing RPC: " << cmd;
|
||||||
QThread::currentThread() == QCoreApplication::instance()->thread();
|
|
||||||
qDebug() << "Doing RPC: isGUI=" << isGuiThread;
|
|
||||||
|
|
||||||
// Create a runner.
|
// Create a runner.
|
||||||
auto runner = new Executor(cmd, args);
|
auto runner = new Executor(cmd, args);
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ private:
|
|||||||
|
|
||||||
void doAutoConnect();
|
void doAutoConnect();
|
||||||
|
|
||||||
|
void createOrRestore(bool dangerous, QString server);
|
||||||
|
|
||||||
void showError(QString explanation);
|
void showError(QString explanation);
|
||||||
void showInformation(QString info, QString detail = "");
|
void showInformation(QString info, QString detail = "");
|
||||||
|
|
||||||
|
|||||||
@@ -417,7 +417,7 @@ void Controller::executeTransaction(Tx tx,
|
|||||||
std::cout << std::setw(2) << params << std::endl;
|
std::cout << std::setw(2) << params << std::endl;
|
||||||
|
|
||||||
zrpc->sendTransaction(QString::fromStdString(params.dump()), [=](const json& reply) {
|
zrpc->sendTransaction(QString::fromStdString(params.dump()), [=](const json& reply) {
|
||||||
if (reply["result"].is_null() || reply["result"] != "success") {
|
if (reply.find("txid") == reply.end()) {
|
||||||
error("", "Couldn't understand Response: " + QString::fromStdString(reply.dump()));
|
error("", "Couldn't understand Response: " + QString::fromStdString(reply.dump()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
151
src/firsttimewizard.cpp
Normal file
151
src/firsttimewizard.cpp
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
#include "firsttimewizard.h"
|
||||||
|
|
||||||
|
#include "ui_newseed.h"
|
||||||
|
#include "ui_restoreseed.h"
|
||||||
|
#include "ui_newwallet.h"
|
||||||
|
|
||||||
|
#include "../lib/silentdragonlitelib.h"
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
FirstTimeWizard::FirstTimeWizard(bool dangerous, QString server)
|
||||||
|
{
|
||||||
|
setWindowTitle("New wallet wizard");
|
||||||
|
this->dangerous = dangerous;
|
||||||
|
this->server = server;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NewOrRestorePage::NewOrRestorePage(FirstTimeWizard *parent) : QWizardPage(parent) {
|
||||||
|
setTitle("Create or Restore wallet.");
|
||||||
|
|
||||||
|
QWidget* pageWidget = new QWidget();
|
||||||
|
Ui_CreateWalletForm form;
|
||||||
|
form.setupUi(pageWidget);
|
||||||
|
|
||||||
|
// Exclusive buttons
|
||||||
|
QObject::connect(form.radioNewWallet, &QRadioButton::clicked, [=](bool checked) {
|
||||||
|
if (checked) {
|
||||||
|
form.radioRestoreWallet->setChecked(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
QObject::connect(form.radioRestoreWallet, &QRadioButton::clicked, [=](bool checked) {
|
||||||
|
if (checked) {
|
||||||
|
form.radioNewWallet->setChecked(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
form.radioNewWallet->setChecked(true);
|
||||||
|
|
||||||
|
registerField("intro.new", form.radioNewWallet);
|
||||||
|
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout;
|
||||||
|
layout->addWidget(pageWidget);
|
||||||
|
setLayout(layout);
|
||||||
|
setCommitPage(true);
|
||||||
|
setButtonText(QWizard::CommitButton, "Next");
|
||||||
|
}
|
||||||
|
|
||||||
|
NewSeedPage::NewSeedPage(FirstTimeWizard *parent) : QWizardPage(parent) {
|
||||||
|
this->parent = parent;
|
||||||
|
|
||||||
|
setTitle("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.
|
||||||
|
char* resp = litelib_initialize_new(parent->dangerous, parent->server.toStdString().c_str());
|
||||||
|
QString 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 seed = QString::fromStdString(parsed["seed"].get<json::string_t>());
|
||||||
|
form.txtSeed->setPlainText(seed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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() {
|
||||||
|
char* resp = litelib_execute("save", "");
|
||||||
|
QString reply = litelib_process_response(resp);
|
||||||
|
|
||||||
|
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" + reply,
|
||||||
|
QMessageBox::Ok);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RestoreSeedPage::RestoreSeedPage(FirstTimeWizard *parent) : QWizardPage(parent) {
|
||||||
|
this->parent = parent;
|
||||||
|
|
||||||
|
setTitle("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]+"), " ");
|
||||||
|
if (seed.trimmed().split(" ").length() != 24) {
|
||||||
|
QMessageBox::warning(this, tr("Failed to restore wallet"),
|
||||||
|
tr("SilentDragonLite needs 24 words to restore wallet"),
|
||||||
|
QMessageBox::Ok);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Attempt to restore wallet with the seed phrase
|
||||||
|
char* resp = litelib_initialize_new_from_phrase(parent->dangerous, parent->server.toStdString().c_str(),
|
||||||
|
seed.toStdString().c_str(), 0);
|
||||||
|
QString reply = litelib_process_response(resp);
|
||||||
|
|
||||||
|
if (reply.toUpper().trimmed() != "OK") {
|
||||||
|
QMessageBox::warning(this, tr("Failed to restore wallet"),
|
||||||
|
tr("Couldn't restore the wallet") + "\n" + reply,
|
||||||
|
QMessageBox::Ok);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
66
src/firsttimewizard.h
Normal file
66
src/firsttimewizard.h
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
#ifndef FIRSTTIMEWIZARD_H
|
||||||
|
#define FIRSTTIMEWIZARD_H
|
||||||
|
|
||||||
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
#include "ui_newseed.h"
|
||||||
|
#include "ui_restoreseed.h"
|
||||||
|
|
||||||
|
class FirstTimeWizard: public QWizard
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FirstTimeWizard(bool dangerous, QString server);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int nextId() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum {
|
||||||
|
Page_NewOrRestore,
|
||||||
|
Page_New,
|
||||||
|
Page_Restore
|
||||||
|
};
|
||||||
|
|
||||||
|
bool dangerous;
|
||||||
|
QString server;
|
||||||
|
|
||||||
|
friend class NewOrRestorePage;
|
||||||
|
friend class NewSeedPage;
|
||||||
|
friend class RestoreSeedPage;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NewOrRestorePage: public QWizardPage {
|
||||||
|
public:
|
||||||
|
NewOrRestorePage(FirstTimeWizard* parent);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class NewSeedPage: public QWizardPage {
|
||||||
|
public:
|
||||||
|
NewSeedPage(FirstTimeWizard* parent);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void initializePage();
|
||||||
|
virtual bool validatePage();
|
||||||
|
|
||||||
|
private:
|
||||||
|
FirstTimeWizard* parent;
|
||||||
|
Ui_NewSeedForm form;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class RestoreSeedPage: public QWizardPage {
|
||||||
|
public:
|
||||||
|
RestoreSeedPage(FirstTimeWizard* parent);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool validatePage();
|
||||||
|
|
||||||
|
private:
|
||||||
|
FirstTimeWizard* parent;
|
||||||
|
Ui_RestoreSeedForm form;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // FIRSTTIMEWIZARD_H
|
||||||
@@ -17,7 +17,7 @@ using json = nlohmann::json;
|
|||||||
// Struct used to hold destination info when sending a Tx.
|
// Struct used to hold destination info when sending a Tx.
|
||||||
struct ToFields {
|
struct ToFields {
|
||||||
QString addr;
|
QString addr;
|
||||||
double amount;
|
qint64 amount;
|
||||||
QString memo;
|
QString memo;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ struct ToFields {
|
|||||||
struct Tx {
|
struct Tx {
|
||||||
QString fromAddr;
|
QString fromAddr;
|
||||||
QList<ToFields> toAddrs;
|
QList<ToFields> toAddrs;
|
||||||
double fee;
|
qint64 fee;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|||||||
63
src/newseed.ui
Normal file
63
src/newseed.ui
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>NewSeedForm</class>
|
||||||
|
<widget class="QWidget" name="NewSeedForm">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>This is your new wallet's seed phrase. PLEASE BACK IT UP SECURELY.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>The seed phrase is the only way to restore the wallet. If you forget the seed phrase, THERE IS NO WAY TO RESTORE YOUR WALLET AND THE FUNDS in it</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPlainTextEdit" name="txtSeed">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
85
src/newwallet.ui
Normal file
85
src/newwallet.ui
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>CreateWalletForm</class>
|
||||||
|
<widget class="QWidget" name="CreateWalletForm">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_3">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QRadioButton" name="radioRestoreWallet">
|
||||||
|
<property name="text">
|
||||||
|
<string>Restore wallet from seed</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Restore an existing wallet, using the 24-word seed. </string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QRadioButton" name="radioNewWallet">
|
||||||
|
<property name="text">
|
||||||
|
<string>Create a new Wallet</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Create a new wallet with a randomly generated seed.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
@@ -17,6 +17,8 @@
|
|||||||
#include <QAbstractTableModel>
|
#include <QAbstractTableModel>
|
||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
|
#include <QWizard>
|
||||||
|
#include <QWizardPage>
|
||||||
#include <QStringBuilder>
|
#include <QStringBuilder>
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
#include <QTableView>
|
#include <QTableView>
|
||||||
|
|||||||
53
src/restoreseed.ui
Normal file
53
src/restoreseed.ui
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>RestoreSeedForm</class>
|
||||||
|
<widget class="QWidget" name="RestoreSeedForm">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Please enter your 24-word seed below</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPlainTextEdit" name="txtSeed">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
@@ -315,7 +315,7 @@ bool Settings::removeFromhushConf(QString confLocation, QString option) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
double Settings::getMinerFee() {
|
double Settings::getMinerFee() {
|
||||||
return 0.0001;
|
return 10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
double Settings::getZboardAmount() {
|
double Settings::getZboardAmount() {
|
||||||
|
|||||||
@@ -119,6 +119,8 @@ public:
|
|||||||
static bool addTohushConf(QString confLocation, QString line);
|
static bool addTohushConf(QString confLocation, QString line);
|
||||||
static bool removeFromhushConf(QString confLocation, QString option);
|
static bool removeFromhushConf(QString confLocation, QString option);
|
||||||
|
|
||||||
|
static QString getChainName() { return QString("test"); }
|
||||||
|
|
||||||
static const QString labelRegExp;
|
static const QString labelRegExp;
|
||||||
|
|
||||||
static const int updateSpeed = 20 * 1000; // 10 sec
|
static const int updateSpeed = 20 * 1000; // 10 sec
|
||||||
|
|||||||
Reference in New Issue
Block a user