Browse Source

Merge pull request #167 from MyHush/dev

v1.3.6
pull/175/head v1.3.6
Denio 4 years ago
committed by GitHub
parent
commit
abb2d4de5b
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      application.qrc
  2. 22
      lib/Cargo.lock
  3. 3
      lib/Cargo.toml
  4. 3
      lib/silentdragonlitelib.h
  5. 28
      lib/src/lib.rs
  6. BIN
      res/SilentDragonLite.png
  7. 239
      res/css/test.css
  8. BIN
      res/dark-01.png
  9. BIN
      res/images/tile.png
  10. BIN
      res/silentdragonlite_ar.qm
  11. 2151
      res/silentdragonlite_ar.ts
  12. BIN
      res/silentdragonlite_ro.qm
  13. 2001
      res/silentdragonlite_ro.ts
  14. 2
      silentdragon-lite.pro
  15. 18928
      src/3rdparty/json/json.hpp
  16. 42
      src/Chat/Chat.cpp
  17. 9
      src/Chat/Helper/ChatDelegator.h
  18. 23
      src/DataStore/ChatDataStore.cpp
  19. 9
      src/DataStore/ChatDataStore.h
  20. 13
      src/DataStore/ContactDataStore.cpp
  21. 3
      src/DataStore/ContactDataStore.h
  22. 4
      src/DataStore/SietchDataStore.h
  23. 4
      src/FileSystem/FileSystem.h
  24. 24
      src/Model/ChatItem.cpp
  25. 5
      src/Model/ChatItem.h
  26. 16
      src/Model/ContactItem.cpp
  27. 5
      src/Model/ContactItem.h
  28. 2
      src/Model/ContactRequest.cpp
  29. 3
      src/Model/ContactRequest.h
  30. 96
      src/addressbook.cpp
  31. 171
      src/chatmodel.cpp
  32. 62
      src/connection.cpp
  33. 34
      src/connection.h
  34. 27
      src/contactrequest.ui
  35. 1173
      src/controller.cpp
  36. 35
      src/controller.h
  37. 113
      src/firsttimewizard.cpp
  38. 1
      src/firsttimewizard.h
  39. 40
      src/liteinterface.cpp
  40. 42
      src/liteinterface.h
  41. 252
      src/mainwindow.cpp
  42. 17
      src/mainwindow.h
  43. 4
      src/mainwindow.ui
  44. 310
      src/newwallet.ui
  45. 2
      src/precompiled.h
  46. 65
      src/restoreseed.ui
  47. 2
      src/sendtab.cpp
  48. 13
      src/settings.h
  49. 5
      src/settings.ui
  50. 2
      src/version.h
  51. 10
      src/websockets.cpp

7
application.qrc

@ -47,6 +47,8 @@
<file>res/addContactBlack.png</file>
<file>res/unknownBlack.png</file>
<file>res/unknownWhite.png</file>
<file>res/hush-passion.png</file>
<file>res/dark-01.png</file>
</qresource>
<qresource prefix="/img">
<file>res/hushdlogo.gif</file>
@ -67,6 +69,7 @@
<file>res/silentdragonlite_fa.qm</file>
<file>res/silentdragonlite_id.qm</file>
<file>res/silentdragonlite_ar.qm</file>
<file>res/silentdragonlite_ro.qm</file>
</qresource>
<qresource prefix="/css">
<file>res/css/Blue.css</file>
@ -74,6 +77,7 @@
<file>res/css/Default.css</file>
<file>res/css/Light.css</file>
<file>res/css/Midnight.css</file>
<file>res/css/test.css</file>
</qresource>
<qresource prefix="/images/blue">
<file>res/images/blue/unchecked.png</file>
@ -85,4 +89,7 @@
<file>res/images/blue/blue_rightArrow_small.png</file>
<file>res/images/blue/blue_qtreeview_selected.png</file>
</qresource>
<qresource prefix="/images">
<file>res/images/tile.png</file>
</qresource>
</RCC>

22
lib/Cargo.lock

@ -194,6 +194,20 @@ dependencies = [
"constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "blake3"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "block-buffer"
version = "0.7.3"
@ -1175,9 +1189,10 @@ dependencies = [
name = "qtlib"
version = "0.1.0"
dependencies = [
"blake3 0.3.4 (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.66 (registry+https://github.com/rust-lang/crates.io-index)",
"silentdragonlitelib 0.1.0 (git+https://github.com/MyHush/silentdragonlite-cli?rev=d2887d07879a93bdd9b2c8bd12504bb977e82fe0)",
"silentdragonlitelib 0.1.0 (git+https://github.com/MyHush/silentdragonlite-cli?rev=07288de82d84b9bf35d1210ccc98eb1e4b757eb7)",
]
[[package]]
@ -1640,7 +1655,7 @@ dependencies = [
[[package]]
name = "silentdragonlitelib"
version = "0.1.0"
source = "git+https://github.com/MyHush/silentdragonlite-cli?rev=d2887d07879a93bdd9b2c8bd12504bb977e82fe0#d2887d07879a93bdd9b2c8bd12504bb977e82fe0"
source = "git+https://github.com/MyHush/silentdragonlite-cli?rev=07288de82d84b9bf35d1210ccc98eb1e4b757eb7#07288de82d84b9bf35d1210ccc98eb1e4b757eb7"
dependencies = [
"base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bellman 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)",
@ -2461,6 +2476,7 @@ dependencies = [
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
"checksum blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a"
"checksum blake2s_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab9e07352b829279624ceb7c64adb4f585dacdb81d35cafae81139ccd617cf44"
"checksum blake3 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "423897d97e11b810c9da22458400b28ec866991c711409073662eb34dc44bfff"
"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
"checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774"
"checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
@ -2631,7 +2647,7 @@ dependencies = [
"checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35"
"checksum sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0"
"checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41"
"checksum silentdragonlitelib 0.1.0 (git+https://github.com/MyHush/silentdragonlite-cli?rev=d2887d07879a93bdd9b2c8bd12504bb977e82fe0)" = "<none>"
"checksum silentdragonlitelib 0.1.0 (git+https://github.com/MyHush/silentdragonlite-cli?rev=07288de82d84b9bf35d1210ccc98eb1e4b757eb7)" = "<none>"
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
"checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6"
"checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85"

3
lib/Cargo.toml

@ -11,4 +11,5 @@ crate-type = ["staticlib"]
[dependencies]
libc = "0.2.58"
lazy_static = "1.4.0"
silentdragonlitelib = { git = "https://github.com/MyHush/silentdragonlite-cli", rev = "d2887d07879a93bdd9b2c8bd12504bb977e82fe0" }
blake3 = "0.3.4"
silentdragonlitelib = { git = "https://github.com/MyHush/silentdragonlite-cli", rev = "07288de82d84b9bf35d1210ccc98eb1e4b757eb7" }

3
lib/silentdragonlitelib.h

@ -9,10 +9,11 @@ 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);
unsigned long long birthday, unsigned long long number);
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);
extern char * blake3_PW (char* pw);
#ifdef __cplusplus
}

28
lib/src/lib.rs

@ -29,6 +29,30 @@ pub extern fn litelib_wallet_exists(chain_name: *const c_char) -> bool {
println!("Wallet exists: {}", config.wallet_exists());
config.wallet_exists()
}
//////hash blake3
#[no_mangle]
pub extern fn blake3_PW(pw: *const c_char) -> *mut c_char{
let passwd = unsafe {
assert!(!pw.is_null());
CStr::from_ptr(pw).to_string_lossy().into_owned()
};
let data = passwd.as_bytes();
// Hash an input all at once.
let hash1 = blake3::hash(data).to_hex();
println!("\nBlake3 Hash: {}", hash1);
//let sttring = CString::new(hash1).unwrap();
let e_str = CString::new(format!("{}", hash1)).unwrap();
return e_str.into_raw();
}
/// Create a new wallet and return the seed for the newly created wallet.
@ -78,7 +102,7 @@ pub extern fn litelib_initialize_new(dangerous: bool, server: *const c_char) ->
/// 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 {
seed: *const c_char, birthday: u64, number: u64) -> *mut c_char {
let server_str = unsafe {
assert!(!server.is_null());
@ -100,7 +124,7 @@ pub extern fn litelib_initialize_new_from_phrase(dangerous: bool, server: *const
}
};
let lightclient = match LightClient::new_from_phrase(seed_str, &config, birthday) {
let lightclient = match LightClient::new_from_phrase(seed_str, &config, birthday, number, false) {
Ok(l) => l,
Err(e) => {
let e_str = CString::new(format!("Error: {}", e)).unwrap();

BIN
res/SilentDragonLite.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

239
res/css/test.css

@ -0,0 +1,239 @@
QWidget, QMainWindow, QMenuBar, QMenu, QDialog, QTabWidget, QTableView, QTableView::item, QScrollArea, QGroupBox, QPlainTextEdit, QLineEdit, QLabel, MainWindow
{
/* background-color: #303335; */
background: transparent;
color: #ffffff;
}
QMainWindow
{
border-image: url(':images/res/images/tile.png') 0 0 0 0 repeat repeat;
color: #ffffff;
}
QTabWidget QTabBar::tab {
padding-left:20px;
padding-right:20px;
padding-top:5px;
padding-bottom:5px;
border: 1px solid #525355;
/*background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.25, stop: 0 #747577, stop: 1 #3E4244);*/
background-color: rgba(0, 0, 0, 128);
}
QTabWidget QTabBar::tab:selected {
min-height: 10px;
/*background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.25, stop: 0 #525355, stop: 1 #303335);*/
background-color: rgba(0, 64, 0, 128);
color:#fff;
border: 1px ridge #000;
}
QTabWidget QTabBar::tab:hover {
/*background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.25, stop: 0 #747577, stop: 1 #3E4244);*/
background-color: rgba(0, 0, 0, 32);
color:#fff;
border: 1px ridge #fff;
min-height: 20px
}
QTabWidget::pane {
background-color: rgba(0, 0, 0, 128);
border: 2px solid rgb(0, 0, 0);
border-top-left-radius: 0px;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
border-top-right-radius: 4px;
top: -2px;
}
QStatusBar {
background-color: rgba(0, 0, 64, 128);
}
QHeaderView { /* Table Header */
/* background-color:#303335;*/
background-color: rgba(0, 0, 0, 64);
border:1px solid #fff;
}
QHeaderView::section { /* Table Header Sections */
qproperty-alignment:center;
/*background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.25, stop: 0 #747577, stop: 1 #3E4244);*/
background: transparent;
color:#fff;
min-height:25px;
font-weight:bold;
font-size:11px;
outline:0;
border:1px solid #525355;
border-right:1px solid #fff;
border-left:1px solid #fff;
padding-left:5px;
padding-right:5px;
padding-top:2px;
padding-bottom:2px;
}
QHeaderView::section:last {
border-right: 0px solid #d7d7d7;
}
QScrollArea {
background:transparent;
border:0px;
}
QTableView { /* Table - has to be selected as a class otherwise it throws off QCalendarWidget */
/*background:#303335;*/
background: transparent;
}
QTableView::item { /* Table Item */
/*background-color:#303335;*/
background: transparent;
border:1px solid #fff;
font-size:12px;
}
QTableView::item:selected { /* Table Item Selected */
background-color:#fff;
color:#000;
}
QMenuBar {
background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.25, stop: 0 #525355, stop: 1 #303335);
color: #fff;
}
QMenuBar::item {
background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.25, stop: 0 #525355, stop: 1 #303335);
color: #fff;
}
QMenuBar::item:selected {
background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.25, stop: 0 #747577, stop: 1 #3E4244);
}
QTabBar::tab {
background-color: rgba(0, 0, 0, 128);
min-width: 150px;
padding: 4px;
border-bottom: 2px solid rgb(68, 49, 141);
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
QTabBar::tab:selected {
/* font: bold; */
border: 2px solid rgb(68, 49, 141);
border-bottom: none;
}
QTabBar::tab:hover {
/* font: bold; */
border: 2px solid rgb(68, 49, 141);
}
QGroupBox {
background-color: rgba(0, 0, 0, 128);
font-weight: bold;
font-style: italic;
border: 1px solid rgba(0, 128, 0, 128);
border-radius: 4px;
padding: 4px;
margin-top: 16px;
}
QGroupBox::title {
subcontrol-origin: margin;
subcontrol-position: top left;
left: 8px;
padding-left: 3px;
padding-right: 3px;
padding-top: 6px;
padding-bottom: 8px;
}
QLineEdit, QPushButton, QPlainTextEdit {
background-color: rgba(10, 7, 20, 128);
min-width: 100px;
border: 1px solid rgb(68, 49, 141);
border-radius: 4px;
padding:5px;
}
QLineEdit:focus, QPushButton:pressed, QPlainTextEdit:focus {
border: 1px solid rgb(216, 00, 255);
}
QLineEdit:hover, QPushButton:hover, QPlainTextEdit:hover {
border: 1px solid rgb(216, 00, 255);
}
QLineEdit:disabled, QPushButton:disabled, QPlainTextEdit:disabled {
border: 1px solid rgb(64, 64, 64);
}
QComboBox {
background-color: rgba(10, 7, 20, 128);
min-height: 28px;
min-width: 80px;
border: 1px solid rgb(68, 49, 141);
border-radius: 4px;
}
QComboBox:hover {
border: 1px solid rgb(216, 00, 255);
}
QComboBox QAbstractItemView {
background-color: rgb(0, 0, 0);
border: 1px solid rgb(68, 49, 141);
border-radius: 4px;
}
QComboBox::item {
background-color: rgb(0, 0, 0);
border: 1px solid rgb(0, 0, 0);
border-radius: 4px;
height:28px;
}
QComboBox::item:selected { /* when user selects item using mouse or keyboard */
background-color: rgb(20, 15, 40);
border: 1px solid rgb(68, 49, 141);
border-radius: 4px;
}
QCheckBox::indicator, QRadioButton::indicator {
border: 2px solid rgb(68, 49, 141);
border-radius: 6px;
}
QCheckBox::indicator:checked, QRadioButton::indicator:checked {
background-color: rgba(0, 255, 0, 128);
}
QCheckBox::indicator:unchecked, QRadioButton::indicator:unchecked {
background-color: rgba(0, 16, 0, 128);
}
QCheckBox::indicator:hover, QRadioButton::indicator:hover {
border: 2px solid rgb(0, 192, 0);
}
QCheckBox::indicator:disabled, QRadioButton::indicator:disabled {
border: 2px solid rgb(64, 64, 64);
}
QWidget.FilledIconLabel /* targets custom ui widget by class name */
{
background-color: rgba(255, 255, 255, 64);
border: 2px solid rgb(255, 0, 0);
}

BIN
res/dark-01.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
res/images/tile.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

BIN
res/silentdragonlite_ar.qm

Binary file not shown.

2151
res/silentdragonlite_ar.ts

File diff suppressed because it is too large

BIN
res/silentdragonlite_ro.qm

Binary file not shown.

2001
res/silentdragonlite_ro.ts

File diff suppressed because it is too large

2
silentdragon-lite.pro

@ -94,7 +94,6 @@ HEADERS += \
src/3rdparty/qrcode/BitBuffer.hpp \
src/3rdparty/qrcode/QrCode.hpp \
src/3rdparty/qrcode/QrSegment.hpp \
src/3rdparty/json/json.hpp \
src/settings.h \
src/txtablemodel.h \
src/qrcodelabel.h \
@ -162,6 +161,7 @@ TRANSLATIONS = res/silentdragonlite_es.ts \
res/silentdragonlite_fa.ts \
res/silentdragonlite_id.ts \
res/silentdragonlite_ar.ts \
res/silentdragonlite_ro.ts \
res/silentdragonlite_tr.ts
include(singleapplication/singleapplication.pri)

18928
src/3rdparty/json/json.hpp

File diff suppressed because it is too large

42
src/Chat/Chat.cpp

@ -46,6 +46,45 @@ void ChatMemoEdit::setLenDisplayLabelChat(QLabel* label) {
this->lenDisplayLabelchat = label;
}
ChatMemoEditRequest::ChatMemoEditRequest(QWidget* parent) : QTextEdit(parent) {
QObject::connect(this, &QTextEdit::textChanged, this, &ChatMemoEditRequest::updateDisplayChatRequest);
}
void ChatMemoEditRequest::updateDisplayChatRequest() {
QString txt = this->toPlainText();
if (lenDisplayLabelchatRequest)
lenDisplayLabelchatRequest->setText(QString::number(txt.toUtf8().size()) + "/" + QString::number(maxlenchatrequest));
if (txt.toUtf8().size() <= maxlenchatrequest) {
// Everything is fine
if (sendRequestButton)
sendRequestButton->setEnabled(true);
if (lenDisplayLabelchatRequest)
lenDisplayLabelchatRequest->setStyleSheet("");
}
else {
// Overweight
if (sendRequestButton)
sendRequestButton->setEnabled(false);
if (lenDisplayLabelchatRequest)
lenDisplayLabelchatRequest->setStyleSheet("color: red;");
}
}
void ChatMemoEditRequest::setMaxLenChatRequest(int len) {
this->maxlenchatrequest = len;
updateDisplayChatRequest();
}
void ChatMemoEditRequest::SetSendRequestButton(QPushButton* button) {
this->sendRequestButton = button;
}
void ChatMemoEditRequest::setLenDisplayLabelChatRequest(QLabel* label) {
this->lenDisplayLabelchatRequest = label;
}
void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view, QLabel *label)
{
@ -59,7 +98,8 @@ void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view, QLabel *label)
if (
(p.getName() == ui->contactNameMemo->text().trimmed()) &&
(p.getPartnerAddress() == c.second.getAddress()) &&
(c.second.isOutgoing() == true))
(c.second.isOutgoing() == true))
{
QStandardItem *Items = new QStandardItem(c.second.toChatLine());

9
src/Chat/Helper/ChatDelegator.h

@ -37,7 +37,7 @@ class ListViewDelegate : public QAbstractItemDelegate
inline QSize sizeHint(QStyleOptionViewItem const &option, QModelIndex const &index) const;
};
inline ListViewDelegate::ListViewDelegate(QObject *parent): QAbstractItemDelegate(parent), d_radius(5), d_toppadding(5), d_bottompadding(3), d_leftpadding(5), d_rightpadding(5), d_verticalmargin(5), d_horizontalmargin(10), d_pointerwidth(4), d_pointerheight(17), d_widthfraction(.6)
inline ListViewDelegate::ListViewDelegate(QObject *parent): QAbstractItemDelegate(parent), d_radius(15), d_toppadding(15), d_bottompadding(3), d_leftpadding(5), d_rightpadding(5), d_verticalmargin(5), d_horizontalmargin(10), d_pointerwidth(4), d_pointerheight(25), d_widthfraction(.6)
{
}
@ -50,7 +50,7 @@ inline void ListViewDelegate::paint(QPainter *painter, QStyleOptionViewItem cons
bodydoc.setDefaultTextOption(textOption);
bodydoc.setDefaultFont(QFont("Roboto", 12));
QString bodytext(index.data(Qt::DisplayRole).toString());
bodydoc.setHtml(bodytext);
bodydoc.setHtml(bodytext.replace("\n", "<br>"));
qreal contentswidth = option.rect.width() * d_widthfraction - d_horizontalmargin - d_pointerwidth - d_leftpadding - d_rightpadding;
bodydoc.setTextWidth(contentswidth);
qreal bodyheight = bodydoc.size().height();
@ -173,7 +173,8 @@ inline QSize ListViewDelegate::sizeHint(QStyleOptionViewItem const &option, QMod
bodydoc.setDefaultTextOption(textOption);
bodydoc.setDefaultFont(QFont("Roboto", 12));
QString bodytext(index.data(Qt::DisplayRole).toString());
bodydoc.setHtml(bodytext);
bodydoc.setHtml(bodytext.replace("\n", "<br>"));
// the width of the contents are the (a fraction of the window width) minus (margins + padding + width of the bubble's tail)
qreal contentswidth = option.rect.width() * d_widthfraction - d_horizontalmargin - d_pointerwidth - d_leftpadding - d_rightpadding;
@ -190,4 +191,4 @@ inline QSize ListViewDelegate::sizeHint(QStyleOptionViewItem const &option, QMod
return size;
}
#endif
#endif

23
src/DataStore/ChatDataStore.cpp

@ -39,6 +39,18 @@ QString ChatDataStore::getPassword()
return _password;
}
QString ChatDataStore::getSendZaddr()
{
return _zaddr;
}
void ChatDataStore::setSendZaddr(QString zaddr)
{
_zaddr = zaddr;
}
void ChatDataStore::setPassword(QString password)
{
@ -47,15 +59,16 @@ void ChatDataStore::setPassword(QString password)
QString ChatDataStore::dump()
{
json chats;
chats["count"] = this->data.size();
json j = {};
QJsonObject chats;
chats["count"] = (qint64)this->data.size();
QJsonArray j;
for (auto &c: this->data)
{
j.push_back(c.second.toJson());
}
chats["chatitems"] = j;
return QString::fromStdString(chats.dump());
QJsonDocument jd_chats = QJsonDocument(chats);
return QLatin1String(jd_chats.toJson(QJsonDocument::Compact));
}
std::map<QString, ChatItem> ChatDataStore::getAllRawChatItems()
@ -124,4 +137,4 @@ std::map<QString, ChatItem> ChatDataStore::getAllMemos()
ChatDataStore* ChatDataStore::instance = nullptr;
bool ChatDataStore::instanced = false;
bool ChatDataStore::instanced = false;

9
src/DataStore/ChatDataStore.h

@ -1,7 +1,6 @@
#ifndef CHATDATASTORE_H
#define CHATDATASTORE_H
#include "../chatmodel.h"
using json = nlohmann::json;
class ChatDataStore
{
@ -26,9 +25,13 @@ class ChatDataStore
std::map<QString, ChatItem> getAllOldContactRequests();
std::map<QString, ChatItem> getAllMemos();
QString getPassword();
QString getSendZaddr();
void setPassword(QString Password);
void setSendZaddr(QString Password);
QString _password;
void setPassword(QString zaddr);
QString _zaddr;
QString dump();
@ -41,4 +44,4 @@ class ChatDataStore
#endif
#endif

13
src/DataStore/ContactDataStore.cpp

@ -33,9 +33,9 @@ ContactItem ContactDataStore::getData(QString key)
QString ContactDataStore::dump()
{
json contacts;
contacts["count"] = this->data.size();
json j = {};
QJsonObject contacts;
contacts["count"] = (qint64)this->data.size();
QJsonArray j = {};
for (auto &c: this->data)
{
qDebug() << c.second.toQTString();
@ -43,8 +43,11 @@ QString ContactDataStore::dump()
j.push_back(c.second.toJson());
}
contacts["contacts"] = j;
return QString::fromStdString(contacts.dump(4));
QJsonDocument jd_contacts = QJsonDocument(contacts);
return QLatin1String(jd_contacts.toJson(QJsonDocument::Compact));
// return QString::fromStdString(contacts.dump(4));
}
ContactDataStore* ContactDataStore::instance = nullptr;
bool ContactDataStore::instanced = false;
bool ContactDataStore::instanced = false;

3
src/DataStore/ContactDataStore.h

@ -2,7 +2,6 @@
#define CONTACTDATASTORE_H
#include "../Model/ContactItem.h"
#include <string>
using json = nlohmann::json;
class ContactDataStore
{
@ -31,4 +30,4 @@ class ContactDataStore
#endif
#endif

4
src/DataStore/SietchDataStore.h

@ -1,8 +1,6 @@
#ifndef SIETCHDATASTORE_H
#define SIETCHDATASTORE_H
using json = nlohmann::json;
class SietchDataStore
{
private:
@ -28,4 +26,4 @@ class SietchDataStore
}
};
#endif
#endif

4
src/FileSystem/FileSystem.h

@ -8,7 +8,7 @@
#include "../Model/ContactItem.h"
#include "../Crypto/FileEncryption.h"
#include <fstream>
using json = nlohmann::json;
class FileSystem
{
private:
@ -28,4 +28,4 @@ class FileSystem
};
#endif
#endif

24
src/Model/ChatItem.cpp

@ -184,17 +184,17 @@ QString ChatItem::toChatLine()
return line;
}
json ChatItem::toJson()
{
json j;
j["_timestamp"] = _timestamp;
j["_address"] = _address.toStdString();
j["_contact"] = _contact.toStdString();
j["_memo"] = _memo.toStdString();
j["_requestZaddr"] = _requestZaddr.toStdString();
j["_type"] = _type.toStdString();
j["_cid"] = _cid.toStdString();
j["_txid"] = _txid.toStdString();
QJsonValue ChatItem::toJson()
{
QJsonObject j;
j["_timestamp"] = (qint64)_timestamp;
j["_address"] = _address;
j["_contact"] = _contact;
j["_memo"] = _memo;
j["_requestZaddr"] = _requestZaddr;
j["_type"] = _type;
j["_cid"] = _cid;
j["_txid"] = _txid;
j["_confirmations"] = _confirmations;
j["_outgoing"] = _outgoing;
return j;
@ -203,4 +203,4 @@ json ChatItem::toJson()
ChatItem::~ChatItem()
{
}
}

5
src/Model/ChatItem.h

@ -5,7 +5,6 @@
#define CHATITEM_H
#include <QString>
using json = nlohmann::json;
class ChatItem
{
@ -53,8 +52,8 @@ class ChatItem
void notarized();
void contact(bool iscontact);
QString toChatLine();
json toJson();
QJsonValue toJson();
~ChatItem();
};
#endif
#endif

16
src/Model/ContactItem.cpp

@ -86,13 +86,13 @@ QString ContactItem::toQTString()
return _name + "|" + _partnerAddress + "|" + _myAddress + "|" + _cid + "|" + _avatar;
}
json ContactItem::toJson()
QJsonValue ContactItem::toJson()
{
json j;
j["_myAddress"] = _myAddress.toStdString();
j["_partnerAddress"] = _partnerAddress.toStdString();
j["_name"] = _name.toStdString();
j["_cid"] = _cid.toStdString();
j["_avatar"] = _avatar.toStdString();
QJsonObject j;
j["_myAddress"] = _myAddress;
j["_partnerAddress"] = _partnerAddress;
j["_name"] = _name;
j["_cid"] = _cid;
j["_avatar"] = _avatar;
return j;
}
}

5
src/Model/ContactItem.h

@ -6,7 +6,6 @@
#include <vector>
#include <QString>
#include "mainwindow.h"
using json = nlohmann::json;
class ContactItem
{
@ -34,7 +33,7 @@ public:
void setcid(QString cid);
void setAvatar(QString avatar);
QString toQTString();
json toJson();
QJsonValue toJson();
};
#endif
#endif

2
src/Model/ContactRequest.cpp

@ -93,4 +93,4 @@ void ContactRequest::clear()
ContactRequest::~ContactRequest()
{
clear();
}
}

3
src/Model/ContactRequest.h

@ -5,7 +5,6 @@
#define CONTACTREQUEST_H
#include <QString>
using json = nlohmann::json;
class ContactRequest
{
@ -37,4 +36,4 @@ class ContactRequest
~ContactRequest();
};
#endif
#endif

96
src/addressbook.cpp

@ -153,8 +153,8 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target)
bool sapling = true;
try
{
rpc->createNewZaddr(sapling, [=] (json reply) {
QString myAddr = QString::fromStdString(reply.get<json::array_t>()[0]);
rpc->createNewZaddr(sapling, [=] (QJsonValue reply) {
QString myAddr = reply.toArray()[0].toString();
QString message = QString("New Chat Address for your partner: ") + myAddr;
QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces);
@ -386,25 +386,56 @@ AddressBook::AddressBook()
void AddressBook::readFromStorage()
{
QFile file(AddressBook::writeableFile());
auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
QString target_decaddr_file = dir.filePath("addresslabels.dat");
QString target_encaddr_file = dir.filePath("addresslabels.dat.enc");
QFile file(target_encaddr_file);
QFile file1(target_decaddr_file);
if (file.exists())
{
// Decrypt first
QString passphraseHash = DataStore::getChatDataStore()->getPassword();
int length = passphraseHash.length();
char *sequence1 = NULL;
sequence1 = new char[length+1];
strncpy(sequence1, passphraseHash.toUtf8(), length+1);
#define PassphraseHashEnd ((const unsigned char *) sequence1)
#define MESSAGE_LEN length
#define PASSWORD sequence
#define KEY_LEN crypto_box_SEEDBYTES
const QByteArray ba = QByteArray::fromHex(passphraseHash.toLatin1());
const unsigned char *pwHash= reinterpret_cast<const unsigned char *>(ba.constData());
FileEncryption::decrypt(target_decaddr_file, target_encaddr_file, pwHash);
allLabels.clear();
file.open(QIODevice::ReadOnly);
QDataStream in(&file); // read the data serialized from the file
file1.open(QIODevice::ReadOnly);
QDataStream in(&file1); // read the data serialized from the file
QString version;
in >> version;
QList<QList<QString>> stuff;
in >> stuff;
//////////////found old addrbook, and rename it to .bak
if (version != "v2")
if (version == "v1")
{
auto filename = QStringLiteral("addresslabels.dat");
auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
QFile address(dir.filePath(filename));
qDebug() << "is v1";
address.rename(dir.filePath("addresslabels.bak"));
}else{
@ -419,21 +450,16 @@ void AddressBook::readFromStorage()
// qDebug() << "Read " << version << " Hush contacts from disk...";
file.close();
file1.close();
FileEncryption::encrypt(target_encaddr_file, target_decaddr_file, pwHash);
file1.remove();
}
else
{
qDebug() << "No Hush contacts found on disk!";
}
// Special.
// Add the default silentdragon donation address if it isn't already present
// QList<QString> allAddresses;
// std::transform(allLabels.begin(), allLabels.end(),
// std::back_inserter(allAddresses), [=] (auto i) { return i.getPartnerAddress(); });
// if (!allAddresses.contains(Settings::getDonationAddr(true))) {
// allLabels.append(QPair<QString, QString>("silentdragon donation", Settings::getDonationAddr(true)));
// }
}
@ -442,12 +468,36 @@ void AddressBook::writeToStorage()
//FileSystem::getInstance()->writeContacts(AddressBook::writeableFile(), DataStore::getContactDataStore()->dump());
// FileSystem::getInstance()->writeContactsOldFormat(AddressBook::writeableFile(), allLabels);
QString passphraseHash = DataStore::getChatDataStore()->getPassword();
int length = passphraseHash.length();
char *sequence1 = NULL;
sequence1 = new char[length+1];
strncpy(sequence1, passphraseHash.toUtf8(), length+1);
#define PassphraseHashEnd ((const unsigned char *) sequence1)
#define MESSAGE_LEN length
#define PASSWORD sequence
#define KEY_LEN crypto_box_SEEDBYTES
const QByteArray ba = QByteArray::fromHex(passphraseHash.toLatin1());
const unsigned char *pwHash= reinterpret_cast<const unsigned char *>(ba.constData());
QFile file(AddressBook::writeableFile());
auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
QString target_encaddr_file = dir.filePath("addresslabels.dat.enc");
QString target_decaddr_file = dir.filePath("addresslabels.dat");
FileEncryption::decrypt(target_decaddr_file, target_encaddr_file, pwHash);
QFile file(target_decaddr_file);
file.open(QIODevice::ReadWrite | QIODevice::Truncate);
QDataStream out(&file); // we will serialize the data into the file
QList<QList<QString>> contacts;
for(auto &item: allLabels)
{
QList<QString> c;
@ -456,10 +506,20 @@ void AddressBook::writeToStorage()
c.push_back(item.getMyAddress());
c.push_back(item.getCid());
c.push_back(item.getAvatar());
contacts.push_back(c);
contacts.push_back(c);
}
out << QString("v2") << contacts;
qDebug()<<"schreibe in Datei: ";
file.close();
FileEncryption::encrypt(target_encaddr_file, target_decaddr_file , pwHash);
QFile file1(target_decaddr_file);
file1.remove();
qDebug()<<"encrypt Addrbook writeToStorage";
}
QString AddressBook::writeableFile()

171
src/chatmodel.cpp

@ -163,7 +163,7 @@ void MainWindow::renderContactRequest(){
if ((c.second.isOutgoing() == false) && (label_contact == c.second.getRequestZaddr()))
if ((c.second.isOutgoing() == false) && (label_contact == c.second.getRequestZaddr() && (c.second.getMemo().startsWith("{") == false)))
{
@ -194,12 +194,12 @@ void MainWindow::renderContactRequest(){
QString label_contactold = index.data(Qt::DisplayRole).toString();
QStandardItemModel* contactMemo = new QStandardItemModel();
if ((c.second.isOutgoing() == false) && (label_contactold == c.second.getContact()))
if ((c.second.isOutgoing() == false) && (label_contactold == c.second.getContact()) && (c.second.getMemo().startsWith("{") == false))
{
QStandardItem* Items = new QStandardItem(c.second.getMemo());
contactMemo->appendRow(Items);
contactMemo->appendRow(Items);
requestContact.requestMemo->setModel(contactMemo);
requestContact.requestMemo->show();
@ -255,7 +255,7 @@ void MainWindow::renderContactRequest(){
ui->listContactWidget);
QMessageBox::information(this, "Added Contact","successfully added your new contact. You can now Chat with this contact");
dialog.close();
});
dialog.exec();
@ -443,43 +443,29 @@ Tx MainWindow::createTxFromChatPage() {
int lengthmemo = memoplain.length();
char *memoplainchar = NULL;
memoplainchar = new char[lengthmemo+1];
strncpy(memoplainchar, memoplain.toLocal8Bit(), lengthmemo +1);
/////////We convert the CID from QString to unsigned char*, so we can encrypt it later
int lengthcid = cid.length();
char *cidchar = NULL;
cidchar = new char[lengthcid+1];
strncpy(cidchar, cid.toLocal8Bit(), lengthcid +1);
QString pubkey = this->getPubkeyByAddress(addr);
QString passphrase = DataStore::getChatDataStore()->getPassword();
QString hashEncryptionKey = passphrase;
int length = hashEncryptionKey.length();
memoplainchar = new char[lengthmemo+2];
strncpy(memoplainchar, memoplain.toUtf8(), lengthmemo +1);
QString pubkey = this->getPubkeyByAddress(addr);
QString passphraseHash = DataStore::getChatDataStore()->getPassword();
int length = passphraseHash.length();
////////////////Generate the secretkey for our message encryption
char *hashEncryptionKeyraw = NULL;
hashEncryptionKeyraw = new char[length+1];
strncpy(hashEncryptionKeyraw, hashEncryptionKey.toLocal8Bit(), length +1);
char *hashEncryptionKeyraw = NULL;
hashEncryptionKeyraw = new char[length+1];
strncpy(hashEncryptionKeyraw, passphraseHash.toUtf8(), length+1);
#define MESSAGEAS1 ((const unsigned char *) hashEncryptionKeyraw)
#define MESSAGEAS1_LEN length
unsigned char hash[crypto_kx_SEEDBYTES];
crypto_hash_sha256(hash,MESSAGEAS1, MESSAGEAS1_LEN);
unsigned char sk[crypto_kx_SECRETKEYBYTES];
unsigned char pk[crypto_kx_PUBLICKEYBYTES];
unsigned char server_rx[crypto_kx_SESSIONKEYBYTES], server_tx[crypto_kx_SESSIONKEYBYTES];
if (crypto_kx_seed_keypair(pk,sk,
hash) !=0) {
MESSAGEAS1) !=0) {
}
////////////////Get the pubkey from Bob, so we can create the share key
@ -493,10 +479,17 @@ Tx MainWindow::createTxFromChatPage() {
}
// Let's try to preserve Unicode characters
QByteArray ba_memo = memoplain.toUtf8();
int ba_memo_length = ba_memo.size();
#define MESSAGE (const unsigned char *) ba_memo.data()
#define MESSAGE_LEN ba_memo_length
////////////Now lets encrypt the message Alice send to Bob//////////////////////////////
#define MESSAGE (const unsigned char *) memoplainchar
#define MESSAGE_LEN lengthmemo
//#define MESSAGE (const unsigned char *) memoplainchar
//#define MESSAGE_LEN lengthmemo
#define CIPHERTEXT_LEN (crypto_secretstream_xchacha20poly1305_ABYTES + MESSAGE_LEN)
unsigned char ciphertext[CIPHERTEXT_LEN];
unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES];
@ -710,16 +703,22 @@ void::MainWindow::addContact()
request.setupUi(&dialog);
Settings::saveRestore(&dialog);
QObject::connect(request.newZaddr, &QPushButton::clicked, [&] () {
try
request.memorequest->setLenDisplayLabelChatRequest(request.memoSizeChatRequest);
try
{
bool sapling = true;
rpc->createNewZaddr(sapling, [=] (json reply) {
QString myAddr = QString::fromStdString(reply.get<json::array_t>()[0]);
rpc->createNewZaddr(sapling, [=] (QJsonValue reply) {
QString myAddr = reply.toArray()[0].toString();
rpc->refreshAddresses();
request.myzaddr->setText(myAddr);
ui->listReceiveAddresses->insertItem(0, myAddr);
ui->listReceiveAddresses->setCurrentIndex(0);
DataStore::getChatDataStore()->setSendZaddr(myAddr);
qDebug()<<"Zaddr: "<<myAddr;
});
}catch(...)
@ -728,10 +727,9 @@ QObject::connect(request.newZaddr, &QPushButton::clicked, [&] () {
qDebug() << QString("Caught something nasty with myZaddr Contact");
}
});
QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces);
QObject::connect(request.sendRequestButton, &QPushButton::clicked, [&] () {
QString addr = request.zaddr->text();
@ -748,78 +746,67 @@ QObject::connect(request.newZaddr, &QPushButton::clicked, [&] () {
contactRequest.setAvatar(avatar);
contactRequest.setLabel(label);
});
QObject::connect(request.sendRequestButton, &QPushButton::clicked, this, &MainWindow::saveandsendContact);
// QObject::connect(request.onlyAdd, &QPushButton::clicked, this, &MainWindow::saveContact);
});
QObject::connect(request.sendRequestButton, &QPushButton::clicked, this, &MainWindow::saveandsendContact);
// QObject::connect(request.onlyAdd, &QPushButton::clicked, this, &MainWindow::saveContact);
dialog.exec();
rpc->refreshContacts(ui->listContactWidget);
}
void MainWindow::saveandsendContact()
{
this->ContactRequest();
this->ContactRequest();
}
// Create a Tx for a contact Request
Tx MainWindow::createTxForSafeContactRequest()
{
Tx tx;
{
CAmount totalAmt;
QString amtStr = "0";
CAmount amt;
QString headerbytes = "";
amt = CAmount::fromDecimalString("0");
totalAmt = totalAmt + amt;
{
CAmount totalAmt;
QString amtStr = "0";
CAmount amt;
QString headerbytes = "";
amt = CAmount::fromDecimalString("0");
totalAmt = totalAmt + amt;
QString cid = contactRequest.getCid();
QString myAddr = contactRequest.getSenderAddress();
QString type = "Cont";
QString addr = contactRequest.getReceiverAddress();
QString cid = contactRequest.getCid();
QString myAddr = DataStore::getChatDataStore()->getSendZaddr();
QString type = "Cont";
QString addr = contactRequest.getReceiverAddress();
QString memo = contactRequest.getMemo();
// QString privkey = rpc->fetchPrivKey(myAddr);
QString passphrase = DataStore::getChatDataStore()->getPassword();
QString hashEncryptionKey = passphrase;
int length = hashEncryptionKey.length();
////////////////Generate the secretkey for our message encryption
char *hashEncryptionKeyraw = NULL;
hashEncryptionKeyraw = new char[length+1];
strncpy(hashEncryptionKeyraw, hashEncryptionKey.toLocal8Bit(), length +1);
#define MESSAGEAS1 ((const unsigned char *) hashEncryptionKeyraw)
#define MESSAGEAS1_LEN length
QString memo = contactRequest.getMemo();
QString passphrase = DataStore::getChatDataStore()->getPassword();
int length = passphrase.length();
unsigned char hash[crypto_kx_SEEDBYTES];
////////////////Generate the secretkey for our message encryption
char *hashEncryptionKeyraw = NULL;
hashEncryptionKeyraw = new char[length+1];
strncpy(hashEncryptionKeyraw, passphrase.toUtf8(), length +1);
crypto_hash_sha256(hash,MESSAGEAS1, MESSAGEAS1_LEN);
#define MESSAGEAS1 ((const unsigned char *) hashEncryptionKeyraw)
#define MESSAGEAS1_LEN length
unsigned char sk[crypto_kx_SECRETKEYBYTES];
unsigned char pk[crypto_kx_PUBLICKEYBYTES];
unsigned char sk[crypto_kx_SECRETKEYBYTES];
unsigned char pk[crypto_kx_PUBLICKEYBYTES];
if (crypto_kx_seed_keypair(pk,sk,
hash) !=0) {
}
if (crypto_kx_seed_keypair(pk, sk, MESSAGEAS1) !=0) {
//
}
QString publicKey = QByteArray(reinterpret_cast<const char*>(pk), crypto_kx_PUBLICKEYBYTES).toHex();
QString publicKey = QByteArray(reinterpret_cast<const char*>(pk), crypto_kx_PUBLICKEYBYTES).toHex();
QString hmemo= createHeaderMemo(type,cid,myAddr,"", publicKey);
QString hmemo= createHeaderMemo(type,cid,myAddr,"", publicKey);
tx.toAddrs.push_back(ToFields{addr, amt, hmemo});
tx.toAddrs.push_back(ToFields{addr, amt, memo});
tx.fee = Settings::getMinerFee();
}
tx.toAddrs.push_back(ToFields{addr, amt, hmemo});
tx.toAddrs.push_back(ToFields{addr, amt, memo});
tx.fee = Settings::getMinerFee();
}
return tx;
}
@ -835,17 +822,7 @@ void MainWindow::ContactRequest() {
return;
}
if (contactRequest.getSenderAddress().size() > 80) {
QMessageBox msg(QMessageBox::Critical, tr("Missing HushChat Address"),
tr("You have to create your HushChat address to send a contact request,\n"),
QMessageBox::Ok, this);
msg.exec();
return;
}
int max = 235;
int max = 512;
QString chattext = contactRequest.getMemo();;
int size = chattext.size();
@ -854,7 +831,7 @@ void MainWindow::ContactRequest() {
// auto addr = "";
// if (! Settings::isZAddress(AddressBook::addressFromAddressLabel(addr->text()))) {
QMessageBox msg(QMessageBox::Critical, tr("Your Message is too long"),
tr("You can only write messages with 235 character maximum \n") + tr("\n Please reduce your message to 235 character."),
tr("You can only write messages with 512 character maximum \n") + tr("\n Please reduce your message to 235 character."),
QMessageBox::Ok, this);
msg.exec();

62
src/connection.cpp

@ -8,7 +8,15 @@
#include "../lib/silentdragonlitelib.h"
#include "precompiled.h"
using json = nlohmann::json;
#ifdef Q_OS_WIN
auto dirwalletconnection = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite/silentdragonlite-wallet.dat");
#endif
#ifdef Q_OS_MACOS
auto dirwalletconnection = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite/silentdragonlite-wallet.dat");
#endif
#ifdef Q_OS_LINUX
auto dirwalletconnection = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".silentdragonlite/silentdragonlite-wallet.dat");
#endif
ConnectionLoader::ConnectionLoader(MainWindow* main, Controller* rpc)
{
@ -93,17 +101,17 @@ void ConnectionLoader::doAutoConnect()
auto me = this;
// After the lib is initialized, try to do get info
connection->doRPC("info", "", [=](auto reply) {
connection->doRPC("info", "", [=](QJsonValue reply) {
// If success, set the connection
main->logger->write("Connection is online.");
connection->setInfo(reply);
isSyncing = new QAtomicInteger<bool>();
isSyncing->store(true);
isSyncing->storeRelaxed(true);
// Do a sync at startup
syncTimer = new QTimer(main);
connection->doRPCWithDefaultErrorHandling("sync", "", [=](auto) {
isSyncing->store(false);
connection->doRPCWithDefaultErrorHandling("sync", "", [=](QJsonValue) {
isSyncing->storeRelaxed(false);
// Cancel the timer
syncTimer->deleteLater();
// When sync is done, set the connection
@ -113,13 +121,13 @@ void ConnectionLoader::doAutoConnect()
// 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()) {
if (isSyncing != nullptr && isSyncing->loadRelaxed()) {
// Get the sync status
connection->doRPC("syncstatus", "", [=](json reply) {
if (isSyncing != nullptr && reply.find("synced_blocks") != reply.end())
connection->doRPC("syncstatus", "", [=](QJsonValue reply) {
if (isSyncing != nullptr && !reply.toObject()["synced_blocks"].isUndefined())
{
qint64 synced = reply["synced_blocks"].get<json::number_unsigned_t>();
qint64 total = reply["total_blocks"].get<json::number_unsigned_t>();
qint64 synced = reply["synced_blocks"].toInt();
qint64 total = reply["total_blocks"].toInt();
me->showInformation(
"Synced " + QString::number(synced) + " / " + QString::number(total)
);
@ -154,6 +162,9 @@ void ConnectionLoader::doRPCSetConnection(Connection* conn)
rpc->setConnection(conn);
d->accept();
QTimer::singleShot(1, [=]() { delete this; });
QFile plaintextWallet(dirwalletconnection);
plaintextWallet.remove();
}
Connection* ConnectionLoader::makeConnection(std::shared_ptr<ConnectionConfig> config)
@ -202,21 +213,26 @@ void Executor::run()
{
char* resp = litelib_execute(this->cmd.toStdString().c_str(), this->args.toStdString().c_str());
QString reply = litelib_process_response(resp);
//qDebug() << "RPC Reply=" << reply;
auto parsed = json::parse(
reply.toStdString().c_str(),
nullptr,
false
);
if (parsed.is_discarded() || parsed.is_null())
QJsonDocument parsed = QJsonDocument::fromJson(reply.toUtf8());
if (parsed.isEmpty() || parsed.isNull())
emit handleError(reply);
else
emit responseReady(parsed);
{
QJsonValue retval;
if (parsed.isObject())
retval = QJsonValue(parsed.object());
else if (parsed.isArray())
retval = QJsonValue(parsed.array());
emit responseReady(retval);
}
}
void Callback::processRPCCallback(json resp)
void Callback::processRPCCallback(QJsonValue resp)
{
this->cb(resp);
// Destroy self
@ -235,10 +251,10 @@ Connection::Connection(MainWindow* m, std::shared_ptr<ConnectionConfig> conf)
this->config = conf;
this->main = m;
// Register the JSON type as a type that can be passed between signals and slots.
qRegisterMetaType<json>("json");
qRegisterMetaType<QJsonValue>("QJsonValue");
}
void Connection::doRPC(const QString cmd, const QString args, const std::function<void(json)>& cb, const std::function<void(QString)>& errCb)
void Connection::doRPC(const QString cmd, const QString args, const std::function<void(QJsonValue)>& cb, const std::function<void(QString)>& errCb)
{
if (shutdownInProgress)
// Ignoring RPC because shutdown in progress
@ -257,14 +273,14 @@ void Connection::doRPC(const QString cmd, const QString args, const std::functio
QThreadPool::globalInstance()->start(runner);
}
void Connection::doRPCWithDefaultErrorHandling(const QString cmd, const QString args, const std::function<void(json)>& cb)
void Connection::doRPCWithDefaultErrorHandling(const QString cmd, const QString args, const std::function<void(QJsonValue)>& cb)
{
doRPC(cmd, args, cb, [=] (QString err) {
this->showTxError(err);
});
}
void Connection::doRPCIgnoreError(const QString cmd, const QString args, const std::function<void(json)>& cb)
void Connection::doRPCIgnoreError(const QString cmd, const QString args, const std::function<void(QJsonValue)>& cb)
{
doRPC(cmd, args, cb, [=] (auto) {
// Ignored error handling

34
src/connection.h

@ -6,8 +6,6 @@
#include "precompiled.h"
using json = nlohmann::json;
class Controller;
struct ConnectionConfig {
@ -57,15 +55,15 @@ private:
class Callback: public QObject {
Q_OBJECT
public:
Callback(const std::function<void(json)> cb, const std::function<void(QString)> errCb) { this->cb = cb; this->errCb = errCb;}
Callback(const std::function<void(QJsonValue)> cb, const std::function<void(QString)> errCb) { this->cb = cb; this->errCb = errCb;}
~Callback() = default;
public slots:
void processRPCCallback(json resp);
void processRPCCallback(QJsonValue resp);
void processError(QString error);
private:
std::function<void(json)> cb;
private:
std::function<void(QJsonValue)> cb;
std::function<void(QString)> errCb;
};
@ -73,14 +71,14 @@ private:
/**
* A runnable that runs some lightclient Command in a non-UI thread.
* It emits the "responseReady" signal, which should be processed in a GUI thread.
*
*
* Since the autoDelete flag is ON, the runnable should be destroyed automatically
* by the threadpool.
* by the threadpool.
*/
class Executor : public QObject, public QRunnable {
Q_OBJECT
public:
public:
Executor(QString cmd, QString args) {
this->cmd = cmd;
this->args = args;
@ -92,12 +90,12 @@ public:
virtual void run();
signals:
void responseReady(json);
void responseReady(QJsonValue);
void handleError(QString);
private:
QString cmd;
QString args;
QString args;
};
/**
@ -116,20 +114,20 @@ public:
void shutdown();
void doRPC(const QString cmd, const QString args, const std::function<void(json)>& cb,
void doRPC(const QString cmd, const QString args, const std::function<void(QJsonValue)>& cb,
const std::function<void(QString)>& errCb);
void doRPCWithDefaultErrorHandling(const QString cmd, const QString args, const std::function<void(json)>& cb);
void doRPCIgnoreError(const QString cmd, const QString args, const std::function<void(json)>& cb) ;
void doRPCWithDefaultErrorHandling(const QString cmd, const QString args, const std::function<void(QJsonValue)>& cb);
void doRPCIgnoreError(const QString cmd, const QString args, const std::function<void(QJsonValue)>& cb) ;
void showTxError(const QString& error);
json getInfo() { return serverInfo; }
void setInfo(const json& info) { serverInfo = info; }
QJsonValue getInfo() { return serverInfo; }
void setInfo(const QJsonValue& info) { serverInfo = info; }
private:
bool shutdownInProgress = false;
json serverInfo;
QJsonValue serverInfo;
};
#endif

27
src/contactrequest.ui

@ -122,22 +122,6 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="newZaddr">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Create New Address</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
@ -394,7 +378,7 @@
</layout>
</item>
<item row="11" column="0">
<widget class="QLabel" name="memoSizeChat">
<widget class="QLabel" name="memoSizeChatRequest">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
@ -407,7 +391,7 @@
</widget>
</item>
<item row="9" column="0" colspan="6">
<widget class="QTextEdit" name="memorequest">
<widget class="ChatMemoEditRequest" name="memorequest">
<property name="placeholderText">
<string>Add a memo to your request</string>
</property>
@ -453,6 +437,13 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ChatMemoEditRequest</class>
<extends>QTextEdit</extends>
<header>mainwindow.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>

1173
src/controller.cpp

File diff suppressed because it is too large

35
src/controller.h

@ -19,7 +19,6 @@
#include "Model/ContactRequestChatItem.h"
#include "Model/ContactItem.h"
#include "contactmodel.h"
using json = nlohmann::json;
struct WatchedTx {
QString opid;
@ -40,7 +39,7 @@ public:
Connection* getConnection() { return zrpc->getConnection(); }
void setConnection(Connection* c);
void refresh(bool force = false);
void refreshAddresses();
void refreshAddresses();
int getLag();
void setLag(int lag);
int _lag;
@ -91,7 +90,7 @@ public:
const std::function<void(QString txid)> submitted,
const std::function<void(QString txid, QString errStr)> error);
void fillTxJsonParams(json& params, Tx tx);
void fillTxJsonParams(QJsonArray &params, Tx tx);
const TxTableModel* getTransactionsModel() { return transactionsTableModel; }
@ -99,58 +98,58 @@ public:
void noConnection();
bool isEmbedded() { return ehushd != nullptr; }
void encryptWallet(QString password, const std::function<void(json)>& cb) {
void encryptWallet(QString password, const std::function<void(QJsonValue)>& cb) {
zrpc->encryptWallet(password, cb);
}
void removeWalletEncryption(QString password, const std::function<void(json)>& cb) {
void removeWalletEncryption(QString password, const std::function<void(QJsonValue)>& cb) {
zrpc->removeWalletEncryption(password, cb); }
void saveWallet(const std::function<void(json)>& cb) { zrpc->saveWallet(cb); }
void saveWallet(const std::function<void(QJsonValue)>& cb) { zrpc->saveWallet(cb); }
void clearWallet(const std::function<void(json)>& cb) { zrpc->clearWallet(cb); }
void clearWallet(const std::function<void(QJsonValue)>& cb) { zrpc->clearWallet(cb); }
void createNewZaddr(bool sapling, const std::function<void(json)>& cb) {
void createNewZaddr(bool sapling, const std::function<void(QJsonValue)>& cb) {
unlockIfEncrypted([=] () {
zrpc->createNewZaddr(sapling, cb);
}, [=](){});
}
void createNewTaddr(const std::function<void(json)>& cb) {
void createNewTaddr(const std::function<void(QJsonValue)>& cb) {
unlockIfEncrypted([=] () {
zrpc->createNewTaddr(cb);
}, [=](){});
}
void createNewSietchZaddr(const std::function<void(json)>& cb) {
void createNewSietchZaddr(const std::function<void(QJsonValue)>& cb) {
unlockIfEncrypted([=] () {
zrpc->createNewSietchZaddr(cb);
}, [=](){});
}
void fetchPrivKey(QString addr, const std::function<void(json)>& cb) {
void fetchPrivKey(QString addr, const std::function<void(QJsonValue)>& cb) {
unlockIfEncrypted([=] () {
zrpc->fetchPrivKey(addr, cb);
},
[=]() {
cb({ {"error", "Failed to unlock wallet"} });
cb(QJsonObject({ {"error", "Failed to unlock wallet"} }) );
});
}
void fetchAllPrivKeys(const std::function<void(json)> cb) {
void fetchAllPrivKeys(const std::function<void(QJsonValue)> cb) {
unlockIfEncrypted([=] () {
zrpc->fetchAllPrivKeys(cb);
},
[=]() {
cb({ {"error", "Failed to unlock wallet"} });
cb(QJsonObject({ {"error", "Failed to unlock wallet"} }));
});
}
void fetchSeed(const std::function<void(json)> cb) {
void fetchSeed(const std::function<void(QJsonValue)> cb) {
unlockIfEncrypted([=] () {
zrpc->fetchSeed(cb);
},
[=]() {
cb({ {"error", "Failed to unlock wallet"} });
cb(QJsonObject({ {"error", "Failed to unlock wallet"} }));
});
}
@ -163,12 +162,12 @@ public:
private:
void processInfo(const json&);
void processInfo(const QJsonValue&);
void refreshBalances();
void refreshTransactions();
void processUnspent (const json& reply, QMap<QString, CAmount>* newBalances, QList<UnspentOutput>* newUnspentOutputs);
void processUnspent (const QJsonValue& reply, QMap<QString, CAmount>* newBalances, QList<UnspentOutput>* newUnspentOutputs);
void updateUI (bool anyUnconfirmed);
void updateUIBalances ();

113
src/firsttimewizard.cpp

@ -8,7 +8,6 @@
#include "../lib/silentdragonlitelib.h"
using json = nlohmann::json;
FirstTimeWizard::FirstTimeWizard(bool dangerous, QString server)
{
@ -16,6 +15,18 @@ FirstTimeWizard::FirstTimeWizard(bool dangerous, QString server)
this->dangerous = dangerous;
this->server = server;
////backup addresslabels.dat if there is one, to restore it later
auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
QString addressbook = dir.filePath("addresslabels.dat.enc");
QFile file(addressbook);
if (file.exists())
{
file.rename(dir.filePath("addresslabels.dat.enc-backup"));
}
// Create the pages
setPage(Page_NewOrRestore, new NewOrRestorePage(this));
setPage(Page_New, new NewSeedPage(this));
@ -40,34 +51,74 @@ int FirstTimeWizard::nextId() const {
NewOrRestorePage::NewOrRestorePage(FirstTimeWizard *parent) : QWizardPage(parent) {
setTitle("Create or Restore wallet.");
QWidget* pageWidget = new QWidget();
Ui_CreateWalletForm form;
form.setupUi(pageWidget);
QGraphicsScene* scene = new QGraphicsScene();
QGraphicsView* view = new QGraphicsView(scene);
form.Logo->setScene(scene);
QPixmap pixmap(":/icons/res/dark-01.png");
scene->addPixmap(pixmap);
form.Logo->show();
parent->button(QWizard::CommitButton)->setEnabled(false);
setButtonText(QWizard::CommitButton, "Next");
auto fnPasswordEdited = [=](const QString&) {
// Enable the Finish button if the passwords match.
QString Password = form.txtPassword->text();
QString passphraseBlank = form.txtPassword->text();
QString passphrase = QString("HUSH3") + passphraseBlank + QString("SDL");
if (!form.txtPassword->text().isEmpty() &&
form.txtPassword->text() == form.txtConfirmPassword->text() && Password.size() >= 16) {
form.txtPassword->text() == form.txtConfirmPassword->text() && passphraseBlank.size() >= 16 ){
form.lblPasswordMatch->setText("");
parent->button(QWizard::CommitButton)->setEnabled(true);
setButtonText(QWizard::CommitButton, "Next");
form.radioRestoreWallet->setEnabled(true);
form.radioNewWallet->setEnabled(true);
form.radioNewWallet->setChecked(true);
DataStore::getChatDataStore()->setPassword(Password);
int length = passphrase.length();
char *sequence = NULL;
sequence = new char[length+1];
strncpy(sequence, passphrase.toUtf8(), length +1);
QString passphraseHash = blake3_PW(sequence);
char *sequence1 = NULL;
sequence1 = new char[length+1];
strncpy(sequence1, passphraseHash.toUtf8(), length+1);
#define MESSAGE ((const unsigned char *) sequence)
#define MESSAGE_LEN length
#define hash ((const unsigned char *) sequence1)
#define PASSWORD sequence
#define KEY_LEN crypto_box_SEEDBYTES
unsigned char key[KEY_LEN];
if (crypto_pwhash
(key, sizeof key, PASSWORD, strlen(PASSWORD), hash,
crypto_pwhash_OPSLIMIT_SENSITIVE, crypto_pwhash_MEMLIMIT_SENSITIVE,
crypto_pwhash_ALG_DEFAULT) != 0) {
/* out of memory */
}
QString passphraseHash1 = QByteArray(reinterpret_cast<const char*>(key), KEY_LEN).toHex();
DataStore::getChatDataStore()->setPassword(passphraseHash1);
//main->setPassword(Password);
//qDebug()<<"Objekt gesetzt";
// Exclusive buttons
QObject::connect(form.radioNewWallet, &QRadioButton::clicked, [=](bool checked) {
if (checked) {
@ -82,6 +133,13 @@ DataStore::getChatDataStore()->setPassword(Password);
}
});
QObject::connect(form.TOS, &QRadioButton::clicked, [=](bool checked) {
if (checked) {
parent->button(QWizard::CommitButton)->setEnabled(true);
}
});
@ -106,6 +164,8 @@ DataStore::getChatDataStore()->setPassword(Password);
form.radioRestoreWallet->setEnabled(false);
form.radioNewWallet->setEnabled(false);
setCommitPage(true);
}
@ -130,14 +190,15 @@ void NewSeedPage::initializePage() {
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()) {
QByteArray ba_reply = reply.toUtf8();
QJsonDocument jd_reply = QJsonDocument::fromJson(ba_reply);
QJsonObject parsed = jd_reply.object();
if (parsed.isEmpty() || parsed["seed"].isNull()) {
form.txtSeed->setPlainText(tr("Error creating a wallet") + "\n" + reply);
} else {
QString seed = QString::fromStdString(parsed["seed"].get<json::string_t>());
QString seed = parsed["seed"].toString();
form.txtSeed->setPlainText(seed);
}
@ -149,8 +210,11 @@ 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()) {
QByteArray ba_reply = reply.toUtf8();
QJsonDocument jd_reply = QJsonDocument::fromJson(ba_reply);
QJsonObject parsed = jd_reply.object();
if (parsed.isEmpty() || parsed["result"].isNull()) {
QMessageBox::warning(this, tr("Failed to save wallet"),
tr("Couldn't save the wallet") + "\n" + reply,
QMessageBox::Ok);
@ -196,10 +260,14 @@ bool RestoreSeedPage::validatePage() {
return false;
}
///Number
QString number_str = form.number->text();
qint64 number = number_str.toUInt();
// 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);
seed.toStdString().c_str(), birthday, number);
QString reply = litelib_process_response(resp);
if (reply.toUpper().trimmed() != "OK") {
@ -215,8 +283,11 @@ bool RestoreSeedPage::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()) {
QByteArray ba_reply = reply.toUtf8();
QJsonDocument jd_reply = QJsonDocument::fromJson(ba_reply);
QJsonObject parsed = jd_reply.object();
if (parsed.isEmpty() || parsed["result"].isNull()) {
QMessageBox::warning(this, tr("Failed to save wallet"),
tr("Couldn't save the wallet") + "\n" + reply,
QMessageBox::Ok);

1
src/firsttimewizard.h

@ -5,6 +5,7 @@
#include "ui_newseed.h"
#include "ui_restoreseed.h"
#include "ui_newwallet.h"
#include "mainwindow.h"

40
src/liteinterface.cpp

@ -20,7 +20,7 @@ bool LiteInterface::haveConnection() {
return conn != nullptr;
}
void LiteInterface::fetchAddresses(const std::function<void(json)>& cb) {
void LiteInterface::fetchAddresses(const std::function<void(QJsonValue)>& cb) {
if (conn == nullptr)
return;
@ -28,21 +28,21 @@ void LiteInterface::fetchAddresses(const std::function<void(json)>& cb) {
}
void LiteInterface::fetchUnspent(const std::function<void(json)>& cb) {
void LiteInterface::fetchUnspent(const std::function<void(QJsonValue)>& cb) {
if (conn == nullptr)
return;
conn->doRPCWithDefaultErrorHandling("notes", "", cb);
}
void LiteInterface::createNewZaddr(bool, const std::function<void(json)>& cb) {
void LiteInterface::createNewZaddr(bool, const std::function<void(QJsonValue)>& cb) {
if (conn == nullptr)
return;
conn->doRPCWithDefaultErrorHandling("new", "zs", cb);
}
void LiteInterface::createNewSietchZaddr(const std::function<void(json)>& cb) {
void LiteInterface::createNewSietchZaddr(const std::function<void(QJsonValue)>& cb) {
if (conn == nullptr)
return;
@ -50,70 +50,70 @@ void LiteInterface::createNewSietchZaddr(const std::function<void(json)>& cb) {
}
void LiteInterface::createNewTaddr(const std::function<void(json)>& cb) {
void LiteInterface::createNewTaddr(const std::function<void(QJsonValue)>& cb) {
if (conn == nullptr)
return;
conn->doRPCWithDefaultErrorHandling("new", "R", cb);
}
void LiteInterface::fetchPrivKey(QString addr, const std::function<void(json)>& cb) {
void LiteInterface::fetchPrivKey(QString addr, const std::function<void(QJsonValue)>& cb) {
if (conn == nullptr)
return;
conn->doRPCWithDefaultErrorHandling("export", addr, cb);
}
void LiteInterface::fetchSeed(const std::function<void(json)>& cb) {
void LiteInterface::fetchSeed(const std::function<void(QJsonValue)>& cb) {
if (conn == nullptr)
return;
conn->doRPCWithDefaultErrorHandling("seed", "", cb);
}
void LiteInterface::fetchBalance(const std::function<void(json)>& cb) {
void LiteInterface::fetchBalance(const std::function<void(QJsonValue)>& cb) {
if (conn == nullptr)
return;
conn->doRPCWithDefaultErrorHandling("balance", "", cb);
}
void LiteInterface::fetchTransactions(const std::function<void(json)>& cb) {
void LiteInterface::fetchTransactions(const std::function<void(QJsonValue)>& cb) {
if (conn == nullptr)
return;
conn->doRPCWithDefaultErrorHandling("list", "", cb);
}
void LiteInterface::saveWallet(const std::function<void(json)>& cb) {
void LiteInterface::saveWallet(const std::function<void(QJsonValue)>& cb) {
if (conn == nullptr)
return;
conn->doRPCWithDefaultErrorHandling("save", "", cb);
}
void LiteInterface::clearWallet(const std::function<void(json)>& cb) {
void LiteInterface::clearWallet(const std::function<void(QJsonValue)>& cb) {
if (conn == nullptr)
return;
conn->doRPCWithDefaultErrorHandling("clear", "", cb);
}
void LiteInterface::unlockWallet(QString password, const std::function<void(json)>& cb) {
void LiteInterface::unlockWallet(QString password, const std::function<void(QJsonValue)>& cb) {
if (conn == nullptr)
return;
conn->doRPCWithDefaultErrorHandling("unlock", password, cb);
}
void LiteInterface::fetchWalletEncryptionStatus(const std::function<void(json)>& cb) {
void LiteInterface::fetchWalletEncryptionStatus(const std::function<void(QJsonValue)>& cb) {
if (conn == nullptr)
return;
conn->doRPCWithDefaultErrorHandling("encryptionstatus", "", cb);
}
void LiteInterface::encryptWallet(QString password, const std::function<void(json)>& cb) {
void LiteInterface::encryptWallet(QString password, const std::function<void(QJsonValue)>& cb) {
if (conn == nullptr)
return;
@ -121,7 +121,7 @@ void LiteInterface::encryptWallet(QString password, const std::function<void(jso
}
void LiteInterface::removeWalletEncryption(QString password, const std::function<void(json)>& cb) {
void LiteInterface::removeWalletEncryption(QString password, const std::function<void(QJsonValue)>& cb) {
if (conn == nullptr)
return;
@ -129,7 +129,7 @@ void LiteInterface::removeWalletEncryption(QString password, const std::function
}
void LiteInterface::sendTransaction(QString params, const std::function<void(json)>& cb,
void LiteInterface::sendTransaction(QString params, const std::function<void(QJsonValue)>& cb,
const std::function<void(QString)>& err) {
if (conn == nullptr)
return;
@ -137,7 +137,7 @@ void LiteInterface::sendTransaction(QString params, const std::function<void(jso
conn->doRPC("send", params, cb, err);
}
void LiteInterface::fetchInfo(const std::function<void(json)>& cb,
void LiteInterface::fetchInfo(const std::function<void(QJsonValue)>& cb,
const std::function<void(QString)>& err) {
if (conn == nullptr)
return;
@ -145,7 +145,7 @@ void LiteInterface::fetchInfo(const std::function<void(json)>& cb,
conn->doRPC("info", "", cb, err);
}
void LiteInterface::fetchSupply(const std::function<void(json)>& cb) {
void LiteInterface::fetchSupply(const std::function<void(QJsonValue)>& cb) {
if (conn == nullptr)
return;
@ -153,7 +153,7 @@ void LiteInterface::fetchSupply(const std::function<void(json)>& cb) {
}
void LiteInterface::fetchLatestBlock(const std::function<void(json)>& cb,
void LiteInterface::fetchLatestBlock(const std::function<void(QJsonValue)>& cb,
const std::function<void(QString)>& err) {
if (conn == nullptr)
return;
@ -166,7 +166,7 @@ void LiteInterface::fetchLatestBlock(const std::function<void(json)>& cb,
* combine the result, and call the callback with a single list containing both the t-addr and z-addr
* private keys
*/
void LiteInterface::fetchAllPrivKeys(const std::function<void(json)> cb) {
void LiteInterface::fetchAllPrivKeys(const std::function<void(QJsonValue)> cb) {
if (conn == nullptr) {
// No connection, just return
return;

42
src/liteinterface.h

@ -6,8 +6,6 @@
#include "camount.h"
#include "connection.h"
using json = nlohmann::json;
// Since each transaction can contain multiple outputs, we separate them out individually
// into a struct with address, amount, memo
struct TransactionItemDetail {
@ -38,43 +36,43 @@ public:
void setConnection(Connection* c);
Connection* getConnection() { return conn; }
void fetchUnspent (const std::function<void(json)>& cb);
void fetchTransactions (const std::function<void(json)>& cb);
void fetchAddresses (const std::function<void(json)>& cb);
void fetchUnspent (const std::function<void(QJsonValue)>& cb);
void fetchTransactions (const std::function<void(QJsonValue)>& cb);
void fetchAddresses (const std::function<void(QJsonValue)>& cb);
void fetchInfo(const std::function<void(json)>& cb,
void fetchInfo(const std::function<void(QJsonValue)>& cb,
const std::function<void(QString)>& err);
void fetchLatestBlock(const std::function<void(json)>& cb,
void fetchLatestBlock(const std::function<void(QJsonValue)>& cb,
const std::function<void(QString)>& err);
void fetchBalance(const std::function<void(json)>& cb);
void fetchBalance(const std::function<void(QJsonValue)>& cb);
void createNewZaddr(bool sapling, const std::function<void(json)>& cb);
void createNewTaddr(const std::function<void(json)>& cb);
void createNewSietchZaddr(const std::function<void(json)>& cb);
void createNewZaddr(bool sapling, const std::function<void(QJsonValue)>& cb);
void createNewTaddr(const std::function<void(QJsonValue)>& cb);
void createNewSietchZaddr(const std::function<void(QJsonValue)>& cb);
void fetchPrivKey(QString addr, const std::function<void(json)>& cb);
void fetchAllPrivKeys(const std::function<void(json)>);
void fetchSeed(const std::function<void(json)>&);
void fetchPrivKey(QString addr, const std::function<void(QJsonValue)>& cb);
void fetchAllPrivKeys(const std::function<void(QJsonValue)>);
void fetchSeed(const std::function<void(QJsonValue)>&);
void saveWallet(const std::function<void(json)>& cb);
void clearWallet(const std::function<void(json)>& cb);
void saveWallet(const std::function<void(QJsonValue)>& cb);
void clearWallet(const std::function<void(QJsonValue)>& cb);
void fetchWalletEncryptionStatus(const std::function<void(json)>& cb);
void fetchSupply(const std::function<void(json)>& cb);
void encryptWallet(QString password, const std::function<void(json)>& cb);
void unlockWallet(QString password, const std::function<void(json)>& cb);
void removeWalletEncryption(QString password, const std::function<void(json)>& cb);
void fetchWalletEncryptionStatus(const std::function<void(QJsonValue)>& cb);
void fetchSupply(const std::function<void(QJsonValue)>& cb);
void encryptWallet(QString password, const std::function<void(QJsonValue)>& cb);
void unlockWallet(QString password, const std::function<void(QJsonValue)>& cb);
void removeWalletEncryption(QString password, const std::function<void(QJsonValue)>& 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 sendTransaction(QString params, const std::function<void(json)>& cb, const std::function<void(QString)>& err);
void sendTransaction(QString params, const std::function<void(QJsonValue)>& cb, const std::function<void(QString)>& err);
private:
Connection* conn = nullptr;

252
src/mainwindow.cpp

@ -33,9 +33,7 @@
#include "Crypto/FileEncryption.h"
#include "DataStore/DataStore.h"
#include "firsttimewizard.h"
using json = nlohmann::json;
#include "../lib/silentdragonlitelib.h"
#ifdef Q_OS_WIN
@ -305,53 +303,31 @@ void MainWindow::closeEvent(QCloseEvent* event) {
fileoldencryption.remove();
// Encrypt our wallet.dat
QString str = DataStore::getChatDataStore()->getPassword();
// QString str = ed.txtPassword->text(); // data comes from user inputs
int length = str.length();
char *sequence = NULL;
sequence = new char[length+1];
strncpy(sequence, str.toLocal8Bit(), length +1);
#define MESSAGE ((const unsigned char *) sequence)
#define MESSAGE_LEN length
unsigned char hash[crypto_secretstream_xchacha20poly1305_KEYBYTES];
QString passphraseHash = DataStore::getChatDataStore()->getPassword();
int length = passphraseHash.length();
crypto_hash_sha256(hash,MESSAGE, MESSAGE_LEN);
char *sequence1 = NULL;
sequence1 = new char[length+1];
strncpy(sequence1, passphraseHash.toUtf8(), length+1);
#define PASSWORD sequence
#define KEY_LEN crypto_box_SEEDBYTES
/////////we use the Hash of the Password as Salt, not perfect but still a good solution.
#define PassphraseHashEnd ((const unsigned char *) sequence1)
#define MESSAGE_LEN length
unsigned char key[KEY_LEN];
#define PASSWORD sequence
#define KEY_LEN crypto_box_SEEDBYTES
if (crypto_pwhash
(key, sizeof key, PASSWORD, strlen(PASSWORD), hash,
crypto_pwhash_OPSLIMIT_SENSITIVE, crypto_pwhash_MEMLIMIT_SENSITIVE,
crypto_pwhash_ALG_DEFAULT) != 0) {
/* out of memory */
}
const QByteArray ba = QByteArray::fromHex(passphraseHash.toLatin1());
const unsigned char *encryptedMemo1 = reinterpret_cast<const unsigned char *>(ba.constData());
auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
// auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
QString source_file = dir.filePath("addresslabels.dat");
QString target_enc_file = dir.filePath("addresslabels.dat.enc");
QString sourceWallet_file = dirwallet;
QString target_encWallet_file = dirwalletenc;
FileEncryption::encrypt(target_enc_file, source_file, key);
FileEncryption::encrypt(target_encWallet_file, sourceWallet_file, key);
///////////////// we rename the plaintext wallet.dat to Backup, for testing.
// FileEncryption::encrypt(target_enc_file, source_file, key);
FileEncryption::encrypt(target_encWallet_file, sourceWallet_file, encryptedMemo1);
QFile wallet(dirwallet);
QFile address(dir.filePath("addresslabels.dat"));
wallet.remove();
address.remove();
}
@ -399,51 +375,49 @@ void MainWindow::encryptWallet() {
if (d.exec() == QDialog::Accepted)
{
QString passphrase = ed.txtPassword->text(); // data comes from user inputs
QString passphraseBlank = ed.txtPassword->text(); // data comes from user inputs
QString passphrase = QString("HUSH3") + passphraseBlank + QString("SDL");
int length = passphrase.length();
DataStore::getChatDataStore()->setPassword(passphrase);
char *sequence = NULL;
sequence = new char[length+1];
strncpy(sequence, passphrase.toLocal8Bit(), length +1);
#define MESSAGE ((const unsigned char *) sequence)
#define MESSAGE_LEN length
unsigned char hash[crypto_secretstream_xchacha20poly1305_KEYBYTES];
crypto_hash_sha256(hash,MESSAGE, MESSAGE_LEN);
char *sequence = NULL;
sequence = new char[length+1];
strncpy(sequence, passphrase.toUtf8(), length +1);
QString passphraseHash = blake3_PW(sequence);
DataStore::getChatDataStore()->setPassword(passphraseHash);
#define PASSWORD sequence
#define KEY_LEN crypto_box_SEEDBYTES
char *sequence1 = NULL;
sequence1 = new char[length+1];
strncpy(sequence1, passphraseHash.toUtf8(), length+1);
#define MESSAGE ((const unsigned char *) sequence)
#define MESSAGE_LEN length
#define hash ((const unsigned char *) sequence1)
/////////we use the Hash of the Password as Salt, not perfect but still a good solution.
#define PASSWORD sequence
#define KEY_LEN crypto_box_SEEDBYTES
unsigned char key[KEY_LEN];
unsigned char key[KEY_LEN];
if (crypto_pwhash
(key, sizeof key, PASSWORD, strlen(PASSWORD), hash,
crypto_pwhash_OPSLIMIT_SENSITIVE, crypto_pwhash_MEMLIMIT_SENSITIVE,
crypto_pwhash_ALG_DEFAULT) != 0) {
/* out of memory */
if (crypto_pwhash
(key, sizeof key, PASSWORD, strlen(PASSWORD), hash,
crypto_pwhash_OPSLIMIT_SENSITIVE, crypto_pwhash_MEMLIMIT_SENSITIVE,
crypto_pwhash_ALG_DEFAULT) != 0) {
/* out of memory */
}
QString passphraseHash1 = QByteArray(reinterpret_cast<const char*>(key), KEY_LEN).toHex();
DataStore::getChatDataStore()->setPassword(passphraseHash1);
auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
QString source_file = dir.filePath("addresslabels.dat");
QString target_enc_file = dir.filePath("addresslabels.dat.enc");
QString sourceWallet_file = dirwallet;
QString target_encWallet_file = dirwalletenc;
FileEncryption::encrypt(target_enc_file, source_file, key);
FileEncryption::encrypt(target_encWallet_file, sourceWallet_file, key);
QFile wallet(dirwallet);
QFile address(dir.filePath("addresslabels.dat"));
wallet.rename(dirwalletbackup);
address.rename(dir.filePath("addresslabels.datBackup"));
QMessageBox::information(this, tr("Wallet Encryption Success"),
QString("Successfully encrypted your wallet"),
@ -484,27 +458,28 @@ void MainWindow::removeWalletEncryption() {
if (d.exec() == QDialog::Accepted)
{
QString str = ed.txtPassword->text(); // data comes from user inputs
int length = str.length();
QString passphraseBlank = ed.txtPassword->text(); // data comes from user inputs
QString passphrase = QString("HUSH3") + passphraseBlank + QString("SDL");
int length = passphrase.length();
char *sequence = NULL;
sequence = new char[length+1];
strncpy(sequence, str.toLocal8Bit(), length +1);
strncpy(sequence, passphrase.toUtf8(), length +1);
#define MESSAGE ((const unsigned char *) sequence)
#define MESSAGE_LEN length
QString passphraseHash = blake3_PW(sequence);
unsigned char hash[crypto_secretstream_xchacha20poly1305_KEYBYTES];
char *sequence1 = NULL;
sequence1 = new char[length+1];
strncpy(sequence1, passphraseHash.toUtf8(), length+1);
crypto_hash_sha256(hash,MESSAGE, MESSAGE_LEN);
#define hash ((const unsigned char *) sequence1)
#define PASSWORD sequence
#define KEY_LEN crypto_box_SEEDBYTES
/////////we use the Hash of the Password as Salt, not perfect but still a good solution.
unsigned char key[KEY_LEN];
if (crypto_pwhash
@ -513,18 +488,14 @@ void MainWindow::removeWalletEncryption() {
crypto_pwhash_ALG_DEFAULT) != 0) {
/* out of memory */
}
auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
QString target_encwallet_file = dirwalletenc;
QString target_decwallet_file = dirwallet;
QString target_encaddr_file = dir.filePath("addresslabels.dat.enc");
QString target_decaddr_file = dir.filePath("addresslabels.dat");
FileEncryption::decrypt(target_decwallet_file, target_encwallet_file, key);
FileEncryption::decrypt(target_decaddr_file, target_encaddr_file, key);
QFile filencrypted(dirwalletenc);
QFile wallet(dirwallet);
@ -556,85 +527,64 @@ void MainWindow::removeWalletEncryptionStartUp() {
QDialog d(this);
Ui_startup ed;
ed.setupUi(&d);
if (d.exec() == QDialog::Accepted)
{
QString password = ed.txtPassword->text(); // data comes from user inputs
int length = password.length();
DataStore::getChatDataStore()->setPassword(password);
QString passphraseBlank = ed.txtPassword->text(); // data comes from user inputs
QString passphrase = QString("HUSH3") + passphraseBlank + QString("SDL");
int length = passphrase.length();
char *sequence = NULL;
sequence = new char[length+1];
strncpy(sequence, password.toLocal8Bit(), length +1);
strncpy(sequence, passphrase.toUtf8(), length +1);
QString passphraseHash = blake3_PW(sequence);
char *sequence1 = NULL;
sequence1 = new char[length+1];
strncpy(sequence1, passphraseHash.toUtf8(), length+1);
#define MESSAGE ((const unsigned char *) sequence)
#define MESSAGE_LEN length
unsigned char hash[crypto_secretstream_xchacha20poly1305_KEYBYTES];
crypto_hash_sha256(hash,MESSAGE, MESSAGE_LEN);
#define hash ((const unsigned char *) sequence1)
#define PASSWORD sequence
#define KEY_LEN crypto_box_SEEDBYTES
/////////we use the Hash of the Password as Salt, not perfect but still a good solution.
#define KEY_LEN crypto_box_SEEDBYTES
unsigned char key[KEY_LEN];
unsigned char key[KEY_LEN];
if (crypto_pwhash
(key, sizeof key, PASSWORD, strlen(PASSWORD), hash,
crypto_pwhash_OPSLIMIT_SENSITIVE, crypto_pwhash_MEMLIMIT_SENSITIVE,
crypto_pwhash_ALG_DEFAULT) != 0) {
if (crypto_pwhash
(key, sizeof key, PASSWORD, strlen(PASSWORD), hash,
crypto_pwhash_OPSLIMIT_SENSITIVE, crypto_pwhash_MEMLIMIT_SENSITIVE,
crypto_pwhash_ALG_DEFAULT) != 0) {
/* out of memory */
}
}
QString passphraseHash1 = QByteArray(reinterpret_cast<const char*>(key), KEY_LEN).toHex();
DataStore::getChatDataStore()->setPassword(passphraseHash1);
{
auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
QString target_encwallet_file = dirwalletenc;
QString target_decwallet_file = dirwallet;
QString target_encaddr_file = dir.filePath("addresslabels.dat.enc");
QString target_decaddr_file = dir.filePath("addresslabels.dat");
FileEncryption::decrypt(target_decwallet_file, target_encwallet_file, key);
FileEncryption::decrypt(target_decaddr_file, target_encaddr_file, key);
}
auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
QFile wallet(dirwallet);
//QFile backup(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.datBACKUP"));*/
if (wallet.size() > 0)
if (wallet.size() == 0)
{
if (fileExists(dirwalletbackup))
{
QMessageBox::information(this, tr("You still have plaintext data on your disk!"),
QString("WARNING: Delete it only if you have a backup of your Wallet Seed."),
QMessageBox::Ok
);
// backup.remove();
}
QMessageBox::information(this, tr("Wallet Encryption Success"),
QString("SDL is ready to Rock"),
QMessageBox::Ok
);
}else{
QMessageBox::critical(this, tr("Wallet Encryption Failed"),
QString("false password please try again"),
QMessageBox::Ok
);
this->removeWalletEncryptionStartUp();
}
}else{}
}else{
@ -731,8 +681,6 @@ void MainWindow::setupSettingsModal() {
QObject::connect(settings.comboBoxTheme, &QComboBox::currentTextChanged, [=] (QString theme_name) {
this->slot_change_theme(theme_name);
// Tell the user to restart
QMessageBox::information(this, tr("Restart"), tr("Please restart Silentdragonlite to have the theme apply"), QMessageBox::Ok);
});
// Get Currency Data
@ -1019,7 +967,7 @@ void MainWindow::exportSeed() {
rpc->fetchSeed([=](json reply) {
rpc->fetchSeed([=](QJsonValue reply) {
if (isJsonError(reply)) {
return;
}
@ -1037,7 +985,7 @@ void MainWindow::exportSeed() {
pui.privKeyTxt->setReadOnly(true);
pui.privKeyTxt->setLineWrapMode(QPlainTextEdit::LineWrapMode::NoWrap);
pui.privKeyTxt->setPlainText(QString::fromStdString(reply.dump()));
pui.privKeyTxt->setPlainText(QLatin1String(QJsonDocument(reply.toObject()).toJson(QJsonDocument::Compact)));
pui.helpLbl->setText(tr("This is your wallet seed. Please back it up carefully and safely."));
@ -1091,14 +1039,14 @@ void MainWindow::exportKeys(QString addr) {
bool allKeys = addr.isEmpty() ? true : false;
auto fnUpdateUIWithKeys = [=](json reply) {
auto fnUpdateUIWithKeys = [=](QJsonValue reply) {
if (isJsonError(reply)) {
return;
}
if (reply.is_discarded() || !reply.is_array()) {
if (reply.isNull() || !reply.isArray()) {
QMessageBox::critical(this, tr("Error getting private keys"),
tr("Error loading private keys: ") + QString::fromStdString(reply.dump()),
tr("Error loading private keys: ") + QLatin1String(QJsonDocument(reply.toObject()).toJson(QJsonDocument::Compact)),
QMessageBox::Ok);
return;
}
@ -1137,8 +1085,8 @@ void MainWindow::exportKeys(QString addr) {
});
QString allKeysTxt;
for (auto i : reply.get<json::array_t>()) {
allKeysTxt = allKeysTxt % QString::fromStdString(i["private_key"]) % " # addr=" % QString::fromStdString(i["address"]) % "\n";
for (auto i : reply.toArray()) {
allKeysTxt = allKeysTxt % i.toObject()["private_key"].toString() % " # addr=" % i.toObject()["address"].toString() % "\n";
}
pui.privKeyTxt->setPlainText(allKeysTxt);
@ -1169,7 +1117,7 @@ void MainWindow::setupBalancesTab() {
QList<QString> allAddresses;
allAddresses = getRPC()->getModel()->getAllZAddresses();
QString depositzaddr = allAddresses[1];
QString depositzaddr = allAddresses[0];
deposithush.qrcodeDisplayDeposit->setQrcodeString(depositzaddr);
deposithush.zaddr->setText(depositzaddr);
@ -1344,6 +1292,8 @@ void MainWindow::setupTransactionsTab() {
void MainWindow::setupchatTab() {
ui->memoTxtChat->setEnabled(false);
/////////////Setting Icons for Chattab and different themes
auto theme = Settings::getInstance()->get_theme_name();
@ -1530,6 +1480,7 @@ void MainWindow::setupchatTab() {
ui->listContactWidget->addAction(HushAction);
ui->listContactWidget->addAction(requestHushAction);
ui->listContactWidget->addAction(subatomicAction);
ui->memoTxtChat->setEnabled(true);
/*QObject::connect(requestHushAction, &QAction::triggered, [=]() {
QModelIndex index = ui->listContactWidget->currentIndex();
@ -1578,6 +1529,7 @@ void MainWindow::setupchatTab() {
});
ui->memoTxtChat->setLenDisplayLabelChat(ui->memoSizeChat);
}
void MainWindow::updateChat()
@ -1592,8 +1544,8 @@ void MainWindow::updateContacts()
}
void MainWindow::addNewZaddr(bool sapling) {
rpc->createNewZaddr(sapling, [=] (json reply) {
QString addr = QString::fromStdString(reply.get<json::array_t>()[0]);
rpc->createNewZaddr(sapling, [=] (QJsonValue reply) {
QString addr = reply.toArray()[0].toString();
// Make sure the RPC class reloads the z-addrs for future use
rpc->refreshAddresses();
@ -1643,8 +1595,8 @@ std::function<void(bool)> MainWindow::addZAddrsToComboList(bool sapling) {
void MainWindow::setupReceiveTab() {
auto addNewTAddr = [=] () {
rpc->createNewTaddr([=] (json reply) {
QString addr = QString::fromStdString(reply.get<json::array_t>()[0]);
rpc->createNewTaddr([=] (QJsonValue reply) {
QString addr = reply.toArray()[0].toString();
// Make sure the RPC class reloads the t-addrs for future use
rpc->refreshAddresses();
@ -1993,7 +1945,7 @@ void MainWindow::slot_change_theme(const QString& theme_name)
if (qFile.open(QFile::ReadOnly))
{
QString styleSheet = QLatin1String(qFile.readAll());
this->setStyleSheet(""); // reset styles
this->setStyleSheet(""); // resets styles, makes app restart unnecessary
this->setStyleSheet(styleSheet);
}
@ -2019,8 +1971,8 @@ void MainWindow::on_givemeZaddr_clicked()
{
bool sapling = true;
rpc->createNewZaddr(sapling, [=] (json reply) {
QString hushchataddr = QString::fromStdString(reply.get<json::array_t>()[0]);
rpc->createNewZaddr(sapling, [=] (QJsonValue reply) {
QString hushchataddr = reply.toArray()[0].toString();
QClipboard *zaddr_Clipboard = QApplication::clipboard();
zaddr_Clipboard ->setText(hushchataddr);
QMessageBox::information(this, "Your new HushChat address was copied to your clipboard!",hushchataddr);

17
src/mainwindow.h

@ -14,7 +14,6 @@ class WSServer;
class WormholeClient;
class ChatModel;
using json = nlohmann::json;
// Struct used to hold destination info when sending a Tx.
struct ToFields {
@ -215,5 +214,21 @@ private:
QPushButton* sendChatButton = nullptr;
};
class ChatMemoEditRequest : public QTextEdit
{
public:
ChatMemoEditRequest(QWidget* parent);
void setMaxLenChatRequest(int len);
void setLenDisplayLabelChatRequest(QLabel* label);
void SetSendRequestButton(QPushButton* button);
void updateDisplayChatRequest();
private:
int maxlenchatrequest = 512;
QLabel* lenDisplayLabelchatRequest = nullptr;
QPushButton* sendRequestButton = nullptr;
};
#endif // MAINWINDOW_H

4
src/mainwindow.ui

@ -59,7 +59,7 @@
<item row="0" column="0" colspan="2">
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>2</number>
<number>5</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
@ -429,7 +429,7 @@
<x>0</x>
<y>0</y>
<width>1226</width>
<height>493</height>
<height>509</height>
</rect>
</property>
<layout class="QVBoxLayout" name="sendToLayout">

310
src/newwallet.ui

@ -6,114 +6,129 @@
<rect>
<x>0</x>
<y>0</y>
<width>437</width>
<height>381</height>
<width>950</width>
<height>717</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>950</width>
<height>734</height>
</size>
</property>
<property name="windowTitle">
<string>Create New SDL Wallet</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="6" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Confirm Passphrase:</string>
</property>
</widget>
</item>
<item row="6" column="1" colspan="2">
<widget class="QLineEdit" name="txtConfirmPassword">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="1" column="0" colspan="3">
<widget class="QGroupBox" name="groupBox_2">
<item row="0" column="0" colspan="3">
<widget class="QGraphicsView" name="Logo">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<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="5" column="1" colspan="2">
<widget class="QLineEdit" name="txtPassword">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
<property name="minimumSize">
<size>
<width>931</width>
<height>192</height>
</size>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContentsOnFirstShow</enum>
</property>
</widget>
</item>
<item row="0" column="0" colspan="3">
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
<item row="1" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</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>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>50</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0" colspan="3">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<widget class="QTextBrowser" name="textBrowser">
<property name="minimumSize">
<size>
<width>931</width>
<height>150</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>949</width>
<height>16777215</height>
</size>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;h1 align=&quot;center&quot; style=&quot; margin-top:18px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:xx-large; font-weight:600;&quot;&gt;Hush + HushChat Terms of Service&lt;/span&gt;&lt;/h1&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;All users of this platform agree to not use it for initiating or threatening any forceful interference or violence on an individual or their property, aka, the &lt;a href=&quot;https://en.wikipedia.org/wiki/Non-aggression_principle&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Non-Aggression Principle&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;THE SERVICE IS PROVIDED “AS IS” AND The Hush Developers DO NOT MAKE ANY SPECIFIC COMMITMENTS OR WARRANTIES ABOUT THE SERVICE.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;By clicking OK, you agree to use Hush, the SilentDragon family of wallets, HushChat, and any software developed by The Hush Developers in accordance with your local laws, that all liabilities related to using this service are your own, and The Hush Developers WILL NOT BE RESPONSIBLE FOR any losses related to using this software.&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_4">
<item row="3" column="0">
<widget class="QRadioButton" name="TOS">
<property name="maximumSize">
<size>
<width>251</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Encryption Passphrase:</string>
<string>I accept the Terms of Service</string>
</property>
</widget>
</item>
<item row="3" column="0">
<item row="3" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>49</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="0" colspan="2">
<widget class="QLabel" name="lblPasswordMatch">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
@ -121,6 +136,12 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>711</width>
<height>0</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">color: red;</string>
</property>
@ -132,7 +153,7 @@
</property>
</widget>
</item>
<item row="3" column="1">
<item row="4" column="2">
<widget class="QLabel" name="label_5">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
@ -145,6 +166,125 @@
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Encryption Passphrase:</string>
</property>
</widget>
</item>
<item row="5" column="1" colspan="2">
<widget class="QLineEdit" name="txtPassword">
<property name="minimumSize">
<size>
<width>611</width>
<height>0</height>
</size>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Confirm Passphrase:</string>
</property>
</widget>
</item>
<item row="6" column="1" colspan="2">
<widget class="QLineEdit" name="txtConfirmPassword">
<property name="minimumSize">
<size>
<width>611</width>
<height>0</height>
</size>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="7" column="0" colspan="3">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="8" column="0" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>431</width>
<height>90</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>431</width>
<height>90</height>
</size>
</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>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>431</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>431</width>
<height>90</height>
</size>
</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>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>

2
src/precompiled.h

@ -71,8 +71,8 @@
#include <QObject>
#include <QApplication>
#include <QDesktopWidget>
#include <QPainterPath>
#include "3rdparty/json/json.hpp"
#include "3rdparty/qrcode/QrCode.hpp"
#define SODIUM_STATIC

65
src/restoreseed.ui

@ -6,24 +6,14 @@
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
<width>498</width>
<height>575</height>
</rect>
</property>
<property name="windowTitle">
<string>Restore Wallet Seed</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">
@ -35,36 +25,36 @@
<property name="title">
<string/>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Wallet Seed</string>
</property>
</widget>
</item>
<item>
<item row="1" column="0">
<widget class="QPlainTextEdit" name="txtSeed">
<property name="readOnly">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Wallet Birthday</string>
</property>
</widget>
</item>
<item>
<item row="3" column="0">
<widget class="QLineEdit" name="txtBirthday">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<item row="4" column="0">
<widget class="QLabel" name="label_4">
<property name="font">
<font>
@ -79,9 +69,48 @@
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Quantity </string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLineEdit" name="number">
<property name="text">
<string>10</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_6">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>The quantity of shielded addresses that gets recreated during the restore process</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<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>
</layout>
</widget>
<resources/>

2
src/sendtab.cpp

@ -9,8 +9,6 @@
#include "recurring.h"
using json = nlohmann::json;
void MainWindow::setupSendTab() {
// Create the validator for send to/amount fields
amtValidator = new QRegExpValidator(QRegExp("[0-9]{0,8}\\.?[0-9]{0,8}"));

13
src/settings.h

@ -4,8 +4,6 @@
#include "precompiled.h"
#include "camount.h"
using json = nlohmann::json;
struct Config {
QString server;
};
@ -67,8 +65,6 @@ public:
void set_currency_name(QString currency_name);
bool isSaplingActive();
void setZECPrice(double p) { ZECPrice = p; }
@ -225,13 +221,12 @@ private:
};
inline bool isJsonResultSuccess(const json& res) {
return res.find("result") != res.end() &&
QString::fromStdString(res["result"].get<json::string_t>()) == "success";
inline bool isJsonResultSuccess(const QJsonValue& res) {
return res.toObject()["result"].toString() == "success";
}
inline bool isJsonError(const json& res) {
return res.find("error") != res.end();
inline bool isJsonError(const QJsonValue& res) {
return !res.toObject()["error"].isNull();
}

5
src/settings.ui

@ -138,6 +138,11 @@
<string>Default</string>
</property>
</item>
<item>
<property name="text">
<string>test</string>
</property>
</item>
</widget>
<widget class="QCheckBox" name="chkFetchPrices">
<property name="geometry">

2
src/version.h

@ -1 +1 @@
#define APP_VERSION "1.3.3"
#define APP_VERSION "1.3.6"

10
src/websockets.cpp

@ -735,9 +735,9 @@ void AppDataServer::processSendTx(QJsonObject sendTx, MainWindow* mainwindow, st
return;
}
json params = json::array();
QJsonArray params;
mainwindow->getRPC()->fillTxJsonParams(params, tx);
std::cout << std::setw(2) << params << std::endl;
//std::cout << std::setw(2) << params << std::endl;
// And send the Tx
mainwindow->getRPC()->executeTransaction(tx,
@ -835,9 +835,9 @@ void AppDataServer::processSendManyTx(QJsonObject sendmanyTx, MainWindow* mainwi
return;
}
json params = json::array();
QJsonArray params;
mainwindow->getRPC()->fillTxJsonParams(params, tx);
std::cout << std::setw(2) << params << std::endl;
//std::cout << std::setw(2) << params << std::endl;
// And send the Tx
mainwindow->getRPC()->executeTransaction(tx,
@ -923,7 +923,7 @@ void AppDataServer::processGetTransactions(MainWindow* mainWindow, std::shared_p
{"amount", model->getAmt(i)},
{"txid", model->getTxId(i)},
{"address", model->getAddr(i)},
{"memo", model->getMemo(i)},
// {"memo", model->getMemo(i)},
{"confirmations", model->getConfirmations(i)}
});
}

Loading…
Cancel
Save