+2
-2
@@ -18,10 +18,10 @@ script:
|
|||||||
- qmake -v
|
- qmake -v
|
||||||
- clang++ -v
|
- clang++ -v
|
||||||
- g++-8 -v
|
- g++-8 -v
|
||||||
- qmake hush-qt-wallet.pro CONFIG+=release -spec linux-clang
|
- qmake silentdragon-lite.pro CONFIG+=release -spec linux-clang
|
||||||
- make CC=clang CXX=clang++ -j2
|
- make CC=clang CXX=clang++ -j2
|
||||||
- make distclean
|
- make distclean
|
||||||
- qmake hush-qt-wallet.pro CONFIG+=release -spec linux-g++
|
- qmake silentdragon-lite.pro CONFIG+=release -spec linux-g++
|
||||||
- res/libsodium/buildlibsodium.sh
|
- res/libsodium/buildlibsodium.sh
|
||||||
- make CC=gcc-8 CXX=g++-8 -j2
|
- make CC=gcc-8 CXX=g++-8 -j2
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
[{"excluded":[],"includePaths":["/home/denio/silentdragon-lite/src/3rdparty","/home/denio/silentdragon-lite/src","/home/denio/silentdragon-lite/singleapplication","/home/denio/silentdragon-lite/res","/home/denio/Qt5.13.1/5.13.1/gcc_64/include","/home/denio/Qt5.13.1/5.13.1/gcc_64/include/QtWidgets","/home/denio/Qt5.13.1/5.13.1/gcc_64/include/QtGui","/home/denio/Qt5.13.1/5.13.1/gcc_64/include/QtWebSockets","/home/denio/Qt5.13.1/5.13.1/gcc_64/include/QtNetwork","/home/denio/Qt5.13.1/5.13.1/gcc_64/include/QtCore","/home/denio/silentdragon-lite/bin","/usr/include/libdrm","/home/denio/silentdragon-lite/src"],"projectFile":"/home/denio/silentdragon-lite/silentdragon-lite.pro","sources":["/home/denio/silentdragon-lite/lib/silentdragonlitelib.h","/home/denio/silentdragon-lite/singleapplication/singleapplication.cpp","/home/denio/silentdragon-lite/singleapplication/singleapplication.h","/home/denio/silentdragon-lite/singleapplication/singleapplication_p.cpp","/home/denio/silentdragon-lite/singleapplication/singleapplication_p.h","/home/denio/silentdragon-lite/src/3rdparty/json/json.hpp","/home/denio/silentdragon-lite/src/3rdparty/qrcode/BitBuffer.cpp","/home/denio/silentdragon-lite/src/3rdparty/qrcode/BitBuffer.hpp","/home/denio/silentdragon-lite/src/3rdparty/qrcode/QrCode.cpp","/home/denio/silentdragon-lite/src/3rdparty/qrcode/QrCode.hpp","/home/denio/silentdragon-lite/src/3rdparty/qrcode/QrSegment.cpp","/home/denio/silentdragon-lite/src/3rdparty/qrcode/QrSegment.hpp","/home/denio/silentdragon-lite/src/about.ui","/home/denio/silentdragon-lite/src/addressbook.cpp","/home/denio/silentdragon-lite/src/addressbook.h","/home/denio/silentdragon-lite/src/addressbook.ui","/home/denio/silentdragon-lite/src/addresscombo.cpp","/home/denio/silentdragon-lite/src/addresscombo.h","/home/denio/silentdragon-lite/src/balancestablemodel.cpp","/home/denio/silentdragon-lite/src/balancestablemodel.h","/home/denio/silentdragon-lite/src/confirm.ui","/home/denio/silentdragon-lite/src/connection.cpp","/home/denio/silentdragon-lite/src/connection.h","/home/denio/silentdragon-lite/src/connection.ui","/home/denio/silentdragon-lite/src/controller.cpp","/home/denio/silentdragon-lite/src/controller.h","/home/denio/silentdragon-lite/src/createhushconfdialog.ui","/home/denio/silentdragon-lite/src/datamodel.cpp","/home/denio/silentdragon-lite/src/datamodel.h","/home/denio/silentdragon-lite/src/fillediconlabel.cpp","/home/denio/silentdragon-lite/src/fillediconlabel.h","/home/denio/silentdragon-lite/src/liteinterface.cpp","/home/denio/silentdragon-lite/src/liteinterface.h","/home/denio/silentdragon-lite/src/logger.cpp","/home/denio/silentdragon-lite/src/logger.h","/home/denio/silentdragon-lite/src/main.cpp","/home/denio/silentdragon-lite/src/mainwindow.cpp","/home/denio/silentdragon-lite/src/mainwindow.h","/home/denio/silentdragon-lite/src/mainwindow.ui","/home/denio/silentdragon-lite/src/memodialog.ui","/home/denio/silentdragon-lite/src/memoedit.cpp","/home/denio/silentdragon-lite/src/memoedit.h","/home/denio/silentdragon-lite/src/migration.ui","/home/denio/silentdragon-lite/src/mobileappconnector.cpp","/home/denio/silentdragon-lite/src/mobileappconnector.h","/home/denio/silentdragon-lite/src/mobileappconnector.ui","/home/denio/silentdragon-lite/src/newrecurring.ui","/home/denio/silentdragon-lite/src/precompiled.h","/home/denio/silentdragon-lite/src/privkey.ui","/home/denio/silentdragon-lite/src/qrcodelabel.cpp","/home/denio/silentdragon-lite/src/qrcodelabel.h","/home/denio/silentdragon-lite/src/recurring.cpp","/home/denio/silentdragon-lite/src/recurring.h","/home/denio/silentdragon-lite/src/recurringdialog.ui","/home/denio/silentdragon-lite/src/recurringmultiple.ui","/home/denio/silentdragon-lite/src/recurringpayments.ui","/home/denio/silentdragon-lite/src/requestdialog.cpp","/home/denio/silentdragon-lite/src/requestdialog.h","/home/denio/silentdragon-lite/src/requestdialog.ui","/home/denio/silentdragon-lite/src/sendtab.cpp","/home/denio/silentdragon-lite/src/settings.cpp","/home/denio/silentdragon-lite/src/settings.h","/home/denio/silentdragon-lite/src/settings.ui","/home/denio/silentdragon-lite/src/txtablemodel.cpp","/home/denio/silentdragon-lite/src/txtablemodel.h","/home/denio/silentdragon-lite/src/viewalladdresses.cpp","/home/denio/silentdragon-lite/src/viewalladdresses.h","/home/denio/silentdragon-lite/src/viewalladdresses.ui","/home/denio/silentdragon-lite/src/websockets.cpp","/home/denio/silentdragon-lite/src/websockets.h"],"translations":["/home/denio/silentdragon-lite/res/zec_qt_wallet_es.ts","/home/denio/silentdragon-lite/res/zec_qt_wallet_fr.ts","/home/denio/silentdragon-lite/res/zec_qt_wallet_de.ts","/home/denio/silentdragon-lite/res/zec_qt_wallet_pt.ts","/home/denio/silentdragon-lite/res/zec_qt_wallet_it.ts","/home/denio/silentdragon-lite/res/zec_qt_wallet_zh.ts","/home/denio/silentdragon-lite/res/zec_qt_wallet_tr.ts","/home/denio/silentdragon-lite/res/zec_qt_wallet_template.ts"]}]
|
||||||
+1
-6
@@ -13,12 +13,7 @@
|
|||||||
<file>res/logobig.gif</file>
|
<file>res/logobig.gif</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
<qresource prefix="/translations">
|
<qresource prefix="/translations">
|
||||||
<file>res/zec_qt_wallet_es.qm</file>
|
<file>res/zec_qt_wallet_de.qm</file>
|
||||||
<file>res/zec_qt_wallet_fr.qm</file>
|
|
||||||
<file>res/zec_qt_wallet_pt.qm</file>
|
|
||||||
<file>res/zec_qt_wallet_it.qm</file>
|
|
||||||
<file>res/zec_qt_wallet_zh.qm</file>
|
|
||||||
<file>res/zec_qt_wallet_tr.qm</file>
|
|
||||||
</qresource>
|
</qresource>
|
||||||
<qresource prefix="/css">
|
<qresource prefix="/css">
|
||||||
<file>res/css/blue.css</file>
|
<file>res/css/blue.css</file>
|
||||||
|
|||||||
Generated
+3
-3
@@ -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=11d5d15e8b03c0a5b6eae1af00ac17fb7660a004)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[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=11d5d15e8b03c0a5b6eae1af00ac17fb7660a004#11d5d15e8b03c0a5b6eae1af00ac17fb7660a004"
|
||||||
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=11d5d15e8b03c0a5b6eae1af00ac17fb7660a004)" = "<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"
|
||||||
|
|||||||
+1
-1
@@ -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 = "11d5d15e8b03c0a5b6eae1af00ac17fb7660a004" }
|
||||||
|
|||||||
@@ -5,13 +5,21 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern bool litelib_wallet_exists (const char* chain_name, const char* dir);
|
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
|
||||||
|
|||||||
+120
-17
@@ -4,7 +4,7 @@ extern crate lazy_static;
|
|||||||
use libc::{c_char};
|
use libc::{c_char};
|
||||||
|
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
use std::sync::{Mutex};
|
use std::sync::{Mutex, Arc};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
use silentdragonlitelib::{commands, lightclient::{LightClient, LightClientConfig}};
|
use silentdragonlitelib::{commands, lightclient::{LightClient, LightClientConfig}};
|
||||||
@@ -13,32 +13,130 @@ use silentdragonlitelib::{commands, lightclient::{LightClient, LightClientConfig
|
|||||||
// so we don't have to keep creating it. We need to store it here, in rust
|
// so we don't have to keep creating it. We need to store it here, in rust
|
||||||
// because we can't return such a complex structure back to C++
|
// because we can't return such a complex structure back to C++
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref LIGHTCLIENT: Mutex<RefCell<Option<LightClient>>> = Mutex::new(RefCell::new(None));
|
static ref LIGHTCLIENT: Mutex<RefCell<Option<Arc<LightClient>>>> = Mutex::new(RefCell::new(None));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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());
|
||||||
|
|
||||||
CStr::from_ptr(server).to_string_lossy().into_owned()
|
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::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 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(Arc::new(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 server = LightClientConfig::get_server_or_default(Some(server_str));
|
||||||
let (config, _latest_block_height) = match LightClientConfig::create(server, dangerous) {
|
let (config, _latest_block_height) = match LightClientConfig::create(server, dangerous) {
|
||||||
Ok((c, h)) => (c, h),
|
Ok((c, h)) => (c, h),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let e_str = CString::new(format!("Error: {}", e)).unwrap();
|
let e_str = CString::new(format!("Error: {}", e)).unwrap();
|
||||||
return e_str.into_raw();
|
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(Arc::new(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) {
|
let lightclient = match LightClient::read_from_disk(&config) {
|
||||||
Ok(l) => l,
|
Ok(l) => l,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -47,7 +145,7 @@ pub extern fn litelib_initialze_existing(dangerous: bool, server: *const c_char)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
LIGHTCLIENT.lock().unwrap().replace(Some(lightclient));
|
LIGHTCLIENT.lock().unwrap().replace(Some(Arc::new(lightclient)));
|
||||||
|
|
||||||
let c_str = CString::new("OK").unwrap();
|
let c_str = CString::new("OK").unwrap();
|
||||||
return c_str.into_raw();
|
return c_str.into_raw();
|
||||||
@@ -69,16 +167,21 @@ pub extern fn litelib_execute(cmd: *const c_char, args: *const c_char) -> *mut c
|
|||||||
|
|
||||||
let resp: String;
|
let resp: String;
|
||||||
{
|
{
|
||||||
let lc = LIGHTCLIENT.lock().unwrap();
|
let lightclient: Arc<LightClient>;
|
||||||
|
{
|
||||||
|
let lc = LIGHTCLIENT.lock().unwrap();
|
||||||
|
|
||||||
if lc.borrow().is_none() {
|
if lc.borrow().is_none() {
|
||||||
let e_str = CString::new("Error: Light Client is not initialized").unwrap();
|
let e_str = CString::new("Error: Light Client is not initialized").unwrap();
|
||||||
return e_str.into_raw();
|
return e_str.into_raw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lightclient = lc.borrow().as_ref().unwrap().clone();
|
||||||
|
};
|
||||||
|
|
||||||
let args = if arg_str.is_empty() { vec![] } else { vec![arg_str.as_ref()] };
|
let args = if arg_str.is_empty() { vec![] } else { vec![arg_str.as_ref()] };
|
||||||
|
|
||||||
resp = commands::do_user_command(&cmd_str, &args, lc.borrow().as_ref().unwrap()).clone();
|
resp = commands::do_user_command(&cmd_str, &args, lightclient.as_ref()).clone();
|
||||||
};
|
};
|
||||||
|
|
||||||
let c_str = CString::new(resp.as_bytes()).unwrap();
|
let c_str = CString::new(resp.as_bytes()).unwrap();
|
||||||
|
|||||||
Binary file not shown.
+537
-1003
File diff suppressed because it is too large
Load Diff
Binary file not shown.
+557
-1039
File diff suppressed because it is too large
Load Diff
Binary file not shown.
+316
-397
File diff suppressed because it is too large
Load Diff
Binary file not shown.
+314
-415
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
+311
-412
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -215,7 +215,7 @@
|
|||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/mainwindow.ui" line="864"/>
|
<location filename="../src/mainwindow.ui" line="864"/>
|
||||||
<source>You are currently not mining</source>
|
<source>This is a Lightwallet, you cant mine with it! not mining</source>
|
||||||
<translation type="unfinished">YOUR_TRANSLATION_HERE</translation>
|
<translation type="unfinished">YOUR_TRANSLATION_HERE</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
@@ -228,17 +228,17 @@
|
|||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/mainwindow.ui" line="891"/>
|
<location filename="../src/mainwindow.ui" line="891"/>
|
||||||
<source>Block height</source>
|
<source>Blockheight</source>
|
||||||
<translation type="unfinished">YOUR_TRANSLATION_HERE</translation>
|
<translation type="unfinished">YOUR_TRANSLATION_HERE</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/mainwindow.ui" line="905"/>
|
<location filename="../src/mainwindow.ui" line="905"/>
|
||||||
<source>Network solution rate</source>
|
<source>Version hushd light rate</source>
|
||||||
<translation type="unfinished">YOUR_TRANSLATION_HERE</translation>
|
<translation type="unfinished">YOUR_TRANSLATION_HERE</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/mainwindow.ui" line="912"/>
|
<location filename="../src/mainwindow.ui" line="912"/>
|
||||||
<source>Connections</source>
|
<source>Vendor</source>
|
||||||
<translation type="unfinished">YOUR_TRANSLATION_HERE</translation>
|
<translation type="unfinished">YOUR_TRANSLATION_HERE</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
@@ -659,7 +659,7 @@ Not starting embedded hushd because --no-embedded was passed</source>
|
|||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/rpc.cpp" line="578"/>
|
<location filename="../src/rpc.cpp" line="578"/>
|
||||||
<source>Block height</source>
|
<source>Blockheight</source>
|
||||||
<translation type="unfinished">YOUR_TRANSLATION_HERE</translation>
|
<translation type="unfinished">YOUR_TRANSLATION_HERE</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
|
|||||||
Binary file not shown.
+334
-346
File diff suppressed because it is too large
Load Diff
Binary file not shown.
+326
-369
File diff suppressed because it is too large
Load Diff
@@ -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 \
|
||||||
@@ -115,6 +120,7 @@ TRANSLATIONS = res/zec_qt_wallet_es.ts \
|
|||||||
res/zec_qt_wallet_it.ts \
|
res/zec_qt_wallet_it.ts \
|
||||||
res/zec_qt_wallet_zh.ts \
|
res/zec_qt_wallet_zh.ts \
|
||||||
res/zec_qt_wallet_tr.ts
|
res/zec_qt_wallet_tr.ts
|
||||||
|
|
||||||
|
|
||||||
include(singleapplication/singleapplication.pri)
|
include(singleapplication/singleapplication.pri)
|
||||||
DEFINES += QAPPLICATION_CLASS=QApplication
|
DEFINES += QAPPLICATION_CLASS=QApplication
|
||||||
|
|||||||
Executable
BIN
Binary file not shown.
@@ -2,12 +2,11 @@
|
|||||||
#include "addressbook.h"
|
#include "addressbook.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
|
|
||||||
BalancesTableModel::BalancesTableModel(QObject *parent)
|
BalancesTableModel::BalancesTableModel(QObject *parent)
|
||||||
: QAbstractTableModel(parent) {
|
: QAbstractTableModel(parent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BalancesTableModel::setNewData(const QMap<QString, qint64> balances,
|
void BalancesTableModel::setNewData(const QMap<QString, double> balances,
|
||||||
const QList<UnspentOutput> outputs)
|
const QList<UnspentOutput> outputs)
|
||||||
{
|
{
|
||||||
loading = false;
|
loading = false;
|
||||||
@@ -22,7 +21,7 @@ void BalancesTableModel::setNewData(const QMap<QString, qint64> balances,
|
|||||||
|
|
||||||
// Process the address balances into a list
|
// Process the address balances into a list
|
||||||
delete modeldata;
|
delete modeldata;
|
||||||
modeldata = new QList<std::tuple<QString, qint64>>();
|
modeldata = new QList<std::tuple<QString, double>>();
|
||||||
std::for_each(balances.keyBegin(), balances.keyEnd(), [=] (auto keyIt) {
|
std::for_each(balances.keyBegin(), balances.keyEnd(), [=] (auto keyIt) {
|
||||||
if (balances.value(keyIt) > 0)
|
if (balances.value(keyIt) > 0)
|
||||||
modeldata->push_back(std::make_tuple(keyIt, balances.value(keyIt)));
|
modeldata->push_back(std::make_tuple(keyIt, balances.value(keyIt)));
|
||||||
@@ -95,7 +94,7 @@ QVariant BalancesTableModel::data(const QModelIndex &index, int role) const
|
|||||||
if(role == Qt::ToolTipRole) {
|
if(role == Qt::ToolTipRole) {
|
||||||
switch (index.column()) {
|
switch (index.column()) {
|
||||||
case 0: return AddressBook::addLabelToAddress(std::get<0>(modeldata->at(index.row())));
|
case 0: return AddressBook::addLabelToAddress(std::get<0>(modeldata->at(index.row())));
|
||||||
case 1: return Settings::getUSDFromhushAmount(std::get<1>(modeldata->at(index.row())));
|
case 1: return Settings::getUSDFormat(std::get<1>(modeldata->at(index.row())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,13 +4,14 @@
|
|||||||
#include "precompiled.h"
|
#include "precompiled.h"
|
||||||
#include "datamodel.h"
|
#include "datamodel.h"
|
||||||
|
|
||||||
|
|
||||||
class BalancesTableModel : public QAbstractTableModel
|
class BalancesTableModel : public QAbstractTableModel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BalancesTableModel(QObject* parent);
|
BalancesTableModel(QObject* parent);
|
||||||
~BalancesTableModel();
|
~BalancesTableModel();
|
||||||
|
|
||||||
void setNewData(const QMap<QString, qint64> balances, const QList<UnspentOutput> outputs);
|
void setNewData(const QMap<QString, double> balances, const QList<UnspentOutput> outputs);
|
||||||
|
|
||||||
int rowCount(const QModelIndex &parent) const;
|
int rowCount(const QModelIndex &parent) const;
|
||||||
int columnCount(const QModelIndex &parent) const;
|
int columnCount(const QModelIndex &parent) const;
|
||||||
@@ -18,7 +19,7 @@ public:
|
|||||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<std::tuple<QString, qint64>>* modeldata = nullptr;
|
QList<std::tuple<QString, double>>* modeldata = nullptr;
|
||||||
QList<UnspentOutput>* utxos = nullptr;
|
QList<UnspentOutput>* utxos = nullptr;
|
||||||
|
|
||||||
bool loading = true;
|
bool loading = true;
|
||||||
|
|||||||
+82
-33
@@ -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"
|
||||||
@@ -20,9 +22,12 @@ ConnectionLoader::ConnectionLoader(MainWindow* main, Controller* rpc) {
|
|||||||
connD->setupUi(d);
|
connD->setupUi(d);
|
||||||
QPixmap logo(":/img/res/logobig.gif");
|
QPixmap logo(":/img/res/logobig.gif");
|
||||||
connD->topIcon->setBasePixmap(logo.scaled(256, 256, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
connD->topIcon->setBasePixmap(logo.scaled(256, 256, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||||
|
|
||||||
|
isSyncing = new QAtomicInteger<bool>();
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectionLoader::~ConnectionLoader() {
|
ConnectionLoader::~ConnectionLoader() {
|
||||||
|
delete isSyncing;
|
||||||
delete connD;
|
delete connD;
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
@@ -42,19 +47,77 @@ 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."));
|
||||||
|
litelib_initialize_existing(config->dangerous, config->server.toStdString().c_str());
|
||||||
|
d->show();
|
||||||
|
}
|
||||||
|
|
||||||
auto connection = makeConnection(config);
|
auto connection = makeConnection(config);
|
||||||
|
|
||||||
// After the lib is initialized, try to do get info
|
// After the lib is initialized, try to do get info
|
||||||
connection->doRPC("info", "", [=](auto reply) {
|
connection->doRPC("info", "", [=](auto reply) {
|
||||||
// If success, set the connection
|
// If success, set the connection
|
||||||
main->logger->write("Connection is online.");
|
main->logger->write("Connection is online.");
|
||||||
this->doRPCSetConnection(connection);
|
|
||||||
}, [=](auto err) {});
|
isSyncing = new QAtomicInteger<bool>();
|
||||||
|
isSyncing->store(true);
|
||||||
|
|
||||||
|
// Do a sync at startup
|
||||||
|
syncTimer = new QTimer(main);
|
||||||
|
connection->doRPCWithDefaultErrorHandling("sync", "", [=](auto) {
|
||||||
|
isSyncing->store(false);
|
||||||
|
|
||||||
|
// Cancel the timer
|
||||||
|
syncTimer->deleteLater();
|
||||||
|
|
||||||
|
// When sync is done, set the connection
|
||||||
|
this->doRPCSetConnection(connection);
|
||||||
|
});
|
||||||
|
|
||||||
|
// While it is syncing, we'll show the status updates while it is alive.
|
||||||
|
QObject::connect(syncTimer, &QTimer::timeout, [=]() {
|
||||||
|
// Check the sync status
|
||||||
|
if (isSyncing != nullptr && isSyncing->load()) {
|
||||||
|
// Get the sync status
|
||||||
|
connection->doRPC("syncstatus", "", [=](json reply) {
|
||||||
|
if (isSyncing != nullptr && reply.find("synced_blocks") != reply.end()) {
|
||||||
|
qint64 synced = reply["synced_blocks"].get<json::number_unsigned_t>();
|
||||||
|
qint64 total = reply["total_blocks"].get<json::number_unsigned_t>();
|
||||||
|
showInformation("Synced " + QString::number(synced) + " / " + QString::number(total));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[=](QString err) {
|
||||||
|
qDebug() << "Sync error" << err;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
syncTimer->setInterval(1* 1000);
|
||||||
|
syncTimer->start();
|
||||||
|
|
||||||
|
}, [=](QString err) {
|
||||||
|
showError(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) {
|
||||||
|
qDebug() << "Connectionloader finished, setting connection";
|
||||||
rpc->setConnection(conn);
|
rpc->setConnection(conn);
|
||||||
|
|
||||||
d->accept();
|
d->accept();
|
||||||
@@ -68,20 +131,9 @@ Connection* ConnectionLoader::makeConnection(std::shared_ptr<ConnectionConfig> c
|
|||||||
|
|
||||||
// Update the UI with the status
|
// Update the UI with the status
|
||||||
void ConnectionLoader::showInformation(QString info, QString detail) {
|
void ConnectionLoader::showInformation(QString info, QString detail) {
|
||||||
static int rescanCount = 0;
|
qDebug() << "Showing info " << info << ":" << detail;
|
||||||
if (detail.toLower().startsWith("rescan")) {
|
|
||||||
rescanCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rescanCount > 10) {
|
|
||||||
detail = detail + "\n" + QObject::tr("This may take several hours");
|
|
||||||
}
|
|
||||||
|
|
||||||
connD->status->setText(info);
|
connD->status->setText(info);
|
||||||
connD->statusDetail->setText(detail);
|
connD->statusDetail->setText(detail);
|
||||||
|
|
||||||
if (rescanCount < 10)
|
|
||||||
main->logger->write(info + ":" + detail);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -94,15 +146,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 +155,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 +181,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 +188,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 +209,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);
|
||||||
|
|||||||
+9
-4
@@ -33,16 +33,21 @@ 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 = "");
|
||||||
|
|
||||||
void doRPCSetConnection(Connection* conn);
|
void doRPCSetConnection(Connection* conn);
|
||||||
|
|
||||||
QDialog* d;
|
QTimer* syncTimer = nullptr;
|
||||||
Ui_ConnectionDialog* connD;
|
QAtomicInteger<bool>* isSyncing = nullptr;
|
||||||
|
|
||||||
MainWindow* main;
|
QDialog* d = nullptr;
|
||||||
Controller* rpc;
|
Ui_ConnectionDialog* connD = nullptr;
|
||||||
|
|
||||||
|
MainWindow* main = nullptr;
|
||||||
|
Controller* rpc = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+73
-146
@@ -64,7 +64,7 @@ void Controller::setConnection(Connection* c) {
|
|||||||
|
|
||||||
this->zrpc->setConnection(c);
|
this->zrpc->setConnection(c);
|
||||||
|
|
||||||
ui->statusBar->showMessage("Ready!");
|
ui->statusBar->showMessage("Your hushd is connected");
|
||||||
|
|
||||||
// See if we need to remove the reindex/rescan flags from the hush.conf file
|
// See if we need to remove the reindex/rescan flags from the hush.conf file
|
||||||
auto hushConfLocation = Settings::getInstance()->gethushdConfLocation();
|
auto hushConfLocation = Settings::getInstance()->gethushdConfLocation();
|
||||||
@@ -96,7 +96,7 @@ void Controller::fillTxJsonParams(json& allRecepients, Tx tx) {
|
|||||||
// Construct the JSON params
|
// Construct the JSON params
|
||||||
json rec = json::object();
|
json rec = json::object();
|
||||||
rec["address"] = toAddr.addr.toStdString();
|
rec["address"] = toAddr.addr.toStdString();
|
||||||
rec["amount"] = toAddr.amount;
|
rec["amount"] = toAddr.amount * 10000000;
|
||||||
if (Settings::isZAddress(toAddr.addr) && !toAddr.memo.trimmed().isEmpty())
|
if (Settings::isZAddress(toAddr.addr) && !toAddr.memo.trimmed().isEmpty())
|
||||||
rec["memo"] = toAddr.memo.toStdString();
|
rec["memo"] = toAddr.memo.toStdString();
|
||||||
|
|
||||||
@@ -120,7 +120,7 @@ void Controller::noConnection() {
|
|||||||
main->ui->statusBar->showMessage(QObject::tr("No Connection"), 1000);
|
main->ui->statusBar->showMessage(QObject::tr("No Connection"), 1000);
|
||||||
|
|
||||||
// Clear balances table.
|
// Clear balances table.
|
||||||
QMap<QString, qint64> emptyBalances;
|
QMap<QString, double> emptyBalances;
|
||||||
QList<UnspentOutput> emptyOutputs;
|
QList<UnspentOutput> emptyOutputs;
|
||||||
balancesTableModel->setNewData(emptyBalances, emptyOutputs);
|
balancesTableModel->setNewData(emptyBalances, emptyOutputs);
|
||||||
|
|
||||||
@@ -161,21 +161,25 @@ void Controller::getInfoThenRefresh(bool force) {
|
|||||||
prevCallSucceeded = true;
|
prevCallSucceeded = true;
|
||||||
|
|
||||||
// Testnet?
|
// Testnet?
|
||||||
|
QString chainName;
|
||||||
if (!reply["chain_name"].is_null()) {
|
if (!reply["chain_name"].is_null()) {
|
||||||
Settings::getInstance()->setTestnet(reply["chain_name"].get<json::string_t>() == "test");
|
chainName = QString::fromStdString(reply["chain_name"].get<json::string_t>());
|
||||||
|
Settings::getInstance()->setTestnet(chainName == "test");
|
||||||
};
|
};
|
||||||
|
|
||||||
// Recurring pamynets are testnet only
|
// Recurring pamynets are testnet only
|
||||||
if (!Settings::getInstance()->isTestnet())
|
if (!Settings::getInstance()->isTestnet())
|
||||||
main->disableRecurring();
|
main->disableRecurring();
|
||||||
|
|
||||||
// Connected, so display checkmark.
|
|
||||||
QIcon i(":/icons/res/connected.gif");
|
|
||||||
main->statusIcon->setPixmap(i.pixmap(16, 16));
|
|
||||||
|
|
||||||
static int lastBlock = 0;
|
static int lastBlock = 0;
|
||||||
int curBlock = reply["latest_block_height"].get<json::number_integer_t>();
|
int curBlock = reply["latest_block_height"].get<json::number_integer_t>();
|
||||||
model->setLatestBlock(curBlock);
|
model->setLatestBlock(curBlock);
|
||||||
|
|
||||||
|
// Connected, so display checkmark.
|
||||||
|
QIcon i(":/icons/res/connected.gif");
|
||||||
|
main->statusLabel->setText(chainName + "(" + QString::number(curBlock) + ")");
|
||||||
|
main->statusIcon->setPixmap(i.pixmap(16, 16));
|
||||||
|
|
||||||
//int version = reply["version"].get<json::string_t>();
|
//int version = reply["version"].get<json::string_t>();
|
||||||
int version = 1;
|
int version = 1;
|
||||||
Settings::getInstance()->sethushdVersion(version);
|
Settings::getInstance()->sethushdVersion(version);
|
||||||
@@ -251,7 +255,7 @@ void Controller::updateUI(bool anyUnconfirmed) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Function to process reply of the listunspent and z_listunspent API calls, used below.
|
// Function to process reply of the listunspent and z_listunspent API calls, used below.
|
||||||
bool Controller::processUnspent(const json& reply, QMap<QString, qint64>* balancesMap, QList<UnspentOutput>* newUtxos) {
|
bool Controller::processUnspent(const json& reply, QMap<QString, double>* balancesMap, QList<UnspentOutput>* newUtxos) {
|
||||||
bool anyUnconfirmed = false;
|
bool anyUnconfirmed = false;
|
||||||
|
|
||||||
auto processFn = [=](const json& array) {
|
auto processFn = [=](const json& array) {
|
||||||
@@ -259,11 +263,11 @@ bool Controller::processUnspent(const json& reply, QMap<QString, qint64>* balanc
|
|||||||
QString qsAddr = QString::fromStdString(it["address"]);
|
QString qsAddr = QString::fromStdString(it["address"]);
|
||||||
int block = it["created_in_block"].get<json::number_unsigned_t>();
|
int block = it["created_in_block"].get<json::number_unsigned_t>();
|
||||||
QString txid = QString::fromStdString(it["created_in_txid"]);
|
QString txid = QString::fromStdString(it["created_in_txid"]);
|
||||||
QString amount = Settings::getDecimalString(it["value"].get<json::number_unsigned_t>());
|
QString amount = Settings::getDecimalString(it["value"].get<json::number_float_t>());
|
||||||
|
|
||||||
newUtxos->push_back(UnspentOutput{ qsAddr, txid, amount, block, true });
|
newUtxos->push_back(UnspentOutput{ qsAddr, txid, amount, block, true });
|
||||||
|
|
||||||
(*balancesMap)[qsAddr] = (*balancesMap)[qsAddr] + it["value"].get<json::number_unsigned_t>();
|
(*balancesMap)[qsAddr] = ((*balancesMap)[qsAddr] + it["value"].get<json::number_float_t>()) /10000000;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -279,26 +283,28 @@ void Controller::refreshBalances() {
|
|||||||
|
|
||||||
// 1. Get the Balances
|
// 1. Get the Balances
|
||||||
zrpc->fetchBalance([=] (json reply) {
|
zrpc->fetchBalance([=] (json reply) {
|
||||||
auto balT = reply["tbalance"].get<json::number_unsigned_t>();
|
auto balT = reply["tbalance"].get<json::number_float_t>();
|
||||||
auto balZ = reply["zbalance"].get<json::number_unsigned_t>();
|
auto balZ = reply["zbalance"].get<json::number_float_t>();
|
||||||
auto balTotal = balT + balZ;
|
auto balTotal = balT + balZ;
|
||||||
|
|
||||||
AppDataModel::getInstance()->setBalances(balT, balZ);
|
AppDataModel::getInstance()->setBalances(balT, balZ);
|
||||||
|
|
||||||
ui->balSheilded ->setText(Settings::gethushDisplayFormat(balZ));
|
ui->balSheilded ->setText(Settings::gethushDisplayFormat(balZ /10000000));
|
||||||
ui->balTransparent->setText(Settings::gethushDisplayFormat(balT));
|
ui->balTransparent->setText(Settings::gethushDisplayFormat(balT /10000000));
|
||||||
ui->balTotal ->setText(Settings::gethushDisplayFormat(balTotal));
|
ui->balTotal ->setText(Settings::gethushDisplayFormat(balTotal /10000000));
|
||||||
|
|
||||||
|
|
||||||
ui->balSheilded ->setToolTip(Settings::gethushDisplayFormat(balZ));
|
ui->balSheilded ->setToolTip(Settings::gethushDisplayFormat(balZ /10000000));
|
||||||
ui->balTransparent->setToolTip(Settings::gethushDisplayFormat(balT));
|
ui->balTransparent->setToolTip(Settings::gethushDisplayFormat(balT /10000000));
|
||||||
ui->balTotal ->setToolTip(Settings::gethushDisplayFormat(balTotal));
|
ui->balTotal ->setToolTip(Settings::gethushDisplayFormat(balTotal /10000000));
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 2. Get the UTXOs
|
// 2. Get the UTXOs
|
||||||
// First, create a new UTXO list. It will be replacing the existing list when everything is processed.
|
// First, create a new UTXO list. It will be replacing the existing list when everything is processed.
|
||||||
auto newUtxos = new QList<UnspentOutput>();
|
auto newUtxos = new QList<UnspentOutput>();
|
||||||
auto newBalances = new QMap<QString, qint64>();
|
auto newBalances = new QMap<QString, double>();
|
||||||
|
|
||||||
// Call the Transparent and Z unspent APIs serially and then, once they're done, update the UI
|
// Call the Transparent and Z unspent APIs serially and then, once they're done, update the UI
|
||||||
zrpc->fetchUnspent([=] (json reply) {
|
zrpc->fetchUnspent([=] (json reply) {
|
||||||
@@ -323,7 +329,7 @@ void Controller::refreshTransactions() {
|
|||||||
|
|
||||||
for (auto& it : reply.get<json::array_t>()) {
|
for (auto& it : reply.get<json::array_t>()) {
|
||||||
QString address;
|
QString address;
|
||||||
qint64 total_amount;
|
double total_amount;
|
||||||
QList<TransactionItemDetail> items;
|
QList<TransactionItemDetail> items;
|
||||||
|
|
||||||
// First, check if there's outgoing metadata
|
// First, check if there's outgoing metadata
|
||||||
@@ -331,7 +337,7 @@ void Controller::refreshTransactions() {
|
|||||||
|
|
||||||
for (auto o: it["outgoing_metadata"].get<json::array_t>()) {
|
for (auto o: it["outgoing_metadata"].get<json::array_t>()) {
|
||||||
QString address = QString::fromStdString(o["address"]);
|
QString address = QString::fromStdString(o["address"]);
|
||||||
qint64 amount = -1 * o["value"].get<json::number_integer_t>(); // Sent items are -ve
|
double amount = -1 * o["value"].get<json::number_float_t>() /10000000;// Sent items are -ve
|
||||||
|
|
||||||
QString memo;
|
QString memo;
|
||||||
if (!o["memo"].is_null()) {
|
if (!o["memo"].is_null()) {
|
||||||
@@ -353,7 +359,7 @@ void Controller::refreshTransactions() {
|
|||||||
it["datetime"].get<json::number_unsigned_t>(),
|
it["datetime"].get<json::number_unsigned_t>(),
|
||||||
address,
|
address,
|
||||||
QString::fromStdString(it["txid"]),
|
QString::fromStdString(it["txid"]),
|
||||||
model->getLatestBlock() - it["block_height"].get<json::number_unsigned_t>(),
|
model->getLatestBlock() - it["block_height"].get<json::number_unsigned_t>(),
|
||||||
items
|
items
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -363,7 +369,7 @@ void Controller::refreshTransactions() {
|
|||||||
|
|
||||||
items.push_back(TransactionItemDetail{
|
items.push_back(TransactionItemDetail{
|
||||||
address,
|
address,
|
||||||
it["amount"].get<json::number_integer_t>(),
|
it["amount"].get<json::number_float_t>(),
|
||||||
""
|
""
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -417,7 +423,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()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -508,11 +514,12 @@ void Controller::refreshhushPrice() {
|
|||||||
if (!zrpc->haveConnection())
|
if (!zrpc->haveConnection())
|
||||||
return noConnection();
|
return noConnection();
|
||||||
|
|
||||||
QUrl cmcURL("https://api.coingecko.com/api/v3/simple/price?ids=hush&vs_currencies=btc%2Cusd%2Ceur&include_market_cap=true&include_24hr_vol=true&include_24hr_change=true");
|
// TODO: use/render all this data
|
||||||
|
QUrl cmcURL("ncies=btc%2Cusd%2Ceur&include_market_cap=true&include_24hr_vol=true&include_24hr_change=true");
|
||||||
|
|
||||||
QNetworkRequest req;
|
QNetworkRequest req;
|
||||||
req.setUrl(cmcURL);
|
req.setUrl(cmcURL);
|
||||||
|
|
||||||
QNetworkAccessManager *manager = new QNetworkAccessManager(this->main);
|
QNetworkAccessManager *manager = new QNetworkAccessManager(this->main);
|
||||||
QNetworkReply *reply = manager->get(req);
|
QNetworkReply *reply = manager->get(req);
|
||||||
|
|
||||||
@@ -524,34 +531,41 @@ void Controller::refreshhushPrice() {
|
|||||||
if (reply->error() != QNetworkReply::NoError) {
|
if (reply->error() != QNetworkReply::NoError) {
|
||||||
auto parsed = json::parse(reply->readAll(), nullptr, false);
|
auto parsed = json::parse(reply->readAll(), nullptr, false);
|
||||||
if (!parsed.is_discarded() && !parsed["error"]["message"].is_null()) {
|
if (!parsed.is_discarded() && !parsed["error"]["message"].is_null()) {
|
||||||
qDebug() << QString::fromStdString(parsed["error"]["message"]);
|
qDebug() << QString::fromStdString(parsed["error"]["message"]);
|
||||||
} else {
|
} else {
|
||||||
qDebug() << reply->errorString();
|
qDebug() << reply->errorString();
|
||||||
}
|
}
|
||||||
Settings::getInstance()->sethushPrice(0);
|
Settings::getInstance()->sethushPrice(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qDebug() << "No network errors";
|
||||||
auto all = reply->readAll();
|
auto all = reply->readAll();
|
||||||
|
|
||||||
auto parsed = json::parse(all, nullptr, false);
|
auto parsed = json::parse(all, nullptr, false);
|
||||||
if (parsed.is_discarded()) {
|
if (parsed.is_discarded()) {
|
||||||
Settings::getInstance()->sethushPrice(0);
|
Settings::getInstance()->sethushPrice(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const json& item : parsed.get<json::array_t>()) {
|
qDebug() << "Parsed JSON";
|
||||||
if (item["symbol"].get<json::string_t>() == Settings::getTokenName().toStdString()) {
|
|
||||||
QString price = QString::fromStdString(item["price_usd"].get<json::string_t>());
|
|
||||||
qDebug() << Settings::getTokenName() << " Price=" << price;
|
|
||||||
Settings::getInstance()->sethushPrice(price.toDouble());
|
|
||||||
|
|
||||||
return;
|
const json& item = parsed.get<json::object_t>();
|
||||||
}
|
const json& hush = item["Hush"].get<json::object_t>();
|
||||||
|
|
||||||
|
if (hush["usd"] >= 0) {
|
||||||
|
qDebug() << "Found hush key in price json";
|
||||||
|
// TODO: support BTC/EUR prices as well
|
||||||
|
QString price = QString::fromStdString(hush["usd"].get<json::string_t>());
|
||||||
|
qDebug() << "HUSH = $" << QString::number((double)hush["usd"]);
|
||||||
|
Settings::getInstance()->sethushPrice( hush["usd"] );
|
||||||
|
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
qDebug() << "No hush key found in JSON! API might be down or we are rate-limited\n";
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (const std::exception& e) {
|
||||||
// If anything at all goes wrong, just set the price to 0 and move on.
|
// If anything at all goes wrong, just set the price to 0 and move on.
|
||||||
qDebug() << QString("Caught something nasty");
|
qDebug() << QString("Caught something nasty: ") << e.what();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If nothing, then set the price to 0;
|
// If nothing, then set the price to 0;
|
||||||
@@ -560,115 +574,28 @@ void Controller::refreshhushPrice() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Controller::shutdownhushd() {
|
void Controller::shutdownhushd() {
|
||||||
// Shutdown embedded hushd if it was started
|
// Save the wallet and exit the lightclient library cleanly.
|
||||||
if (ehushd == nullptr || ehushd->processId() == 0 || !zrpc->haveConnection()) {
|
if (zrpc->haveConnection()) {
|
||||||
// No hushd running internally, just return
|
QDialog d(main);
|
||||||
return;
|
Ui_ConnectionDialog connD;
|
||||||
|
connD.setupUi(&d);
|
||||||
|
connD.topIcon->setBasePixmap(QIcon(":/icons/res/icon.ico").pixmap(256, 256));
|
||||||
|
connD.status->setText(QObject::tr("Please wait for SilentDragonLite to exit"));
|
||||||
|
connD.statusDetail->setText(QObject::tr("Waiting for hushd to exit"));
|
||||||
|
|
||||||
|
bool finished = false;
|
||||||
|
|
||||||
|
zrpc->saveWallet([&] (json) {
|
||||||
|
if (!finished)
|
||||||
|
d.accept();
|
||||||
|
finished = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!finished)
|
||||||
|
d.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
// json payload = {
|
|
||||||
// {"jsonrpc", "1.0"},
|
|
||||||
// {"id", "someid"},
|
|
||||||
// {"method", "stop"}
|
|
||||||
// };
|
|
||||||
|
|
||||||
// getConnection()->doRPCWithDefaultErrorHandling(payload, [=](auto) {});
|
|
||||||
// getConnection()->shutdown();
|
|
||||||
|
|
||||||
// QDialog d(main);
|
|
||||||
// Ui_ConnectionDialog connD;
|
|
||||||
// connD.setupUi(&d);
|
|
||||||
// connD.topIcon->setBasePixmap(QIcon(":/icons/res/icon.ico").pixmap(256, 256));
|
|
||||||
// connD.status->setText(QObject::tr("Please wait for silentdragon to exit"));
|
|
||||||
// connD.statusDetail->setText(QObject::tr("Waiting for hushd to exit"));
|
|
||||||
|
|
||||||
// QTimer waiter(main);
|
|
||||||
|
|
||||||
// // We capture by reference all the local variables because of the d.exec()
|
|
||||||
// // below, which blocks this function until we exit.
|
|
||||||
// int waitCount = 0;
|
|
||||||
// QObject::connect(&waiter, &QTimer::timeout, [&] () {
|
|
||||||
// waitCount++;
|
|
||||||
|
|
||||||
// if ((ehushd->atEnd() && ehushd->processId() == 0) ||
|
|
||||||
// waitCount > 30 ||
|
|
||||||
// getConnection()->config->hushDaemon) { // If hushd is daemon, then we don't have to do anything else
|
|
||||||
// qDebug() << "Ended";
|
|
||||||
// waiter.stop();
|
|
||||||
// QTimer::singleShot(1000, [&]() { d.accept(); });
|
|
||||||
// } else {
|
|
||||||
// qDebug() << "Not ended, continuing to wait...";
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// waiter.start(1000);
|
|
||||||
|
|
||||||
// // Wait for the hush process to exit.
|
|
||||||
// if (!Settings::getInstance()->isHeadless()) {
|
|
||||||
// d.exec();
|
|
||||||
// } else {
|
|
||||||
// while (waiter.isActive()) {
|
|
||||||
// QCoreApplication::processEvents();
|
|
||||||
|
|
||||||
// QThread::sleep(1);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// // Fetch the Z-board topics list
|
|
||||||
// void Controller::getZboardTopics(std::function<void(QMap<QString, QString>)> cb) {
|
|
||||||
// if (!zrpc->haveConnection())
|
|
||||||
// return noConnection();
|
|
||||||
|
|
||||||
// QUrl cmcURL("http://z-board.net/listTopics");
|
|
||||||
|
|
||||||
// QNetworkRequest req;
|
|
||||||
// req.setUrl(cmcURL);
|
|
||||||
|
|
||||||
// QNetworkReply *reply = conn->restclient->get(req);
|
|
||||||
|
|
||||||
// QObject::connect(reply, &QNetworkReply::finished, [=] {
|
|
||||||
// reply->deleteLater();
|
|
||||||
|
|
||||||
// try {
|
|
||||||
// if (reply->error() != QNetworkReply::NoError) {
|
|
||||||
// auto parsed = json::parse(reply->readAll(), nullptr, false);
|
|
||||||
// if (!parsed.is_discarded() && !parsed["error"]["message"].is_null()) {
|
|
||||||
// qDebug() << QString::fromStdString(parsed["error"]["message"]);
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// qDebug() << reply->errorString();
|
|
||||||
// }
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// auto all = reply->readAll();
|
|
||||||
|
|
||||||
// auto parsed = json::parse(all, nullptr, false);
|
|
||||||
// if (parsed.is_discarded()) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// QMap<QString, QString> topics;
|
|
||||||
// for (const json& item : parsed["topics"].get<json::array_t>()) {
|
|
||||||
// if (item.find("addr") == item.end() || item.find("topicName") == item.end())
|
|
||||||
// return;
|
|
||||||
|
|
||||||
// QString addr = QString::fromStdString(item["addr"].get<json::string_t>());
|
|
||||||
// QString topic = QString::fromStdString(item["topicName"].get<json::string_t>());
|
|
||||||
|
|
||||||
// topics.insert(topic, addr);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// cb(topics);
|
|
||||||
// }
|
|
||||||
// catch (...) {
|
|
||||||
// // If anything at all goes wrong, just set the price to 0 and move on.
|
|
||||||
// qDebug() << QString("Caught something nasty");
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a Sapling address from the user's wallet
|
* Get a Sapling address from the user's wallet
|
||||||
*/
|
*/
|
||||||
|
|||||||
+1
-1
@@ -78,7 +78,7 @@ private:
|
|||||||
|
|
||||||
void refreshTransactions();
|
void refreshTransactions();
|
||||||
|
|
||||||
bool processUnspent (const json& reply, QMap<QString, qint64>* newBalances, QList<UnspentOutput>* newUtxos);
|
bool processUnspent (const json& reply, QMap<QString, double>* newBalances, QList<UnspentOutput>* newUtxos);
|
||||||
void updateUI (bool anyUnconfirmed);
|
void updateUI (bool anyUnconfirmed);
|
||||||
|
|
||||||
void getInfoThenRefresh(bool force);
|
void getInfoThenRefresh(bool force);
|
||||||
|
|||||||
+2
-2
@@ -7,7 +7,7 @@ DataModel::DataModel() {
|
|||||||
QWriteLocker locker(lock);
|
QWriteLocker locker(lock);
|
||||||
|
|
||||||
utxos = new QList<UnspentOutput>();
|
utxos = new QList<UnspentOutput>();
|
||||||
balances = new QMap<QString, qint64>();
|
balances = new QMap<QString, double>();
|
||||||
usedAddresses = new QMap<QString, bool>();
|
usedAddresses = new QMap<QString, bool>();
|
||||||
zaddresses = new QList<QString>();
|
zaddresses = new QList<QString>();
|
||||||
taddresses = new QList<QString>();
|
taddresses = new QList<QString>();
|
||||||
@@ -44,7 +44,7 @@ void DataModel::replaceTaddresses(QList<QString>* newT) {
|
|||||||
taddresses = newT;
|
taddresses = newT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataModel::replaceBalances(QMap<QString, qint64>* newBalances) {
|
void DataModel::replaceBalances(QMap<QString, double>* newBalances) {
|
||||||
QWriteLocker locker(lock);
|
QWriteLocker locker(lock);
|
||||||
Q_ASSERT(newBalances);
|
Q_ASSERT(newBalances);
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -18,7 +18,7 @@ class DataModel {
|
|||||||
public:
|
public:
|
||||||
void replaceZaddresses(QList<QString>* newZ);
|
void replaceZaddresses(QList<QString>* newZ);
|
||||||
void replaceTaddresses(QList<QString>* newZ);
|
void replaceTaddresses(QList<QString>* newZ);
|
||||||
void replaceBalances(QMap<QString, qint64>* newBalances);
|
void replaceBalances(QMap<QString, double>* newBalances);
|
||||||
void replaceUTXOs(QList<UnspentOutput>* utxos);
|
void replaceUTXOs(QList<UnspentOutput>* utxos);
|
||||||
|
|
||||||
void markAddressUsed(QString address);
|
void markAddressUsed(QString address);
|
||||||
@@ -29,8 +29,8 @@ public:
|
|||||||
const QList<QString> getAllZAddresses() { QReadLocker locker(lock); return *zaddresses; }
|
const QList<QString> getAllZAddresses() { QReadLocker locker(lock); return *zaddresses; }
|
||||||
const QList<QString> getAllTAddresses() { QReadLocker locker(lock); return *taddresses; }
|
const QList<QString> getAllTAddresses() { QReadLocker locker(lock); return *taddresses; }
|
||||||
const QList<UnspentOutput> getUTXOs() { QReadLocker locker(lock); return *utxos; }
|
const QList<UnspentOutput> getUTXOs() { QReadLocker locker(lock); return *utxos; }
|
||||||
const QMap<QString, qint64> getAllBalances() { QReadLocker locker(lock); return *balances; }
|
const QMap<QString, double> getAllBalances() { QReadLocker locker(lock); return *balances; }
|
||||||
const QMap<QString, bool> getUsedAddresses() { QReadLocker locker(lock); return *usedAddresses; }
|
const QMap<QString, bool> getUsedAddresses() { QReadLocker locker(lock); return *usedAddresses; }
|
||||||
|
|
||||||
|
|
||||||
DataModel();
|
DataModel();
|
||||||
@@ -39,7 +39,7 @@ private:
|
|||||||
int latestBlock;
|
int latestBlock;
|
||||||
|
|
||||||
QList<UnspentOutput>* utxos = nullptr;
|
QList<UnspentOutput>* utxos = nullptr;
|
||||||
QMap<QString, qint64>* balances = nullptr;
|
QMap<QString, double>* balances = nullptr;
|
||||||
QMap<QString, bool>* usedAddresses = nullptr;
|
QMap<QString, bool>* usedAddresses = nullptr;
|
||||||
QList<QString>* zaddresses = nullptr;
|
QList<QString>* zaddresses = nullptr;
|
||||||
QList<QString>* taddresses = nullptr;
|
QList<QString>* taddresses = nullptr;
|
||||||
|
|||||||
@@ -0,0 +1,178 @@
|
|||||||
|
#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\t]+"), " ");
|
||||||
|
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. Validate birthday
|
||||||
|
QString birthday_str = form.txtBirthday->text();
|
||||||
|
bool ok;
|
||||||
|
qint64 birthday = birthday_str.toUInt(&ok);
|
||||||
|
if (!ok) {
|
||||||
|
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 it as '0' if you don't know what it should be."),
|
||||||
|
QMessageBox::Ok);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 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(), birthday);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Finally attempt to save the wallet
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -39,7 +39,7 @@ void LiteInterface::createNewZaddr(bool, const std::function<void(json)>& cb) {
|
|||||||
if (conn == nullptr)
|
if (conn == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
conn->doRPCWithDefaultErrorHandling("new", "zs", cb);
|
conn->doRPCWithDefaultErrorHandling("new", "zs1", cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LiteInterface::createNewTaddr(const std::function<void(json)>& cb) {
|
void LiteInterface::createNewTaddr(const std::function<void(json)>& cb) {
|
||||||
@@ -70,6 +70,13 @@ void LiteInterface::fetchTransactions(const std::function<void(json)>& cb) {
|
|||||||
conn->doRPCWithDefaultErrorHandling("list", "", cb);
|
conn->doRPCWithDefaultErrorHandling("list", "", cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LiteInterface::saveWallet(const std::function<void(json)>& cb) {
|
||||||
|
if (conn == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
conn->doRPCWithDefaultErrorHandling("save", "", cb);
|
||||||
|
}
|
||||||
|
|
||||||
void LiteInterface::sendTransaction(QString params, const std::function<void(json)>& cb,
|
void LiteInterface::sendTransaction(QString params, const std::function<void(json)>& cb,
|
||||||
const std::function<void(QString)>& err) {
|
const std::function<void(QString)>& err) {
|
||||||
if (conn == nullptr)
|
if (conn == nullptr)
|
||||||
|
|||||||
+5
-2
@@ -11,7 +11,7 @@ using json = nlohmann::json;
|
|||||||
// into a struct with address, amount, memo
|
// into a struct with address, amount, memo
|
||||||
struct TransactionItemDetail {
|
struct TransactionItemDetail {
|
||||||
QString address;
|
QString address;
|
||||||
qint64 amount;
|
double amount;
|
||||||
QString memo;
|
QString memo;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -45,12 +45,15 @@ public:
|
|||||||
const std::function<void(QString)>& err);
|
const std::function<void(QString)>& err);
|
||||||
|
|
||||||
void fetchBalance(const std::function<void(json)>& cb);
|
void fetchBalance(const std::function<void(json)>& cb);
|
||||||
|
|
||||||
|
|
||||||
void createNewZaddr(bool sapling, const std::function<void(json)>& cb);
|
void createNewZaddr(bool sapling, const std::function<void(json)>& cb);
|
||||||
void createNewTaddr(const std::function<void(json)>& cb);
|
void createNewTaddr(const std::function<void(json)>& cb);
|
||||||
|
|
||||||
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 saveWallet(const std::function<void(json)>& cb);
|
||||||
|
|
||||||
//void importZPrivKey(QString addr, bool rescan, const std::function<void(json)>& cb);
|
//void importZPrivKey(QString addr, bool rescan, const std::function<void(json)>& cb);
|
||||||
//void importTPrivKey(QString addr, bool rescan, const std::function<void(json)>& cb);
|
//void importTPrivKey(QString addr, bool rescan, const std::function<void(json)>& cb);
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ struct ToFields {
|
|||||||
struct Tx {
|
struct Tx {
|
||||||
QString fromAddr;
|
QString fromAddr;
|
||||||
QList<ToFields> toAddrs;
|
QList<ToFields> toAddrs;
|
||||||
double fee;
|
double fee;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|||||||
+12
-12
@@ -22,7 +22,7 @@
|
|||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QTabWidget" name="tabWidget">
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>2</number>
|
<number>4</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="tab">
|
<widget class="QWidget" name="tab">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
@@ -935,7 +935,7 @@
|
|||||||
<item row="5" column="0" colspan="3">
|
<item row="5" column="0" colspan="3">
|
||||||
<widget class="QLabel" name="label_14">
|
<widget class="QLabel" name="label_14">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>You are currently not mining</string>
|
<string>This is a Lightwallet, you cant mine with it!</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -953,7 +953,7 @@
|
|||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="2">
|
<item row="2" column="2">
|
||||||
<widget class="QLabel" name="numconnections">
|
<widget class="QLabel" name="version">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Loading...</string>
|
<string>Loading...</string>
|
||||||
</property>
|
</property>
|
||||||
@@ -962,12 +962,12 @@
|
|||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QLabel" name="heightLabel">
|
<widget class="QLabel" name="heightLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Block height</string>
|
<string>Blockheight</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="2">
|
<item row="3" column="2">
|
||||||
<widget class="QLabel" name="solrate">
|
<widget class="QLabel" name="Vendor">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Loading...</string>
|
<string>Loading...</string>
|
||||||
</property>
|
</property>
|
||||||
@@ -976,19 +976,19 @@
|
|||||||
<item row="3" column="0">
|
<item row="3" column="0">
|
||||||
<widget class="QLabel" name="label_12">
|
<widget class="QLabel" name="label_12">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Network solution rate</string>
|
<string>Version hushd light</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QLabel" name="label_8">
|
<widget class="QLabel" name="label_8">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Connections</string>
|
<string>Vendor</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="2">
|
<item row="1" column="2">
|
||||||
<widget class="QLabel" name="blockheight">
|
<widget class="QLabel" name="blockHeight">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Loading...</string>
|
<string>Loading...</string>
|
||||||
</property>
|
</property>
|
||||||
@@ -1122,17 +1122,17 @@
|
|||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Send Duke Feedback</string>
|
<string>&Send Duke Feedback</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionDiscord">
|
<action name="actionDiscord">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Hush Discord</string>
|
<string>&Hush Discord</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionWebsite">
|
<action name="actionWebsite">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Hush Website</string>
|
<string>&Hush Website</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionCheck_for_Updates">
|
<action name="actionCheck_for_Updates">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Check github.com for &updates</string>
|
<string>Check github.com for &updates</string>
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
<?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="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Wallet Seed</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPlainTextEdit" name="txtSeed">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Wallet Birthday</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="txtBirthday">
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>9</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Wallet birthday is the block height at which the wallet had the first transaction. If you don't know this, you can leave it as "0" (It'll take longer to rescan)</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
+1
-1
@@ -315,7 +315,7 @@ bool Settings::removeFromhushConf(QString confLocation, QString option) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
double Settings::getMinerFee() {
|
double Settings::getMinerFee() {
|
||||||
return 0.0001;
|
return 0.01;
|
||||||
}
|
}
|
||||||
|
|
||||||
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