+2
-2
@@ -18,10 +18,10 @@ script:
|
||||
- qmake -v
|
||||
- clang++ -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 distclean
|
||||
- qmake hush-qt-wallet.pro CONFIG+=release -spec linux-g++
|
||||
- qmake silentdragon-lite.pro CONFIG+=release -spec linux-g++
|
||||
- res/libsodium/buildlibsodium.sh
|
||||
- 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>
|
||||
</qresource>
|
||||
<qresource prefix="/translations">
|
||||
<file>res/zec_qt_wallet_es.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>
|
||||
<file>res/zec_qt_wallet_de.qm</file>
|
||||
</qresource>
|
||||
<qresource prefix="/css">
|
||||
<file>res/css/blue.css</file>
|
||||
|
||||
Generated
+3
-3
@@ -1051,7 +1051,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"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)",
|
||||
"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]]
|
||||
@@ -1467,7 +1467,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "silentdragonlitelib"
|
||||
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 = [
|
||||
"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)",
|
||||
@@ -2481,7 +2481,7 @@ dependencies = [
|
||||
"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 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 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"
|
||||
|
||||
+1
-1
@@ -11,4 +11,4 @@ crate-type = ["staticlib"]
|
||||
[dependencies]
|
||||
libc = "0.2.58"
|
||||
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" {
|
||||
#endif
|
||||
|
||||
extern bool litelib_wallet_exists (const char* chain_name, const char* dir);
|
||||
extern char * litelib_initialze_existing (bool dangerous, const char* server);
|
||||
extern char * litelib_execute (const char* s, const char* args);
|
||||
extern void litelib_rust_free_string (char* s);
|
||||
extern bool litelib_wallet_exists (const char* chain_name);
|
||||
extern char * litelib_initialize_new (bool dangerous, const char* server);
|
||||
extern char * litelib_initialize_new_from_phrase
|
||||
(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
|
||||
}
|
||||
#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
|
||||
|
||||
+120
-17
@@ -4,7 +4,7 @@ extern crate lazy_static;
|
||||
use libc::{c_char};
|
||||
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::sync::{Mutex};
|
||||
use std::sync::{Mutex, Arc};
|
||||
use std::cell::RefCell;
|
||||
|
||||
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
|
||||
// because we can't return such a complex structure back to C++
|
||||
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
|
||||
|
||||
|
||||
// Initialize a new lightclient and store its value
|
||||
#[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 {
|
||||
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::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 (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(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) {
|
||||
Ok(l) => l,
|
||||
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();
|
||||
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 lc = LIGHTCLIENT.lock().unwrap();
|
||||
let lightclient: Arc<LightClient>;
|
||||
{
|
||||
let lc = LIGHTCLIENT.lock().unwrap();
|
||||
|
||||
if lc.borrow().is_none() {
|
||||
let e_str = CString::new("Error: Light Client is not initialized").unwrap();
|
||||
return e_str.into_raw();
|
||||
}
|
||||
if lc.borrow().is_none() {
|
||||
let e_str = CString::new("Error: Light Client is not initialized").unwrap();
|
||||
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()] };
|
||||
|
||||
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();
|
||||
|
||||
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>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
@@ -228,17 +228,17 @@
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.ui" line="891"/>
|
||||
<source>Block height</source>
|
||||
<source>Blockheight</source>
|
||||
<translation type="unfinished">YOUR_TRANSLATION_HERE</translation>
|
||||
</message>
|
||||
<message>
|
||||
<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>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/mainwindow.ui" line="912"/>
|
||||
<source>Connections</source>
|
||||
<source>Vendor</source>
|
||||
<translation type="unfinished">YOUR_TRANSLATION_HERE</translation>
|
||||
</message>
|
||||
<message>
|
||||
@@ -659,7 +659,7 @@ Not starting embedded hushd because --no-embedded was passed</source>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/rpc.cpp" line="578"/>
|
||||
<source>Block height</source>
|
||||
<source>Blockheight</source>
|
||||
<translation type="unfinished">YOUR_TRANSLATION_HERE</translation>
|
||||
</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
|
||||
|
||||
SOURCES += \
|
||||
src/firsttimewizard.cpp \
|
||||
src/main.cpp \
|
||||
src/mainwindow.cpp \
|
||||
src/balancestablemodel.cpp \
|
||||
@@ -62,6 +63,7 @@ SOURCES += \
|
||||
src/liteinterface.cpp
|
||||
|
||||
HEADERS += \
|
||||
src/firsttimewizard.h \
|
||||
src/mainwindow.h \
|
||||
src/precompiled.h \
|
||||
src/balancestablemodel.h \
|
||||
@@ -91,7 +93,10 @@ HEADERS += \
|
||||
FORMS += \
|
||||
src/mainwindow.ui \
|
||||
src/migration.ui \
|
||||
src/newseed.ui \
|
||||
src/newwallet.ui \
|
||||
src/recurringpayments.ui \
|
||||
src/restoreseed.ui \
|
||||
src/settings.ui \
|
||||
src/about.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_zh.ts \
|
||||
res/zec_qt_wallet_tr.ts
|
||||
|
||||
|
||||
include(singleapplication/singleapplication.pri)
|
||||
DEFINES += QAPPLICATION_CLASS=QApplication
|
||||
|
||||
Executable
BIN
Binary file not shown.
@@ -2,12 +2,11 @@
|
||||
#include "addressbook.h"
|
||||
#include "settings.h"
|
||||
|
||||
|
||||
BalancesTableModel::BalancesTableModel(QObject *parent)
|
||||
: QAbstractTableModel(parent) {
|
||||
}
|
||||
|
||||
void BalancesTableModel::setNewData(const QMap<QString, qint64> balances,
|
||||
void BalancesTableModel::setNewData(const QMap<QString, double> balances,
|
||||
const QList<UnspentOutput> outputs)
|
||||
{
|
||||
loading = false;
|
||||
@@ -22,7 +21,7 @@ void BalancesTableModel::setNewData(const QMap<QString, qint64> balances,
|
||||
|
||||
// Process the address balances into a list
|
||||
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) {
|
||||
if (balances.value(keyIt) > 0)
|
||||
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) {
|
||||
switch (index.column()) {
|
||||
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 "datamodel.h"
|
||||
|
||||
|
||||
class BalancesTableModel : public QAbstractTableModel
|
||||
{
|
||||
public:
|
||||
BalancesTableModel(QObject* parent);
|
||||
~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 columnCount(const QModelIndex &parent) const;
|
||||
@@ -18,7 +19,7 @@ public:
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||
|
||||
private:
|
||||
QList<std::tuple<QString, qint64>>* modeldata = nullptr;
|
||||
QList<std::tuple<QString, double>>* modeldata = nullptr;
|
||||
QList<UnspentOutput>* utxos = nullptr;
|
||||
|
||||
bool loading = true;
|
||||
|
||||
+82
-33
@@ -2,9 +2,11 @@
|
||||
#include "mainwindow.h"
|
||||
#include "settings.h"
|
||||
#include "ui_connection.h"
|
||||
#include "firsttimewizard.h"
|
||||
#include "ui_createhushconfdialog.h"
|
||||
#include "controller.h"
|
||||
|
||||
|
||||
#include "../lib/silentdragonlitelib.h"
|
||||
|
||||
#include "precompiled.h"
|
||||
@@ -20,9 +22,12 @@ ConnectionLoader::ConnectionLoader(MainWindow* main, Controller* rpc) {
|
||||
connD->setupUi(d);
|
||||
QPixmap logo(":/img/res/logobig.gif");
|
||||
connD->topIcon->setBasePixmap(logo.scaled(256, 256, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||
|
||||
isSyncing = new QAtomicInteger<bool>();
|
||||
}
|
||||
|
||||
ConnectionLoader::~ConnectionLoader() {
|
||||
ConnectionLoader::~ConnectionLoader() {
|
||||
delete isSyncing;
|
||||
delete connD;
|
||||
delete d;
|
||||
}
|
||||
@@ -42,19 +47,77 @@ void ConnectionLoader::doAutoConnect() {
|
||||
|
||||
// Initialize the library
|
||||
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);
|
||||
|
||||
// After the lib is initialized, try to do get info
|
||||
connection->doRPC("info", "", [=](auto reply) {
|
||||
// If success, set the connection
|
||||
// If success, set the connection
|
||||
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) {
|
||||
qDebug() << "Connectionloader finished, setting connection";
|
||||
rpc->setConnection(conn);
|
||||
|
||||
d->accept();
|
||||
@@ -68,20 +131,9 @@ Connection* ConnectionLoader::makeConnection(std::shared_ptr<ConnectionConfig> c
|
||||
|
||||
// Update the UI with the status
|
||||
void ConnectionLoader::showInformation(QString info, QString detail) {
|
||||
static int rescanCount = 0;
|
||||
if (detail.toLower().startsWith("rescan")) {
|
||||
rescanCount++;
|
||||
}
|
||||
|
||||
if (rescanCount > 10) {
|
||||
detail = detail + "\n" + QObject::tr("This may take several hours");
|
||||
}
|
||||
|
||||
qDebug() << "Showing info " << info << ":" << detail;
|
||||
connD->status->setText(info);
|
||||
connD->statusDetail->setText(detail);
|
||||
|
||||
if (rescanCount < 10)
|
||||
main->logger->write(info + ":" + detail);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,15 +146,7 @@ void ConnectionLoader::showError(QString explanation) {
|
||||
d->close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************************
|
||||
* 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
|
||||
QString litelib_process_response(char* resp) {
|
||||
char* resp_copy = new char[strlen(resp) + 1];
|
||||
strcpy(resp_copy, resp);
|
||||
litelib_rust_free_string(resp);
|
||||
@@ -111,6 +155,17 @@ void Executor::run() {
|
||||
memset(resp_copy, '-', strlen(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;
|
||||
auto parsed = json::parse(reply.toStdString().c_str(), nullptr, false);
|
||||
if (parsed.is_discarded() || parsed.is_null()) {
|
||||
@@ -126,8 +181,6 @@ void Executor::run() {
|
||||
|
||||
|
||||
void Callback::processRPCCallback(json resp) {
|
||||
const bool isGuiThread = QThread::currentThread() == QCoreApplication::instance()->thread();
|
||||
qDebug() << "Doing RPC callback: isGUI=" << isGuiThread;
|
||||
this->cb(resp);
|
||||
|
||||
// Destroy self
|
||||
@@ -135,8 +188,6 @@ void Callback::processRPCCallback(json resp) {
|
||||
}
|
||||
|
||||
void Callback::processError(QString resp) {
|
||||
const bool isGuiThread = QThread::currentThread() == QCoreApplication::instance()->thread();
|
||||
qDebug() << "Doing RPC callback: isGUI=" << isGuiThread;
|
||||
this->errCb(resp);
|
||||
|
||||
// Destroy self
|
||||
@@ -158,9 +209,7 @@ void Connection::doRPC(const QString cmd, const QString args, const std::functio
|
||||
return;
|
||||
}
|
||||
|
||||
const bool isGuiThread =
|
||||
QThread::currentThread() == QCoreApplication::instance()->thread();
|
||||
qDebug() << "Doing RPC: isGUI=" << isGuiThread;
|
||||
qDebug() << "Doing RPC: " << cmd;
|
||||
|
||||
// Create a runner.
|
||||
auto runner = new Executor(cmd, args);
|
||||
|
||||
+9
-4
@@ -33,16 +33,21 @@ private:
|
||||
|
||||
void doAutoConnect();
|
||||
|
||||
void createOrRestore(bool dangerous, QString server);
|
||||
|
||||
void showError(QString explanation);
|
||||
void showInformation(QString info, QString detail = "");
|
||||
|
||||
void doRPCSetConnection(Connection* conn);
|
||||
|
||||
QDialog* d;
|
||||
Ui_ConnectionDialog* connD;
|
||||
QTimer* syncTimer = nullptr;
|
||||
QAtomicInteger<bool>* isSyncing = nullptr;
|
||||
|
||||
MainWindow* main;
|
||||
Controller* rpc;
|
||||
QDialog* d = nullptr;
|
||||
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);
|
||||
|
||||
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
|
||||
auto hushConfLocation = Settings::getInstance()->gethushdConfLocation();
|
||||
@@ -96,7 +96,7 @@ void Controller::fillTxJsonParams(json& allRecepients, Tx tx) {
|
||||
// Construct the JSON params
|
||||
json rec = json::object();
|
||||
rec["address"] = toAddr.addr.toStdString();
|
||||
rec["amount"] = toAddr.amount;
|
||||
rec["amount"] = toAddr.amount * 10000000;
|
||||
if (Settings::isZAddress(toAddr.addr) && !toAddr.memo.trimmed().isEmpty())
|
||||
rec["memo"] = toAddr.memo.toStdString();
|
||||
|
||||
@@ -120,7 +120,7 @@ void Controller::noConnection() {
|
||||
main->ui->statusBar->showMessage(QObject::tr("No Connection"), 1000);
|
||||
|
||||
// Clear balances table.
|
||||
QMap<QString, qint64> emptyBalances;
|
||||
QMap<QString, double> emptyBalances;
|
||||
QList<UnspentOutput> emptyOutputs;
|
||||
balancesTableModel->setNewData(emptyBalances, emptyOutputs);
|
||||
|
||||
@@ -161,21 +161,25 @@ void Controller::getInfoThenRefresh(bool force) {
|
||||
prevCallSucceeded = true;
|
||||
|
||||
// Testnet?
|
||||
QString chainName;
|
||||
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
|
||||
if (!Settings::getInstance()->isTestnet())
|
||||
main->disableRecurring();
|
||||
|
||||
// Connected, so display checkmark.
|
||||
QIcon i(":/icons/res/connected.gif");
|
||||
main->statusIcon->setPixmap(i.pixmap(16, 16));
|
||||
|
||||
static int lastBlock = 0;
|
||||
int curBlock = reply["latest_block_height"].get<json::number_integer_t>();
|
||||
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 = 1;
|
||||
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.
|
||||
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;
|
||||
|
||||
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"]);
|
||||
int block = it["created_in_block"].get<json::number_unsigned_t>();
|
||||
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 });
|
||||
|
||||
(*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
|
||||
zrpc->fetchBalance([=] (json reply) {
|
||||
auto balT = reply["tbalance"].get<json::number_unsigned_t>();
|
||||
auto balZ = reply["zbalance"].get<json::number_unsigned_t>();
|
||||
auto balT = reply["tbalance"].get<json::number_float_t>();
|
||||
auto balZ = reply["zbalance"].get<json::number_float_t>();
|
||||
auto balTotal = balT + balZ;
|
||||
|
||||
AppDataModel::getInstance()->setBalances(balT, balZ);
|
||||
|
||||
ui->balSheilded ->setText(Settings::gethushDisplayFormat(balZ));
|
||||
ui->balTransparent->setText(Settings::gethushDisplayFormat(balT));
|
||||
ui->balTotal ->setText(Settings::gethushDisplayFormat(balTotal));
|
||||
ui->balSheilded ->setText(Settings::gethushDisplayFormat(balZ /10000000));
|
||||
ui->balTransparent->setText(Settings::gethushDisplayFormat(balT /10000000));
|
||||
ui->balTotal ->setText(Settings::gethushDisplayFormat(balTotal /10000000));
|
||||
|
||||
|
||||
ui->balSheilded ->setToolTip(Settings::gethushDisplayFormat(balZ));
|
||||
ui->balTransparent->setToolTip(Settings::gethushDisplayFormat(balT));
|
||||
ui->balTotal ->setToolTip(Settings::gethushDisplayFormat(balTotal));
|
||||
ui->balSheilded ->setToolTip(Settings::gethushDisplayFormat(balZ /10000000));
|
||||
ui->balTransparent->setToolTip(Settings::gethushDisplayFormat(balT /10000000));
|
||||
ui->balTotal ->setToolTip(Settings::gethushDisplayFormat(balTotal /10000000));
|
||||
|
||||
|
||||
});
|
||||
|
||||
// 2. Get the UTXOs
|
||||
// First, create a new UTXO list. It will be replacing the existing list when everything is processed.
|
||||
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
|
||||
zrpc->fetchUnspent([=] (json reply) {
|
||||
@@ -323,7 +329,7 @@ void Controller::refreshTransactions() {
|
||||
|
||||
for (auto& it : reply.get<json::array_t>()) {
|
||||
QString address;
|
||||
qint64 total_amount;
|
||||
double total_amount;
|
||||
QList<TransactionItemDetail> items;
|
||||
|
||||
// First, check if there's outgoing metadata
|
||||
@@ -331,7 +337,7 @@ void Controller::refreshTransactions() {
|
||||
|
||||
for (auto o: it["outgoing_metadata"].get<json::array_t>()) {
|
||||
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;
|
||||
if (!o["memo"].is_null()) {
|
||||
@@ -353,7 +359,7 @@ void Controller::refreshTransactions() {
|
||||
it["datetime"].get<json::number_unsigned_t>(),
|
||||
address,
|
||||
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
|
||||
});
|
||||
} else {
|
||||
@@ -363,7 +369,7 @@ void Controller::refreshTransactions() {
|
||||
|
||||
items.push_back(TransactionItemDetail{
|
||||
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;
|
||||
|
||||
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()));
|
||||
}
|
||||
|
||||
@@ -508,11 +514,12 @@ void Controller::refreshhushPrice() {
|
||||
if (!zrpc->haveConnection())
|
||||
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;
|
||||
req.setUrl(cmcURL);
|
||||
|
||||
|
||||
QNetworkAccessManager *manager = new QNetworkAccessManager(this->main);
|
||||
QNetworkReply *reply = manager->get(req);
|
||||
|
||||
@@ -524,34 +531,41 @@ void Controller::refreshhushPrice() {
|
||||
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"]);
|
||||
qDebug() << QString::fromStdString(parsed["error"]["message"]);
|
||||
} else {
|
||||
qDebug() << reply->errorString();
|
||||
}
|
||||
Settings::getInstance()->sethushPrice(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << "No network errors";
|
||||
auto all = reply->readAll();
|
||||
|
||||
auto parsed = json::parse(all, nullptr, false);
|
||||
if (parsed.is_discarded()) {
|
||||
Settings::getInstance()->sethushPrice(0);
|
||||
return;
|
||||
}
|
||||
|
||||
for (const json& item : parsed.get<json::array_t>()) {
|
||||
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());
|
||||
qDebug() << "Parsed JSON";
|
||||
|
||||
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.
|
||||
qDebug() << QString("Caught something nasty");
|
||||
qDebug() << QString("Caught something nasty: ") << e.what();
|
||||
}
|
||||
|
||||
// If nothing, then set the price to 0;
|
||||
@@ -560,115 +574,28 @@ void Controller::refreshhushPrice() {
|
||||
}
|
||||
|
||||
void Controller::shutdownhushd() {
|
||||
// Shutdown embedded hushd if it was started
|
||||
if (ehushd == nullptr || ehushd->processId() == 0 || !zrpc->haveConnection()) {
|
||||
// No hushd running internally, just return
|
||||
return;
|
||||
// Save the wallet and exit the lightclient library cleanly.
|
||||
if (zrpc->haveConnection()) {
|
||||
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 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
|
||||
*/
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ private:
|
||||
|
||||
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 getInfoThenRefresh(bool force);
|
||||
|
||||
+2
-2
@@ -7,7 +7,7 @@ DataModel::DataModel() {
|
||||
QWriteLocker locker(lock);
|
||||
|
||||
utxos = new QList<UnspentOutput>();
|
||||
balances = new QMap<QString, qint64>();
|
||||
balances = new QMap<QString, double>();
|
||||
usedAddresses = new QMap<QString, bool>();
|
||||
zaddresses = new QList<QString>();
|
||||
taddresses = new QList<QString>();
|
||||
@@ -44,7 +44,7 @@ void DataModel::replaceTaddresses(QList<QString>* newT) {
|
||||
taddresses = newT;
|
||||
}
|
||||
|
||||
void DataModel::replaceBalances(QMap<QString, qint64>* newBalances) {
|
||||
void DataModel::replaceBalances(QMap<QString, double>* newBalances) {
|
||||
QWriteLocker locker(lock);
|
||||
Q_ASSERT(newBalances);
|
||||
|
||||
|
||||
+4
-4
@@ -18,7 +18,7 @@ class DataModel {
|
||||
public:
|
||||
void replaceZaddresses(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 markAddressUsed(QString address);
|
||||
@@ -29,8 +29,8 @@ public:
|
||||
const QList<QString> getAllZAddresses() { QReadLocker locker(lock); return *zaddresses; }
|
||||
const QList<QString> getAllTAddresses() { QReadLocker locker(lock); return *taddresses; }
|
||||
const QList<UnspentOutput> getUTXOs() { QReadLocker locker(lock); return *utxos; }
|
||||
const QMap<QString, qint64> getAllBalances() { QReadLocker locker(lock); return *balances; }
|
||||
const QMap<QString, bool> getUsedAddresses() { QReadLocker locker(lock); return *usedAddresses; }
|
||||
const QMap<QString, double> getAllBalances() { QReadLocker locker(lock); return *balances; }
|
||||
const QMap<QString, bool> getUsedAddresses() { QReadLocker locker(lock); return *usedAddresses; }
|
||||
|
||||
|
||||
DataModel();
|
||||
@@ -39,7 +39,7 @@ private:
|
||||
int latestBlock;
|
||||
|
||||
QList<UnspentOutput>* utxos = nullptr;
|
||||
QMap<QString, qint64>* balances = nullptr;
|
||||
QMap<QString, double>* balances = nullptr;
|
||||
QMap<QString, bool>* usedAddresses = nullptr;
|
||||
QList<QString>* zaddresses = 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)
|
||||
return;
|
||||
|
||||
conn->doRPCWithDefaultErrorHandling("new", "zs", cb);
|
||||
conn->doRPCWithDefaultErrorHandling("new", "zs1", 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);
|
||||
}
|
||||
|
||||
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,
|
||||
const std::function<void(QString)>& err) {
|
||||
if (conn == nullptr)
|
||||
|
||||
+5
-2
@@ -11,7 +11,7 @@ using json = nlohmann::json;
|
||||
// into a struct with address, amount, memo
|
||||
struct TransactionItemDetail {
|
||||
QString address;
|
||||
qint64 amount;
|
||||
double amount;
|
||||
QString memo;
|
||||
};
|
||||
|
||||
@@ -45,12 +45,15 @@ public:
|
||||
const std::function<void(QString)>& err);
|
||||
|
||||
void fetchBalance(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 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 importTPrivKey(QString addr, bool rescan, const std::function<void(json)>& cb);
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ struct ToFields {
|
||||
struct Tx {
|
||||
QString fromAddr;
|
||||
QList<ToFields> toAddrs;
|
||||
double fee;
|
||||
double fee;
|
||||
};
|
||||
|
||||
namespace Ui {
|
||||
|
||||
+12
-12
@@ -22,7 +22,7 @@
|
||||
<item row="0" column="0">
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
<number>4</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
@@ -935,7 +935,7 @@
|
||||
<item row="5" column="0" colspan="3">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>You are currently not mining</string>
|
||||
<string>This is a Lightwallet, you cant mine with it!</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -953,7 +953,7 @@
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="numconnections">
|
||||
<widget class="QLabel" name="version">
|
||||
<property name="text">
|
||||
<string>Loading...</string>
|
||||
</property>
|
||||
@@ -962,12 +962,12 @@
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="heightLabel">
|
||||
<property name="text">
|
||||
<string>Block height</string>
|
||||
<string>Blockheight</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLabel" name="solrate">
|
||||
<widget class="QLabel" name="Vendor">
|
||||
<property name="text">
|
||||
<string>Loading...</string>
|
||||
</property>
|
||||
@@ -976,19 +976,19 @@
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string>Network solution rate</string>
|
||||
<string>Version hushd light</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Connections</string>
|
||||
<string>Vendor</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="blockheight">
|
||||
<widget class="QLabel" name="blockHeight">
|
||||
<property name="text">
|
||||
<string>Loading...</string>
|
||||
</property>
|
||||
@@ -1122,17 +1122,17 @@
|
||||
<property name="text">
|
||||
<string>&Send Duke Feedback</string>
|
||||
</property>
|
||||
</action>
|
||||
</action>
|
||||
<action name="actionDiscord">
|
||||
<property name="text">
|
||||
<string>&Hush Discord</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionWebsite">
|
||||
</action>
|
||||
<action name="actionWebsite">
|
||||
<property name="text">
|
||||
<string>&Hush Website</string>
|
||||
</property>
|
||||
</action>
|
||||
</action>
|
||||
<action name="actionCheck_for_Updates">
|
||||
<property name="text">
|
||||
<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 <QTranslator>
|
||||
#include <QClipboard>
|
||||
#include <QWizard>
|
||||
#include <QWizardPage>
|
||||
#include <QStringBuilder>
|
||||
#include <QAbstractItemModel>
|
||||
#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() {
|
||||
return 0.0001;
|
||||
return 0.01;
|
||||
}
|
||||
|
||||
double Settings::getZboardAmount() {
|
||||
|
||||
@@ -119,6 +119,8 @@ public:
|
||||
static bool addTohushConf(QString confLocation, QString line);
|
||||
static bool removeFromhushConf(QString confLocation, QString option);
|
||||
|
||||
static QString getChainName() { return QString("test"); }
|
||||
|
||||
static const QString labelRegExp;
|
||||
|
||||
static const int updateSpeed = 20 * 1000; // 10 sec
|
||||
|
||||
Reference in New Issue
Block a user