Merge pull request #4 from DenioD/chat

Chat
This commit is contained in:
Strider
2020-05-28 18:19:20 +02:00
committed by GitHub
50 changed files with 3907 additions and 596 deletions

View File

@@ -48,3 +48,9 @@ b FileSystem::writeContacts
r r
n n
q q
r
b FileEncryption::encrypt
r
s
n
q

View File

@@ -26,7 +26,7 @@ SilentDragonLite does automatic note and utxo management, which means it doesn't
## Compiling from source ## Compiling from source
* SilentDragonLite is written in C++ 14, and can be compiled with g++/clang++/visual c++. * SilentDragonLite is written in C++ 14, and can be compiled with g++/clang++/visual c++.
* It also depends on Qt5, which you can get from [here](https://www.qt.io/download). * It also depends on Qt5, which you can get from [here](https://www.qt.io/download).
* You'll need Rust v1.37 + * You'll need Rust v1.41 +
## Building on Linux ## Building on Linux

View File

@@ -33,12 +33,9 @@
<file>res/add_contact.png</file> <file>res/add_contact.png</file>
<file>res/notification.png</file> <file>res/notification.png</file>
<file>res/rahmen-message.png</file> <file>res/rahmen-message.png</file>
<file>res/upload.png</file>
<file>res/upload.svg</file>
<file>res/message-icon.svg</file> <file>res/message-icon.svg</file>
<file>res/lock.svg</file>
<file>res/lock.png</file>
<file>res/lock_green.png</file> <file>res/lock_green.png</file>
<file>res/lock_orange.png</file>
<file>res/unlocked.png</file> <file>res/unlocked.png</file>
<file>res/getAddrWhite.png</file> <file>res/getAddrWhite.png</file>
<file>res/send-white.png</file> <file>res/send-white.png</file>
@@ -48,6 +45,8 @@
<file>res/sendBlack.png</file> <file>res/sendBlack.png</file>
<file>res/requestBlack.png</file> <file>res/requestBlack.png</file>
<file>res/addContactBlack.png</file> <file>res/addContactBlack.png</file>
<file>res/unknownBlack.png</file>
<file>res/unknownWhite.png</file>
</qresource> </qresource>
<qresource prefix="/img"> <qresource prefix="/img">
@@ -65,6 +64,7 @@
<file>res/silentdragonlite_it.qm</file> <file>res/silentdragonlite_it.qm</file>
<file>res/silentdragonlite_hr.qm</file> <file>res/silentdragonlite_hr.qm</file>
<file>res/silentdragonlite_fa.qm</file> <file>res/silentdragonlite_fa.qm</file>
<file>res/silentdragonlite_id.qm</file>
</qresource> </qresource>
<qresource prefix="/css"> <qresource prefix="/css">
<file>res/css/blue.css</file> <file>res/css/blue.css</file>

6
lib/Cargo.lock generated
View File

@@ -1177,7 +1177,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (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/DenioD/silentdragonlite-cli?rev=fb07cae93c706cce929beef98690109e5f2d7592)", "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=d196ad938a22810c0b6b4164e6bf8f1db0409763)",
] ]
[[package]] [[package]]
@@ -1640,7 +1640,7 @@ dependencies = [
[[package]] [[package]]
name = "silentdragonlitelib" name = "silentdragonlitelib"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=fb07cae93c706cce929beef98690109e5f2d7592#fb07cae93c706cce929beef98690109e5f2d7592" source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=d196ad938a22810c0b6b4164e6bf8f1db0409763#d196ad938a22810c0b6b4164e6bf8f1db0409763"
dependencies = [ dependencies = [
"base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bellman 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", "bellman 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)",
@@ -2631,7 +2631,7 @@ dependencies = [
"checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35"
"checksum sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" "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 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/DenioD/silentdragonlite-cli?rev=fb07cae93c706cce929beef98690109e5f2d7592)" = "<none>" "checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=d196ad938a22810c0b6b4164e6bf8f1db0409763)" = "<none>"
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
"checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "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" "checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85"

View File

@@ -11,4 +11,4 @@ crate-type = ["staticlib"]
[dependencies] [dependencies]
libc = "0.2.58" libc = "0.2.58"
lazy_static = "1.4.0" lazy_static = "1.4.0"
silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "fb07cae93c706cce929beef98690109e5f2d7592" } silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "d196ad938a22810c0b6b4164e6bf8f1db0409763" }

View File

@@ -1,2 +1,2 @@
break FileSystem::writeContacts break FileEncryption::encrypt

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 12 KiB

BIN
res/lock_orange.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 929 B

BIN
res/silentdragonlite_id.qm Normal file

Binary file not shown.

2002
res/silentdragonlite_id.ts Normal file

File diff suppressed because it is too large Load Diff

BIN
res/unknownBlack.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
res/unknownWhite.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
res/unkownBlack.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Svg Vector Icons : http://www.onlinewebfonts.com/icon -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg fill="#EB4F38" width="16px" height="16px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
<metadata> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata>
<g><g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"><path d="M4631.2,5015.7c-634.2-57.5-1212.8-212.7-1755.1-475.2c-546.1-264.4-894.8-513.5-1339.3-959.9c-446.4-446.4-676.4-766.4-948.4-1322.1c-231.8-469.4-367.9-914-454.1-1465.8c-46-308.5-46-1032.7,1.9-1341.2c90.1-586.3,239.5-1057.6,488.6-1548.1c254.8-496.3,494.3-822,912-1239.7c438.8-440.7,764.5-674.4,1302.9-938.9c343-168.6,567.1-252.9,915.9-344.9c1452.4-383.2,2981.4-76.6,4209.5,839.2c233.8,176.3,756.8,699.3,933.1,933.1C9909.8-1493,10170.4,202.7,9610.9,1779.6c-168.6,475.2-484.8,1032.7-812.4,1437c-187.8,231.8-609.3,640-837.3,810.5C7286.8,4532.9,6530,4849,5685,4979.3C5491.5,5008.1,4817,5033,4631.2,5015.7z M5483.8,4622.9C7206.3,4450.5,8697,3264.5,9273.7,1605.2C9540,836.9,9593.7-44.5,9419.3-855c-176.3-818.1-615.1-1615.2-1224.3-2222.6c-714.7-716.6-1619-1159.2-2630.7-1293.3c-293.2-38.3-845-38.3-1138.1,0C2906.7-4171.6,1600-3240.4,933.2-1880.1c-320,651.4-461.8,1272.2-461.8,2013.8c0,730,139.9,1331.6,461.8,1990.8C1370.1,3015.4,2102,3747.3,2993,4184.2C3788.1,4571.2,4583.3,4713,5483.8,4622.9z"/><path d="M4589,2237.5c-431.1-103.5-768.3-486.7-814.3-927.4c-13.4-136,9.6-197.3,92-231.8c107.3-44.1,208.8,40.2,208.8,172.4c0,151.4,107.3,373.6,243.3,502c208.8,197.3,513.5,258.7,791.3,162.9c180.1-63.2,385.1-268.2,452.2-452.2c24.9-63.2,34.5-172.4,42.2-406.2l7.7-321.9H4431.9H3249.7l-46-47.9l-47.9-46v-1439v-1438.9l47.9-46l46-47.9h1592.2h1592.2l46,47.9l47.9,46v1438.9v1439l-47.9,46c-44.1,46-55.6,47.9-302.7,47.9h-258.7l-9.6,341c-7.7,287.4-15.3,358.3-49.8,457.9c-97.7,272.1-298.9,498.2-548,618.9C5068,2270.1,4832.3,2296.9,4589,2237.5z M6221.5-797.5v-1226.2H4841.9H3462.4v1226.2V428.8h1379.5h1379.5V-797.5z"/><path d="M4688.6,97.3c-36.4-11.5-111.1-65.2-162.9-118.8c-136-134.1-174.4-279.7-120.7-454.1c26.8-92,145.6-231.8,226.1-264.4l57.5-23v-402.4c0-398.5,0-400.4,47.9-446.4c61.3-63.2,149.4-63.2,210.8,0c47.9,46,47.9,47.9,47.9,446.4V-763l57.5,23c80.5,32.6,199.3,172.4,226.1,264.4c53.6,174.4,15.3,320-120.7,454.1C5023.9,114.5,4866.8,152.9,4688.6,97.3z M4947.3-232.3c95.8-93.9,28.7-258.7-105.4-258.7c-36.4,0-76.6,17.3-105.4,47.9c-30.7,28.7-47.9,69-47.9,105.4c0,36.4,17.2,76.6,47.9,105.4c28.7,30.7,69,47.9,105.4,47.9S4918.6-201.6,4947.3-232.3z"/></g></g>
</svg>

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 218.8 283.5" style="enable-background:new 0 0 218.8 283.5;" xml:space="preserve">
<g>
<path d="M109.4,0L0,109.4h62.5v93.8h93.8v-93.8h62.5L109.4,0z M0,234.4v31.3h218.8v-31.3H0z M0,234.4"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 476 B

View File

@@ -83,7 +83,8 @@ SOURCES += \
src/Chat/Helper/ChatIDGenerator.cpp \ src/Chat/Helper/ChatIDGenerator.cpp \
src/Chat/Chat.cpp \ src/Chat/Chat.cpp \
src/FileSystem/FileSystem.cpp \ src/FileSystem/FileSystem.cpp \
src/Crypto/FileEncryption.cpp src/Crypto/FileEncryption.cpp \
src/Crypto/passwd.cpp
HEADERS += \ HEADERS += \
src/firsttimewizard.h \ src/firsttimewizard.h \
@@ -121,6 +122,7 @@ HEADERS += \
FORMS += \ FORMS += \
src/contactrequest.ui \ src/contactrequest.ui \
src/encryption.ui \ src/encryption.ui \
src/hushrequest.ui \
src/mainwindow.ui \ src/mainwindow.ui \
src/migration.ui \ src/migration.ui \
src/newseed.ui \ src/newseed.ui \
@@ -132,6 +134,7 @@ FORMS += \
src/confirm.ui \ src/confirm.ui \
src/privkey.ui \ src/privkey.ui \
src/memodialog.ui \ src/memodialog.ui \
src/startupencryption.ui \
src/viewalladdresses.ui \ src/viewalladdresses.ui \
src/connection.ui \ src/connection.ui \
src/addressbook.ui \ src/addressbook.ui \
@@ -141,6 +144,7 @@ FORMS += \
src/requestContactDialog.ui \ src/requestContactDialog.ui \
src/newrecurring.ui \ src/newrecurring.ui \
src/requestdialog.ui \ src/requestdialog.ui \
src/removeencryption.ui \
src/recurringmultiple.ui \ src/recurringmultiple.ui \
src/chatbubbleme.ui \ src/chatbubbleme.ui \
src/chatbubblepartner.ui src/chatbubblepartner.ui
@@ -155,6 +159,7 @@ TRANSLATIONS = res/silentdragonlite_es.ts \
res/silentdragonlite_hr.ts \ res/silentdragonlite_hr.ts \
res/silentdragonlite_sr.ts \ res/silentdragonlite_sr.ts \
res/silentdragonlite_fa.ts \ res/silentdragonlite_fa.ts \
res/silentdragonlite_id.ts \
res/silentdragonlite_tr.ts res/silentdragonlite_tr.ts
include(singleapplication/singleapplication.pri) include(singleapplication/singleapplication.pri)

View File

@@ -7,43 +7,43 @@
Chat::Chat() {} Chat::Chat() {}
ChatMemoEdit::ChatMemoEdit(QWidget* parent) : QTextEdit(parent) { ChatMemoEdit::ChatMemoEdit(QWidget* parent) : QTextEdit(parent) {
QObject::connect(this, &QTextEdit::textChanged, this, &ChatMemoEdit::updateDisplay); QObject::connect(this, &QTextEdit::textChanged, this, &ChatMemoEdit::updateDisplayChat);
} }
void ChatMemoEdit::updateDisplay() { void ChatMemoEdit::updateDisplayChat() {
QString txt = this->toPlainText(); QString txt = this->toPlainText();
if (lenDisplayLabel) if (lenDisplayLabelchat)
lenDisplayLabel->setText(QString::number(txt.toUtf8().size()) + "/" + QString::number(maxlen)); lenDisplayLabelchat->setText(QString::number(txt.toUtf8().size()) + "/" + QString::number(maxlenchat));
if (txt.toUtf8().size() <= maxlen) { if (txt.toUtf8().size() <= maxlenchat) {
// Everything is fine // Everything is fine
if (sendChatButton) if (sendChatButton)
sendChatButton->setEnabled(true); sendChatButton->setEnabled(true);
if (lenDisplayLabel) if (lenDisplayLabelchat)
lenDisplayLabel->setStyleSheet(""); lenDisplayLabelchat->setStyleSheet("");
} }
else { else {
// Overweight // Overweight
if (sendChatButton) if (sendChatButton)
sendChatButton->setEnabled(false); sendChatButton->setEnabled(false);
if (lenDisplayLabel) if (lenDisplayLabelchat)
lenDisplayLabel->setStyleSheet("color: red;"); lenDisplayLabelchat->setStyleSheet("color: red;");
} }
} }
void ChatMemoEdit::setMaxLen(int len) { void ChatMemoEdit::setMaxLenChat(int len) {
this->maxlen = len; this->maxlenchat = len;
updateDisplay(); updateDisplayChat();
} }
void ChatMemoEdit::SetSendChatButton(QPushButton* button) { void ChatMemoEdit::SetSendChatButton(QPushButton* button) {
this->sendChatButton = button; this->sendChatButton = button;
} }
void ChatMemoEdit::setLenDisplayLabel(QLabel* label) { void ChatMemoEdit::setLenDisplayLabelChat(QLabel* label) {
this->lenDisplayLabel = label; this->lenDisplayLabelchat = label;
} }
void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view, QLabel *label) void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view, QLabel *label)
@@ -55,7 +55,6 @@ void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view, QLabel *label)
{ {
for (auto &c : DataStore::getChatDataStore()->getAllMemos()) for (auto &c : DataStore::getChatDataStore()->getAllMemos())
{ {
//////Render only Memos for selected contacts. Do not render empty Memos //// Render only memos where cid=cid
if ( if (
(p.getName() == ui->contactNameMemo->text().trimmed()) && (p.getName() == ui->contactNameMemo->text().trimmed()) &&
@@ -69,6 +68,7 @@ void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view, QLabel *label)
chat->appendRow(Items); chat->appendRow(Items);
ui->listChat->setModel(chat); ui->listChat->setModel(chat);
} }
else else
{ {
@@ -86,6 +86,8 @@ void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view, QLabel *label)
Items1->setData(INCOMING, Qt::UserRole + 1); Items1->setData(INCOMING, Qt::UserRole + 1);
chat->appendRow(Items1); chat->appendRow(Items1);
ui->listChat->setModel(chat); ui->listChat->setModel(chat);
} }
else else
{ {
@@ -95,3 +97,5 @@ void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view, QLabel *label)
} }
} }
} }

View File

@@ -7,42 +7,48 @@ void FileEncryption::showConfig()
int FileEncryption::encrypt(QString target_file, QString source_file, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) int FileEncryption::encrypt(QString target_file, QString source_file, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES])
{ {
unsigned char buf_in[FILEENCRYPTION_CHUNK_SIZE]; unsigned char plain_data[FILEENCRYPTION_CHUNK_SIZE];
unsigned char buf_out[FILEENCRYPTION_CHUNK_SIZE + crypto_secretstream_xchacha20poly1305_ABYTES]; unsigned char cipher_data[FILEENCRYPTION_CHUNK_SIZE + crypto_secretstream_xchacha20poly1305_ABYTES];
unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES];
crypto_secretstream_xchacha20poly1305_state st; crypto_secretstream_xchacha20poly1305_state state;
FILE *fp_t, *fp_s; FILE *target, *source;
unsigned long long out_len; unsigned long long cipher_len;
size_t rlen; size_t rlen;
int eof; int eof;
unsigned char tag; unsigned char tag;
fp_s = fopen(source_file.toStdString().c_str(), "rb"); if(!FileEncryption::exists(source_file.toStdString()))
fp_t = fopen(target_file.toStdString().c_str(), "wb"); {
crypto_secretstream_xchacha20poly1305_init_push(&st, header, key); qDebug() << "File not exits" << source_file;
fwrite(header, 1, sizeof header, fp_t); return -1;
}
source = fopen(source_file.toStdString().c_str(), "rb");
target = fopen(target_file.toStdString().c_str(), "wb");
crypto_secretstream_xchacha20poly1305_init_push(&state, header, key);
fwrite(header, 1, sizeof header, target);
do do
{ {
rlen = fread(buf_in, 1, sizeof buf_in, fp_s); rlen = fread(plain_data, 1, sizeof plain_data, source);
eof = feof(fp_s); eof = feof(source);
tag = eof ? crypto_secretstream_xchacha20poly1305_TAG_FINAL : 0; tag = eof ? crypto_secretstream_xchacha20poly1305_TAG_FINAL : 0;
crypto_secretstream_xchacha20poly1305_push( crypto_secretstream_xchacha20poly1305_push(
&st, &state,
buf_out, cipher_data,
&out_len, &cipher_len,
buf_in, plain_data,
rlen, rlen,
NULL, NULL,
0, 0,
tag tag
); );
fwrite(buf_out, 1, (size_t) out_len, fp_t); fwrite(cipher_data, 1, (size_t) cipher_len, target);
} }
while (! eof); while (! eof);
fclose(fp_t); fclose(target);
fclose(fp_s); fclose(source);
return 0; return 0;
} }
@@ -59,6 +65,12 @@ int FileEncryption::decrypt(QString target_file, QString source_file, const unsi
int ret = -1; int ret = -1;
unsigned char tag; unsigned char tag;
if(!FileEncryption::exists(source_file.toStdString()))
{
qDebug() << "File not exits" << source_file;
return -1;
}
fp_s = fopen(source_file.toStdString().c_str(), "rb"); fp_s = fopen(source_file.toStdString().c_str(), "rb");
fp_t = fopen(target_file.toStdString().c_str(), "wb"); fp_t = fopen(target_file.toStdString().c_str(), "wb");
fread(header, 1, sizeof header, fp_s); fread(header, 1, sizeof header, fp_s);

View File

@@ -3,11 +3,17 @@
#include <stdio.h> #include <stdio.h>
#include <sodium.h> #include <sodium.h>
#include <QString> #include <QString>
#include <fstream>
#define FILEENCRYPTION_CHUNK_SIZE 4096 #define FILEENCRYPTION_CHUNK_SIZE 4096
class FileEncryption class FileEncryption
{ {
private:
inline static bool exists (const std::string& name) {
std::ifstream f(name.c_str());
return f.good();
}
public: public:
static void showConfig(); static void showConfig();
static int encrypt(QString target_file, QString source_file, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]); static int encrypt(QString target_file, QString source_file, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]);

60
src/Crypto/passwd.cpp Normal file
View File

@@ -0,0 +1,60 @@
#include "passwd.h"
void PASSWD::show_hex_buff(unsigned char buf[])
{
int i;
for (uint8_t i=0; i < crypto_secretstream_xchacha20poly1305_KEYBYTES; i++)
printf("%02X ", buf[i]);
printf("\n");
}
const unsigned char* PASSWD::key(QString password)
{
int length = password.length();
char *sequence = NULL;
sequence = new char[length+1];
strncpy(sequence, password.toLocal8Bit(), length +1);
#define MESSAGE ((const unsigned char *) sequence)
#define MESSAGE_LEN length
unsigned char hash[crypto_secretstream_xchacha20poly1305_KEYBYTES];
crypto_hash_sha256(hash, MESSAGE, MESSAGE_LEN);
qDebug()<<"Generating SaltHash from password: " <<sequence;
/////////we use the Hash of the Password as Salt, not perfect but still a good solution.
#define PASSWORD sequence
#define KEY_LEN crypto_box_SEEDBYTES
unsigned char key[KEY_LEN];
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 */
}
qDebug()<<"Generating cryptographic key from password: " <<sequence;
// crypto_generichash(blacke2hash, sizeof hash, MESSAGE, MESSAGE_LEN, NULL, 0);
//for(uint8_t i = 0; i < crypto_secretstream_xchacha20poly1305_KEYBYTES/2; i++)
// hash[i] = blacke2hash[i];
// for(uint8_t i = crypto_secretstream_xchacha20poly1305_KEYBYTES/2; i < crypto_secretstream_xchacha20poly1305_KEYBYTES; i++)
// hash[i] = sha256hash[i];
// delete[] sha256hash;
//delete[] blacke2hash;
qDebug()<<"secret key generated:\n";
PASSWD::show_hex_buff(key);
return key;
}

14
src/Crypto/passwd.h Normal file
View File

@@ -0,0 +1,14 @@
#ifndef PASSWD_H
#define PASSWD_H
#include <stdio.h>
#include <sodium.h>
#include <QString>
class PASSWD
{
public:
static void show_hex_buff(unsigned char buf[]);
static const unsigned char* key(QString);
};
#endif

View File

@@ -3,6 +3,8 @@
#include "ChatDataStore.h" #include "ChatDataStore.h"
#include "addressbook.h" #include "addressbook.h"
#include "chatmodel.h"
ChatDataStore* ChatDataStore::getInstance() ChatDataStore* ChatDataStore::getInstance()
{ {
@@ -58,10 +60,9 @@ std::map<QString, ChatItem> ChatDataStore::getAllNewContactRequests()
if ( if (
(c.second.isOutgoing() == false) && (c.second.isOutgoing() == false) &&
(c.second.getType() == "Cont") && (c.second.getType() == "Cont") &&
(c.second.getContact() == "") (c.second.isContact() == false)
) )
{ {
filteredItems[c.first] = c.second; filteredItems[c.first] = c.second;
} }

View File

@@ -1,7 +1,11 @@
#include "FileSystem.h" // Copyright 2019-2020 The Hush developers
// GPLv3
#include "FileSystem.h"
#include <QString> #include <QString>
#include <QList> #include <QList>
#include "../Crypto/passwd.h"
#include "addressbook.h"
FileSystem::FileSystem() FileSystem::FileSystem()
{ {
@@ -98,7 +102,6 @@ QList<ContactItem> FileSystem::readContactsOldFormat(QString file)
qDebug() << "Detected old addressbook format"; qDebug() << "Detected old addressbook format";
QList<QList<QString>> stuff; QList<QList<QString>> stuff;
in >> stuff; in >> stuff;
//qDebug() << "Stuff: " << stuff;
for (int i=0; i < stuff.size(); i++) for (int i=0; i < stuff.size(); i++)
{ {
ContactItem contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3],stuff[i][4]); ContactItem contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3],stuff[i][4]);

View File

@@ -1,3 +1,5 @@
// Copyright 2019-2020 The Hush developers
// GPLv3
#ifndef FILESYSTEM_H #ifndef FILESYSTEM_H
#define FILESYSTEM_H #define FILESYSTEM_H

View File

@@ -5,7 +5,7 @@
ChatItem::ChatItem() {} ChatItem::ChatItem() {}
ChatItem::ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, int confirmations) ChatItem::ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, int confirmations, bool notarize, bool iscontact)
{ {
_timestamp = timestamp; _timestamp = timestamp;
_address = address; _address = address;
@@ -17,9 +17,11 @@ ChatItem::ChatItem(long timestamp, QString address, QString contact, QString mem
_txid = txid; _txid = txid;
_confirmations = confirmations; _confirmations = confirmations;
_outgoing = false; _outgoing = false;
_notarize = notarize;
_iscontact = iscontact;
} }
ChatItem::ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, int confirmations, bool outgoing) ChatItem::ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, int confirmations, bool outgoing, bool notarize, bool iscontact)
{ {
_timestamp = timestamp; _timestamp = timestamp;
_address = address; _address = address;
@@ -31,6 +33,9 @@ ChatItem::ChatItem(long timestamp, QString address, QString contact, QString mem
_txid = txid; _txid = txid;
_confirmations = confirmations; _confirmations = confirmations;
_outgoing = outgoing; _outgoing = outgoing;
_notarize = notarize;
_iscontact = iscontact;
} }
long ChatItem::getTimestamp() long ChatItem::getTimestamp()
@@ -81,6 +86,16 @@ bool ChatItem::isOutgoing()
return _outgoing; return _outgoing;
} }
bool ChatItem::isNotarized()
{
return _notarize;
}
bool ChatItem::isContact()
{
return _iscontact;
}
void ChatItem::setTimestamp(long timestamp) void ChatItem::setTimestamp(long timestamp)
{ {
_timestamp = timestamp; _timestamp = timestamp;
@@ -128,6 +143,15 @@ void ChatItem::toggleOutgo()
{ {
_outgoing = true; _outgoing = true;
} }
void ChatItem::notarized()
{
_notarize = false;
}
void ChatItem::contact(bool iscontact)
{
_iscontact = iscontact;
}
QString ChatItem::toChatLine() QString ChatItem::toChatLine()
@@ -136,14 +160,25 @@ QString ChatItem::toChatLine()
QString lock; QString lock;
myDateTime.setTime_t(_timestamp); myDateTime.setTime_t(_timestamp);
if (_confirmations == 0){ if (_notarize == true)
{
lock = "<b> <img src=':/icons/res/lock_orange.png'><b>";
}else{
lock = "<b> <img src=':/icons/res/unlocked.png'><b>"; lock = "<b> <img src=':/icons/res/unlocked.png'><b>";
}else{ }
if ((_confirmations > 0) && (_notarize == false))
{
lock = "<b> <img src=':/icons/res/lock_green.png'><b>"; lock = "<b> <img src=':/icons/res/lock_green.png'><b>";
}
}
qDebug()<<_notarize;
QString line = QString("<small>") + myDateTime.toString("dd.MM.yyyy hh:mm"); QString line = QString("<small>") + myDateTime.toString("dd.MM.yyyy hh:mm");
line += QString(lock) + QString("</small>"); line += QString(lock) + QString("</small>");
line += QString("<p>") + _memo.toHtmlEscaped() + QString("</p>"); line += QString("<p>") + _memo.toHtmlEscaped() + QString("</p>");

View File

@@ -20,11 +20,13 @@ class ChatItem
QString _txid; QString _txid;
int _confirmations; int _confirmations;
bool _outgoing = false; bool _outgoing = false;
bool _notarize = false;
bool _iscontact = false;
public: public:
ChatItem(); ChatItem();
ChatItem(long timestamp, QString address, QString contact, QString memo,QString requestZaddr, QString type, QString cid, QString txid, int confirmations); ChatItem(long timestamp, QString address, QString contact, QString memo,QString requestZaddr, QString type, QString cid, QString txid, int confirmations, bool notarize, bool iscontact);
ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, int confirmations, bool outgoing); ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, int confirmations, bool outgoing, bool notarize, bool iscontact);
long getTimestamp(); long getTimestamp();
QString getAddress(); QString getAddress();
QString getContact(); QString getContact();
@@ -35,6 +37,9 @@ class ChatItem
QString getTxid(); QString getTxid();
int getConfirmations(); int getConfirmations();
bool isOutgoing(); bool isOutgoing();
bool isdouble();
bool isNotarized();
bool isContact();
void setTimestamp(long timestamp); void setTimestamp(long timestamp);
void setAddress(QString address); void setAddress(QString address);
void setContact(QString contact); void setContact(QString contact);
@@ -45,6 +50,8 @@ class ChatItem
void setTxid(QString txid); void setTxid(QString txid);
void setConfirmations(int confirmations); void setConfirmations(int confirmations);
void toggleOutgo(); void toggleOutgo();
void notarized();
void contact(bool iscontact);
QString toChatLine(); QString toChatLine();
json toJson(); json toJson();
~ChatItem(); ~ChatItem();

View File

@@ -1,4 +1,9 @@
// Copyright 2019-2020 The Hush developers
// GPLv3
#include "ContactItem.h" #include "ContactItem.h"
#include "chatmodel.h"
#include "Model/ChatItem.h"
#include "controller.h"
ContactItem::ContactItem() {} ContactItem::ContactItem() {}

View File

@@ -1,8 +1,11 @@
// Copyright 2019-2020 The Hush developers
// GPLv3
#ifndef CONTACTITEM_H #ifndef CONTACTITEM_H
#define CONTACTITEM_H #define CONTACTITEM_H
#include <vector> #include <vector>
#include <QString> #include <QString>
#include "mainwindow.h"
using json = nlohmann::json; using json = nlohmann::json;
class ContactItem class ContactItem

View File

@@ -40,7 +40,10 @@ void AddressBookModel::loadData()
QSettings().value( QSettings().value(
"addresstablegeometry" "addresstablegeometry"
).toByteArray() ).toByteArray()
); );
} }
void AddressBookModel::addNewLabel(QString label, QString addr, QString myAddr, QString cid, QString avatar) void AddressBookModel::addNewLabel(QString label, QString addr, QString myAddr, QString cid, QString avatar)

View File

@@ -25,6 +25,7 @@ public:
QVariant headerData(int section, Qt::Orientation orientation, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const;
private: private:
void loadData(); void loadData();
void saveData(); void saveData();
@@ -33,6 +34,7 @@ private:
//QList<QPair<QString, QString>> labels; //QList<QPair<QString, QString>> labels;
QList<ContactItem> labels; QList<ContactItem> labels;
QStringList headers; QStringList headers;
}; };
class AddressBook { class AddressBook {
@@ -68,6 +70,10 @@ public:
private: private:
AddressBook(); AddressBook();
@@ -77,6 +83,7 @@ private:
QString writeableFile(); QString writeableFile();
QList<ContactItem> allLabels; QList<ContactItem> allLabels;
static AddressBook* instance; static AddressBook* instance;
}; };

View File

@@ -8,7 +8,6 @@
#include "ui_mainwindow.h" #include "ui_mainwindow.h"
#include "ui_requestContactDialog.h" #include "ui_requestContactDialog.h"
#include "addressbook.h" #include "addressbook.h"
#include "ui_memodialog.h"
#include "ui_contactrequest.h" #include "ui_contactrequest.h"
#include <QtWidgets> #include <QtWidgets>
#include <QUuid> #include <QUuid>
@@ -54,7 +53,6 @@ void ChatModel::clear()
void ChatModel::addMessage(ChatItem item) void ChatModel::addMessage(ChatItem item)
{ {
QString key = ChatIDGenerator::getInstance()->generateID(item); //this->generateChatItemID(item); QString key = ChatIDGenerator::getInstance()->generateID(item); //this->generateChatItemID(item);
// qDebug() << "inserting chatitem with id: " << key;
this->chatItems[key] = item; this->chatItems[key] = item;
} }
@@ -74,7 +72,25 @@ void ChatModel::showMessages()
} }
void ChatModel::addAddressbylabel(QString address, QString label)
{
this->AddressbyLabelMap[address] = label;
}
QString ChatModel::Addressbylabel(QString address)
{
for(auto& pair : this->AddressbyLabelMap)
{
}
if(this->AddressbyLabelMap.count(address) > 0)
{
return this->AddressbyLabelMap[address];
}
return QString("0xdeadbeef");
}
void MainWindow::renderContactRequest(){ void MainWindow::renderContactRequest(){
@@ -83,27 +99,53 @@ void MainWindow::renderContactRequest(){
requestContact.setupUi(&dialog); requestContact.setupUi(&dialog);
Settings::saveRestore(&dialog); Settings::saveRestore(&dialog);
QString icon;
auto theme = Settings::getInstance()->get_theme_name();
if (theme == "dark" || theme == "midnight") {
icon = ":/icons/res/unknownWhite.png";
}else{
icon = ":/icons/res/unknownBlack.png";
}
QPixmap unknownWhite(icon);
QIcon addnewAddrIcon(unknownWhite);
QStandardItemModel* contactRequest = new QStandardItemModel(); QStandardItemModel* contactRequest = new QStandardItemModel();
for (auto &c : DataStore::getChatDataStore()->getAllNewContactRequests()) for (auto &c : DataStore::getChatDataStore()->getAllNewContactRequests())
{ {
QStandardItem* Items = new QStandardItem(c.second.getAddress()); QStandardItem* Items = new QStandardItem(QString("Unknown Sender"));
contactRequest->appendRow(Items); contactRequest->appendRow(Items);
requestContact.requestContact->setModel(contactRequest); requestContact.requestContact->setModel(contactRequest);
Items->setData(QIcon(addnewAddrIcon),Qt::DecorationRole);
requestContact.requestContact->setIconSize(QSize(40,50));
requestContact.requestContact->setUniformItemSizes(true);
requestContact.requestContact->show(); requestContact.requestContact->show();
requestContact.zaddrnew->setVisible(false);
requestContact.zaddrnew->setText(c.second.getAddress());
} }
QStandardItemModel* contactRequestOld = new QStandardItemModel(); QStandardItemModel* contactRequestOld = new QStandardItemModel();
for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) for (auto &p : AddressBook::getInstance()->getAllAddressLabels())
for (auto &c : DataStore::getChatDataStore()->getAllOldContactRequests()) for (auto &c : DataStore::getChatDataStore()->getAllOldContactRequests())
{ {
if (p.getPartnerAddress() == c.second.getRequestZaddr()) if (p.getPartnerAddress() == c.second.getRequestZaddr())
{ {
QStandardItem* Items = new QStandardItem(c.second.getAddress()); QStandardItem* Items = new QStandardItem(p.getName());
contactRequestOld->appendRow(Items); contactRequestOld->appendRow(Items);
requestContact.requestContactOld->setModel(contactRequestOld); requestContact.requestContactOld->setModel(contactRequestOld);
requestContact.zaddrold->setVisible(false);
requestContact.zaddrold->setText(c.second.getAddress());
requestContact.requestContactOld->show(); requestContact.requestContactOld->show();
}else{} }else{}
} }
@@ -116,7 +158,7 @@ void MainWindow::renderContactRequest(){
QString label_contact = index.data(Qt::DisplayRole).toString(); QString label_contact = index.data(Qt::DisplayRole).toString();
QStandardItemModel* contactMemo = new QStandardItemModel(); QStandardItemModel* contactMemo = new QStandardItemModel();
if ((c.second.isOutgoing() == false) && (label_contact == c.second.getAddress()) && (c.second.getType() != "Cont")) if ((c.second.isOutgoing() == false) && (requestContact.zaddrnew->text() == c.second.getAddress()) && (c.second.getType() != "Cont"))
{ {
@@ -139,11 +181,11 @@ void MainWindow::renderContactRequest(){
QObject::connect(requestContact.requestContactOld, &QTableView::clicked, [&] () { QObject::connect(requestContact.requestContactOld, &QTableView::clicked, [&] () {
for (auto &c : DataStore::getChatDataStore()->getAllRawChatItems()){ for (auto &c : DataStore::getChatDataStore()->getAllRawChatItems()){
QModelIndex index = requestContact.requestContactOld->currentIndex(); /* QModelIndex index = requestContact.requestContactOld->currentIndex();
QString label_contactold = index.data(Qt::DisplayRole).toString(); QString label_contactold = index.data(Qt::DisplayRole).toString();*/
QStandardItemModel* contactMemo = new QStandardItemModel(); QStandardItemModel* contactMemo = new QStandardItemModel();
if ((c.second.isOutgoing() == false) && (label_contactold == c.second.getAddress()) && (c.second.getType() != "Cont")) if ((c.second.isOutgoing() == false) && (requestContact.zaddrold->text() == c.second.getAddress()) && (c.second.getType() != "Cont"))
{ {
@@ -220,6 +262,11 @@ void ChatModel::addrequestZaddr(QString tx, QString requestZaddr)
this->requestZaddrMap[tx] = requestZaddr; this->requestZaddrMap[tx] = requestZaddr;
} }
void ChatModel::addconfirmations(QString tx, int confirmation)
{
this->confirmationsMap[tx] = confirmation;
}
QString ChatModel::getCidByTx(QString tx) QString ChatModel::getCidByTx(QString tx)
{ {
for(auto& pair : this->cidMap) for(auto& pair : this->cidMap)
@@ -235,6 +282,21 @@ QString ChatModel::getCidByTx(QString tx)
return QString("0xdeadbeef"); return QString("0xdeadbeef");
} }
QString ChatModel::getConfirmationByTx(QString tx)
{
for(auto& pair : this->confirmationsMap)
{
}
if(this->confirmationsMap.count(tx) > 0)
{
return this->confirmationsMap[tx];
}
return QString("0xdeadbeef");
}
QString ChatModel::getrequestZaddrByTx(QString tx) QString ChatModel::getrequestZaddrByTx(QString tx)
{ {
for(auto& pair : this->requestZaddrMap) for(auto& pair : this->requestZaddrMap)
@@ -260,6 +322,11 @@ void ChatModel::killrequestZaddrCache()
this->requestZaddrMap.clear(); this->requestZaddrMap.clear();
} }
void ChatModel::killConfirmationCache()
{
this->confirmationsMap.clear();
}
QString MainWindow::createHeaderMemo(QString type, QString cid, QString zaddr, int version=0, int headerNumber=1) QString MainWindow::createHeaderMemo(QString type, QString cid, QString zaddr, int version=0, int headerNumber=1)
{ {
@@ -335,13 +402,11 @@ void MainWindow::sendChat() {
// Create a Tx from the values on the send tab. Note that this Tx object // Create a Tx from the values on the send tab. Note that this Tx object
// might not be valid yet. // might not be valid yet.
// Memos can only be used with zAddrs. So check that first QString Name = ui->contactNameMemo->text();
// for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) int sizename = Name.size();
qDebug()<< sizename;
if (ui->contactNameMemo->text().trimmed().isEmpty() || ui->memoTxtChat->toPlainText().trimmed().isEmpty()) { if (ui->contactNameMemo->text().trimmed().isEmpty() || ui->memoTxtChat->toPlainText().trimmed().isEmpty()) {
// auto addr = "";
// if (! Settings::isZAddress(AddressBook::addressFromAddressLabel(addr->text()))) {
QMessageBox msg(QMessageBox::Critical, tr("You have to select a contact and insert a Memo"), 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"), tr("You have selected no Contact from Contactlist,\n") + tr("\nor your Memo is empty"),
QMessageBox::Ok, this); QMessageBox::Ok, this);
@@ -350,6 +415,20 @@ void MainWindow::sendChat() {
return; return;
} }
int max = 512;
QString chattext = ui->memoTxtChat->toPlainText();
int size = chattext.size();
if (size > max){
QMessageBox msg(QMessageBox::Critical, tr("Your Message is too long"),
tr("You can only write messages with 512 character maximum \n") + tr("\n Please reduce your message to 512 character."),
QMessageBox::Ok, this);
msg.exec();
return;
}
Tx tx = createTxFromChatPage(); Tx tx = createTxFromChatPage();
QString error = doSendChatTxValidations(tx); QString error = doSendChatTxValidations(tx);
@@ -384,11 +463,12 @@ void MainWindow::sendChat() {
} }
connD->status->setText(tr("Please wait...")); connD->status->setText(tr("Please wait..."));
connD->statusDetail->setText(tr("Your Message will be send")); connD->statusDetail->setText(tr("Your Message will be sent"));
d->show(); d->show();
ui->memoTxtChat->clear(); ui->memoTxtChat->clear();
// And send the Tx // And send the Tx
rpc->executeTransaction(tx, rpc->executeTransaction(tx,
[=] (QString txid) { [=] (QString txid) {
@@ -397,6 +477,7 @@ void MainWindow::sendChat() {
connD->status->setText(tr("Done!")); connD->status->setText(tr("Done!"));
connD->statusDetail->setText(txid); connD->statusDetail->setText(txid);
QTimer::singleShot(1000, [=]() { QTimer::singleShot(1000, [=]() {
d->accept(); d->accept();
d->close(); d->close();
@@ -406,7 +487,7 @@ void MainWindow::sendChat() {
}); });
// Force a UI update so we get the unconfirmed Tx // Force a UI update so we get the unconfirmed Tx
// rpc->refresh(true); rpc->refresh(true);
ui->memoTxtChat->clear(); ui->memoTxtChat->clear();
}, },
@@ -425,6 +506,8 @@ void MainWindow::sendChat() {
QMessageBox::critical(this, QObject::tr("Transaction Error"), errStr, QMessageBox::Ok); QMessageBox::critical(this, QObject::tr("Transaction Error"), errStr, QMessageBox::Ok);
} }
); );
// rpc->refresh(true);
} }
QString MainWindow::doSendChatTxValidations(Tx tx) { QString MainWindow::doSendChatTxValidations(Tx tx) {
@@ -450,7 +533,7 @@ QString MainWindow::doSendChatTxValidations(Tx tx) {
auto available = rpc->getModel()->getAvailableBalance(); auto available = rpc->getModel()->getAvailableBalance();
if (available < total) { if (available < total) {
return tr("Not enough available funds to send this transaction\n\nHave: %1\nNeed: %2\n\nNote: Funds need 3 confirmations before they can be spent") 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()); .arg(available.toDecimalhushString(), total.toDecimalhushString());
} }
@@ -499,7 +582,7 @@ void::MainWindow::addContact()
}); });
QObject::connect(request.sendRequestButton, &QPushButton::clicked, this, &MainWindow::saveandsendContact); QObject::connect(request.sendRequestButton, &QPushButton::clicked, this, &MainWindow::saveandsendContact);
QObject::connect(request.onlyAdd, &QPushButton::clicked, this, &MainWindow::saveContact); // QObject::connect(request.onlyAdd, &QPushButton::clicked, this, &MainWindow::saveContact);
dialog.exec(); dialog.exec();
@@ -510,95 +593,6 @@ void::MainWindow::addContact()
void MainWindow::saveandsendContact() void MainWindow::saveandsendContact()
{ {
this->ContactRequest(); this->ContactRequest();
QString addr = contactRequest.getReceiverAddress();
QString newLabel = contactRequest.getLabel();
QString myAddr = contactRequest.getSenderAddress();
QString cid = contactRequest.getCid();
QString avatar = contactRequest.getAvatar();
contactRequest.clear();
if (addr.isEmpty() || newLabel.isEmpty())
{
QMessageBox::critical(
this,
QObject::tr("Address or Label Error"),
QObject::tr("Address or Label cannot be empty"),
QMessageBox::Ok
);
return;
}
// Test if address is valid.
if (!Settings::isValidAddress(addr))
{
QMessageBox::critical(
this,
QObject::tr("Address Format Error"),
QObject::tr("%1 doesn't seem to be a valid hush address.").arg(addr),
QMessageBox::Ok
);
return;
}
///////Todo: Test if label allready exist!
////// Success, so show it
AddressBook::getInstance()->addAddressLabel(newLabel, addr, myAddr, cid, avatar);
QMessageBox::information(
this,
QObject::tr("Added Contact"),
QObject::tr("successfully added your new contact").arg(newLabel),
QMessageBox::Ok
);
return;
}
void MainWindow::saveContact()
{
QString addr = contactRequest.getReceiverAddress();
QString newLabel = contactRequest.getLabel();
QString myAddr = contactRequest.getSenderAddress();
QString cid = contactRequest.getCid();
QString avatar = contactRequest.getAvatar();
if (addr.isEmpty() || newLabel.isEmpty())
{
QMessageBox::critical(
this,
QObject::tr("Address or Label Error"),
QObject::tr("Address or Label cannot be empty"),
QMessageBox::Ok
);
return;
}
// Test if address is valid.
if (!Settings::isValidAddress(addr))
{
QMessageBox::critical(
this,
QObject::tr("Address Format Error"),
QObject::tr("%1 doesn't seem to be a valid hush address.").arg(addr),
QMessageBox::Ok
);
return;
}
///////Todo: Test if label allready exist!
////// Success, so show it
AddressBook::getInstance()->addAddressLabel(newLabel, addr, myAddr, cid, avatar);
QMessageBox::information(
this,
QObject::tr("Added Contact"),
QObject::tr("successfully added your new contact").arg(newLabel),
QMessageBox::Ok
);
return;
} }
@@ -647,6 +641,22 @@ void MainWindow::ContactRequest() {
return; return;
} }
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 512 character maximum \n") + tr("\n Please reduce your message to 512 character."),
QMessageBox::Ok, this);
msg.exec();
return;
}
Tx tx = createTxForSafeContactRequest(); Tx tx = createTxForSafeContactRequest();
QString error = doSendRequestTxValidations(tx); QString error = doSendRequestTxValidations(tx);
@@ -681,7 +691,7 @@ void MainWindow::ContactRequest() {
} }
connD->status->setText(tr("Please wait...")); connD->status->setText(tr("Please wait..."));
connD->statusDetail->setText(tr("Your Contact will be send")); connD->statusDetail->setText(tr("Your contact request will be sent"));
d->show(); d->show();
ui->memoTxtChat->clear(); ui->memoTxtChat->clear();
@@ -701,7 +711,46 @@ void MainWindow::ContactRequest() {
delete d; delete d;
}); });
QString addr = contactRequest.getReceiverAddress();
QString newLabel = contactRequest.getLabel();
QString myAddr = contactRequest.getSenderAddress();
QString cid = contactRequest.getCid();
QString avatar = contactRequest.getAvatar();
if (addr.isEmpty() || newLabel.isEmpty())
{
QMessageBox::critical(
this,
QObject::tr("Address or Label Error"),
QObject::tr("Address or Label cannot be empty"),
QMessageBox::Ok
);
return;
}
// Test if address is valid.
if (!Settings::isValidAddress(addr))
{
QMessageBox::critical(
this,
QObject::tr("Address Format Error"),
QObject::tr("%1 doesn't seem to be a valid hush address.").arg(addr),
QMessageBox::Ok
);
return;
}
///////Todo: Test if label allready exist!
////// Success, so show it
AddressBook::getInstance()->addAddressLabel(newLabel, addr, myAddr, cid, avatar);
QMessageBox::information(
this,
QObject::tr("Added Contact"),
QObject::tr("successfully added your new contact").arg(newLabel),
QMessageBox::Ok
);
return;
// Force a UI update so we get the unconfirmed Tx // Force a UI update so we get the unconfirmed Tx
// rpc->refresh(true); // rpc->refresh(true);
ui->memoTxtChat->clear(); ui->memoTxtChat->clear();
@@ -750,9 +799,11 @@ QString MainWindow::doSendRequestTxValidations(Tx tx) {
auto available = rpc->getModel()->getAvailableBalance(); auto available = rpc->getModel()->getAvailableBalance();
if (available < total) { if (available < total) {
return tr("Not enough available funds to send this transaction\n\nHave: %1\nNeed: %2\n\nNote: Funds need 5 confirmations before they can be spent") 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()); .arg(available.toDecimalhushString(), total.toDecimalhushString());
} }
return ""; return "";
} }

View File

@@ -20,6 +20,7 @@
#include "Chat/Helper/ChatDelegator.h" #include "Chat/Helper/ChatDelegator.h"
#include "Chat/Helper/ChatIDGenerator.h" #include "Chat/Helper/ChatIDGenerator.h"
namespace Ui { namespace Ui {
class MainWindow; class MainWindow;
} }
@@ -32,7 +33,9 @@ class ChatModel
MainWindow* main; MainWindow* main;
std::map<QString, QString> cidMap; std::map<QString, QString> cidMap;
std::map<QString, QString> requestZaddrMap; std::map<QString, QString> requestZaddrMap;
std::map<QString, QString> confirmationsMap;
std::map<int, std::tuple<QString, QString, QString>> sendrequestMap; std::map<int, std::tuple<QString, QString, QString>> sendrequestMap;
std::map<QString, QString> AddressbyLabelMap;
public: public:
ChatModel() {}; ChatModel() {};
@@ -45,14 +48,19 @@ class ChatModel
void triggerRequest(); void triggerRequest();
void showMessages(); void showMessages();
void clear(); void clear();
void addAddressbylabel(QString addr, QString label);
void addMessage(ChatItem item); void addMessage(ChatItem item);
void addMessage(QString timestamp, ChatItem item); void addMessage(QString timestamp, ChatItem item);
void addCid(QString tx, QString cid); void addCid(QString tx, QString cid);
void addrequestZaddr(QString tx, QString requestZaddr); void addrequestZaddr(QString tx, QString requestZaddr);
void addconfirmations(QString tx, int confirmation);
void addSendRequest(int i, QString myAddr, QString cid, QString addr ); void addSendRequest(int i, QString myAddr, QString cid, QString addr );
QString getCidByTx(QString tx); QString getCidByTx(QString tx);
QString getrequestZaddrByTx(QString tx); QString getrequestZaddrByTx(QString tx);
QString getConfirmationByTx(QString tx);
QString Addressbylabel(QString addr);
void killCidCache(); void killCidCache();
void killConfirmationCache();
void killrequestZaddrCache(); void killrequestZaddrCache();
}; };

View File

@@ -5,6 +5,13 @@
#include "addressbook.h" #include "addressbook.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "chatmodel.h" #include "chatmodel.h"
#include "requestdialog.h"
#include "ui_requestdialog.h"
#include "ui_hushrequest.h"
#include "settings.h"
#include "controller.h"
void ContactModel::renderContactList(QListView* view) void ContactModel::renderContactList(QListView* view)
{ {
@@ -18,6 +25,7 @@ void ContactModel::renderContactList(QListView* view)
QStandardItem* Items1 = new QStandardItem(c.getName()); QStandardItem* Items1 = new QStandardItem(c.getName());
Items1->setData(QIcon(avatar),Qt::DecorationRole); Items1->setData(QIcon(avatar),Qt::DecorationRole);
contact->appendRow(Items1); contact->appendRow(Items1);
view->setModel(contact); view->setModel(contact);
view->setIconSize(QSize(60,70)); view->setIconSize(QSize(60,70));
@@ -26,6 +34,110 @@ void ContactModel::renderContactList(QListView* view)
view->show(); view->show();
}
}
void MainWindow::showRequesthush() {
Ui_hushrequest req;
QDialog d(this);
req.setupUi(&d);
Settings::saveRestore(&d);
QString label = ui->contactNameMemo->text();
for(auto &p : AddressBook::getInstance()->getAllAddressLabels())
{
if (p.getName() == label)
{
QString addr = p.getPartnerAddress();
QString myzaddr = p.getMyAddress();
req.txtFrom->setText(addr);
req.lblAddressInfo->setText(myzaddr);
// Amount textbox
req.txtAmount->setValidator(this->getAmountValidator());
QObject::connect(req.txtAmount, &QLineEdit::textChanged, [=] (auto text) {
CAmount amount = CAmount::fromDecimalString(text);
if (Settings::getInstance()->get_currency_name() == "USD") {
req.txtAmountUSD->setText(amount.toDecimalUSDString());
} else if (Settings::getInstance()->get_currency_name() == "EUR") {
req.txtAmountUSD->setText(amount.toDecimalEURString());
} else if (Settings::getInstance()->get_currency_name() == "BTC") {
req.txtAmountUSD->setText(amount.toDecimalBTCString());
} else if (Settings::getInstance()->get_currency_name() == "CNY") {
req.txtAmountUSD->setText(amount.toDecimalCNYString());
} else if (Settings::getInstance()->get_currency_name() == "RUB") {
req.txtAmountUSD->setText(amount.toDecimalRUBString());
} else if (Settings::getInstance()->get_currency_name() == "CAD") {
req.txtAmountUSD->setText(amount.toDecimalCADString());
} else if (Settings::getInstance()->get_currency_name() == "SGD") {
req.txtAmountUSD->setText(amount.toDecimalSGDString());
} else if (Settings::getInstance()->get_currency_name() == "CHF") {
req.txtAmountUSD->setText(amount.toDecimalCHFString());
} else if (Settings::getInstance()->get_currency_name() == "INR") {
req.txtAmountUSD->setText(amount.toDecimalINRString());
} else if (Settings::getInstance()->get_currency_name() == "GBP") {
req.txtAmountUSD->setText(amount.toDecimalGBPString());
} else if (Settings::getInstance()->get_currency_name() == "AUD") {
req.txtAmountUSD->setText(amount.toDecimalBTCString());
}
});
CAmount amount = CAmount::fromDecimalString(req.txtAmount->text());
if (Settings::getInstance()->get_currency_name() == "USD") {
req.txtAmountUSD->setText(amount.toDecimalUSDString());
} else if (Settings::getInstance()->get_currency_name() == "EUR") {
req.txtAmountUSD->setText(amount.toDecimalEURString());
} else if (Settings::getInstance()->get_currency_name() == "BTC") {
req.txtAmountUSD->setText(amount.toDecimalBTCString());
} else if (Settings::getInstance()->get_currency_name() == "CNY") {
req.txtAmountUSD->setText(amount.toDecimalCNYString());
} else if (Settings::getInstance()->get_currency_name() == "RUB") {
req.txtAmountUSD->setText(amount.toDecimalRUBString());
} else if (Settings::getInstance()->get_currency_name() == "CAD") {
req.txtAmountUSD->setText(amount.toDecimalCADString());
} else if (Settings::getInstance()->get_currency_name() == "SGD") {
req.txtAmountUSD->setText(amount.toDecimalSGDString());
} else if (Settings::getInstance()->get_currency_name() == "CHF") {
req.txtAmountUSD->setText(amount.toDecimalCHFString());
} else if (Settings::getInstance()->get_currency_name() == "INR") {
req.txtAmountUSD->setText(amount.toDecimalINRString());
} else if (Settings::getInstance()->get_currency_name() == "GBP") {
req.txtAmountUSD->setText(amount.toDecimalGBPString());
} else if (Settings::getInstance()->get_currency_name() == "AUD") {
req.txtAmountUSD->setText(amount.toDecimalBTCString());
}
req.txtMemo->setAcceptButton(req.buttonBox->button(QDialogButtonBox::Ok));
req.txtMemo->setLenDisplayLabel(req.lblMemoLen);
req.txtMemo->setMaxLen(400);
req.txtFrom->setFocus();
}
}
if (d.exec() == QDialog::Accepted) {
// Construct a hush Payment URI with the data and pay it immediately.
CAmount amount = CAmount::fromDecimalString(req.txtAmount->text());
QString memoURI = "hush:" + req.lblAddressInfo->text()
+ "?amt=" + amount.toDecimalString()
+ "&memo=" + QUrl::toPercentEncoding(req.txtMemo->toPlainText());
QString sendURI = "hush:" + AddressBook::addressFromAddressLabel(req.txtFrom->text())
+ "?amt=0.0001"
+ "&memo=" + QUrl::toPercentEncoding(memoURI);
// If the disclosed address in the memo doesn't have a balance, it will automatically fallback to the default
// sapling address
this->payhushURI(sendURI, req.lblAddressInfo->text());
} }
} }

View File

@@ -5,13 +5,17 @@
#include "Model/ContactItem.h" #include "Model/ContactItem.h"
#include <QListWidget> #include <QListWidget>
#include "mainwindow.h"
class ContactModel class ContactModel
{ {
public: public:
ContactModel() {} ContactModel() {}
void renderContactList(QListView* view); void renderContactList(QListView* view);
}; };
#endif #endif

View File

@@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>777</width> <width>780</width>
<height>427</height> <height>427</height>
</rect> </rect>
</property> </property>
@@ -233,7 +233,7 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="7" column="1" colspan="3"> <item row="7" column="1">
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="label_2">
<property name="text"> <property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Insert a memo for your request&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Insert a memo for your request&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@@ -318,36 +318,11 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="9" column="2">
<widget class="QPushButton" name="onlyAdd">
<property name="maximumSize">
<size>
<width>152</width>
<height>25</height>
</size>
</property>
<property name="baseSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Only add this contact</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
<item row="9" column="3" colspan="2"> <item row="9" column="3" colspan="2">
<widget class="QPushButton" name="sendRequestButton"> <widget class="QPushButton" name="sendRequestButton">
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>188</width> <width>300</width>
<height>25</height> <height>25</height>
</size> </size>
</property> </property>
@@ -358,7 +333,7 @@
</size> </size>
</property> </property>
<property name="text"> <property name="text">
<string>Add Contact &amp; send request</string> <string>Add Contact and send request</string>
</property> </property>
<property name="autoDefault"> <property name="autoDefault">
<bool>false</bool> <bool>false</bool>

View File

@@ -237,12 +237,15 @@ void Controller::getInfoThenRefresh(bool force)
zrpc->fetchInfo([=] (const json& reply) { zrpc->fetchInfo([=] (const json& reply) {
prevCallSucceeded = true; prevCallSucceeded = true;
int curBlock = reply["latest_block_height"].get<json::number_integer_t>(); int curBlock = reply["latest_block_height"].get<json::number_integer_t>();
int longestchain = reply["longestchain"].get<json::number_integer_t>(); bool doUpdate = force || (model->getLatestBlock() != curBlock);
int notarized = reply["notarized"].get<json::number_integer_t>();
int difficulty = reply["difficulty"].get<json::number_integer_t>(); int difficulty = reply["difficulty"].get<json::number_integer_t>();
int blocks_until_halving= 340000 - curBlock; 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) ;
bool doUpdate = force || (model->getLatestBlock() != curBlock); int longestchain = reply["longestchain"].get<json::number_integer_t>();
int notarized = reply["notarized"].get<json::number_integer_t>();
model->setLatestBlock(curBlock); model->setLatestBlock(curBlock);
if ( if (
Settings::getInstance()->get_currency_name() == "EUR" || Settings::getInstance()->get_currency_name() == "EUR" ||
@@ -258,7 +261,11 @@ void Controller::getInfoThenRefresh(bool force)
); );
ui->longestchain->setText( ui->longestchain->setText(
"Block: " + QLocale(QLocale::German).toString(longestchain) "Block: " + QLocale(QLocale::German).toString(longestchain)
); );
ui->difficulty->setText( ui->difficulty->setText(
QLocale(QLocale::German).toString(difficulty) QLocale(QLocale::German).toString(difficulty)
); );
@@ -540,8 +547,12 @@ void Controller::getInfoThenRefresh(bool force)
refreshAddresses(); // This calls refreshZSentTransactions() and refreshReceivedZTrans() refreshAddresses(); // This calls refreshZSentTransactions() and refreshReceivedZTrans()
refreshTransactions(); refreshTransactions();
} }
int lag = longestchain - notarized ;
this->setLag(lag);
}, [=](QString err) { }, [=](QString err) {
// hushd has probably disappeared. // hushd has probably disappeared.
this->noConnection(); this->noConnection();
// Prevent multiple dialog boxes, because these are called async // Prevent multiple dialog boxes, because these are called async
@@ -562,6 +573,20 @@ void Controller::getInfoThenRefresh(bool force)
}); });
} }
int Controller::getLag()
{
return _lag;
}
void Controller::setLag(int lag)
{
_lag = lag;
}
void Controller::refreshAddresses() void Controller::refreshAddresses()
{ {
if (!zrpc->haveConnection()) if (!zrpc->haveConnection())
@@ -872,11 +897,32 @@ void Controller::refreshTransactions() {
// Check for Memos // Check for Memos
if (confirmations == 0) {
chatModel->addconfirmations(txid, confirmations);
}
if ((confirmations == 1) && (chatModel->getConfirmationByTx(txid) != QString("0xdeadbeef"))){
DataStore::getChatDataStore()->clear();
chatModel->killConfirmationCache();
this->refresh(true);
}
QString memo; QString memo;
if (!o["memo"].is_null()) { if (!o["memo"].is_null()) {
memo = QString::fromStdString(o["memo"]); memo = QString::fromStdString(o["memo"]);
QString cid; QString cid;
bool isNotarized;
if (confirmations > getLag())
{
isNotarized = true;
}else{
isNotarized = false;
}
qDebug()<<"Conf : " << confirmations;
ChatItem item = ChatItem( ChatItem item = ChatItem(
datetime, datetime,
@@ -888,15 +934,17 @@ void Controller::refreshTransactions() {
cid, cid,
txid, txid,
confirmations, confirmations,
true true,
isNotarized,
false
); );
// qDebug()<<"Memo : " <<memo;
// qDebug()<<"Confirmation :" << confirmations;
DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item);
} }
items.push_back(TransactionItemDetail{address, amount, memo}); items.push_back(TransactionItemDetail{address, amount, memo});
total_amount = total_amount + amount; total_amount = total_amount + amount;
} }
@@ -944,6 +992,28 @@ void Controller::refreshTransactions() {
QString cid; QString cid;
int position; int position;
QString requestZaddr; QString requestZaddr;
bool isContact;
for (auto &p : AddressBook::getInstance()->getAllAddressLabels())
{
if (p.getPartnerAddress() == requestZaddr)
{
chatModel->addAddressbylabel(address, requestZaddr);
} else{}
if (chatModel->Addressbylabel(address) != QString("0xdeadbeef")){
isContact = true;
}else{
isContact = false;
}
if (!it["memo"].is_null()) { if (!it["memo"].is_null()) {
@@ -960,6 +1030,7 @@ void Controller::refreshTransactions() {
} }
if (chatModel->getCidByTx(txid) != QString("0xdeadbeef")){ if (chatModel->getCidByTx(txid) != QString("0xdeadbeef")){
cid = chatModel->getCidByTx(txid); cid = chatModel->getCidByTx(txid);
@@ -974,7 +1045,19 @@ void Controller::refreshTransactions() {
}else{ }else{
requestZaddr = ""; requestZaddr = "";
} }
position = it["position"].get<json::number_integer_t>(); position = it["position"].get<json::number_integer_t>();
bool isNotarized;
if (confirmations > getLag())
{
isNotarized = true;
}else{
isNotarized = false;
}
ChatItem item = ChatItem( ChatItem item = ChatItem(
datetime, datetime,
address, address,
@@ -985,16 +1068,17 @@ void Controller::refreshTransactions() {
cid, cid,
txid, txid,
confirmations, confirmations,
false false,
isNotarized,
isContact
); );
// qDebug()<< "Position : " << position;
// qDebug()<<"Confirmation :" << confirmations;
DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item);
} }
} }
}
} }
qDebug()<<"get Lag" << getLag();
// Calculate the total unspent amount that's pending. This will need to be // 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 // shown in the UI so the user can keep track of pending funds

View File

@@ -1,3 +1,6 @@
// Copyright 2019-2020 The Hush developers
// GPLv3
#ifndef RPCCLIENT_H #ifndef RPCCLIENT_H
#define RPCCLIENT_H #define RPCCLIENT_H
@@ -38,6 +41,9 @@ public:
void setConnection(Connection* c); void setConnection(Connection* c);
void refresh(bool force = false); void refresh(bool force = false);
void refreshAddresses(); void refreshAddresses();
int getLag();
void setLag(int lag);
int _lag;
void checkForUpdate(bool silent = true); void checkForUpdate(bool silent = true);
void refreshZECPrice(); void refreshZECPrice();

View File

@@ -14,65 +14,23 @@
<string>Encrypt Your Wallet</string> <string>Encrypt Your Wallet</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="3" column="0" colspan="2"> <item row="0" column="0">
<widget class="Line" name="line_2"> <spacer name="verticalSpacer_2">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Vertical</enum>
</property> </property>
</widget> <property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item> </item>
<item row="5" column="0"> <item row="1" column="0" colspan="3">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Encryption Password:</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Confirm Password:</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLineEdit" name="txtConfirmPassword">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QLabel" name="lblPasswordMatch">
<property name="styleSheet">
<string notr="true">color: red;</string>
</property>
<property name="text">
<string>Passwords don't match</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="txtPassword">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="8" column="0" colspan="2">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="label_2">
<property name="text"> <property name="text">
<string>WARNING: If you forget your password, the only way to recover the wallet is from the seed phrase.</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:14pt; color:#ef2929;&quot;&gt;WARNING:&lt;/span&gt; If you forget your passphrase the only way to recover the wallet is from the seed phrase. If you dont have Backup your seed phrase, please do it now!&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignCenter</set> <set>Qt::AlignCenter</set>
@@ -82,6 +40,81 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0">
<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="3" column="0" rowspan="2" colspan="3">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="4" column="2" rowspan="2">
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;16 letters minimum&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QLabel" name="lblPasswordMatch">
<property name="styleSheet">
<string notr="true">color: red;</string>
</property>
<property name="text">
<string>Passphrase don't match</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Encryption Passphrase:</string>
</property>
</widget>
</item>
<item row="6" column="1" colspan="2">
<widget class="QLineEdit" name="txtPassword">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Confirm Passphrase:</string>
</property>
</widget>
</item>
<item row="7" column="1" colspan="2">
<widget class="QLineEdit" name="txtConfirmPassword">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="8" column="0" colspan="3">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="9" column="0" colspan="2"> <item row="9" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox"> <widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation"> <property name="orientation">
@@ -95,32 +128,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="0" colspan="2">
<spacer name="verticalSpacer_2">
<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="2" column="0" colspan="2">
<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>
</layout> </layout>
</widget> </widget>
<tabstops> <tabstops>

156
src/hushrequest.ui Normal file
View File

@@ -0,0 +1,156 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>hushrequest</class>
<widget class="QDialog" name="hushrequest">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>663</width>
<height>529</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="lblPixmap">
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="lblHeader">
<property name="text">
<string>Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lblAddress">
<property name="text">
<string>Request From</string>
</property>
</widget>
</item>
<item row="1" column="1">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>541</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0" colspan="2">
<widget class="QLabel" name="txtFrom">
<property name="text">
<string>zaddr</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="lblAmount">
<property name="text">
<string>Amount in </string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QLineEdit" name="txtAmount">
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="placeholderText">
<string>Amount</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="txtAmountUSD">
<property name="text">
<string>Amount USD</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Memo</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLabel" name="lblMemoLen">
<property name="text">
<string notr="true">0 / 512</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="7" column="0" colspan="2">
<widget class="MemoEdit" name="txtMemo">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>My Address</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QLabel" name="lblAddressInfo">
<property name="text">
<string>The recipient will see this address in the &quot;to&quot; field when they pay your request.</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>MemoEdit</class>
<extends>QPlainTextEdit</extends>
<header>memoedit.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@@ -21,15 +21,36 @@
#include "ui_requestContactDialog.h" #include "ui_requestContactDialog.h"
#include "chatmodel.h" #include "chatmodel.h"
#include "requestdialog.h" #include "requestdialog.h"
#include "ui_startupencryption.h"
#include "ui_removeencryption.h"
#include "websockets.h" #include "websockets.h"
#include "sodium.h"
#include "sodium/crypto_generichash_blake2b.h"
#include <QRegularExpression> #include <QRegularExpression>
#include "FileSystem/FileSystem.h"
#include "Crypto/passwd.h"
#include "Crypto/FileEncryption.h"
using json = nlohmann::json; using json = nlohmann::json;
#ifdef Q_OS_WIN
auto dirwallet = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite/silentdragonlite-wallet.dat");
auto dirwalletenc = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite/silentdragonlite-wallet-enc.dat");
auto dirwalletbackup = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite/silentdragonlite-wallet.datBackup");
#endif
#ifdef Q_OS_UNIX
auto dirwallet = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".silentdragonlite/silentdragonlite-wallet.dat");
auto dirwalletenc = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat");
auto dirwalletbackup = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".silentdragonlite/silentdragonlite-wallet.datBackup");
#endif
MainWindow::MainWindow(QWidget *parent) : MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), QMainWindow(parent),
ui(new Ui::MainWindow) ui(new Ui::MainWindow)
{ {
// Include css // Include css
QString theme_name; QString theme_name;
try try
@@ -47,12 +68,19 @@ MainWindow::MainWindow(QWidget *parent) :
ui->setupUi(this); ui->setupUi(this);
logger = new Logger(this, QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite-wallet.log")); logger = new Logger(this, QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite-wallet.log"));
// Check for encryption
if(fileExists(dirwalletenc))
{
this->removeWalletEncryptionStartUp();
}
ui->memoTxtChat->setAutoFillBackground(false); ui->memoTxtChat->setAutoFillBackground(false);
ui->memoTxtChat->setPlaceholderText("Send Message"); ui->memoTxtChat->setPlaceholderText("Send Message");
ui->memoTxtChat->setTextColor(Qt::white); ui->memoTxtChat->setTextColor(Qt::white);
// Status Bar // Status Bar
setupStatusBar(); setupStatusBar();
@@ -181,6 +209,12 @@ MainWindow::MainWindow(QWidget *parent) :
} }
} }
bool MainWindow::fileExists(QString path)
{
QFileInfo check_file(path);
return (check_file.exists() && check_file.isFile());
}
void MainWindow::createWebsocket(QString wormholecode) { void MainWindow::createWebsocket(QString wormholecode) {
qDebug() << "Listening for app connections on port 8777"; qDebug() << "Listening for app connections on port 8777";
// Create the websocket server, for listening to direct connections // Create the websocket server, for listening to direct connections
@@ -234,6 +268,10 @@ void MainWindow::doClose() {
closeEvent(nullptr); closeEvent(nullptr);
} }
void MainWindow::doClosePw() {
closeEventpw(nullptr);
}
void MainWindow::closeEvent(QCloseEvent* event) { void MainWindow::closeEvent(QCloseEvent* event) {
QSettings s; QSettings s;
@@ -243,6 +281,78 @@ void MainWindow::closeEvent(QCloseEvent* event) {
s.sync(); s.sync();
// Let the RPC know to shut down any running service.
rpc->shutdownhushd();
// Check is encryption is ON for SDl
if(fileExists(dirwalletenc))
{
// delete old file before
//auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
QFile fileoldencryption(dirwalletenc);
fileoldencryption.remove();
// Encrypt our wallet.dat
QString str = this->getPassword();
// QString str = ed.txtPassword->text(); // data comes from user inputs
int length = str.length();
char *sequence = NULL;
sequence = new char[length+1];
strncpy(sequence, str.toLocal8Bit(), length +1);
#define MESSAGE ((const unsigned char *) sequence)
#define MESSAGE_LEN length
unsigned char hash[crypto_secretstream_xchacha20poly1305_KEYBYTES];
crypto_hash_sha256(hash,MESSAGE, MESSAGE_LEN);
#define PASSWORD sequence
#define KEY_LEN crypto_box_SEEDBYTES
/////////we use the Hash of the Password as Salt, not perfect but still a good solution.
unsigned char key[KEY_LEN];
if (crypto_pwhash
(key, sizeof key, PASSWORD, strlen(PASSWORD), hash,
crypto_pwhash_OPSLIMIT_SENSITIVE, crypto_pwhash_MEMLIMIT_SENSITIVE,
crypto_pwhash_ALG_DEFAULT) != 0) {
/* out of memory */
}
auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
// auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
QString source_file = dir.filePath("addresslabels.dat");
QString target_enc_file = dir.filePath("addresslabels.dat.enc");
QString sourceWallet_file = dirwallet;
QString target_encWallet_file = dirwalletenc;
FileEncryption::encrypt(target_enc_file, source_file, key);
FileEncryption::encrypt(target_encWallet_file, sourceWallet_file, key);
///////////////// we rename the plaintext wallet.dat to Backup, for testing.
QFile wallet(dirwallet);
QFile address(dir.filePath("addresslabels.dat"));
wallet.remove();
address.remove();
}
// Bubble up
if (event)
QMainWindow::closeEvent(event);
}
void MainWindow::closeEventpw(QCloseEvent* event) {
// Let the RPC know to shut down any running service. // Let the RPC know to shut down any running service.
rpc->shutdownhushd(); rpc->shutdownhushd();
@@ -253,124 +363,299 @@ void MainWindow::closeEvent(QCloseEvent* event) {
void MainWindow::encryptWallet() { void MainWindow::encryptWallet() {
// Check if wallet is already encrypted
auto encStatus = rpc->getModel()->getEncryptionStatus();
if (encStatus.first) {
QMessageBox::information(this, tr("Wallet is already encrypted"),
tr("Your wallet is already encrypted with a password.\nPlease use 'Remove Wallet Encryption' if you want to remove the wallet encryption."),
QMessageBox::Ok
);
return;
}
QDialog d(this); QDialog d(this);
Ui_encryptionDialog ed; Ui_encryptionDialog ed;
ed.setupUi(&d); ed.setupUi(&d);
// Handle edits on the password box // Handle edits on the password box
auto fnPasswordEdited = [=](const QString&) { auto fnPasswordEdited = [=](const QString&) {
// Enable the OK button if the passwords match. // Enable the OK button if the passwords match.
QString password = ed.txtPassword->text();
if (!ed.txtPassword->text().isEmpty() && if (!ed.txtPassword->text().isEmpty() &&
ed.txtPassword->text() == ed.txtConfirmPassword->text()) { ed.txtPassword->text() == ed.txtConfirmPassword->text() && password.size() >= 16) {
ed.lblPasswordMatch->setText("");
ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
} else {
ed.lblPasswordMatch->setText(tr("Passphrase don't match or You have entered too few letters (16 minimum)"));
ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
}
};
QObject::connect(ed.txtConfirmPassword, &QLineEdit::textChanged, fnPasswordEdited);
QObject::connect(ed.txtPassword, &QLineEdit::textChanged, fnPasswordEdited);
if (d.exec() == QDialog::Accepted)
{
QString str = ed.txtPassword->text(); // data comes from user inputs
int length = str.length();
this->setPassword(str);
char *sequence = NULL;
sequence = new char[length+1];
strncpy(sequence, str.toLocal8Bit(), length +1);
#define MESSAGE ((const unsigned char *) sequence)
#define MESSAGE_LEN length
unsigned char hash[crypto_secretstream_xchacha20poly1305_KEYBYTES];
crypto_hash_sha256(hash,MESSAGE, MESSAGE_LEN);
#define PASSWORD sequence
#define KEY_LEN crypto_box_SEEDBYTES
/////////we use the Hash of the Password as Salt, not perfect but still a good solution.
unsigned char key[KEY_LEN];
if (crypto_pwhash
(key, sizeof key, PASSWORD, strlen(PASSWORD), hash,
crypto_pwhash_OPSLIMIT_SENSITIVE, crypto_pwhash_MEMLIMIT_SENSITIVE,
crypto_pwhash_ALG_DEFAULT) != 0) {
/* out of memory */
}
auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
QString source_file = dir.filePath("addresslabels.dat");
QString target_enc_file = dir.filePath("addresslabels.dat.enc");
QString sourceWallet_file = dirwallet;
QString target_encWallet_file = dirwalletenc;
FileEncryption::encrypt(target_enc_file, source_file, key);
FileEncryption::encrypt(target_encWallet_file, sourceWallet_file, key);
QFile wallet(dirwallet);
QFile address(dir.filePath("addresslabels.dat"));
wallet.rename(dirwalletbackup);
address.rename(dir.filePath("addresslabels.datBackup"));
}
}
void MainWindow::removeWalletEncryption() {
QDialog d(this);
Ui_removeencryption ed;
ed.setupUi(&d);
auto fnPasswordEdited = [=](const QString&) {
QString password = ed.txtPassword->text();
// Enable the OK button if the passwords match.
if (!ed.txtPassword->text().isEmpty() &&
ed.txtPassword->text() == ed.txtConfirmPassword->text() && password.size() >= 16) {
ed.lblPasswordMatch->setText(""); ed.lblPasswordMatch->setText("");
ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
} else { } else {
ed.lblPasswordMatch->setText(tr("Passwords don't match")); ed.lblPasswordMatch->setText(tr("Passwords don't match"));
ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
} }
}; };
QObject::connect(ed.txtConfirmPassword, &QLineEdit::textChanged, fnPasswordEdited); QObject::connect(ed.txtConfirmPassword, &QLineEdit::textChanged, fnPasswordEdited);
QObject::connect(ed.txtPassword, &QLineEdit::textChanged, fnPasswordEdited); QObject::connect(ed.txtPassword, &QLineEdit::textChanged, fnPasswordEdited);
ed.txtPassword->setText(""); if (d.exec() == QDialog::Accepted)
ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); {
QString str = ed.txtPassword->text(); // data comes from user inputs
int length = str.length();
auto fnShowError = [=](QString title, const json& res) { char *sequence = NULL;
QMessageBox::critical(this, title, sequence = new char[length+1];
tr("Error was:\n") + QString::fromStdString(res.dump()), strncpy(sequence, str.toLocal8Bit(), length +1);
QMessageBox::Ok
);
};
if (d.exec() == QDialog::Accepted) { #define MESSAGE ((const unsigned char *) sequence)
rpc->encryptWallet(ed.txtPassword->text(), [=](json res) { #define MESSAGE_LEN length
if (isJsonResultSuccess(res)) {
// Save the wallet
rpc->saveWallet([=] (json reply) {
if (isJsonResultSuccess(reply)) {
QMessageBox::information(this, tr("Wallet Encrypted"),
tr("Your wallet was successfully encrypted! The password will be needed to send funds or export private keys."),
QMessageBox::Ok
);
} else {
fnShowError(tr("Wallet Encryption Failed"), reply);
}
});
// And then refresh the UI unsigned char hash[crypto_secretstream_xchacha20poly1305_KEYBYTES];
rpc->refresh(true);
} else { crypto_hash_sha256(hash,MESSAGE, MESSAGE_LEN);
fnShowError(tr("Wallet Encryption Failed"), res);
} #define PASSWORD sequence
}); #define KEY_LEN crypto_box_SEEDBYTES
}
/////////we use the Hash of the Password as Salt, not perfect but still a good solution.
unsigned char key[KEY_LEN];
if (crypto_pwhash
(key, sizeof key, PASSWORD, strlen(PASSWORD), hash,
crypto_pwhash_OPSLIMIT_SENSITIVE, crypto_pwhash_MEMLIMIT_SENSITIVE,
crypto_pwhash_ALG_DEFAULT) != 0) {
/* out of memory */
} }
void MainWindow::removeWalletEncryption() {
// Check if wallet is already encrypted
auto encStatus = rpc->getModel()->getEncryptionStatus(); auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
if (!encStatus.first) { auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
QMessageBox::information(this, tr("Wallet is not encrypted"), QString target_encwallet_file = dirwalletenc;
tr("Your wallet is not encrypted with a password."), QString target_decwallet_file = dirwallet;
QString target_encaddr_file = dir.filePath("addresslabels.dat.enc");
QString target_decaddr_file = dir.filePath("addresslabels.dat");
FileEncryption::decrypt(target_decwallet_file, target_encwallet_file, key);
FileEncryption::decrypt(target_decaddr_file, target_encaddr_file, key);
QFile filencrypted(dirwalletenc);
QFile wallet(dirwallet);
if (wallet.size() > 0)
{
QMessageBox::information(this, tr("Wallet decryption Success"),
QString("Successfully delete the encryption"),
QMessageBox::Ok QMessageBox::Ok
); );
return;
}
bool ok; filencrypted.remove();
QString password = QInputDialog::getText(this, tr("Wallet Password"),
tr("Please enter your wallet password"), QLineEdit::Password, "", &ok);
// If cancel was pressed, just return }else{
if (!ok) {
return;
}
if (password.isEmpty()) { qDebug()<<"verschlüsselung gescheitert ";
QMessageBox::critical(this, tr("Wallet Decryption Failed"),
tr("Please enter a password to decrypt your wallet!"),
QMessageBox::Ok
);
return;
}
rpc->removeWalletEncryption(password, [=] (json res) { QMessageBox::critical(this, tr("Wallet Encryption Failed"),
if (isJsonResultSuccess(res)) { QString("False password, please try again"),
// Save the wallet
rpc->saveWallet([=] (json reply) {
if(isJsonResultSuccess(reply)) {
QMessageBox::information(this, tr("Wallet Encryption Removed"),
tr("Your wallet was successfully decrypted! You will no longer need a password to send funds or export private keys."),
QMessageBox::Ok
);
} else {
QMessageBox::critical(this, tr("Wallet Decryption Failed"),
QString::fromStdString(reply["error"].get<json::string_t>()),
QMessageBox::Ok
);
}
});
// And then refresh the UI
rpc->refresh(true);
} else {
QMessageBox::critical(this, tr("Wallet Decryption Failed"),
QString::fromStdString(res["error"].get<json::string_t>()),
QMessageBox::Ok QMessageBox::Ok
); );
} this->removeWalletEncryption();
}); }
}
}
void MainWindow::removeWalletEncryptionStartUp() {
QDialog d(this);
Ui_startup ed;
ed.setupUi(&d);
// Handle edits on the password box
auto fnPasswordEdited = [=](const QString&) {
QString password = ed.txtPassword->text();
// Enable the OK button if the passwords match.
if (!ed.txtPassword->text().isEmpty() &&
ed.txtPassword->text() == ed.txtConfirmPassword->text() && password.size() >= 16) {
ed.lblPasswordMatch->setText("");
ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
} else {
ed.lblPasswordMatch->setText(tr("Passwords don't match or under-lettered"));
ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
}
};
QObject::connect(ed.txtConfirmPassword, &QLineEdit::textChanged, fnPasswordEdited);
QObject::connect(ed.txtPassword, &QLineEdit::textChanged, fnPasswordEdited);
if (d.exec() == QDialog::Accepted)
{
QString str = ed.txtPassword->text(); // data comes from user inputs
int length = str.length();
this->setPassword(str);
char *sequence = NULL;
sequence = new char[length+1];
strncpy(sequence, str.toLocal8Bit(), length +1);
#define MESSAGE ((const unsigned char *) sequence)
#define MESSAGE_LEN length
unsigned char hash[crypto_secretstream_xchacha20poly1305_KEYBYTES];
crypto_hash_sha256(hash,MESSAGE, MESSAGE_LEN);
#define PASSWORD sequence
#define KEY_LEN crypto_box_SEEDBYTES
/////////we use the Hash of the Password as Salt, not perfect but still a good solution.
unsigned char key[KEY_LEN];
if (crypto_pwhash
(key, sizeof key, PASSWORD, strlen(PASSWORD), hash,
crypto_pwhash_OPSLIMIT_SENSITIVE, crypto_pwhash_MEMLIMIT_SENSITIVE,
crypto_pwhash_ALG_DEFAULT) != 0) {
/* out of memory */
}
{
auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
QString target_encwallet_file = dirwalletenc;
QString target_decwallet_file = dirwallet;
QString target_encaddr_file = dir.filePath("addresslabels.dat.enc");
QString target_decaddr_file = dir.filePath("addresslabels.dat");
FileEncryption::decrypt(target_decwallet_file, target_encwallet_file, key);
FileEncryption::decrypt(target_decaddr_file, target_encaddr_file, key);
}
auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
QFile wallet(dirwallet);
//QFile backup(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.datBACKUP"));*/
if (wallet.size() > 0)
{
if (fileExists(dirwalletbackup))
{
QMessageBox::warning(this, tr("You have still Plaintextdata on your disk!"),
QString("WARNING: Delete it only if you have a backup of your Wallet Seed."),
QMessageBox::Ok
);
// backup.remove();
}
QMessageBox::information(this, tr("Wallet Encryption Success"),
QString("SDL is ready to Rock"),
QMessageBox::Ok
);
}else{
qDebug()<<"verschlüsselung gescheitert ";
QMessageBox::critical(this, tr("Wallet Encryption Failed"),
QString("false password please try again"),
QMessageBox::Ok
);
this->removeWalletEncryptionStartUp();
}
}else{
this->doClosePw();
}
}
QString MainWindow::getPassword()
{
return _password;
}
void MainWindow::setPassword(QString password)
{
_password = password;
} }
void MainWindow::setupStatusBar() { void MainWindow::setupStatusBar() {
@@ -923,6 +1208,7 @@ void MainWindow::setupTransactionsTab() {
ui->listChat->setMinimumSize(200,350); ui->listChat->setMinimumSize(200,350);
ui->listChat->setItemDelegate(new ListViewDelegate()); ui->listChat->setItemDelegate(new ListViewDelegate());
ui->listChat->show(); ui->listChat->show();
ui->transactionsTable->setContextMenuPolicy(Qt::CustomContextMenu); ui->transactionsTable->setContextMenuPolicy(Qt::CustomContextMenu);
// Table right click // Table right click
QObject::connect(ui->transactionsTable, &QTableView::customContextMenuRequested, [=] (QPoint pos) { QObject::connect(ui->transactionsTable, &QTableView::customContextMenuRequested, [=] (QPoint pos) {
@@ -1052,9 +1338,6 @@ void MainWindow::setupchatTab() {
ui->memoTxtChat->setTextColor("Black"); ui->memoTxtChat->setTextColor("Black");
} }
QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChat); QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChat);
QObject::connect(ui->safeContactRequest, &QPushButton::clicked, this, &MainWindow::addContact); QObject::connect(ui->safeContactRequest, &QPushButton::clicked, this, &MainWindow::addContact);
QObject::connect(ui->pushContact, &QPushButton::clicked, this , &MainWindow::renderContactRequest); QObject::connect(ui->pushContact, &QPushButton::clicked, this , &MainWindow::renderContactRequest);
@@ -1069,18 +1352,67 @@ void MainWindow::setupchatTab() {
for(auto &p : AddressBook::getInstance()->getAllAddressLabels()) for(auto &p : AddressBook::getInstance()->getAllAddressLabels())
if (label_contact == p.getName()) { if (label_contact == p.getName()) {
// ui->ContactZaddr->setText(p.getPartnerAddress());
// ui->MyZaddr->setText(p.getMyAddress());
ui->contactNameMemo->setText(p.getName()); ui->contactNameMemo->setText(p.getName());
ui->memoTxtChat->clear(); rpc->refresh(true);
rpc->refresh(true);
// updateChat();
} }
}); });
QMenu* contextMenu;
QAction* requestAction;
QAction* editAction;
QAction* HushAction;
QAction* requestHushAction;
QAction* subatomicAction;
contextMenu = new QMenu(ui->listContactWidget);
requestAction = new QAction("Send a contact request - coming soon",contextMenu);
editAction = new QAction("Delete this contact",contextMenu);
HushAction = new QAction("Send a friend some Hush - coming soon",contextMenu);
requestHushAction = new QAction("Request some Hush - coming soon",contextMenu);
subatomicAction = new QAction("Make a subatomic swap with a friend- coming soon",contextMenu);
ui->listContactWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
ui->listContactWidget->addAction(requestAction);
ui->listContactWidget->addAction(editAction);
ui->listContactWidget->addAction(HushAction);
ui->listContactWidget->addAction(requestHushAction);
ui->listContactWidget->addAction(subatomicAction);
QObject::connect(requestHushAction, &QAction::triggered, [=]() {
QModelIndex index = ui->listContactWidget->currentIndex();
QString label_contact = index.data(Qt::DisplayRole).toString();
ui->memoTxtChat->setLenDisplayLabel(ui->memoSizeChat); for(auto &p : AddressBook::getInstance()->getAllAddressLabels())
if (label_contact == p.getName()) {
ui->contactNameMemo->setText(p.getName());
rpc->refresh(true);
}
MainWindow::showRequesthush();
});
QObject::connect(editAction, &QAction::triggered, [=]() {
QModelIndex index = ui->listContactWidget->currentIndex();
QString label_contact = index.data(Qt::DisplayRole).toString();
for(auto &p : AddressBook::getInstance()->getAllAddressLabels())
if (label_contact == p.getName()) {
QString label1 = p.getName();
QString addr = p.getPartnerAddress();
QString myzaddr = p.getMyAddress();
QString cid = p.getCid();
QString avatar = p.getAvatar();
AddressBook::getInstance()->removeAddressLabel(label1, addr, myzaddr, cid,avatar);
rpc->refreshContacts(
ui->listContactWidget);
rpc->refresh(true);
}
});
ui->memoTxtChat->setLenDisplayLabelChat(ui->memoSizeChat);
} }
@@ -1089,13 +1421,11 @@ void MainWindow::updateChat()
{ {
rpc->refreshChat(ui->listChat,ui->memoSizeChat); rpc->refreshChat(ui->listChat,ui->memoSizeChat);
rpc->refresh(true); rpc->refresh(true);
} }
void MainWindow::updateContacts() void MainWindow::updateContacts()
{ {
//rpc->refreshContacts(ui->listContactWidget);
} }
void MainWindow::addNewZaddr(bool sapling) { void MainWindow::addNewZaddr(bool sapling) {

View File

@@ -51,6 +51,8 @@ public:
QString doSendChatTxValidations(Tx tx); QString doSendChatTxValidations(Tx tx);
QString doSendRequestTxValidations(Tx tx); QString doSendRequestTxValidations(Tx tx);
QString getCid(); QString getCid();
QString getPassword();
void setPassword(QString Password);
void replaceWormholeClient(WormholeClient* newClient); void replaceWormholeClient(WormholeClient* newClient);
bool isWebsocketListening(); bool isWebsocketListening();
@@ -58,8 +60,9 @@ public:
void stopWebsocket(); void stopWebsocket();
void saveContact(); void saveContact();
void saveandsendContact(); void saveandsendContact();
void setMaxLen(int len); void showRequesthush();
void updateDisplay(); // void setmaxlenChat(int len);
// void updateDisplay();
void balancesReady(); void balancesReady();
@@ -86,6 +89,7 @@ public:
Logger* logger; Logger* logger;
void doClose(); void doClose();
void doClosePw();
QString createHeaderMemo(QString type, QString cid, QString zaddr, int version, int headerNumber); QString createHeaderMemo(QString type, QString cid, QString zaddr, int version, int headerNumber);
public slots: public slots:
@@ -100,7 +104,9 @@ private slots:
private: private:
bool fileExists(QString path);
void closeEvent(QCloseEvent* event); void closeEvent(QCloseEvent* event);
void closeEventpw(QCloseEvent* event);
void setupSendTab(); void setupSendTab();
@@ -119,6 +125,7 @@ private:
void setupStatusBar(); void setupStatusBar();
void clearSendForm(); void clearSendForm();
QString _password;
Tx createTxFromSendPage(); Tx createTxFromSendPage();
bool confirmTx(Tx tx, RecurringPaymentInfo* rpi); bool confirmTx(Tx tx, RecurringPaymentInfo* rpi);
@@ -129,6 +136,7 @@ private:
void encryptWallet(); void encryptWallet();
void removeWalletEncryption(); void removeWalletEncryption();
void removeWalletEncryptionStartUp();
void cancelButton(); void cancelButton();
void sendButton(); void sendButton();
@@ -192,14 +200,14 @@ class ChatMemoEdit : public QTextEdit
public: public:
ChatMemoEdit(QWidget* parent); ChatMemoEdit(QWidget* parent);
void setMaxLen(int len); void setMaxLenChat(int len);
void setLenDisplayLabel(QLabel* label); void setLenDisplayLabelChat(QLabel* label);
void SetSendChatButton(QPushButton* button); void SetSendChatButton(QPushButton* button);
void updateDisplay(); void updateDisplayChat();
private: private:
int maxlen = 512; int maxlenchat = 512;
QLabel* lenDisplayLabel = nullptr; QLabel* lenDisplayLabelchat = nullptr;
QPushButton* sendChatButton = nullptr; QPushButton* sendChatButton = nullptr;
}; };

View File

@@ -1378,7 +1378,10 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="editTriggers"> <property name="editTriggers">
<set>QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked</set> <set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property> </property>
<property name="alternatingRowColors"> <property name="alternatingRowColors">
<bool>false</bool> <bool>false</bool>
@@ -1386,6 +1389,9 @@
<property name="selectionMode"> <property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum> <enum>QAbstractItemView::SingleSelection</enum>
</property> </property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectItems</enum>
</property>
</widget> </widget>
<widget class="QLabel" name="label_39"> <widget class="QLabel" name="label_39">
<property name="geometry"> <property name="geometry">
@@ -1419,10 +1425,16 @@
<set>QTextEdit::AutoNone</set> <set>QTextEdit::AutoNone</set>
</property> </property>
<property name="lineWrapMode"> <property name="lineWrapMode">
<enum>QTextEdit::FixedColumnWidth</enum> <enum>QTextEdit::FixedPixelWidth</enum>
</property> </property>
<property name="lineWrapColumnOrWidth"> <property name="lineWrapColumnOrWidth">
<number>80</number> <number>600</number>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::TextEditorInteraction</set>
</property> </property>
</widget> </widget>
<widget class="QLabel" name="contactNameMemo"> <widget class="QLabel" name="contactNameMemo">
@@ -1505,6 +1517,9 @@
<height>521</height> <height>521</height>
</rect> </rect>
</property> </property>
<property name="toolTip">
<string>The locks shows you the status of the message. Red lock = unconfirmed, green lock = min. 1 confirmations, orange lock = message is notarized</string>
</property>
<property name="verticalScrollBarPolicy"> <property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum> <enum>Qt::ScrollBarAsNeeded</enum>
</property> </property>
@@ -1515,7 +1530,7 @@
<enum>QAbstractScrollArea::AdjustToContents</enum> <enum>QAbstractScrollArea::AdjustToContents</enum>
</property> </property>
<property name="editTriggers"> <property name="editTriggers">
<set>QAbstractItemView::AllEditTriggers</set> <set>QAbstractItemView::NoEditTriggers</set>
</property> </property>
<property name="resizeMode"> <property name="resizeMode">
<enum>QListView::Adjust</enum> <enum>QListView::Adjust</enum>

View File

@@ -74,7 +74,7 @@
<customwidget> <customwidget>
<class>MemoEdit</class> <class>MemoEdit</class>
<extends>QPlainTextEdit</extends> <extends>QPlainTextEdit</extends>
<header>memoedit.h</header> <header location="global">memoedit.h</header>
</customwidget> </customwidget>
</customwidgets> </customwidgets>
<resources/> <resources/>

197
src/removeencryption.ui Normal file
View File

@@ -0,0 +1,197 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>removeencryption</class>
<widget class="QDialog" name="removeencryption">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Remove your Wallet encryption</string>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>50</x>
<y>260</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 class="QLabel" name="label">
<property name="geometry">
<rect>
<x>260</x>
<y>170</y>
<width>133</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;16 letters minimum&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>10</x>
<y>229</y>
<width>157</width>
<height>25</height>
</rect>
</property>
<property name="text">
<string>Confirm Passphrase:</string>
</property>
</widget>
<widget class="Line" name="line_2">
<property name="geometry">
<rect>
<x>10</x>
<y>164</y>
<width>382</width>
<height>3</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QLineEdit" name="txtConfirmPassword">
<property name="geometry">
<rect>
<x>173</x>
<y>229</y>
<width>219</width>
<height>25</height>
</rect>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>10</x>
<y>56</y>
<width>382</width>
<height>56</height>
</rect>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:14pt; color:#ef2929;&quot;&gt;WARNING:&lt;/span&gt; If yo remove your encryption, all your Data is Plaintext on your Disk!&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
<widget class="Line" name="line">
<property name="geometry">
<rect>
<x>10</x>
<y>260</y>
<width>382</width>
<height>3</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>10</x>
<y>198</y>
<width>157</width>
<height>25</height>
</rect>
</property>
<property name="text">
<string>Encryption Passphrase:</string>
</property>
</widget>
<widget class="QLabel" name="lblPasswordMatch">
<property name="geometry">
<rect>
<x>10</x>
<y>175</y>
<width>243</width>
<height>17</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">color: red;</string>
</property>
<property name="text">
<string>Passphrase don't match</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QLineEdit" name="txtPassword">
<property name="geometry">
<rect>
<x>173</x>
<y>198</y>
<width>219</width>
<height>25</height>
</rect>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>removeencryption</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>removeencryption</receiver>
<slot>close()</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>

View File

@@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>812</width> <width>850</width>
<height>495</height> <height>495</height>
</rect> </rect>
</property> </property>
@@ -27,7 +27,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="3" colspan="2"> <item row="0" column="2" colspan="3">
<widget class="QLabel" name="label_3"> <widget class="QLabel" name="label_3">
<property name="text"> <property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Memo of the request&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Memo of the request&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@@ -97,12 +97,12 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0" rowspan="6" colspan="2"> <item row="3" column="0" rowspan="8">
<widget class="QListView" name="requestContactOld"> <widget class="QListView" name="requestContactOld">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>256</width> <width>256</width>
<height>192</height> <height>190</height>
</size> </size>
</property> </property>
<property name="mouseTracking"> <property name="mouseTracking">
@@ -119,14 +119,21 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="2" colspan="2"> <item row="3" column="1" colspan="3">
<widget class="QLabel" name="label_4">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Details of the request&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="4" column="1" colspan="3">
<widget class="QLabel" name="label_8"> <widget class="QLabel" name="label_8">
<property name="text"> <property name="text">
<string>Request from :</string> <string>Request from :</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="4" colspan="3"> <item row="4" column="4" colspan="3">
<widget class="QLineEdit" name="requestZaddr"> <widget class="QLineEdit" name="requestZaddr">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
@@ -142,14 +149,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="2"> <item row="5" column="1" colspan="2">
<widget class="QLabel" name="label_7"> <widget class="QLabel" name="label_7">
<property name="text"> <property name="text">
<string>My Zaddr :</string> <string>My Zaddr :</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="4" colspan="3"> <item row="5" column="4" colspan="3">
<widget class="QLineEdit" name="requestMyAddr"> <widget class="QLineEdit" name="requestMyAddr">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
@@ -165,24 +172,24 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="2" colspan="2"> <item row="6" column="1" colspan="3">
<widget class="QLabel" name="label_5"> <widget class="QLabel" name="label_5">
<property name="text"> <property name="text">
<string>Give a Nickname:</string> <string>Give a Nickname:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="4" colspan="2"> <item row="6" column="4" colspan="2">
<widget class="QLineEdit" name="requestLabel"/> <widget class="QLineEdit" name="requestLabel"/>
</item> </item>
<item row="6" column="2" colspan="3"> <item row="7" column="1" colspan="4">
<widget class="QLabel" name="label_6"> <widget class="QLabel" name="label_6">
<property name="text"> <property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;right&quot;&gt;Choose a avatar for your contact :&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;right&quot;&gt;Choose a avatar for your contact :&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="2" colspan="2"> <item row="8" column="1" rowspan="2" colspan="3">
<widget class="QComboBox" name="comboBoxAvatar"> <widget class="QComboBox" name="comboBoxAvatar">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
@@ -328,7 +335,7 @@
</item> </item>
</widget> </widget>
</item> </item>
<item row="7" column="5" rowspan="2"> <item row="8" column="5" rowspan="2">
<widget class="QPushButton" name="cancel"> <widget class="QPushButton" name="cancel">
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
@@ -353,7 +360,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="6" rowspan="2"> <item row="8" column="6" rowspan="2">
<widget class="QPushButton" name="pushButton"> <widget class="QPushButton" name="pushButton">
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
@@ -369,17 +376,24 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="3" colspan="2"> <item row="10" column="1">
<widget class="QLabel" name="requestCID"> <widget class="QLabel" name="zaddrold">
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
<item row="10" column="3">
<widget class="QLabel" name="zaddrnew">
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="2" colspan="5"> <item row="10" column="2">
<widget class="QLabel" name="label_4"> <widget class="QLabel" name="requestCID">
<property name="text"> <property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Details of the request&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string/>
</property> </property>
</widget> </widget>
</item> </item>

View File

@@ -14,9 +14,124 @@
<string>Payment Request</string> <string>Payment Request</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="10" column="1">
<widget class="QLabel" name="label">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="lblAddress">
<property name="text">
<string>Request From</string>
</property>
</widget>
</item>
<item row="15" column="3">
<widget class="QLabel" name="lblAddressInfo">
<property name="text">
<string>The recipient will see this address in the &quot;to&quot; field when they pay your request.</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="12" column="1" colspan="3">
<widget class="MemoEdit" name="txtMemo">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="lblPixmap">
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="18" column="1" colspan="3"> <item row="18" column="1" colspan="3">
<widget class="AddressCombo" name="cmbMyAddress"/> <widget class="AddressCombo" name="cmbMyAddress"/>
</item> </item>
<item row="14" column="1">
<widget class="QLabel" name="label_4">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="5" column="1" colspan="3">
<widget class="QLabel" name="lblSaplingWarning">
<property name="styleSheet">
<string notr="true">color: red;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Memo</string>
</property>
</widget>
</item>
<item row="20" 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="11" column="3">
<widget class="QLabel" name="lblMemoLen">
<property name="text">
<string notr="true">0 / 512</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="13" column="1" colspan="3">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QLabel" name="txtAmountUSD">
<property name="text">
<string>Amount USD</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="21" column="0" colspan="4">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="3"> <item row="2" column="3">
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
@@ -41,65 +156,13 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="21" column="0" colspan="4"> <item row="0" column="2" colspan="2">
<widget class="Line" name="line"> <widget class="QLabel" name="lblHeader">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="lblAddress">
<property name="text"> <property name="text">
<string>Request From</string> <string>Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you.</string>
</property> </property>
</widget> <property name="wordWrap">
</item> <bool>true</bool>
<item row="15" column="1">
<widget class="QLabel" name="label_2">
<property name="text">
<string>My Address</string>
</property>
</widget>
</item>
<item row="5" column="1" colspan="3">
<widget class="QLabel" name="lblSaplingWarning">
<property name="styleSheet">
<string notr="true">color: red;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLabel" name="lblAmount">
<property name="text">
<string>Amount in </string>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QLabel" name="label">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="24" column="2" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="14" column="1">
<widget class="QLabel" name="label_4">
<property name="text">
<string/>
</property> </property>
</widget> </widget>
</item> </item>
@@ -119,20 +182,20 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1" colspan="3"> <item row="15" column="1">
<widget class="Line" name="line_3"> <widget class="QLabel" name="label_2">
<property name="orientation"> <property name="text">
<enum>Qt::Horizontal</enum> <string>My Address</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="12" column="1" colspan="3"> <item row="24" column="2" colspan="2">
<widget class="MemoEdit" name="txtMemo"> <widget class="QDialogButtonBox" name="buttonBox">
<property name="sizePolicy"> <property name="orientation">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred"> <enum>Qt::Horizontal</enum>
<horstretch>0</horstretch> </property>
<verstretch>0</verstretch> <property name="standardButtons">
</sizepolicy> <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property> </property>
</widget> </widget>
</item> </item>
@@ -146,83 +209,20 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="13" column="1" colspan="3"> <item row="6" column="1">
<widget class="Line" name="line_2"> <widget class="QLabel" name="lblAmount">
<property name="text">
<string>Amount in </string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="3">
<widget class="Line" name="line_3">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item row="15" column="3">
<widget class="QLabel" name="lblAddressInfo">
<property name="text">
<string>The recipient will see this address in the &quot;to&quot; field when they pay your request.</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="11" column="3">
<widget class="QLabel" name="lblMemoLen">
<property name="text">
<string notr="true">0 / 512</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QLabel" name="txtAmountUSD">
<property name="text">
<string>Amount USD</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="20" 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="11" column="1">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Memo</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="lblPixmap">
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="2" colspan="2">
<widget class="QLabel" name="lblHeader">
<property name="text">
<string>Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<customwidgets> <customwidgets>

View File

@@ -937,7 +937,7 @@ QString MainWindow::doSendTxValidations(Tx tx) {
auto available = rpc->getModel()->getAvailableBalance(); auto available = rpc->getModel()->getAvailableBalance();
if (available < total) { if (available < total) {
return tr("Not enough available funds to send this transaction\n\nHave: %1\nNeed: %2\n\nNote: Funds need 5 confirmations before they can be spent") 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()); .arg(available.toDecimalhushString(), total.toDecimalhushString());
} }

184
src/startupencryption.ui Normal file
View File

@@ -0,0 +1,184 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>startup</class>
<widget class="QDialog" name="startup">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>SDL Startup Decryption</string>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>50</x>
<y>260</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 class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>10</x>
<y>229</y>
<width>127</width>
<height>25</height>
</rect>
</property>
<property name="text">
<string>Confirm Password:</string>
</property>
</widget>
<widget class="Line" name="line_2">
<property name="geometry">
<rect>
<x>10</x>
<y>166</y>
<width>382</width>
<height>3</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QLineEdit" name="txtConfirmPassword">
<property name="geometry">
<rect>
<x>162</x>
<y>229</y>
<width>230</width>
<height>25</height>
</rect>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>10</x>
<y>58</y>
<width>382</width>
<height>56</height>
</rect>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If you have forgotten your password, restore your wallet with your seed!&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
<widget class="Line" name="line">
<property name="geometry">
<rect>
<x>10</x>
<y>260</y>
<width>382</width>
<height>3</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>10</x>
<y>198</y>
<width>146</width>
<height>25</height>
</rect>
</property>
<property name="text">
<string>Encryption Password:</string>
</property>
</widget>
<widget class="QLabel" name="lblPasswordMatch">
<property name="geometry">
<rect>
<x>10</x>
<y>175</y>
<width>382</width>
<height>17</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">color: red;</string>
</property>
<property name="text">
<string>Passwords don't match</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QLineEdit" name="txtPassword">
<property name="geometry">
<rect>
<x>162</x>
<y>198</y>
<width>230</width>
<height>25</height>
</rect>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>startup</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>startup</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>