Browse Source

Merge pull request #1 from MyHush/master

Sync to upstream
pull/189/head
jahway603 4 years ago
committed by GitHub
parent
commit
41932e4587
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 13
      .travis.yml
  2. 2
      README.md
  3. 30
      application.qrc
  4. 160
      lib/Cargo.lock
  5. 3
      lib/Cargo.toml
  6. 9
      lib/silentdragonlitelib.h
  7. 40
      lib/src/lib.rs
  8. BIN
      res/SilentDragonLite.png
  9. 239
      res/css/test.css
  10. BIN
      res/dark-01.png
  11. BIN
      res/emoji/SD.png
  12. BIN
      res/emoji/emoji1.png
  13. BIN
      res/emoji/face-with-rolling-eyes.png
  14. BIN
      res/emoji/face-with-tongue.png
  15. BIN
      res/emoji/face_with_3hearts.png
  16. BIN
      res/emoji/heart_shaped_eyes.png
  17. BIN
      res/emoji/hush-money-white.png
  18. BIN
      res/emoji/innocent.png
  19. BIN
      res/emoji/joy.png
  20. BIN
      res/emoji/laughing.png
  21. BIN
      res/emoji/money-mouth.png
  22. BIN
      res/emoji/nauseated-face.png
  23. BIN
      res/emoji/partying_face.png
  24. BIN
      res/emoji/pile-of-poo.png
  25. BIN
      res/emoji/serious-face-with-symbols-covering-mouth.png
  26. BIN
      res/emoji/smiling-face-with-sunglasses.png
  27. BIN
      res/emoji/stuck-out.png
  28. BIN
      res/emoji/sweet_smile.png
  29. BIN
      res/hush-money-white.png
  30. BIN
      res/hush-money.png
  31. BIN
      res/images/tile.png
  32. BIN
      res/money-mouth.png
  33. BIN
      res/money-outgoing.png
  34. 13
      res/silentdragonlite.desktop
  35. BIN
      res/silentdragonlite_ar.qm
  36. 2151
      res/silentdragonlite_ar.ts
  37. BIN
      res/silentdragonlite_ro.qm
  38. 2001
      res/silentdragonlite_ro.ts
  39. 7
      silentdragon-lite.pro
  40. 40
      src/Chat/Chat.cpp
  41. 48
      src/Chat/Helper/ChatDelegator.h
  42. 56
      src/DataStore/ChatDataStore.cpp
  43. 8
      src/DataStore/ChatDataStore.h
  44. 2
      src/DataStore/ContactDataStore.cpp
  45. 1
      src/FileSystem/FileSystem.h
  46. 40
      src/Model/ChatItem.cpp
  47. 91
      src/addressbook.cpp
  48. 181
      src/chatmodel.cpp
  49. 58
      src/connection.cpp
  50. 4
      src/connection.h
  51. 27
      src/contactrequest.ui
  52. 660
      src/controller.cpp
  53. 1
      src/controller.h
  54. 339
      src/emoji.ui
  55. 99
      src/firsttimewizard.cpp
  56. 4
      src/firsttimewizard.h
  57. 1144
      src/mainwindow.cpp
  58. 33
      src/mainwindow.h
  59. 71
      src/mainwindow.ui
  60. 310
      src/newwallet.ui
  61. 3
      src/precompiled.h
  62. 10
      src/recurring.cpp
  63. 72
      src/restoreSeed.ui
  64. 65
      src/restoreseed.ui
  65. 9
      src/scripts/mkrelease.sh
  66. 114
      src/seedrestore.ui
  67. 276
      src/sendHushTransactionChat.ui
  68. 2
      src/sendtab.cpp
  69. 2
      src/settings.h
  70. 5
      src/settings.ui
  71. 2
      src/version.h
  72. 2
      src/websockets.cpp

13
.travis.yml

@ -1,4 +1,6 @@
language: rust
rust:
- 1.41.0
matrix:
include:
@ -16,14 +18,15 @@ before_script:
before_install:
- rustup component add rustfmt --toolchain stable-x86_64-unknown-linux-gnu
- rustup component add rustfmt --toolchain 1.41.0-x86_64-unknown-linux-gnu
- gem install bundler
- curl -sSL https://sh.rustup.rs | sh -s -- -y --default-toolchain=nightly --profile=minimal
- curl -sSL https://sh.rustup.rs | sh -s -- -y --default-toolchain=stable --profile=minimal
- export PATH="$PATH:$HOME/.cargo/bin"
- sudo add-apt-repository ppa:beineri/opt-qt591-xenial -y
- sudo add-apt-repository ppa:beineri/opt-qt-5.14.2-xenial -y
- sudo apt-get update -qq
- sudo apt-get install qt59base qt59websockets libgl1-mesa-dev
- source /opt/qt59/bin/qt59-env.sh
- sudo apt-get install libsodium-dev pkg-config
- sudo apt-get install qt514base qt514websockets libgl1-mesa-dev
- source /opt/qt514/bin/qt514-env.sh
- chmod +x res/libsodium/buildlibsodium.sh
script:

2
README.md

@ -22,7 +22,7 @@ sudo apt install torsocks
```
## Connection to our TOR onion service Server
```
* Open SDL Edit->Settings->LightwalletServer->rnhk4pwlsbaqzx7wcqfy47lijf2opklstaukq35reiz5rn76crfqpjqd.onion:9067
* Open SDL Edit->Settings->LightwalletServer->6onaaujm4ozaokzu.onion:80
* Open the folder of SDL in a Terminal -> Enter: TORSOCKS_LOG_LEVEL=1 torsocks -i ./SilentDragonLite
```
## Note Management

30
application.qrc

@ -47,6 +47,11 @@
<file>res/addContactBlack.png</file>
<file>res/unknownBlack.png</file>
<file>res/unknownWhite.png</file>
<file>res/dark-01.png</file>
<file>res/money-mouth.png</file>
<file>res/money-outgoing.png</file>
<file>res/hush-money-white.png</file>
</qresource>
<qresource prefix="/img">
<file>res/hushdlogo.gif</file>
@ -57,6 +62,26 @@
<file>res/loaderblack.gif</file>
<file>res/loaderwhite.gif</file>
</qresource>
<qresource prefix="/emoji">
<file>res/emoji/emoji1.png</file>
<file>res/emoji/laughing.png</file>
<file>res/emoji/money-mouth.png</file>
<file>res/emoji/joy.png</file>
<file>res/emoji/innocent.png</file>
<file>res/emoji/partying_face.png</file>
<file>res/emoji/face_with_3hearts.png</file>
<file>res/emoji/face-with-rolling-eyes.png</file>
<file>res/emoji/face-with-tongue.png</file>
<file>res/emoji/heart_shaped_eyes.png</file>
<file>res/emoji/nauseated-face.png</file>
<file>res/emoji/pile-of-poo.png</file>
<file>res/emoji/serious-face-with-symbols-covering-mouth.png</file>
<file>res/emoji/smiling-face-with-sunglasses.png</file>
<file>res/emoji/stuck-out.png</file>
<file>res/emoji/sweet_smile.png</file>
<file>res/emoji/hush-money-white.png</file>
<file>res/emoji/SD.png</file>
</qresource>
<qresource prefix="/translations">
<file>res/silentdragonlite_de.qm</file>
<file>res/silentdragonlite_es.qm</file>
@ -67,6 +92,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 +100,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 +112,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>

160
lib/Cargo.lock

@ -128,14 +128,6 @@ name = "base58"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "base64"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "base64"
version = "0.11.0"
@ -194,6 +186,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"
@ -301,16 +307,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "core-foundation"
version = "0.6.4"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "core-foundation-sys"
version = "0.6.2"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -584,7 +590,7 @@ dependencies = [
[[package]]
name = "h2"
version = "0.2.1"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -596,8 +602,8 @@ dependencies = [
"indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -673,23 +679,23 @@ dependencies = [
[[package]]
name = "hyper"
version = "0.13.2"
version = "0.13.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-channel 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-util 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"h2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"h2 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1036,7 +1042,7 @@ dependencies = [
[[package]]
name = "percent-encoding"
version = "1.0.1"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -1175,9 +1181,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=6c3f6f22bfc642c714c1e43f6e09cb4d34c7a1de)",
]
[[package]]
@ -1475,10 +1482,10 @@ dependencies = [
[[package]]
name = "rustls"
version = "0.16.0"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"ring 0.16.11 (registry+https://github.com/rust-lang/crates.io-index)",
"sct 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1487,13 +1494,13 @@ dependencies = [
[[package]]
name = "rustls-native-certs"
version = "0.1.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustls 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"security-framework 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"security-framework 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1542,21 +1549,22 @@ dependencies = [
[[package]]
name = "security-framework"
version = "0.3.4"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"security-framework-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"security-framework-sys 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "security-framework-sys"
version = "0.3.3"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1640,7 +1648,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=6c3f6f22bfc642c714c1e43f6e09cb4d34c7a1de#6c3f6f22bfc642c714c1e43f6e09cb4d34c7a1de"
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)",
@ -1667,9 +1675,9 @@ dependencies = [
"sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"sodiumoxide 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-rustls 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tonic 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-rustls 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tonic 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tonic-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
"webpki-roots 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1828,7 +1836,7 @@ dependencies = [
[[package]]
name = "tokio"
version = "0.2.11"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1845,13 +1853,13 @@ dependencies = [
"pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-macros 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-macros 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-macros"
version = "0.2.4"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1861,18 +1869,18 @@ dependencies = [
[[package]]
name = "tokio-rustls"
version = "0.12.2"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"rustls 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-util"
version = "0.2.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1880,31 +1888,31 @@ dependencies = [
"futures-sink 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tonic"
version = "0.1.1"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"async-stream 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"async-trait 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-util 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)",
"percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.13.6 (registry+https://github.com/rust-lang/crates.io-index)",
"percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"prost-derive 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustls-native-certs 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-rustls 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustls-native-certs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-rustls 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tower 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-balance 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-load 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1953,7 +1961,7 @@ dependencies = [
"pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-discover 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-load 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1970,7 +1978,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1998,7 +2006,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -2011,7 +2019,7 @@ dependencies = [
"futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-discover 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -2032,7 +2040,7 @@ name = "tower-make"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -2045,7 +2053,7 @@ dependencies = [
"futures-util 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -2056,7 +2064,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -2072,7 +2080,7 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -2453,7 +2461,6 @@ dependencies = [
"checksum backtrace 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)" = "7f80256bc78f67e7df7e36d77366f636ed976895d91fe2ab9efa3973e8fe8c4f"
"checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491"
"checksum base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83"
"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
"checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
"checksum bech32 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cdcf67bb7ba7797a081cd19009948ab533af7c355d5caf1d08c777582d351e9c"
"checksum bellman 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)" = "<none>"
@ -2461,6 +2468,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"
@ -2476,8 +2484,8 @@ dependencies = [
"checksum chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
"checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d"
"checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
"checksum core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171"
"checksum core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac"
"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
"checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19"
"checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4"
@ -2512,7 +2520,7 @@ dependencies = [
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
"checksum group 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)" = "<none>"
"checksum h2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9433d71e471c1736fd5a61b671fc0b148d7a2992f666c958d03cd8feb3b88d1"
"checksum h2 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "79b7246d7e4b979c03fa093da39cfb3617a96bbeee6310af63991668d7e843ff"
"checksum hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da"
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
"checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772"
@ -2522,7 +2530,7 @@ dependencies = [
"checksum http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b"
"checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9"
"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
"checksum hyper 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fa1c527bbc634be72aa7ba31e4e4def9bbb020f5416916279b7c705cd838893e"
"checksum hyper 0.13.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a6e7655b9594024ad0ee439f3b5a7299369dc2a3f459b47c696f9ff676f9aa1f"
"checksum indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b54058f0a6ff80b6803da8faf8997cde53872b38f4023728f6830b06cd3c0dc"
"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
"checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484"
@ -2562,7 +2570,7 @@ dependencies = [
"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337"
"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9"
"checksum pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9"
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
"checksum petgraph 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29c127eea4a29ec6c85d153c59dc1213f33ec74cead30fe4730aecc88cc1fd92"
"checksum pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7804a463a8d9572f13453c516a5faea534a2403d7ced2f0c7e100eeff072772c"
"checksum pin-project-internal 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f"
@ -2612,16 +2620,16 @@ dependencies = [
"checksum rust-embed-utils 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97655158074ccb2d2cfb1ccb4c956ef0f4054e43a2c1e71146d4991e6961e105"
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b25a18b1bf7387f0145e7f8324e700805aade3842dd3db2e74e4cdeb4677c09e"
"checksum rustls-native-certs 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51ffebdbb48c14f84eba0b715197d673aff1dd22cc1007ca647e28483bbcc307"
"checksum rustls 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d4a31f5d68413404705d6982529b0e11a9aacd4839d1d6222ee3b8cb4015e1"
"checksum rustls-native-certs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a75ffeb84a6bd9d014713119542ce415db3a3e4748f0bfce1e1416cd224a23a5"
"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
"checksum same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
"checksum schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021"
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
"checksum sct 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c"
"checksum secp256k1 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e0344a794ff109f85547039536028e12f313178ac1545e49fdf16a530d900a7b"
"checksum security-framework 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8ef2429d7cefe5fd28bd1d2ed41c944547d4ff84776f5935b456da44593a16df"
"checksum security-framework-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e31493fc37615debb8c5090a7aeb4a9730bc61e77ab10b9af59f1a202284f895"
"checksum security-framework 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "97bbedbe81904398b6ebb054b3e912f99d55807125790f3198ac990d98def5b0"
"checksum security-framework-sys 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "17bf11d99252f512695eb468de5516e5cf75455521e69dfe343f3b74e4748405"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449"
@ -2631,7 +2639,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=6c3f6f22bfc642c714c1e43f6e09cb4d34c7a1de)" = "<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"
@ -2649,11 +2657,11 @@ dependencies = [
"checksum thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1"
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
"checksum tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c1c5676413eaeb1ea35300a0224416f57abc3bd251657e0fafc12c47ff98c060"
"checksum tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8fdd17989496f49cdc57978c96f0c9fe5e4a58a8bddc6813c449a4624f6a030b"
"checksum tokio-macros 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f4b1e7ed7d5d4c2af3d999904b0eebe76544897cdbfb2b9684bed2174ab20f7c"
"checksum tokio-rustls 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "141afec0978abae6573065a48882c6bae44c5cc61db9b511ac4abf6a09bfd9cc"
"checksum tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930"
"checksum tonic 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08283643b1d483eb7f3fc77069e63b5cba3e4db93514b3d45470e67f123e4e48"
"checksum tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d099fa27b9702bed751524694adbe393e18b36b204da91eb1cbbbbb4a5ee2d58"
"checksum tokio-macros 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389"
"checksum tokio-rustls 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4adb8b3e5f86b707f1b54e7c15b6de52617a823608ccda98a15d3a24222f265a"
"checksum tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499"
"checksum tonic 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4afef9ce97ea39593992cf3fa00ff33b1ad5eb07665b31355df63a690e38c736"
"checksum tonic-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0436413ba71545bcc6c2b9a0f9d78d72deb0123c6a75ccdfe7c056f9930f5e52"
"checksum tower 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd3169017c090b7a28fce80abaad0ab4f5566423677c9331bb320af7e49cfe62"
"checksum tower-balance 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a792277613b7052448851efcf98a2c433e6f1d01460832dc60bef676bc275d4c"

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 = "6c3f6f22bfc642c714c1e43f6e09cb4d34c7a1de" }

9
lib/silentdragonlitelib.h

@ -6,13 +6,14 @@ extern "C" {
#endif
extern bool litelib_wallet_exists (const char* chain_name);
extern char * litelib_initialize_new (bool dangerous, const char* server);
extern char * litelib_initialize_new (const char* server);
extern char * litelib_initialize_new_from_phrase
(bool dangerous, const char* server, const char* seed,
unsigned long long birthday);
extern char * litelib_initialize_existing (bool dangerous, const char* server);
(const char* server, const char* seed,
unsigned long long birthday, unsigned long long number);
extern char * litelib_initialize_existing (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
}

40
lib/src/lib.rs

@ -29,11 +29,35 @@ 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.
#[no_mangle]
pub extern fn litelib_initialize_new(dangerous: bool, server: *const c_char) -> *mut c_char {
pub extern fn litelib_initialize_new(server: *const c_char) -> *mut c_char {
let server_str = unsafe {
assert!(!server.is_null());
@ -41,7 +65,7 @@ pub extern fn litelib_initialize_new(dangerous: bool, server: *const c_char) ->
};
let server = LightClientConfig::get_server_or_default(Some(server_str));
let (config, latest_block_height) = match LightClientConfig::create(server, dangerous) {
let (config, latest_block_height) = match LightClientConfig::create(server) {
Ok((c, h)) => (c, h),
Err(e) => {
let e_str = CString::new(format!("Error: {}", e)).unwrap();
@ -77,8 +101,8 @@ 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 {
pub extern fn litelib_initialize_new_from_phrase(server: *const c_char,
seed: *const c_char, birthday: u64, number: u64, overwrite: bool) -> *mut c_char {
let server_str = unsafe {
assert!(!server.is_null());
@ -92,7 +116,7 @@ pub extern fn litelib_initialize_new_from_phrase(dangerous: bool, server: *const
};
let server = LightClientConfig::get_server_or_default(Some(server_str));
let (config, _latest_block_height) = match LightClientConfig::create(server, dangerous) {
let (config, _latest_block_height) = match LightClientConfig::create(server) {
Ok((c, h)) => (c, h),
Err(e) => {
let e_str = CString::new(format!("Error: {}", e)).unwrap();
@ -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, overwrite) {
Ok(l) => l,
Err(e) => {
let e_str = CString::new(format!("Error: {}", e)).unwrap();
@ -119,7 +143,7 @@ pub extern fn litelib_initialize_new_from_phrase(dangerous: bool, server: *const
// Initialize a new lightclient and store its value
#[no_mangle]
pub extern fn litelib_initialize_existing(dangerous: bool, server: *const c_char) -> *mut c_char {
pub extern fn litelib_initialize_existing(server: *const c_char) -> *mut c_char {
let server_str = unsafe {
assert!(!server.is_null());
@ -127,7 +151,7 @@ pub extern fn litelib_initialize_existing(dangerous: bool, server: *const c_char
};
let server = LightClientConfig::get_server_or_default(Some(server_str));
let (config, _latest_block_height) = match LightClientConfig::create(server, dangerous) {
let (config, _latest_block_height) = match LightClientConfig::create(server) {
Ok((c, h)) => (c, h),
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/emoji/SD.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

BIN
res/emoji/emoji1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
res/emoji/face-with-rolling-eyes.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

BIN
res/emoji/face-with-tongue.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

BIN
res/emoji/face_with_3hearts.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
res/emoji/heart_shaped_eyes.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
res/emoji/hush-money-white.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
res/emoji/innocent.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
res/emoji/joy.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
res/emoji/laughing.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
res/emoji/money-mouth.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
res/emoji/nauseated-face.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

BIN
res/emoji/partying_face.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
res/emoji/pile-of-poo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

BIN
res/emoji/serious-face-with-symbols-covering-mouth.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
res/emoji/smiling-face-with-sunglasses.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
res/emoji/stuck-out.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
res/emoji/sweet_smile.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
res/hush-money-white.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
res/hush-money.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
res/images/tile.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

BIN
res/money-mouth.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
res/money-outgoing.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

13
res/silentdragonlite.desktop

@ -0,0 +1,13 @@
[Desktop Entry]
Name=SilentDragonLite
Comment=Lightclient UI wallet for Hush
GenericName=Wallet
Exec=SilentDragonLite %u
Icon=SilentDragonLite
Type=Application
StartupNotify=true
StartupWMClass=SilentDragonLite
Categories=Utility;
MimeType=x-scheme-handler/hush;
Keywords=SilentDragonLite;

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

7
silentdragon-lite.pro

@ -14,6 +14,7 @@ QT += widgets
QT += websockets
TARGET = SilentDragonLite
TEMPLATE = app
@ -49,6 +50,7 @@ SOURCES += \
src/3rdparty/qrcode/BitBuffer.cpp \
src/3rdparty/qrcode/QrCode.cpp \
src/3rdparty/qrcode/QrSegment.cpp \
src/3rdparty/json/json.hpp \
src/settings.cpp \
src/sendtab.cpp \
src/txtablemodel.cpp \
@ -94,7 +96,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 \
@ -122,6 +123,7 @@ HEADERS += \
FORMS += \
src/contactrequest.ui \
src/deposithush.ui \
src/emoji.ui \
src/encryption.ui \
src/hushrequest.ui \
src/mainwindow.ui \
@ -130,6 +132,8 @@ FORMS += \
src/newwallet.ui \
src/recurringpayments.ui \
src/restoreseed.ui \
src/seedrestore.ui \
src/sendHushTransactionChat.ui \
src/settings.ui \
src/about.ui \
src/confirm.ui \
@ -162,6 +166,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)

40
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)
{
@ -60,6 +99,7 @@ void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view, QLabel *label)
(p.getName() == ui->contactNameMemo->text().trimmed()) &&
(p.getPartnerAddress() == c.second.getAddress()) &&
(c.second.isOutgoing() == true))
{
QStandardItem *Items = new QStandardItem(c.second.toChatLine());

48
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,28 @@ 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>"));
bodydoc.setHtml(bodytext.replace(":smiley:", "<img src=':/emoji/res/emoji/emoji1.png'>"));
bodydoc.setHtml(bodytext.replace(":-)", "<img src=':/emoji/res/emoji/emoji1.png'>"));
bodydoc.setHtml(bodytext.replace(":money_mouth:", "<img src=':/emoji/res/emoji/money-mouth.png'>"));
bodydoc.setHtml(bodytext.replace(":laughing:", "<img src=':/emoji/res/emoji/laughing.png'>"));
bodydoc.setHtml(bodytext.replace(":sweet_smile:", "<img src=':/emoji/res/emoji/sweet_smile.png'>"));
bodydoc.setHtml(bodytext.replace(":joy:", "<img src=':/emoji/res/emoji/joy.png'>"));
bodydoc.setHtml(bodytext.replace(":innocent:", "<img src=':/emoji/res/emoji/innocent.png'>"));
bodydoc.setHtml(bodytext.replace(":partying_face:", "<img src=':/emoji/res/emoji/partying_face.png'>"));
bodydoc.setHtml(bodytext.replace(":fire:", "<img src=':/emoji/res/emoji/fire.png'>"));
bodydoc.setHtml(bodytext.replace(":rolling_eyes:", "<img src=':/emoji/res/emoji/face-with-rolling-eyes.png'>"));
bodydoc.setHtml(bodytext.replace(":stuck_out_tongue:", "<img src=':/emoji/res/emoji/face-with-tongue.png'>"));
bodydoc.setHtml(bodytext.replace(":face_with_3hearts:", "<img src=':/emoji/res/emoji/face_with_3hearts.png'>"));
bodydoc.setHtml(bodytext.replace(":heart_eyes:", "<img src=':/emoji/res/emoji/heart_shaped_eyes.png'>"));
bodydoc.setHtml(bodytext.replace(":nauseated:", "<img src=':/emoji/res/emoji/nauseated-face.png'>"));
bodydoc.setHtml(bodytext.replace(":poop:", "<img src=':/emoji/res/emoji/pile-of-poo.png'>"));
bodydoc.setHtml(bodytext.replace(":symbols_mouth:", "<img src=':/emoji/res/emoji/serious-face-with-symbols-covering-mouth.png'>"));
bodydoc.setHtml(bodytext.replace(":sunglass:", "<img src=':/emoji/res/emoji/smiling-face-with-sunglasses.png'>"));
bodydoc.setHtml(bodytext.replace(":stuck_out:", "<img src=':/emoji/res/emoji/stuck-out.png'>"));
bodydoc.setHtml(bodytext.replace(";p", "<img src=':/emoji/res/emoji/stuck-out.png'>"));
bodydoc.setHtml(bodytext.replace(":hush_white:", "<img src=':/emoji/res/emoji/hush-money-white.png'>"));
bodydoc.setHtml(bodytext.replace(":sd:", "<img src=':/emoji/res/emoji/SD.png'>"));
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 +194,28 @@ 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>"));
bodydoc.setHtml(bodytext.replace(":smiley:", "<img src=':/emoji/res/emoji/emoji1.png'>"));
bodydoc.setHtml(bodytext.replace(":-)", "<img src=':/emoji/res/emoji/emoji1.png'>"));
bodydoc.setHtml(bodytext.replace(":money_mouth:", "<img src=':/emoji/res/emoji/money-mouth.png'>"));
bodydoc.setHtml(bodytext.replace(":laughing:", "<img src=':/emoji/res/emoji/laughing.png'>"));
bodydoc.setHtml(bodytext.replace(":sweet_smile:", "<img src=':/emoji/res/emoji/sweet_smile.png'>"));
bodydoc.setHtml(bodytext.replace(":joy:", "<img src=':/emoji/res/emoji/joy.png'>"));
bodydoc.setHtml(bodytext.replace(":innocent:", "<img src=':/emoji/res/emoji/innocent.png'>"));
bodydoc.setHtml(bodytext.replace(":partying_face:", "<img src=':/emoji/res/emoji/partying_face.png'>"));
bodydoc.setHtml(bodytext.replace(":fire:", "<img src=':/emoji/res/emoji/fire.png'>"));
bodydoc.setHtml(bodytext.replace(":rolling_eyes:", "<img src=':/emoji/res/emoji/face-with-rolling-eyes.png'>"));
bodydoc.setHtml(bodytext.replace(":stuck_out_tongue:", "<img src=':/emoji/res/emoji/face-with-tongue.png'>"));
bodydoc.setHtml(bodytext.replace(":face_with_3hearts:", "<img src=':/emoji/res/emoji/face_with_3hearts.png'>"));
bodydoc.setHtml(bodytext.replace(":heart_eyes:", "<img src=':/emoji/res/emoji/heart_shaped_eyes.png'>"));
bodydoc.setHtml(bodytext.replace(":nauseated:", "<img src=':/emoji/res/emoji/nauseated-face.png'>"));
bodydoc.setHtml(bodytext.replace(":poop:", "<img src=':/emoji/res/emoji/pile-of-poo.png'>"));
bodydoc.setHtml(bodytext.replace(":symbols_mouth:", "<img src=':/emoji/res/emoji/serious-face-with-symbols-covering-mouth.png'>"));
bodydoc.setHtml(bodytext.replace(":sunglass:", "<img src=':/emoji/res/emoji/smiling-face-with-sunglasses.png'>"));
bodydoc.setHtml(bodytext.replace(":stuck_out:", "<img src=':/emoji/res/emoji/stuck-out.png'>"));
bodydoc.setHtml(bodytext.replace(";p", "<img src=':/emoji/res/emoji/stuck-out.png'>"));
bodydoc.setHtml(bodytext.replace(":hush_white:", "<img src=':/emoji/res/emoji/hush-money-white.png'>"));
bodydoc.setHtml(bodytext.replace(":sd:", "<img src=':/emoji/res/emoji/SD.png'>"));
// 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;

56
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,7 +59,7 @@ void ChatDataStore::setPassword(QString password)
QString ChatDataStore::dump()
{
json chats;
json chats;
chats["count"] = this->data.size();
json j = {};
for (auto &c: this->data)
@ -55,7 +67,7 @@ QString ChatDataStore::dump()
j.push_back(c.second.toJson());
}
chats["chatitems"] = j;
return QString::fromStdString(chats.dump());
return QString::fromStdString(chats.dump());
}
std::map<QString, ChatItem> ChatDataStore::getAllRawChatItems()
@ -103,6 +115,46 @@ std::map<QString, ChatItem> ChatDataStore::getAllOldContactRequests()
return filteredItems;
}
std::map<QString, ChatItem> ChatDataStore::getAllCashMemosIncoming()
{
std::map<QString, ChatItem> filteredItems;
for(auto &c: this->data)
{
if (
(c.second.isOutgoing() == false) &&
(c.second.getType() == "Money") &&
(c.second.getMemo().startsWith("{"))
)
{
filteredItems[c.first] = c.second;
}
}
return filteredItems;
}
std::map<QString, ChatItem> ChatDataStore::getAllCashMemosOutgoing()
{
std::map<QString, ChatItem> filteredItems;
for(auto &c: this->data)
{
if (
(c.second.isOutgoing() == true) &&
(c.second.getType() == "Money") &&
(c.second.getMemo().startsWith("{"))
)
{
filteredItems[c.first] = c.second;
}
}
return filteredItems;
}
std::map<QString, ChatItem> ChatDataStore::getAllMemos()
{
std::map<QString, ChatItem> filteredItems;

8
src/DataStore/ChatDataStore.h

@ -23,13 +23,19 @@ class ChatDataStore
ChatItem getData(QString key);
std::map<QString, ChatItem> getAllRawChatItems();
std::map<QString, ChatItem> getAllNewContactRequests();
std::map<QString, ChatItem> getAllCashMemosOutgoing();
std::map<QString, ChatItem> getAllCashMemosIncoming();
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();
~ChatDataStore()

2
src/DataStore/ContactDataStore.cpp

@ -43,7 +43,7 @@ QString ContactDataStore::dump()
j.push_back(c.second.toJson());
}
contacts["contacts"] = j;
return QString::fromStdString(contacts.dump(4));
return QString::fromStdString(contacts.dump(4));
}
ContactDataStore* ContactDataStore::instance = nullptr;

1
src/FileSystem/FileSystem.h

@ -9,6 +9,7 @@
#include "../Crypto/FileEncryption.h"
#include <fstream>
using json = nlohmann::json;
class FileSystem
{
private:

40
src/Model/ChatItem.cpp

@ -158,6 +158,9 @@ QString ChatItem::toChatLine()
{
QDateTime myDateTime;
QString lock;
QString money;
QString moneyText;
QString moneyTextRequest;
myDateTime.setTime_t(_timestamp);
if (_notarize == true)
@ -175,15 +178,48 @@ QString ChatItem::toChatLine()
{
lock = "<b> <img src=':/icons/res/lock_green.png'><b>";
}
}else{}
if (_memo.startsWith("Money transaction of :"))
{
if (_outgoing == true)
{
moneyText = QString("<br>") + QString("<br>") + QString("<pr> Outgoing Money Transaction </pr>") + QString("<b> <img src=':/icons/res/money-outgoing.png'><b>");
}else{
moneyText = QString("<br>") + QString("<br>") + QString("<pr> Incoming Money Transaction </pr>") + QString("<b> <img src=':/icons/res/money-mouth.png'><b>");
}
}else{money = "";
moneyText = ""; }
if (_memo.startsWith("Request of :"))
{
if (_outgoing == true)
{
moneyTextRequest = QString("<br>") + QString("<br>") + QString("<pr> Outgoing Hush Request </pr>") + QString("<b> <img src=':/icons/res/money-outgoing.png'><b>");
}else{
moneyTextRequest = QString("<br>") + QString("<br>") + QString("<pr> Incoming Hush Request </pr>") + QString("<b> <img src=':/icons/res/money-mouth.png'><b>");
}
}else{moneyTextRequest = "";
moneyTextRequest = ""; }
QString line = QString("<small>") + myDateTime.toString("yyyy-MM-dd hh:mm");
line += QString(lock) + QString("</small>");
line += QString(lock) + QString(moneyText) + QString(moneyTextRequest) + QString("</small>");
line +=QString("<p>") + _memo.toHtmlEscaped() + QString("</p>");
return line;
}
json ChatItem::toJson()
{
json j;

91
src/addressbook.cpp

@ -250,6 +250,9 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target)
);
parent->ui->listChat->verticalScrollBar()->setValue(
parent->ui->listChat->verticalScrollBar()->maximum());
});
// AddressBook::getInstance()->addAddressLabel(newLabel, ab.addr->text(), cid);
@ -386,25 +389,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 +453,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)));
// }
}
@ -443,11 +472,35 @@ void AddressBook::writeToStorage()
// FileSystem::getInstance()->writeContactsOldFormat(AddressBook::writeableFile(), allLabels);
QString passphraseHash = DataStore::getChatDataStore()->getPassword();
int length = passphraseHash.length();
QFile file(AddressBook::writeableFile());
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());
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;
@ -457,9 +510,19 @@ void AddressBook::writeToStorage()
c.push_back(item.getCid());
c.push_back(item.getAvatar());
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()

181
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();
@ -434,8 +434,6 @@ Tx MainWindow::createTxFromChatPage() {
QString type = "Memo";
QString addr = c.getPartnerAddress();
/////////User input for chatmemos
QString memoplain = ui->memoTxtChat->toPlainText().trimmed();
@ -443,35 +441,21 @@ 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];
@ -479,7 +463,9 @@ Tx MainWindow::createTxFromChatPage() {
unsigned char server_rx[crypto_kx_SESSIONKEYBYTES], server_tx[crypto_kx_SESSIONKEYBYTES];
if (crypto_kx_seed_keypair(pk,sk,
hash) !=0) {
MESSAGEAS1) !=0) {
this->logger->write("Suspicious keypair, bail out ");
}
////////////////Get the pubkey from Bob, so we can create the share key
@ -489,14 +475,21 @@ Tx MainWindow::createTxFromChatPage() {
if (crypto_kx_server_session_keys(server_rx, server_tx,
pk, sk, pubkeyBob) != 0) {
/* Suspicious client public key, bail out */
this->logger->write("Suspicious client public send key, bail out ");
}
// 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];
@ -522,7 +515,6 @@ Tx MainWindow::createTxFromChatPage() {
/////Ciphertext Memo
QString memo = QByteArray(reinterpret_cast<const char*>(ciphertext), CIPHERTEXT_LEN).toHex();
tx.toAddrs.push_back(ToFields{addr, amt, hmemo});
tx.toAddrs.push_back(ToFields{addr, amt, memo});
@ -549,6 +541,7 @@ void MainWindow::sendChat() {
QMessageBox msg(QMessageBox::Critical, tr("You have to select a contact and insert a Memo"),
tr("You have selected no Contact from Contactlist,\n") + tr("\nor your Memo is empty"),
QMessageBox::Ok, this);
ui->memoTxtChat->setEnabled(true);
msg.exec();
return;
@ -578,6 +571,7 @@ void MainWindow::sendChat() {
QMessageBox::Ok, this);
msg.exec();
ui->memoTxtChat->setEnabled(true);
// abort the Tx
return;
@ -597,6 +591,7 @@ void MainWindow::sendChat() {
movie->start();
ui->sendChatButton->show();
ui->sendChatButton->setEnabled(false);
ui->memoTxtChat->setEnabled(true);
} else {
@ -606,6 +601,8 @@ void MainWindow::sendChat() {
movie1->start();
ui->sendChatButton->show();
ui->sendChatButton->setEnabled(false);
ui->memoTxtChat->setEnabled(true);
}
ui->memoTxtChat->clear();
@ -624,6 +621,8 @@ void MainWindow::sendChat() {
ui->sendChatButton->setIcon(sendIcon);
movie->stop();
ui->sendChatButton->setEnabled(true);
ui->memoTxtChat->setEnabled(true);
}else{
QPixmap send(":/icons/res/sendBlack.png");
@ -631,6 +630,7 @@ void MainWindow::sendChat() {
ui->sendChatButton->setIcon(sendIcon);
movie1->stop();
ui->sendChatButton->setEnabled(true);
ui->memoTxtChat->setEnabled(true);
}
});
@ -643,6 +643,7 @@ void MainWindow::sendChat() {
// Errored out
[=] (QString opid, QString errStr) {
ui->statusBar->showMessage(QObject::tr(" Tx ") % opid % QObject::tr(" failed"), 15 * 1000);
ui->memoTxtChat->setEnabled(true);
if (!opid.isEmpty())
errStr = QObject::tr("The transaction with id ") % opid % QObject::tr(" failed. The error was") + ":\n\n" + errStr;
@ -657,6 +658,7 @@ void MainWindow::sendChat() {
ui->sendChatButton->setIcon(sendIcon);
movie->stop();
ui->sendChatButton->setEnabled(true);
ui->memoTxtChat->setEnabled(true);
}else{
QPixmap send(":/icons/res/sendBlack.png");
@ -664,6 +666,7 @@ void MainWindow::sendChat() {
ui->sendChatButton->setIcon(sendIcon);
movie1->stop();
ui->sendChatButton->setEnabled(true);
ui->memoTxtChat->setEnabled(true);
}
@ -681,6 +684,7 @@ QString MainWindow::doSendChatTxValidations(Tx tx) {
if (!Settings::isValidAddress(toAddr.addr)) {
QString addr = (toAddr.addr.length() > 100 ? toAddr.addr.left(100) + "..." : toAddr.addr);
return QString(tr("Recipient Address ")) % addr % tr(" is Invalid");
ui->memoTxtChat->setEnabled(true);
}
// This technically shouldn't be possible, but issue #62 seems to have discovered a bug
@ -698,6 +702,7 @@ QString MainWindow::doSendChatTxValidations(Tx tx) {
if (available < total) {
return tr("Not enough available funds to send this transaction\n\nHave: %1\nNeed: %2\n\nNote: Funds need 1 confirmations before they can be spent")
.arg(available.toDecimalhushString(), total.toDecimalhushString());
ui->memoTxtChat->setEnabled(true);
}
return "";
@ -710,9 +715,11 @@ 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]);
@ -720,6 +727,10 @@ QObject::connect(request.newZaddr, &QPushButton::clicked, [&] () {
request.myzaddr->setText(myAddr);
ui->listReceiveAddresses->insertItem(0, myAddr);
ui->listReceiveAddresses->setCurrentIndex(0);
DataStore::getChatDataStore()->setSendZaddr(myAddr);
qDebug()<<"Zaddr: "<<myAddr;
});
}catch(...)
@ -728,7 +739,6 @@ QObject::connect(request.newZaddr, &QPushButton::clicked, [&] () {
qDebug() << QString("Caught something nasty with myZaddr Contact");
}
});
QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces);
@ -748,77 +758,66 @@ 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);
dialog.exec();
QObject::connect(request.sendRequestButton, &QPushButton::clicked, this, &MainWindow::saveandsendContact);
rpc->refreshContacts(ui->listContactWidget);
// 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();
QString memo = contactRequest.getMemo();
QString passphrase = DataStore::getChatDataStore()->getPassword();
int length = passphrase.length();
////////////////Generate the secretkey for our message encryption
char *hashEncryptionKeyraw = NULL;
hashEncryptionKeyraw = new char[length+1];
strncpy(hashEncryptionKeyraw, passphrase.toUtf8(), length +1);
////////////////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
unsigned char sk[crypto_kx_SECRETKEYBYTES];
unsigned char pk[crypto_kx_PUBLICKEYBYTES];
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];
if (crypto_kx_seed_keypair(pk,sk,
hash) !=0) {
}
QString publicKey = QByteArray(reinterpret_cast<const char*>(pk), crypto_kx_PUBLICKEYBYTES).toHex();
if (crypto_kx_seed_keypair(pk, sk, MESSAGEAS1) !=0) {
this->logger->write("Suspicious client public contact request key, bail out ");
}
QString hmemo= createHeaderMemo(type,cid,myAddr,"", publicKey);
QString publicKey = QByteArray(reinterpret_cast<const char*>(pk), crypto_kx_PUBLICKEYBYTES).toHex();
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,26 +834,14 @@ 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();
if (size > max){
// 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();

58
src/connection.cpp

@ -10,6 +10,16 @@
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)
{
this->main = main;
@ -59,7 +69,6 @@ void ConnectionLoader::doAutoConnect()
{
qDebug() << "Doing autoconnect";
auto config = std::shared_ptr<ConnectionConfig>(new ConnectionConfig());
config->dangerous = false;
config->server = Settings::getInstance()->getSettings().server;
// Initialize the library
@ -70,7 +79,6 @@ void ConnectionLoader::doAutoConnect()
{
main->logger->write(QObject::tr("Using existing wallet."));
char* resp = litelib_initialize_existing(
config->dangerous,
config->server.toStdString().c_str()
);
QString response = litelib_process_response(resp);
@ -85,7 +93,7 @@ void ConnectionLoader::doAutoConnect()
else
{
main->logger->write(QObject::tr("Create/restore wallet."));
createOrRestore(config->dangerous, config->server);
createOrRestore(config->server);
d->show();
}
@ -97,13 +105,16 @@ void ConnectionLoader::doAutoConnect()
// If success, set the connection
main->logger->write("Connection is online.");
connection->setInfo(reply);
main->logger->write("getting Connection reply");
isSyncing = new QAtomicInteger<bool>();
isSyncing->store(true);
isSyncing->storeRelaxed(true);
main->logger->write("isSyncing");
// Do a sync at startup
syncTimer = new QTimer(main);
main->logger->write("Beginning sync");
connection->doRPCWithDefaultErrorHandling("sync", "", [=](auto) {
isSyncing->store(false);
isSyncing->storeRelaxed(false);
// Cancel the timer
syncTimer->deleteLater();
// When sync is done, set the connection
@ -113,10 +124,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
try {
connection->doRPC("syncstatus", "", [=](json reply) {
if (isSyncing != nullptr && reply.find("synced_blocks") != reply.end())
{
qint64 synced = reply["synced_blocks"].get<json::number_unsigned_t>();
qint64 total = reply["total_blocks"].get<json::number_unsigned_t>();
@ -128,32 +142,56 @@ void ConnectionLoader::doAutoConnect()
[=](QString err) {
qDebug() << "Sync error" << err;
});
}catch (...)
{
main->logger->write("catch sync progress reply");
}
}
});
syncTimer->setInterval(1* 1000);
syncTimer->start();
main->logger->write("Start sync timer");
}, [=](QString err) {
showError(err);
});
}
void ConnectionLoader::createOrRestore(bool dangerous, QString server)
void ConnectionLoader::createOrRestore(QString server)
{
// Close the startup dialog, since we'll be showing the wizard
d->hide();
// Create a wizard
FirstTimeWizard wizard(dangerous, server);
FirstTimeWizard wizard(server);
main->logger->write("Start new Wallet with FirstimeWizard");
wizard.exec();
}
void ConnectionLoader::doRPCSetConnection(Connection* conn)
{
qDebug() << "Connectionloader finished, setting connection";
main->logger->write("Connectionloader finished, setting connection");
rpc->setConnection(conn);
d->accept();
QTimer::singleShot(1, [=]() { delete this; });
try
{
QFile plaintextWallet(dirwalletconnection);
main->logger->write("Path to Wallet.dat : " );
plaintextWallet.remove();
}catch (...)
{
main->logger->write("no Plaintext wallet.dat");
}
}
Connection* ConnectionLoader::makeConnection(std::shared_ptr<ConnectionConfig> config)
@ -202,7 +240,6 @@ 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,
@ -212,7 +249,8 @@ void Executor::run()
emit handleError(reply);
else
emit responseReady(parsed);
emit responseReady(parsed);
}

4
src/connection.h

@ -5,14 +5,12 @@
#include "ui_connection.h"
#include "precompiled.h"
using json = nlohmann::json;
class Controller;
struct ConnectionConfig {
QString server;
bool dangerous;
QString proxy;
};
@ -34,7 +32,7 @@ private:
void doAutoConnect();
void createOrRestore(bool dangerous, QString server);
void createOrRestore(QString server);
void showError(QString explanation);
void showInformation(QString info, QString detail = "");

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>

660
src/controller.cpp

@ -17,6 +17,7 @@ ContactModel *contactModel = new ContactModel();
using json = nlohmann::json;
Controller::Controller(MainWindow* main)
{
auto cl = new ConnectionLoader(main, this);
@ -102,6 +103,9 @@ void Controller::setConnection(Connection* c)
ui->listContactWidget
);
ui->listChat->verticalScrollBar()->setValue(
ui->listChat->verticalScrollBar()->maximum());
}
std::string Controller::encryptDecrypt(std::string toEncrypt)
@ -141,12 +145,11 @@ void Controller::fillTxJsonParams(json& allRecepients, Tx tx)
DataStore::getSietchDataStore()->setData(QString("Sietch") + QString(i), zdust.toUtf8());
} );
}
// Set sietch zdust addr to json.
// Using DataStore singelton, to store the data into the dusts, bing bada boom :D
// Using DataStore singelton, to store the data into the dust.
for(uint8_t i = 0; i < 6; i++)
{
dust.at(i)["address"] = DataStore::getSietchDataStore()->getData(QString("Sietch" + QString(i))).toStdString();
dust.at(i)["address"] = DataStore::getSietchDataStore()->getData(QString("Sietch" + QString(i))).toStdString();
}
DataStore::getSietchDataStore()->clear(); // clears the datastore
@ -157,42 +160,41 @@ void Controller::fillTxJsonParams(json& allRecepients, Tx tx)
const int randomStringLength = sizerandomString;
QString randomString;
QRandomGenerator *gen = QRandomGenerator::system();
for(int i=0; i<randomStringLength; ++i)
{
int index = qrand() % possibleCharacters.length();
// int index = qrand() % possibleCharacters.length();
int index = gen->bounded(0, possibleCharacters.length() - 1);
QChar nextChar = possibleCharacters.at(index);
randomString.append(nextChar);
}
for(uint8_t i = 0; i < 6; i++)
for(uint8_t i = 0; i < 6; i++)
{
int length = randomString.length();
int randomSize = rand() % 120 +10;
char *randomHash = NULL;
randomHash = new char[length+1];
strncpy(randomHash, randomString.toLocal8Bit(), length +1);
#define MESSAGE ((const unsigned char *) randomHash)
#define MESSAGE_LEN length
#define MESSAGE_LEN1 length + randomSize
unsigned char hash[crypto_secretstream_xchacha20poly1305_ABYTES];
unsigned char hash[crypto_secretstream_xchacha20poly1305_ABYTES];
crypto_generichash(hash, sizeof hash,
crypto_generichash(hash, sizeof hash,
MESSAGE, MESSAGE_LEN1,
NULL, 0);
std::string decryptedMemo(reinterpret_cast<char*>(hash),MESSAGE_LEN1);
std::string encrypt = this->encryptDecrypt(decryptedMemo);
QString randomHashafter1 = QByteArray(reinterpret_cast<const char*>(encrypt.c_str()),encrypt.size()).toHex();
dust.at(i)["memo"] = randomHashafter1.toStdString();
std::string decryptedMemo(reinterpret_cast<char*>(hash),MESSAGE_LEN1);
std::string encrypt = this->encryptDecrypt(decryptedMemo);
QString randomHashafter1 = QByteArray(reinterpret_cast<const char*>(encrypt.c_str()),encrypt.size()).toHex();
dust.at(i)["memo"] = randomHashafter1.toStdString();
}
for(uint8_t i = 0; i < 6; i++)
for(auto &it: dust)
{
dust.at(i)["amount"] = 0;
it["amount"] = 0;
}
@ -205,10 +207,10 @@ dust.at(i)["memo"] = randomHashafter1.toStdString();
if (Settings::isZAddress(toAddr.addr) && !toAddr.memo.trimmed().isEmpty())
rec["memo"] = toAddr.memo.toStdString();
allRecepients.push_back(rec) ;
allRecepients.push_back(rec);
}
allRecepients.insert(std::begin(allRecepients), {
allRecepients.insert(std::begin(allRecepients), {
dust.at(0),
dust.at(1),
dust.at(2),
@ -217,6 +219,8 @@ dust.at(i)["memo"] = randomHashafter1.toStdString();
dust.at(5)
}) ;
qDebug()<<"ADDR DUST";
}
void Controller::noConnection()
@ -288,12 +292,10 @@ void Controller::getInfoThenRefresh(bool force)
bool doUpdate = force || (model->getLatestBlock() != curBlock);
int difficulty = reply["difficulty"].get<json::number_integer_t>();
int blocks_until_halving= 340000 - curBlock;
int halving_days = (blocks_until_halving * 150) / (60*60*24) ;
int halving_days = (blocks_until_halving * 150) / (60 * 60 * 24) ;
int longestchain = reply["longestchain"].get<json::number_integer_t>();
int notarized = reply["notarized"].get<json::number_integer_t>();
model->setLatestBlock(curBlock);
if (
Settings::getInstance()->get_currency_name() == "EUR" ||
@ -309,11 +311,7 @@ void Controller::getInfoThenRefresh(bool force)
);
ui->longestchain->setText(
"Block: " + QLocale(QLocale::German).toString(longestchain)
);
ui->difficulty->setText(
QLocale(QLocale::German).toString(difficulty)
);
@ -342,12 +340,9 @@ void Controller::getInfoThenRefresh(bool force)
);
}
ui->Version->setText(
QString::fromStdString(reply["version"].get<json::string_t>())
);
ui->Vendor->setText(
QString::fromStdString(reply["vendor"].get<json::string_t>())
);
ui->Version->setText(QString::fromStdString(reply["version"].get<json::string_t>()));
ui->Vendor->setText(QString::fromStdString(reply["vendor"].get<json::string_t>()));
main->logger->write(
QString("Refresh. curblock ") % QString::number(curBlock) % ", update=" % (doUpdate ? "true" : "false")
);
@ -359,7 +354,6 @@ void Controller::getInfoThenRefresh(bool force)
QString chainName = Settings::getInstance()->isTestnet() ? "test" : "main";
main->statusLabel->setText(chainName + "(" + QString::number(curBlock) + ")");
// use currency ComboBox as input
if (Settings::getInstance()->get_currency_name() == "USD")
@ -377,8 +371,6 @@ void Controller::getInfoThenRefresh(bool force)
" $ " + (QLocale(QLocale::English).toString(cap,'f', 2))
);
}
else if (Settings::getInstance()->get_currency_name() == "EUR")
{
@ -568,7 +560,7 @@ void Controller::getInfoThenRefresh(bool force)
zrpc->fetchSupply([=] (const json& reply) {
int supply = reply["supply"].get<json::number_integer_t>();
int zfunds = reply["zfunds"].get<json::number_integer_t>();
int total = reply["total"].get<json::number_integer_t>();
int total = reply["total"].get<json::number_integer_t>();;
if (
Settings::getInstance()->get_currency_name() == "EUR" ||
Settings::getInstance()->get_currency_name() == "CHF" ||
@ -595,7 +587,7 @@ void Controller::getInfoThenRefresh(bool force)
refreshAddresses(); // This calls refreshZSentTransactions() and refreshReceivedZTrans()
refreshTransactions();
}
refreshBalances();
int lag = longestchain - notarized ;
this->setLag(lag);
}, [=](QString err) {
@ -690,7 +682,7 @@ void Controller::processUnspent(const json& reply, QMap<QString, CAmount>* balan
CAmount amount = CAmount::fromqint64(it["value"].get<json::number_unsigned_t>());
bool spendable = it["unconfirmed_spent"].is_null() && it["spent"].is_null(); // TODO: Wait for 1 confirmations
bool pending = !it["unconfirmed_spent"].is_null();
bool pending = !it["unconfirmed_spent"].is_null();;
unspentOutputs->push_back(
UnspentOutput{ qsAddr, txid, amount, block, spendable, pending }
@ -878,7 +870,6 @@ void Controller::refreshBalances()
CAmount balAvailable = balT + balVerified;
model->setAvailableBalance(balAvailable);
updateUIBalances();
});
// 2. Get the UTXOs
@ -917,6 +908,7 @@ void Controller::refreshTransactions() {
QList<TransactionItem> txdata;
for (auto& it : reply.get<json::array_t>()) {
{
QString address;
CAmount total_amount;
QList<TransactionItemDetail> items;
@ -924,10 +916,11 @@ void Controller::refreshTransactions() {
long confirmations;
if (it.find("unconfirmed") != it.end() && it["unconfirmed"].get<json::boolean_t>()) {
confirmations = 0;
} else {
}else{
confirmations = model->getLatestBlock() - it["block_height"].get<json::number_integer_t>() + 1;
}
auto txid = QString::fromStdString(it["txid"]);
auto datetime = it["datetime"].get<json::number_integer_t>();
@ -935,193 +928,183 @@ void Controller::refreshTransactions() {
if (!it["outgoing_metadata"].is_null()) {
for (auto o: it["outgoing_metadata"].get<json::array_t>())
{
// if (chatModel->getCidByTx(txid) == QString("0xdeadbeef")){
QString address;
{
// if (chatModel->getCidByTx(txid) == QString("0xdeadbeef")){
QString address;
address = QString::fromStdString(o["address"]);
// Sent items are -ve
CAmount amount = CAmount::fromqint64(-1* o["value"].get<json::number_unsigned_t>());
// Check for Memos
// Check for Memos
if (confirmations == 0) {
chatModel->addconfirmations(txid, confirmations);
}
if (confirmations == 0) {
chatModel->addconfirmations(txid, confirmations);
}
if ((confirmations == 1) && (chatModel->getConfirmationByTx(txid) != QString("0xdeadbeef"))){
DataStore::getChatDataStore()->clear();
chatModel->killConfirmationCache();
chatModel->killMemoCache();
this->refresh(true);
}
if ((confirmations > 0) && (chatModel->getConfirmationByTx(txid) != QString("0xdeadbeef"))) {
DataStore::getChatDataStore()->clear();
chatModel->killConfirmationCache();
chatModel->killMemoCache();
this->refresh(true);
}
QString memo;
QString cid;
QString headerbytes;
QString publickey;
if (!o["memo"].is_null()) {
memo = QString::fromStdString(o["memo"].get<json::string_t>());
if (memo.startsWith("{")) {
try
{
QJsonDocument headermemo = QJsonDocument::fromJson(memo.toUtf8());
cid = headermemo["cid"].toString();
headerbytes = headermemo["e"].toString();
memo = QString::fromStdString(o["memo"].get<json::string_t>());
chatModel->addCid(txid, cid);
chatModel->addHeader(txid, headerbytes);
if (memo.startsWith("{")) {
try
{
QJsonDocument headermemo = QJsonDocument::fromJson(memo.toUtf8());
} catch(...)
cid = headermemo["cid"].toString();
headerbytes = headermemo["e"].toString();
{
chatModel->addCid(txid, cid);
chatModel->addHeader(txid, headerbytes);
}
}
}
catch (...)
{
// on any exception caught
}
}
bool isNotarized;
if (confirmations > getLag())
{
isNotarized = true;
}else{
}
else
{
isNotarized = false;
}
if (chatModel->getCidByTx(txid) != QString("0xdeadbeef")){
cid = chatModel->getCidByTx(txid);
}else{
cid = "";
}
if (chatModel->getHeaderByTx(txid) != QString("0xdeadbeef")){
headerbytes = chatModel->getHeaderByTx(txid);
}else{
headerbytes = "";
}
if (main->getPubkeyByAddress(address) != QString("0xdeadbeef")){
publickey = main->getPubkeyByAddress(address);
}else{
publickey = "";
}
/////We need to filter out Memos smaller then the ciphertext size, or it will dump
if ((memo.startsWith("{") == false) && (headerbytes.length() > 20))
{
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);
const QByteArray pubkeyBobArray = QByteArray::fromHex(publickey.toLatin1());
const unsigned char *pubkeyBob = reinterpret_cast<const unsigned char *>(pubkeyBobArray.constData());
#define MESSAGEAS1 ((const unsigned char *) hashEncryptionKeyraw)///////////
#define MESSAGEAS1_LEN length
if (chatModel->getCidByTx(txid) != QString("0xdeadbeef"))
{
cid = chatModel->getCidByTx(txid);
}
else
{
cid = "";
}
unsigned char hash1[crypto_kx_SEEDBYTES];
if (chatModel->getHeaderByTx(txid) != QString("0xdeadbeef"))
{
headerbytes = chatModel->getHeaderByTx(txid);
}
else
{
headerbytes = "";
}
crypto_hash_sha256(hash1,MESSAGEAS1, MESSAGEAS1_LEN);
unsigned char sk[crypto_kx_SECRETKEYBYTES];
unsigned char pk[crypto_kx_PUBLICKEYBYTES];
if (main->getPubkeyByAddress(address) != QString("0xdeadbeef"))
{
publickey = main->getPubkeyByAddress(address);
}
else
{
publickey = "";
}
if (crypto_kx_seed_keypair(pk,sk,
hash1) !=0) {
}
/////We need to filter out Memos smaller then the ciphertext size, or it will dump
if ((memo.startsWith("{") == false) && (headerbytes.length() > 20))
{
QString passphrase = DataStore::getChatDataStore()->getPassword();
int length = passphrase.length();
unsigned char server_rx[crypto_kx_SESSIONKEYBYTES], server_tx[crypto_kx_SESSIONKEYBYTES];
////////////////Generate the secretkey for our message encryption
char *hashEncryptionKeyraw = NULL;
hashEncryptionKeyraw = new char[length+1];
strncpy(hashEncryptionKeyraw, passphrase.toUtf8(), length +1);
const QByteArray pubkeyBobArray = QByteArray::fromHex(publickey.toLatin1());
const unsigned char *pubkeyBob = reinterpret_cast<const unsigned char *>(pubkeyBobArray.constData());
////////////////Get the pubkey from Bob, so we can create the share key
#define MESSAGEAS1 ((const unsigned char *) hashEncryptionKeyraw) ///////////
#define MESSAGEAS1_LEN length
unsigned char sk[crypto_kx_SECRETKEYBYTES];
unsigned char pk[crypto_kx_PUBLICKEYBYTES];
/////Create the shared key for sending the message
if (crypto_kx_seed_keypair(pk, sk, MESSAGEAS1) !=0)
{
main->logger->write("Keypair outgoing error");
}
if (crypto_kx_server_session_keys(server_rx, server_tx,
pk, sk, pubkeyBob) != 0) {
/* Suspicious client public key, bail out */
}
unsigned char server_rx[crypto_kx_SESSIONKEYBYTES], server_tx[crypto_kx_SESSIONKEYBYTES];
const QByteArray ba = QByteArray::fromHex(memo.toLatin1());
const unsigned char *encryptedMemo = reinterpret_cast<const unsigned char *>(ba.constData());
////////////////Get the pubkey from Bob, so we can create the share key
const QByteArray ba1 = QByteArray::fromHex(headerbytes.toLatin1());
const unsigned char *header = reinterpret_cast<const unsigned char *>(ba1.constData());
/////Create the shared key for sending the message
int encryptedMemoSize1 = ba.length();
if (crypto_kx_server_session_keys(server_rx, server_tx, pk, sk, pubkeyBob) != 0)
{
main->logger->write("Suspicious client public outgoing key, bail out ");
}
QString memodecrypt;
const QByteArray ba = QByteArray::fromHex(memo.toUtf8());
const unsigned char *encryptedMemo = reinterpret_cast<const unsigned char *>(ba.constData());
if (encryptedMemoSize1 > 15)
{
//////unsigned char* as message from QString
#define MESSAGE2 (const unsigned char *) encryptedMemo
const QByteArray ba1 = QByteArray::fromHex(headerbytes.toLatin1());
const unsigned char *header = reinterpret_cast<const unsigned char *>(ba1.constData());
///////// length of the encrypted message
#define CIPHERTEXT1_LEN encryptedMemoSize1
int encryptedMemoSize1 = ba.length();
///////Message length is smaller then the encrypted message
#define MESSAGE1_LEN encryptedMemoSize1 - crypto_secretstream_xchacha20poly1305_ABYTES
QString memodecrypt;
//////Set the length of the decrypted message
if ((encryptedMemoSize1 - crypto_secretstream_xchacha20poly1305_ABYTES) > 0)
{
//////unsigned char* as message from QString
#define MESSAGE2 (const unsigned char *) encryptedMemo
unsigned char decrypted[MESSAGE1_LEN];
unsigned char tag[crypto_secretstream_xchacha20poly1305_TAG_FINAL];
crypto_secretstream_xchacha20poly1305_state state;
///////// length of the encrypted message
#define CIPHERTEXT1_LEN encryptedMemoSize1
/////Our decrypted message is now in decrypted. We need it as QString to render it
/////Only the QString gives weird data, so convert first to std::string
// crypto_secretstream_xchacha20poly1305_keygen(client_rx);
if (crypto_secretstream_xchacha20poly1305_init_pull(&state, header, server_tx) != 0) {
/* Invalid header, no need to go any further */
}
///////Message length is smaller then the encrypted message
#define MESSAGE1_LEN encryptedMemoSize1 - crypto_secretstream_xchacha20poly1305_ABYTES
if (crypto_secretstream_xchacha20poly1305_pull
(&state, decrypted, NULL, tag, MESSAGE2, CIPHERTEXT1_LEN, NULL, 0) != 0) {
/* Invalid/incomplete/corrupted ciphertext - abort */
}
//////Set the length of the decrypted message
std::string decryptedMemo(reinterpret_cast<char*>(decrypted),MESSAGE1_LEN);
unsigned char decrypted[MESSAGE1_LEN];
unsigned char tag[crypto_secretstream_xchacha20poly1305_TAG_FINAL];
crypto_secretstream_xchacha20poly1305_state state;
memodecrypt = QString::fromUtf8( decryptedMemo.data(), decryptedMemo.size());
/////Our decrypted message is now in decrypted. We need it as QString to render it
/////Only the QString gives weird data, so convert first to std::string
// crypto_secretstream_xchacha20poly1305_keygen(client_rx);
if (crypto_secretstream_xchacha20poly1305_init_pull(&state, header, server_tx) != 0) {
/* Invalid header, no need to go any further */
}
}else{
memodecrypt = "";
if (crypto_secretstream_xchacha20poly1305_pull
(&state, decrypted, NULL, tag, MESSAGE2, CIPHERTEXT1_LEN, NULL, 0) != 0) {
/* Invalid/incomplete/corrupted ciphertext - abort */
}
}
/////Now we can convert it to QString
std::string decryptedMemo(reinterpret_cast<char*>(decrypted),MESSAGE1_LEN);
memodecrypt = QString::fromUtf8( decryptedMemo.data(), decryptedMemo.size());
}
else
{
memodecrypt = "";
}
//////////////Give us the output of the decrypted message as debug to see if it was successfully
/////Now we can convert it to QString
//////////////Give us the output of the decrypted message as debug to see if it was successfully
ChatItem item = ChatItem(
ChatItem item = ChatItem(
datetime,
address,
QString(""),
@ -1135,49 +1118,46 @@ void Controller::refreshTransactions() {
isNotarized,
false
);
DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item);
updateUIBalances();
DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item);
// updateUIBalances();
}
}
items.push_back(TransactionItemDetail{address, amount, memo});
total_amount = total_amount + amount;
}
}
{
QList<QString> addresses;
QList<QString> addresses;
for (auto item : items) {
// Concat all the addresses
addresses.push_back(item.address);
address = addresses.join(",");
// Concat all the addresses
addresses.push_back(item.address);
address = addresses.join(",");
}
}
}
txdata.push_back(TransactionItem{
"send", datetime, address, txid,confirmations, items
});
} else {
// Incoming Transaction
}
else
{
{ // Incoming Transaction
address = (it["address"].is_null() ? "" : QString::fromStdString(it["address"]));
model->markAddressUsed(address);
QString memo;
if (!it["memo"].is_null()) {
memo = QString::fromStdString(it["memo"]);
}
items.push_back(TransactionItemDetail{
address,
address,
CAmount::fromqint64(it["amount"].get<json::number_integer_t>()),
memo
memo
});
TransactionItem tx{
@ -1185,6 +1165,8 @@ void Controller::refreshTransactions() {
};
txdata.push_back(tx);
}
QString type;
QString publickey;
@ -1197,8 +1179,8 @@ void Controller::refreshTransactions() {
if (!it["memo"].is_null()) {
if (memo.startsWith("{")) {
try
{
try
{
QJsonDocument headermemo = QJsonDocument::fromJson(memo.toUtf8());
cid = headermemo["cid"].toString();
@ -1215,178 +1197,167 @@ void Controller::refreshTransactions() {
main->addPubkey(requestZaddr, publickey);
}
} catch(...)
{
}
}
if (chatModel->getCidByTx(txid) != QString("0xdeadbeef")){
}
catch (...)
{
// on any exception
}
}
if (chatModel->getCidByTx(txid) != QString("0xdeadbeef"))
{
cid = chatModel->getCidByTx(txid);
}else{
cid = "";
}
else
{
cid = "";
}
if (chatModel->getrequestZaddrByTx(txid) != QString("0xdeadbeef")){
if (chatModel->getrequestZaddrByTx(txid) != QString("0xdeadbeef"))
{
requestZaddr = chatModel->getrequestZaddrByTx(txid);
}else{
requestZaddr = "";
}
else
{
requestZaddr = "";
}
if (chatModel->getHeaderByTx(txid) != QString("0xdeadbeef")){
if (chatModel->getHeaderByTx(txid) != QString("0xdeadbeef"))
{
headerbytes = chatModel->getHeaderByTx(txid);
}else{
headerbytes = "";
}
else
{
headerbytes = "";
}
if (main->getPubkeyByAddress(requestZaddr) != QString("0xdeadbeef")){
if (main->getPubkeyByAddress(requestZaddr) != QString("0xdeadbeef"))
{
publickey = main->getPubkeyByAddress(requestZaddr);
}else{
publickey = "";
}
else
{
publickey = "";
}
if (contactModel->getContactbyAddress(requestZaddr) != QString("0xdeadbeef")){
isContact = true;
contactname = contactModel->getContactbyAddress(requestZaddr);
if (contactModel->getContactbyAddress(requestZaddr) != QString("0xdeadbeef"))
{
isContact = true;
contactname = contactModel->getContactbyAddress(requestZaddr);
}
else
{
isContact = false;
contactname = "";
}
}else{
bool isNotarized;
isContact = false;
contactname = "";
if (confirmations > getLag())
{
isNotarized = true;
}
else
{
isNotarized = false;
}
}
int position = it["position"].get<json::number_integer_t>();
bool isNotarized;
int ciphercheck = memo.length() - crypto_secretstream_xchacha20poly1305_ABYTES;
if (confirmations > getLag())
if ((memo.startsWith("{") == false) && (headerbytes > 0) && (ciphercheck > 0))
{
if (chatModel->getMemoByTx(txid) == QString("0xdeadbeef"))
{
isNotarized = true;
}else{
isNotarized = false;
}
int position = it["position"].get<json::number_integer_t>();
if ((memo.startsWith("{") == false) && (headerbytes > 0))
{
if (chatModel->getMemoByTx(txid) == QString("0xdeadbeef")){
if (position == 1)
{
chatModel->addMemo(txid, headerbytes);
}else{}
QString passphrase = DataStore::getChatDataStore()->getPassword();
QString hashEncryptionKey = passphrase;
int length = hashEncryptionKey.length();
char *hashEncryptionKeyraw = NULL;
hashEncryptionKeyraw = new char[length+1];
strncpy(hashEncryptionKeyraw, hashEncryptionKey.toLocal8Bit(), length +1);
//const QByteArray ba2 = QByteArray::fromHex(hashEncryptionKey.toLatin1());
// const unsigned char *hashEncryptionKeyraw = reinterpret_cast<const unsigned char *>(ba2.constData());
const QByteArray pubkeyBobArray = QByteArray::fromHex(publickey.toLatin1());
const unsigned char *pubkeyBob = reinterpret_cast<const unsigned char *>(pubkeyBobArray.constData());
if (position == 1)
{
chatModel->addMemo(txid, headerbytes);
}
else
{
//
}
QString passphrase = DataStore::getChatDataStore()->getPassword();
int length = passphrase.length();
#define MESSAGEAS1 ((const unsigned char *) hashEncryptionKeyraw)///////////
#define MESSAGEAS1_LEN length
char *hashEncryptionKeyraw = NULL;
hashEncryptionKeyraw = new char[length+1];
strncpy(hashEncryptionKeyraw, passphrase.toUtf8(), length +1);
const QByteArray pubkeyBobArray = QByteArray::fromHex(publickey.toLatin1());
const unsigned char *pubkeyBob = reinterpret_cast<const unsigned char *>(pubkeyBobArray.constData());
unsigned char hash1[crypto_kx_SEEDBYTES];
#define MESSAGEAS1 ((const unsigned char *) hashEncryptionKeyraw)///////////
#define MESSAGEAS1_LEN length
crypto_hash_sha256(hash1,MESSAGEAS1, MESSAGEAS1_LEN);
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,
hash1) !=0) {
if (crypto_kx_seed_keypair(pk, sk, MESSAGEAS1) !=0)
{
main->logger->write("Suspicious outgoing key pair, bail out ");
}
unsigned char client_rx[crypto_kx_SESSIONKEYBYTES], client_tx[crypto_kx_SESSIONKEYBYTES];
}
unsigned char client_rx[crypto_kx_SESSIONKEYBYTES], client_tx[crypto_kx_SESSIONKEYBYTES];
////////////////Get the pubkey from Bob, so we can create the share key
/////Create the shared key for sending the message
////////////////Get the pubkey from Bob, so we can create the share key
if (crypto_kx_client_session_keys(client_rx, client_tx, pk, sk, pubkeyBob) != 0)
{
main->logger->write("Suspicious client public incoming key, bail out ");
}
const QByteArray ba = QByteArray::fromHex(memo.toUtf8());
const unsigned char *encryptedMemo = reinterpret_cast<const unsigned char *>(ba.constData());
/////Create the shared key for sending the message
const QByteArray ba1 = QByteArray::fromHex(headerbytes.toLatin1());
const unsigned char *header = reinterpret_cast<const unsigned char *>(ba1.constData());
if (crypto_kx_client_session_keys(client_rx, client_tx,
pk, sk, pubkeyBob) != 0) {
/* Suspicious client public key, bail out */
}
int encryptedMemoSize1 = ba.length();
int headersize = ba1.length();
//////unsigned char* as message from QString
#define MESSAGE2 (const unsigned char *) encryptedMemo
///////// length of the encrypted message
#define CIPHERTEXT1_LEN encryptedMemoSize1
const QByteArray ba = QByteArray::fromHex(memo.toLatin1());
const unsigned char *encryptedMemo = reinterpret_cast<const unsigned char *>(ba.constData());
///////Message length is smaller then the encrypted message
#define MESSAGE1_LEN encryptedMemoSize1 - crypto_secretstream_xchacha20poly1305_ABYTES
const QByteArray ba1 = QByteArray::fromHex(headerbytes.toLatin1());
const unsigned char *header = reinterpret_cast<const unsigned char *>(ba1.constData());
//////Set the length of the decrypted message
int encryptedMemoSize1 = ba.length();
int headersize = ba1.length();
unsigned char decrypted[MESSAGE1_LEN+1];
unsigned char tag[crypto_secretstream_xchacha20poly1305_TAG_FINAL];
crypto_secretstream_xchacha20poly1305_state state;
//////unsigned char* as message from QString
#define MESSAGE2 (const unsigned char *) encryptedMemo
/////Our decrypted message is now in decrypted. We need it as QString to render it
/////Only the QString gives weird data, so convert first to std::string
// crypto_secretstream_xchacha20poly1305_keygen(client_rx);
if (crypto_secretstream_xchacha20poly1305_init_pull(&state, header, client_rx) != 0) {
main->logger->write("Invalid header incoming, no need to go any further ");
}
///////// length of the encrypted message
#define CIPHERTEXT1_LEN encryptedMemoSize1
if (crypto_secretstream_xchacha20poly1305_pull
(&state, decrypted, NULL, tag, MESSAGE2, CIPHERTEXT1_LEN, NULL, 0) != 0) {
main->logger->write("Invalid/incomplete/corrupted ciphertext - abort");
}
///////Message length is smaller then the encrypted message
#define MESSAGE1_LEN encryptedMemoSize1 - crypto_secretstream_xchacha20poly1305_ABYTES
std::string decryptedMemo(reinterpret_cast<char*>(decrypted),MESSAGE1_LEN);
//////Set the length of the decrypted message
/////Now we can convert it to QString
QString memodecrypt;
unsigned char decrypted[MESSAGE1_LEN];
unsigned char tag[crypto_secretstream_xchacha20poly1305_TAG_FINAL];
crypto_secretstream_xchacha20poly1305_state state;
/////Our decrypted message is now in decrypted. We need it as QString to render it
/////Only the QString gives weird data, so convert first to std::string
// crypto_secretstream_xchacha20poly1305_keygen(client_rx);
if (crypto_secretstream_xchacha20poly1305_init_pull(&state, header, client_rx) != 0) {
/* Invalid header, no need to go any further */
}
if (crypto_secretstream_xchacha20poly1305_pull
(&state, decrypted, NULL, tag, MESSAGE2, CIPHERTEXT1_LEN, NULL, 0) != 0) {
/* Invalid/incomplete/corrupted ciphertext - abort */
}
std::string decryptedMemo(reinterpret_cast<char*>(decrypted),MESSAGE1_LEN);
/////Now we can convert it to QString
QString memodecrypt;
memodecrypt = QString::fromUtf8( decryptedMemo.data(), decryptedMemo.size());
memodecrypt = QString::fromUtf8( decryptedMemo.data(), decryptedMemo.size());
// }
//////////////Give us the output of the decrypted message as debug to see if it was successfully
// }
//////////////Give us the output of the decrypted message as debug to see if it was successfully
ChatItem item = ChatItem(
ChatItem item = ChatItem(
datetime,
address,
contactname,
@ -1400,33 +1371,39 @@ void Controller::refreshTransactions() {
isNotarized,
isContact
);
DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item);
}else{
DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item);
}
}else{
}
else
{
//
}
ChatItem item = ChatItem(
datetime,
address,
contactname,
memo,
requestZaddr,
type,
cid,
txid,
confirmations,
false,
isNotarized,
isContact
);
}
else
{
ChatItem item = ChatItem(
datetime,
address,
contactname,
memo,
requestZaddr,
type,
cid,
txid,
confirmations,
false,
isNotarized,
isContact
);
DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item);
}
}
}
}
}
}
}
// Calculate the total unspent amount that's pending. This will need to be
// shown in the UI so the user can keep track of pending funds
@ -1444,13 +1421,14 @@ void Controller::refreshTransactions() {
// Update UI Balance
updateUIBalances();
// Update model data, which updates the table view
// Update model data, which updates the table view
transactionsTableModel->replaceData(txdata);
chat->renderChatBox(ui, ui->listChat,ui->memoSizeChat);
ui->listChat->verticalScrollBar()->setValue(
ui->listChat->verticalScrollBar()->maximum());
});
});
}
void Controller::refreshChat(QListView *listWidget, QLabel *label)
@ -1464,6 +1442,8 @@ void Controller::refreshChat(QListView *listWidget, QLabel *label)
void Controller::refreshContacts(QListView *listWidget)
{
contactModel->renderContactList(listWidget);
ui->listChat->verticalScrollBar()->setValue(
ui->listChat->verticalScrollBar()->maximum());
}
// If the wallet is encrpyted and locked, we need to unlock it
@ -1858,7 +1838,7 @@ void Controller::refreshZECPrice()
Settings::getInstance()->setBTCVolume( hush["btc_24h_vol"]);
}
if (hush["cny_24h_vol"] >= 0)
if (hush["cny_24h_vol"] >= 0)
{
qDebug() << "HUSH = cny_24h_vol" << QString::number((double)hush["cny_24h_vol"]);
Settings::getInstance()->setCNYVolume( hush["cny_24h_vol"]);

1
src/controller.h

@ -19,6 +19,7 @@
#include "Model/ContactRequestChatItem.h"
#include "Model/ContactItem.h"
#include "contactmodel.h"
using json = nlohmann::json;
struct WatchedTx {

339
src/emoji.ui

@ -0,0 +1,339 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>emojiDialog</class>
<widget class="QDialog" name="emojiDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>261</width>
<height>150</height>
</rect>
</property>
<property name="windowTitle">
<string>Emoji</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QPushButton" name="smiley">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/emoji/res/emoji/emoji1.png</normalon>
</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="laughing">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/emoji/res/emoji/laughing.png</normalon>
</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="sweet_smile">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/emoji/res/emoji/sweet_smile.png</normalon>
</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="joy">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/emoji/res/emoji/joy.png</normalon>
</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="innocent">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/emoji/res/emoji/innocent.png</normalon>
</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="partying_face">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/emoji/res/emoji/partying_face.png</normalon>
</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="money">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/icons/res/money-mouth.png</normalon>
</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QPushButton" name="rolling_eyes">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/emoji/res/emoji/face-with-rolling-eyes.png</normalon>
</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="tongue">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/emoji/res/emoji/face-with-tongue.png</normalon>
</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="hearts3">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/emoji/res/emoji/face_with_3hearts.png</normalon>
</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="heart_eyes">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/emoji/res/emoji/heart_shaped_eyes.png</normalon>
</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="nauseated">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/emoji/res/emoji/nauseated-face.png</normalon>
</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="poop">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/emoji/res/emoji/pile-of-poo.png</normalon>
</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="symbols_mouth">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/emoji/res/emoji/serious-face-with-symbols-covering-mouth.png</normalon>
</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QPushButton" name="sunglass">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/emoji/res/emoji/smiling-face-with-sunglasses.png</normalon>
</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="stuck_out">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/emoji/res/emoji/stuck-out.png</normalon>
</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="hush_white">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/emoji/res/emoji/hush-money-white.png</normalon>
</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="sd">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/emoji/res/emoji/SD.png</normalon>
</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

99
src/firsttimewizard.cpp

@ -8,14 +8,24 @@
#include "../lib/silentdragonlitelib.h"
using json = nlohmann::json;
FirstTimeWizard::FirstTimeWizard(bool dangerous, QString server)
FirstTimeWizard::FirstTimeWizard(QString server)
{
setWindowTitle("New wallet wizard");
this->dangerous = dangerous;
this->server = server;
////backup addresslabels.dat if there is one, to restore it later
auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
QString addressbook = dir.filePath("addresslabels.dat.enc");
QFile file(addressbook);
if (file.exists())
{
file.rename(dir.filePath("addresslabels.dat.enc-backup"));
}
// Create the pages
setPage(Page_NewOrRestore, new NewOrRestorePage(this));
setPage(Page_New, new NewSeedPage(this));
@ -40,29 +50,81 @@ 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");
form.txtPassword->setEnabled(false);
form.txtConfirmPassword->setEnabled(false);
QObject::connect(form.TOS, &QRadioButton::clicked, [=](bool checked) {
if (checked) {
form.txtPassword->setEnabled(true);
form.txtConfirmPassword->setEnabled(true);
}
});
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);
parent->button(QWizard::CommitButton)->setEnabled(true);
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];
DataStore::getChatDataStore()->setPassword(Password);
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";
@ -85,6 +147,8 @@ DataStore::getChatDataStore()->setPassword(Password);
} else {
form.lblPasswordMatch->setText(tr("Passphrase don't match or You have entered too few letters (16 minimum)"));
@ -108,6 +172,8 @@ DataStore::getChatDataStore()->setPassword(Password);
setCommitPage(true);
}
NewSeedPage::NewSeedPage(FirstTimeWizard *parent) : QWizardPage(parent) {
@ -127,7 +193,7 @@ NewSeedPage::NewSeedPage(FirstTimeWizard *parent) : QWizardPage(parent) {
void NewSeedPage::initializePage() {
// Call the library to create a new wallet.
char* resp = litelib_initialize_new(parent->dangerous, parent->server.toStdString().c_str());
char* resp = litelib_initialize_new(parent->server.toStdString().c_str());
QString reply = litelib_process_response(resp);
auto parsed = json::parse(reply.toStdString().c_str(), nullptr, false);
@ -136,8 +202,6 @@ void NewSeedPage::initializePage() {
} else {
QString seed = QString::fromStdString(parsed["seed"].get<json::string_t>());
form.txtSeed->setPlainText(seed);
}
@ -151,6 +215,7 @@ bool NewSeedPage::validatePage() {
auto parsed = json::parse(reply.toStdString().c_str(), nullptr, false);
if (parsed.is_discarded() || parsed.is_null() || parsed.find("result") == parsed.end()) {
QMessageBox::warning(this, tr("Failed to save wallet"),
tr("Couldn't save the wallet") + "\n" + reply,
QMessageBox::Ok);
@ -196,10 +261,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);
char* resp = litelib_initialize_new_from_phrase(parent->server.toStdString().c_str(),
seed.toStdString().c_str(), birthday, number);
QString reply = litelib_process_response(resp);
if (reply.toUpper().trimmed() != "OK") {

4
src/firsttimewizard.h

@ -5,6 +5,7 @@
#include "ui_newseed.h"
#include "ui_restoreseed.h"
#include "ui_newwallet.h"
#include "mainwindow.h"
@ -15,7 +16,7 @@ class FirstTimeWizard: public QWizard
public:
FirstTimeWizard(bool dangerous, QString server);
FirstTimeWizard(QString server);
protected:
@ -28,7 +29,6 @@ private:
Page_Restore
};
bool dangerous;
QString server;
friend class NewOrRestorePage;

1144
src/mainwindow.cpp

File diff suppressed because it is too large

33
src/mainwindow.h

@ -7,6 +7,8 @@
#include "recurring.h"
#include "firsttimewizard.h"
using json = nlohmann::json;
// Forward declare to break circular dependency.
class Controller;
class Settings;
@ -14,7 +16,6 @@ class WSServer;
class WormholeClient;
class ChatModel;
using json = nlohmann::json;
// Struct used to hold destination info when sending a Tx.
struct ToFields {
@ -50,12 +51,18 @@ public:
QString doSendTxValidations(Tx tx);
QString doSendChatTxValidations(Tx tx);
QString doSendChatMoneyTxValidations(Tx tx);
QString doSendRequestTxValidations(Tx tx);
QString doSendChatMoneyRequestTxValidations(Tx tx);
QString getCid();
QString getAmt();
QString getMoneyMemo();
QString getPassword();
std::map<QString, QString> pubkeyMap;
QString getPubkeyByAddress(QString requestZaddr);
void setPassword(QString Password);
void setAmt(QString Amt);
void setMoneyMemo(QString MoneyMemo);
void addPubkey(QString requestZaddr, QString pubkey);
@ -106,12 +113,15 @@ private slots:
void on_givemeZaddr_clicked();
void on_emojiButton_clicked();
private:
bool fileExists(QString path);
void closeEvent(QCloseEvent* event);
void closeEventpw(QCloseEvent* event);
QString _password;
QString _amt;
QString _moneymemo;
void setupSendTab();
@ -136,7 +146,8 @@ private:
Tx createTxFromChatPage();
Tx createTxForSafeContactRequest();
Tx createTxFromSendChatPage();
Tx createTxFromSendRequestChatPage();
void encryptWallet();
void removeWalletEncryption();
@ -145,6 +156,8 @@ private:
void cancelButton();
void sendButton();
void sendChat();
void sendMoneyChat();
void sendMoneyRequestChat();
void addContact();
void ContactRequest();
@ -215,5 +228,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

71
src/mainwindow.ui

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>1274</width>
<width>1308</width>
<height>779</height>
</rect>
</property>
@ -59,7 +59,7 @@
<item row="0" column="0" colspan="2">
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>2</number>
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
@ -428,8 +428,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1226</width>
<height>493</height>
<width>1260</width>
<height>509</height>
</rect>
</property>
<layout class="QVBoxLayout" name="sendToLayout">
@ -1341,8 +1341,8 @@
<attribute name="title">
<string>HushChat</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_7">
<item row="0" column="1" rowspan="4">
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_18" stretch="0,0,0,0">
@ -1546,7 +1546,7 @@
</item>
</layout>
</item>
<item row="0" column="5" rowspan="4">
<item row="0" column="1">
<layout class="QVBoxLayout" name="verticalLayout_11">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
@ -1683,6 +1683,12 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>850</width>
<height>0</height>
</size>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
@ -1706,9 +1712,48 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="emojiButton">
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/emoji/res/emoji/emoji1.png</normalon>
</iconset>
</property>
<property name="iconSize">
<size>
<width>17</width>
<height>17</height>
</size>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item alignment="Qt::AlignBottom">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QPushButton" name="sendChatButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
@ -1716,6 +1761,12 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>50</height>
</size>
</property>
<property name="baseSize">
<size>
<width>100</width>
@ -1747,7 +1798,7 @@
</property>
</widget>
</item>
<item alignment="Qt::AlignHCenter">
<item>
<widget class="QLabel" name="memoSizeChat">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@ -1783,7 +1834,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>1274</width>
<width>1308</width>
<height>22</height>
</rect>
</property>

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/>

3
src/precompiled.h

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

10
src/recurring.cpp

@ -319,7 +319,7 @@ QString Recurring::writeableFile() {
auto filename = QStringLiteral("recurringpayments.json");
auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
if (!dir.exists())
if (dir.exists())
QDir().mkpath(dir.absolutePath());
if (Settings::getInstance()->isTestnet()) {
@ -353,6 +353,9 @@ void Recurring::removeRecurringInfo(QString hash) {
void Recurring::readFromStorage() {
if (writeableFile().isEmpty())
{
QFile file(writeableFile());
file.open(QIODevice::ReadOnly);
@ -365,10 +368,14 @@ void Recurring::readFromStorage() {
auto p = RecurringPaymentInfo::fromJson(k.toObject());
payments.insert(p.getHash(), p);
}
}else{}
}
void Recurring::writeToStorage() {
if (writeableFile().isEmpty())
{
QFile file(writeableFile());
file.open(QIODevice::ReadWrite | QIODevice::Truncate);
@ -381,6 +388,7 @@ void Recurring::writeToStorage() {
out << QJsonDocument(arr).toJson();
file.close();
}else{}
}
/**

72
src/restoreSeed.ui

@ -0,0 +1,72 @@
<ui version="4.0" >
<author></author>
<comment></comment>
<exportmacro></exportmacro>
<class>Dialog</class>
<widget class="QDialog" name="Dialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle" >
<string>Dialog</string>
</property>
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="geometry" >
<rect>
<x>30</x>
<y>240</y>
<width>341</width>
<height>32</height>
</rect>
</property>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</widget>
<pixmapfunction></pixmapfunction>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel" >
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel" >
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

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/>

9
src/scripts/mkrelease.sh

@ -35,6 +35,15 @@ rm -rf bin/SilentDragonLite* > /dev/null
# Build the lib first
cd lib && make release && cd ..
make -j$(nproc) > /dev/null
make install INSTALL_ROOT=AppDir
# now, build AppImage using linuxdeploy and linuxdeploy-plugin-qt
# download linuxdeploy and its Qt plugin
wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
wget https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage
# make them executable
chmod +x linuxdeploy*.AppImage
echo "[OK]"

114
src/seedrestore.ui

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Restore</class>
<widget class="QDialog" name="Restore">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>637</width>
<height>429</height>
</rect>
</property>
<property name="windowTitle">
<string>Restore your Wallet</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="3">
<widget class="QPlainTextEdit" name="seed">
<property name="minimumSize">
<size>
<width>0</width>
<height>284</height>
</size>
</property>
</widget>
</item>
<item row="1" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Birthday :</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Quantity :</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1" colspan="2">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QPlainTextEdit" name="birthday">
<property name="minimumSize">
<size>
<width>529</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>25</height>
</size>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="quantity">
<property name="minimumSize">
<size>
<width>529</width>
<height>0</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0" colspan="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>521</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="restore">
<property name="maximumSize">
<size>
<width>89</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Restore</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

276
src/sendHushTransactionChat.ui

@ -0,0 +1,276 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>transactionHush</class>
<widget class="QDialog" name="transactionHush">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>212</width>
<height>405</height>
</rect>
</property>
<property name="windowTitle">
<string>Send or Request Hush</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>To :</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetFixedSize</enum>
</property>
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QListView" name="contactName">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>70</height>
</size>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="sizeConstraint">
<enum>QLayout::SetFixedSize</enum>
</property>
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QLabel" name="label_6">
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Amount: </string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="amountChat">
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="baseSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maxLength">
<number>9</number>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="placeholderText">
<string>Amount</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="maximumSize">
<size>
<width>35</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Hush</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Memo :</string>
</property>
</widget>
</item>
<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>40</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="0" colspan="2">
<widget class="QLineEdit" name="MemoMoney">
<property name="minimumSize">
<size>
<width>0</width>
<height>41</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>41</height>
</size>
</property>
<property name="maxLength">
<number>100</number>
</property>
</widget>
</item>
<item row="5" column="1">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>39</height>
</size>
</property>
</spacer>
</item>
<item row="6" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="sizeConstraint">
<enum>QLayout::SetFixedSize</enum>
</property>
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QPushButton" name="requestHush">
<property name="text">
<string>Request Hush</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="sendHush">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>25</height>
</size>
</property>
<property name="text">
<string>Send Hush</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="7" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="sizeConstraint">
<enum>QLayout::SetFixedSize</enum>
</property>
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>transactionHush</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

2
src/sendtab.cpp

@ -8,9 +8,9 @@
#include "controller.h"
#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}"));

2
src/settings.h

@ -67,8 +67,6 @@ public:
void set_currency_name(QString currency_name);
bool isSaplingActive();
void setZECPrice(double p) { ZECPrice = p; }

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.8"

2
src/websockets.cpp

@ -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