diff --git a/.gdb_history b/.gdb_history index 4e303b8..06f6849 100644 --- a/.gdb_history +++ b/.gdb_history @@ -48,3 +48,9 @@ b FileSystem::writeContacts r n q +r +b FileEncryption::encrypt +r +s +n +q diff --git a/README.md b/README.md index a36f828..31d4041 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ SilentDragonLite does automatic note and utxo management, which means it doesn't ## Compiling from source * 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). -* You'll need Rust v1.37 + +* You'll need Rust v1.41 + ## Building on Linux diff --git a/application.qrc b/application.qrc index bf9a3b9..bb3c02c 100644 --- a/application.qrc +++ b/application.qrc @@ -33,12 +33,9 @@ res/add_contact.png res/notification.png res/rahmen-message.png - res/upload.png - res/upload.svg res/message-icon.svg - res/lock.svg - res/lock.png res/lock_green.png + res/lock_orange.png res/unlocked.png res/getAddrWhite.png res/send-white.png @@ -48,6 +45,8 @@ res/sendBlack.png res/requestBlack.png res/addContactBlack.png + res/unknownBlack.png + res/unknownWhite.png @@ -65,6 +64,7 @@ res/silentdragonlite_it.qm res/silentdragonlite_hr.qm res/silentdragonlite_fa.qm + res/silentdragonlite_id.qm res/css/blue.css diff --git a/lib/Cargo.lock b/lib/Cargo.lock index 07f7981..e0ea0c9 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -1177,7 +1177,7 @@ version = "0.1.0" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=fb07cae93c706cce929beef98690109e5f2d7592)", + "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=d196ad938a22810c0b6b4164e6bf8f1db0409763)", ] [[package]] @@ -1640,7 +1640,7 @@ dependencies = [ [[package]] name = "silentdragonlitelib" 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 = [ "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)", @@ -2631,7 +2631,7 @@ dependencies = [ "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" "checksum sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" "checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" -"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=fb07cae93c706cce929beef98690109e5f2d7592)" = "" +"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=d196ad938a22810c0b6b4164e6bf8f1db0409763)" = "" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 1d49baf..dba0c30 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -11,4 +11,4 @@ crate-type = ["staticlib"] [dependencies] libc = "0.2.58" lazy_static = "1.4.0" -silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "fb07cae93c706cce929beef98690109e5f2d7592" } +silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "d196ad938a22810c0b6b4164e6bf8f1db0409763" } diff --git a/peda-session-SilentDragonLite.txt b/peda-session-SilentDragonLite.txt index f57fa7c..6f620bf 100644 --- a/peda-session-SilentDragonLite.txt +++ b/peda-session-SilentDragonLite.txt @@ -1,2 +1,2 @@ -break FileSystem::writeContacts +break FileEncryption::encrypt diff --git a/res/getAddrBlack.png b/res/getAddrBlack.png index 2ede956..d90c9a5 100644 Binary files a/res/getAddrBlack.png and b/res/getAddrBlack.png differ diff --git a/res/getAddrWhite.png b/res/getAddrWhite.png index 6caeeae..28b30fb 100644 Binary files a/res/getAddrWhite.png and b/res/getAddrWhite.png differ diff --git a/res/lock_orange.png b/res/lock_orange.png new file mode 100644 index 0000000..11a5c55 Binary files /dev/null and b/res/lock_orange.png differ diff --git a/res/silentdragonlite_id.qm b/res/silentdragonlite_id.qm new file mode 100644 index 0000000..a4a9338 Binary files /dev/null and b/res/silentdragonlite_id.qm differ diff --git a/res/silentdragonlite_id.ts b/res/silentdragonlite_id.ts new file mode 100644 index 0000000..54163a4 --- /dev/null +++ b/res/silentdragonlite_id.ts @@ -0,0 +1,2002 @@ + + + + + AddressBookModel + + + Label + Label + + + + Address + Alamat + + + + BalancesTableModel + + + Address + Alamat + + + + Amount + Jumlah + + + + ConnectionDialog + + + SilentDragonLite + SilentDragonLite + + + + Starting Up + Memulai + + + + Controller + + + Wallet Password + Password Alamat + + + + Your wallet is encrypted. +Please enter your wallet password + Wallet Anda terkunci. Mohon masukkan Password Alamat Anda + + + + + Wallet Decryption Failed + Gagal Mengdeskripsi Dompet + + + + Please enter a valid password + Mohon Masukkan Password yang benar + + + + Failed to unlock wallet + Gagal Membuka Dompet + + + + CreateWalletForm + + + Form + Form + + + + Restore wallet from seed + Mengembalikan Dompet menggunakan Seed + + + + Restore an existing wallet, using the 24-word seed. + Mengembalikan Dompet menggunakan 24 Kata Seed + + + + Create a new Wallet + Membuat Dompet Baru + + + + Create a new wallet with a randomly generated seed. + Membuat Dompet baru dengan Seed acak + + + + MainWindow + + + SilentDragonLite + SilentDragonLite + + + + Balance + Balance + + + + Summary + Ringkasan + + + + Shielded + Shielded + + + + Notarized + Notarized + + + + Transparent + Transparan + + + + Total + Total + + + + Your node is still syncing, balances may not be updated. + Node anda masih Menyinkronisasi, balance mungkin tidak di perbarui + + + + Some transactions are not yet confirmed. Balances may change. + Beberapa transaksi belum di konfirmasi. Balance bisa berubah + + + + Address Balances + Alamat balance + + + + + Send + Kirim + + + + Total notarized funds available: + Total Biaya yang tersedia + + + + Send To + Kirim ke + + + + Recipient + Penerima + + + + + + + + Address + Alamat + + + + + Address Book + Buku Alamat + + + + + + + Amount + Jumlah + + + + Max Available + Tersedia Maksimal + + + + + + + Memo + Memo + + + + Add Recipient + Tambah Penerima + + + + Recurring payment + Pembayaran Berulang + + + + Every month, starting 12-May-2012, for 6 payments + Setiap Bulan, Mulai 12-Mei-2012, untuk 6 Pembayaran + + + + Edit Schedule + Sunting Jadwal + + + + + Miner Fee + Bayaran Penambang + + + + 0 + 0 + + + + Cancel + Batalkan + + + + Receive + Terima + + + + Address Type + Jenis Alamat + + + + z-Addr + z-Addr + + + + t-Addr + t-Addr + + + + Next Address + Alamat Berikutnya + + + + Information about Hush + Informasi Tentang Hush + + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Blockchain Information</span></p></body></html> + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Blockchain Information</span></p></body></html> + + + + + + + + + + + + + + + <html><head/><body><p align="center">|</p></body></html> + <html><head/><body><p align="center">|</p></body></html> + + + + Next Halving + Halving Berikutnya + + + + Difficulty + Difficulty + + + + Last Notarized Block + Notarized Block Terakhir kali + + + + Total Supply + Total Suplai + + + + Longestchain + Longestchain + + + + BlockHeight + BlockHeight + + + + Supply zAddr + zAddr Suplai + + + + Supply tAddr + tAddr Suplai + + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Market Information</span></p></body></html> + + + + + Market Cap + Kapitalisasi Pasar + + + + Volume on Exchanges + Volume di Pasar + + + + <html><head/><body><p align="center">This is a Lightwallet, you cant mine with it!</p></body></html> + <html><head/><body><p align="center">This is a Lightwallet, you cant mine with it!</p></body></html> + + + + View All Addresses + Lihat semua Alamat + + + + Label + Label + + + + Update Label + Perbarui Label + + + + Address balance + Alamat balance + + + + Optional + Pilihan + + + + + Export Private Key + Mengekspor Private Key + + + + Your node is still syncing, balances may not be updated + Node anda masih Menyinkron, Balance mungkin tidak di perbarui + + + + Transactions + Transaksi + + + + + + + + + + + + + + + Loading... + Memuat... + + + + Version hushlightd + Version hushlightd + + + + Vendor + Vendor + + + + &File + &File + + + + &Help + &Help + + + + &Apps + &Apps + + + + &Edit + &Edit + + + + E&xit + E&xit + + + + &About + &About + + + + &Settings + &Settings + + + + Ctrl+P + Ctrl+P + + + + &Send DenioD Feedback + &Send DenioD Feedback + + + + &Hush Discord + &Hush Discord + + + + &Hush Website + &Hush Website + + + + Check github.com for &updates + Lihat github.com for &updates + + + + &Export all private keys + &Export semua Private Keys + + + + Address &book + Alamat &book + + + + Ctrl+B + Ctrl+B + + + + &Export seed phrase + &Export Kata Seed + + + + + Export transactions + Ekspor Transaksi + + + + Pay hush &URI... + Pay hush &URI... + + + + Connect mobile &app + Sambung ke Mobile &app + + + + Ctrl+M + Ctrl+M + + + + &Recurring Payments + &Recurring Payments + + + + Request hush... + Meminta Hush + + + + File a bug... + File-nya Bug + + + + Encrypt Wallet + Enkripsi Dompet + + + + Remove Wallet Encryption + Menghilangkan Enkripsi Dompet + + + + Rescan + Re-scan + + + + Wallet is already encrypted + Domper sudah di Enkripsi + + + + Your wallet is already encrypted with a password. +Please use 'Remove Wallet Encryption' if you want to remove the wallet encryption. + Dompet anda sudah di Enkripsi menggunakan Password. +Mohon Gunakan 'Hapus Enkripsi Dompet' Jika anda ingin menghapus Enkripsi Dompet Anda + + + + Passwords don't match + Passwords don't match + + + + Error was: + + Error: + + + + Wallet Encrypted + Dompet ter-Enkripsi + + + + Your wallet was successfully encrypted! The password will be needed to send funds or export private keys. + Dompet berhasil di Enkripsi! Password akan dibutuhkan untuk mengirim dana atau mengeskpor Private Keys + + + + + Wallet Encryption Failed + Enkripsi Dompet Gagal + + + + Wallet is not encrypted + Dompet tidak di Enkripsi + + + + Your wallet is not encrypted with a password. + Dompet anda tidak di Enkripsi dengan Password + + + + Wallet Password + Password Dompet + + + + Please enter your wallet password + Mohon masukkan Password Dompet Anda + + + + + + Wallet Decryption Failed + Deskripsi Dompet Gagal + + + + Please enter a password to decrypt your wallet! + Mohon masukkan Password anda untuk mengdekripsi Dompet ! + + + + Wallet Encryption Removed + Enrkipsi Dompet di Hapus + + + + Your wallet was successfully decrypted! You will no longer need a password to send funds or export private keys. + Dompet anda berhasil di Dekripsi! Anda tidak perlu lagi Password untuk mengirim Dana atau Mengekspor Private Keys + + + + + Copy txid + Copy txid + + + + + Copy block explorer link + Copy Link block explorer + + + + View tx on block explorer + Lihat TX di Block Explorer + + + + Refresh + Segarkan + + + + Restart + Mengulang + + + + Please restart Silentdragonlite to have the theme apply + Mohon Restart Silentdragonlite untuk menampilkan Tema yang di pilih + + + + Currency Change + Ubah Mata Uang + + + + Some feedback about SilentDragonlite or Hush... + Beberapa feedback tentang SilentDragonlite atau Hush + + + + This change can take a few seconds. + Perubahan ini bisa membutuhkan beberapa detik + + + + or SilentDragonLite + atau SilentDragonLite + + + + Send DenioD some private and shielded feedback about + Kirim DenioD beberapa feedback tentang Privasi dan Shielded + + + + Paste HUSH URI + Paste HUSH URI + + + + Error paying HUSH URI + Error membayar HUSH URI + + + + URI should be of the form 'hush:<addr>?amt=x&memo=y + URI harus berada di Form 'hush:<addr>?amt=x&memo=y + + + + Error + Error + + + + Error exporting transactions, file was not saved + Error mengeskpor transaksi, File mungkin tidak disimpan + + + + This is your wallet seed. Please back it up carefully and safely. + Ini adalah Dompet seed anda. Mohon di back up dengan hati hati dan aman + + + + + Save File + Simpan file + + + + + Unable to open file + Tidak bisa membuka File + + + + Error getting private keys + Error mendapatkan Private Keys + + + + Error loading private keys: + Error memuat Private Keys + + + + These are all the private keys for all the addresses in your wallet + Ini adalah semua private keys untuk semua alamat di dompet Anda + + + + Private key for + Private key untuk + + + + + Copy address + Copy Alamat + + + + + + Copied to clipboard + Ter copy di Clipboard + + + + Get private key + Dapatkan Private Key + + + + + View on block explorer + Lihat di block explorer + + + + View Payment Request + Lihat Permintaan bayaran + + + + View Memo + Lihat memo + + + + Reply to + Balas ke + + + + Created new t-Addr + Membuat t-Addr baru + + + + Copy Address + Copy Alamat + + + + Address has been previously used + Alamat sebelumnya sudah digunakan + + + + Address is unused + Alamat belum digunakan + + + + Cannot support multiple addresses + Tidak mendukung Alamat Ganda + + + + Recurring payments doesn't currently support multiple addresses + Pembayaran Berulang doesn't Belum mendukung Alamat Ganda + + + + Recipient + Penerima + + + + Only z-addresses can have memos + Hanya z-Addresess yang mempunya memos + + + + Memos can only be used with z-addresses + Memo hanya bisa di gunakan untuk z-Addresses + + + + The memo field can only be used with a z-address. + + Memo hanya bisa digunakan untuk z-Address + + + + +doesn't look like a z-address + doesn't kelihatannya bukan z-Address + + + + Transaction Error + Transaksi Error + + + + Please wait... + Mohon tunggu... + + + + Computing your transaction + Mengkomputasi transaksi Anda + + + + Done! + Selesai! + + + + Recipient Address + Alamat Penerima + + + + is Invalid + Tidak valid + + + + Amount for address '%1' is invalid! + Jumlah untuk alamat '%1' Tidak valid! + + + + Not enough available funds to send this transaction + +Have: %1 +Need: %2 + +Note: Funds need 5 confirmations before they can be spent + Tidak memiliki dana yang cukup untuk melakukan transaksi ini +Memiliki: %1 +Membutuhkan: %2 + +Note: Dana membutuhkan 5 konfirmasi sebelum mereka bisa digunakan + + + + MemoDialog + + + + Memo + Memo + + + + Include Reply Address + Masukkan Alamat Balasan + + + + MemoEdit + + + Reply to + Balas ke + + + + MigrationDialog + + + Migration Turnstile + Migrasi Turnstile + + + + Migration History + Sejarah Migrasi + + + + Migrated Amount + Jumlah yang di migrasi + + + + Unmigrated Amount + Jumlah yang tidak di migrasi + + + + Sprout -> Sapling migration enabled + Sprout -> Sapling migration diaktifkan + + + + If enabled, hushd will slowly migrate your Sprout shielded funds to your Sapling address. + Jika di aktifkan, Hushd bisa perlahan memigrasikan dana Sprout yang terlindungi Anda ke Sapling Adress. + + + + MobileAppConnector + + + Connect Mobile App + Sambung ke Aplikasi Mobile + + + + Scan this QRCode from your silentdragon companion app to connect your phone + Scan QRCode dari Silentdragon kompani anda untuk menyambung ke Hp + + + + QR Code + Kode QR + + + + Connection String + String Koneksi + + + + Allow connections over the internet via silentdragon wormhole + Memperbolehkan Koneksi ke Internet menggunakan Silentdragon Wormhole + + + + silentdragon Companion App + Silentdragon Aplikasi Kompani + + + + Disconnect + Disconnect + + + + + TextLabel + Label Teks + + + + Last seen: + Terakhir Kali dilihat + + + + Connection type: + Tipe koneksi + + + + NewSeedForm + + + Form + Form + + + + This is your new wallet's seed phrase. PLEASE BACK IT UP SECURELY. + Ini adalah Dompet baru Anda's seed phrase. MOHON DI BACK UP SECARA AMAN + + + + The seed phrase is the only way to restore the wallet. If you forget the seed phrase, THERE IS NO WAY TO RESTORE YOUR WALLET AND THE FUNDS in it + Seed Phrase adalah salah satu jalan untuk mengembalikan dompet. Jika anda melupakan Seec phrase, TIDAK ADA CARA UNTUK MENGEMBALIKAN DOMPET DAN DANA di dalamnya + + + + NewSeedPage + + + Error creating a wallet + Error membuat dompet + + + + Failed to save wallet + Gagal menyimpan Dompet + + + + Couldn't save the wallet + Couldn't save the wallet + + + + PrivKey + + + Private Keys + Private Keys + + + + QObject + + + Pick + Pilih + + + + Address or Label Error + Alamat atau Label Error + + + + Address or Label cannot be empty + Alamat atau Label tidak bisa kosong + + + + Address Format Error + Format Alamat Error + + + + %1 doesn't seem to be a valid hush address. + %1 doesn't kelihatannya bukan Alamat HUSH yang valid + + + + Label Error + Label error + + + + The label '%1' already exists. Please remove the existing label. + Label nya '%1' sudah ada. Mohon hapus label yang sudah digunakan + + + + Import Address Book + Impor Buku Alamat + + + + Unable to open file + Tidak bisa membuka file + + + + Address Book Import Done + Buku Alamat selesai di Impor + + + + Imported %1 new Address book entries + Ter-Impor%1 Buku Alamat Baru + + + + Copy address + Copy Alamat + + + + Copied to clipboard + Ter-copy ke Clipboard + + + + Delete label + Delet Label + + + + Attempting to initialize library with + Mencoba untuk menginilisiasi Library dengan + + + + Using existing wallet. + Menggunakan Dompet yang sudah ada + + + + Create/restore wallet. + Buat/mengembalikan Dompet + + + + + Connection Error + Koneksi error + + + + + + Transaction Error + Transaksi Error + + + + There was an error sending the transaction. The error was: + Ada error dalam mengirim transaksi. Error nya: + + + + + No Connection + Tidak ada Koneksi + + + + There was an error connecting to hushd. The error was + Ada error dalam mengkoneksikan ke Hushd. Error nya: + + + + + + Tx + Tx + + + + + + failed + Gagal + + + + + The transaction with id + Transaksi dengan ID + + + + + failed. The error was + Gagal. Error nya: + + + + Update Available + Pembaruan tersedia + + + + A new release v%1 is available! You have v%2. + +Would you like to visit the releases page? + Rilis Pembaruan v%1 telah tersedia! Versi Anda Sekarang v%2. + +Maukah anda mengunjungi laman pembaruan ini + + + + No updates available + Tidak ada Pembaruan tersedia + + + + You already have the latest release v%1 + Anda sudah memiliki Versi terbaru dari v%1 + + + + Please wait for SilentDragonLite to exit + Mohon tunggu untuk SilentDragonLite untuk keluar + + + + Waiting for hushd to exit + Menunggu untuk hushd untuk keluar + + + + No hush price was available to convert from USD + Tidak ada harga hush yang tersedia untuk di konversikan ke USD + + + + View on block explorer + Lihat di block explorer + + + + View Error + Lihat error + + + + Reported Error + Error yang di laporkan + + + + + Are you sure you want to delete the recurring payment? + Apakah Anda yakin untuk menghapus Pembayaran berulang? + + + + All future payments will be cancelled. + Semua Pembayaran nantinya akan di batalkan + + + + Tx submitted (right click to copy) txid: + Tx di berikan (pencet kanan untuk copy) txid: + + + + Type + Tipe + + + + Address + Alamat + + + + Date/Time + Tanggal/Waktu + + + + Confirmations + Konfirmasi + + + + Amount + Jumlah + + + + Connected directly + Terkoneksi langsung + + + + Connected over the internet via silentdragon wormhole service + Terkoneksi langsung ke Internet via Silentdragon wormhole service + + + + + Node is still syncing. + Node masih menyinkron + + + + + No sapling or transparent addresses with enough balance to spend. + Tidak ada sapling atau transparan address dengan balance yang cukup untuk digunakan + + + + RecurringDialog + + + Dialog + Dialog + + + + View + Lihat + + + + Delete + Delet + + + + RecurringListViewModel + + + Amount + Jumlah + + + + Schedule + Jadwal + + + + Payments Left + Pembayaran tersisa + + + + Next Payment + Pembayaran Selanjutnya + + + + To + Kepada + + + + Every + Setiap + + + + None + None + + + + RecurringPayments + + + Payments + Pembayaran + + + + RecurringPaymentsListViewModel + + + Date + Tanggal + + + + Status + Status + + + + Txid + Txid + + + + Not due yet + Belum Jatuh Tempo + + + + Pending + Pending + + + + Skipped + Dilewati + + + + Paid + Ter-bayar + + + + Error + Error + + + + + Unknown + Tidak diketahui + + + + RecurringPending + + + Dialog + Dialog + + + + No payments will be processed. You can manually pay them from the Recurring Payments Dialog box + Tidak ada transaksi yang akan di proses. Anda bisa secara manual membayar mereka dari Pembayaran Berulang Kotak Dialog + + + + Schedule + Jadwal + + + + How should silentdragon proceed? + Bagaimana Silentdragon harus diproses? + + + + Pay All in 1 Tx + Bayar semua dengan 1 Tx + + + + Only the latest pending payment will be processed. All previous pending payments will be skipped + Hanya Pembayaran pending terakhir kali yang akan di proses. Semua Pembayaran pending yang dulu akan di lewati + + + + Pay Latest Only + Bayar terakhir kali saja + + + + Pay None + Tidak membayar + + + + All pending payments collected, added up and paid in a single transaction + Semua pembayaran pending di kumpulkan, Di tambahkan dan di Bayar dalam satu transaksi + + + + Description + Dekripsi + + + + To + Kepada + + + + The following recurring payment has multiple payments pending + Pembayaran Berulang yang ini mempunyai pembayaran ganda yang pending + + + + RequestDialog + + + Payment Request + Permintaan bayaran + + + + AddressBook + Buku Alamat + + + + Request From + Meminta dari + + + + My Address + Alamat saya + + + + Amount in + Dalam Jumlah + + + + z address + Alamat z + + + + Amount + Jumlah + + + + The recipient will see this address in the "to" field when they pay your request. + Penerima akan melihat alamat di "to" laha saat mereka membayar permintaan anda + + + + Amount USD + Jumlah USD + + + + Memo + Memo + + + + TextLabel + Label Teks + + + + 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. + Permintaan Pembayaran dari Alamat Sapling. Anda'akan mengirim sebuah 0.0001 hush untuk transaksi kepada alamat menggunakan hush payment URI. Memo nya akan di masukkan ke dalam transaksi apabila alamat tersebut membayar anda + + + + Error paying hush URI + Error membayar hush URI + + + + URI should be of the form 'hush:<addr>?amt=x&memo=y + URI seharusnya berdasarkan form 'hush:<addr>?amt=x&memo=y + + + + Pay To + Bayar Ke + + + + Pay + Bayar + + + + You are paying a payment request. Your address will not be visible to the person requesting this payment. + Anda membayar sebua permintaan pembayaran. Alamat anda tidak akan terlihat kepada orang yang melakukan permintaan ini + + + + Can only request from Sapling addresses + Hanya bisa di minta dari Alamat Sapling + + + + RestoreSeedForm + + + Form + Form + + + + Please enter your 24-word seed below + Mohon masukkan 24-word seed anda berikut + + + + Wallet Seed + Dompet seed + + + + Wallet Birthday + Ulang tahun Dompet + + + + 0 + 0 + + + + Wallet birthday is the block height at which the wallet had the first transaction. If you don't know this, you can leave it as "0" (It'll take longer to rescan) + Ulang Tahun Dompet adalah block height dimana dompet itu melakukan transaksi pertamanya. Jika anda don't tidak tahu ini, Anda bisa tinggalkan ini seperti "0" (It'ini akan memakan beberpa waktu untuk rescan) + + + + RestoreSeedPage + + + + Failed to restore wallet + Gagal untuk mengembalikan Dompet + + + + SilentDragonLite needs 24 words to restore wallet + SilentDragonLite membutuhkan 24 kata untuk mengembalikan dompet + + + + Failed to parse wallet birthday + Gagal menguraikan Ulang tahun dompet + + + + Couldn't understand wallet birthday. This should be a block height from where to rescan the wallet. You can leave it as '0' if you don't know what it should be. + Tidak'mengerti Ulang tahun Dompet. Ini seharusnya merupakan Block Height dimana dompet anda untuk rescan. Anda bisa tinggalkan sebagai '0'Jika anda'tidak tahu apa yang seharusnya terjadi. + + + + Couldn't restore the wallet + Tidak'bisa mengembalikan dompett + + + + Failed to save wallet + Gagal menyimpan dompet + + + + Couldn't save the wallet + Tidak'bisa menyimpan dompet + + + + Settings + + + Settings + Konfigurasi + + + + Connection + Koneksi + + + + Lightwallet Server + Server Lightwallet + + + + Options + Options + + + + default + default + + + + blue + biru + + + + light + terang + + + + dark + Gelap + + + + Fetch hush prices + Menangkap harga hush + + + + Check github for updates at startup + Periksa github untuk pembaruan dan permulaan + + + + Connect to github on startup to check for updates + Sambung ke github untuk permulaan untuk memeriksa pembaruan + + + + Theme + Tema + + + + Connect to the internet to fetch hush prices + Sambung ke internet untuk mengambil harga hush + + + + Currency + Mata uang + + + + AUD + AUD + + + + BTC + BTC + + + + CAD + CAD + + + + CHF + CHF + + + + CNY + CNY + + + + EUR + EUR + + + + GBP + GBP + + + + INR + INR + + + + RUB + RUB + + + + USD + USD + + + + ViewAddressesDialog + + + All Addresses + Semua Alamat + + + + Export All Keys + Mengekspor semua Keys + + + + ViewAllAddressesModel + + + Address + Alamat + + + + Balance (%1) + Balance (%1) + + + + about + + + About + Tentang + + + + addressBook + + + Address Book + Buku Alamat + + + + Add New Address + Tambah Alamat Baru + + + + Address (z-Addr or t-Addr) + Alamat (z-Addr or t-Addr) + + + + Label + Label + + + + Add to Address Book + Tambahkan ke Buku Alamat + + + + Import Address Book + Impor Buku Alamat + + + + confirm + + + Confirm Transaction + Konfirmasi Transaksi + + + + To + Kepada + + + + Recurring Payment + Pembayaran berulang + + + + TextLabel + Label Teks + + + + You are sending a transaction while your node is still syncing. This may not work. + Anda sedang mengirim transaksi saat node anda masih menyinkronisasi. Ini tidak akan bekerja + + + + createhushConf + + + Configure hush.conf + configure hush.conf + + + + Your hush node will be configured for you automatically + Node Hush Andan akan di konfigurasikan untuk Anda secara otomatis + + + + Show Advanced Configuration + Tampilkan Konfigurasi tambahan + + + + Allow connections to the internet to check for updates, get hush prices etc... + Perbolehkan koneksi ke internet untuk memerika pembaruan, mendapatkan harga hush dll + + + + Use custom datadir + Gunakan custom datadir + + + + Choose directory + Pilih direktori + + + + Please note that you'll need to already have a Tor service configured on port 9050 + Mohon ketahui bahwa Anda'akan membutuhkan Tor service di konfigurasikan di port 9050 + + + + Connect to the internet for updates and price feeds + Sambungkan ke Internet untuk pembaruan dan berita harga + + + + Please choose a directory to store your wallet.dat and blockchain + Mohon pilih direktori untuk menyimpan wallet.dat anda dan blockchain + + + + Connect over Tor + Sambung menggunakan Tor + + + + encryptionDialog + + + Encrypt Your Wallet + Enkripsi Dompet anda + + + + Encryption Password: + Enkripsi Password + + + + Confirm Password: + Konfirmasi Passowrd + + + + Passwords don't match + Passwords tidak'tepat + + + + WARNING: If you forget your password, the only way to recover the wallet is from the seed phrase. + PERINGATAN: Jika anda lupa password anda, salah satu cara untuk mengembalikan dompet adalah dari Seed phrase + + + + newRecurringDialog + + + Edit Schedule + Sunting Jadwal + + + + Payment Description + Deskripsi Pembayaran + + + + Schedule + Jadwal + + + + Next Payment + Pembayaran selanjutnya + + + + Amount + Jumlah + + + + Memo + Memo + + + + To + Kepada + + + + From + Dari + + + + Number of payments + Angka Pembayaran + + + \ No newline at end of file diff --git a/res/unknownBlack.png b/res/unknownBlack.png new file mode 100644 index 0000000..faf65e0 Binary files /dev/null and b/res/unknownBlack.png differ diff --git a/res/unknownWhite.png b/res/unknownWhite.png new file mode 100644 index 0000000..7853e1e Binary files /dev/null and b/res/unknownWhite.png differ diff --git a/res/unkownBlack.png b/res/unkownBlack.png new file mode 100644 index 0000000..faf65e0 Binary files /dev/null and b/res/unkownBlack.png differ diff --git a/res/unlocked.svg b/res/unlocked.svg deleted file mode 100644 index 50ff5e1..0000000 --- a/res/unlocked.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - Svg Vector Icons : http://www.onlinewebfonts.com/icon - - diff --git a/res/upload.png b/res/upload.png deleted file mode 100644 index b6f3c1f..0000000 Binary files a/res/upload.png and /dev/null differ diff --git a/res/upload.svg b/res/upload.svg deleted file mode 100644 index 9f31b60..0000000 --- a/res/upload.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - diff --git a/silentdragon-lite.pro b/silentdragon-lite.pro index 86f38b0..90b261b 100644 --- a/silentdragon-lite.pro +++ b/silentdragon-lite.pro @@ -83,7 +83,8 @@ SOURCES += \ src/Chat/Helper/ChatIDGenerator.cpp \ src/Chat/Chat.cpp \ src/FileSystem/FileSystem.cpp \ - src/Crypto/FileEncryption.cpp + src/Crypto/FileEncryption.cpp \ + src/Crypto/passwd.cpp HEADERS += \ src/firsttimewizard.h \ @@ -121,6 +122,7 @@ HEADERS += \ FORMS += \ src/contactrequest.ui \ src/encryption.ui \ + src/hushrequest.ui \ src/mainwindow.ui \ src/migration.ui \ src/newseed.ui \ @@ -132,6 +134,7 @@ FORMS += \ src/confirm.ui \ src/privkey.ui \ src/memodialog.ui \ + src/startupencryption.ui \ src/viewalladdresses.ui \ src/connection.ui \ src/addressbook.ui \ @@ -141,6 +144,7 @@ FORMS += \ src/requestContactDialog.ui \ src/newrecurring.ui \ src/requestdialog.ui \ + src/removeencryption.ui \ src/recurringmultiple.ui \ src/chatbubbleme.ui \ src/chatbubblepartner.ui @@ -155,6 +159,7 @@ TRANSLATIONS = res/silentdragonlite_es.ts \ res/silentdragonlite_hr.ts \ res/silentdragonlite_sr.ts \ res/silentdragonlite_fa.ts \ + res/silentdragonlite_id.ts \ res/silentdragonlite_tr.ts include(singleapplication/singleapplication.pri) diff --git a/src/Chat/Chat.cpp b/src/Chat/Chat.cpp index 30a827d..cdc3814 100644 --- a/src/Chat/Chat.cpp +++ b/src/Chat/Chat.cpp @@ -7,43 +7,43 @@ Chat::Chat() {} 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(); - if (lenDisplayLabel) - lenDisplayLabel->setText(QString::number(txt.toUtf8().size()) + "/" + QString::number(maxlen)); + if (lenDisplayLabelchat) + lenDisplayLabelchat->setText(QString::number(txt.toUtf8().size()) + "/" + QString::number(maxlenchat)); - if (txt.toUtf8().size() <= maxlen) { + if (txt.toUtf8().size() <= maxlenchat) { // Everything is fine if (sendChatButton) sendChatButton->setEnabled(true); - if (lenDisplayLabel) - lenDisplayLabel->setStyleSheet(""); + if (lenDisplayLabelchat) + lenDisplayLabelchat->setStyleSheet(""); } else { // Overweight if (sendChatButton) sendChatButton->setEnabled(false); - if (lenDisplayLabel) - lenDisplayLabel->setStyleSheet("color: red;"); + if (lenDisplayLabelchat) + lenDisplayLabelchat->setStyleSheet("color: red;"); } } -void ChatMemoEdit::setMaxLen(int len) { - this->maxlen = len; - updateDisplay(); +void ChatMemoEdit::setMaxLenChat(int len) { + this->maxlenchat = len; + updateDisplayChat(); } void ChatMemoEdit::SetSendChatButton(QPushButton* button) { this->sendChatButton = button; } -void ChatMemoEdit::setLenDisplayLabel(QLabel* label) { - this->lenDisplayLabel = label; +void ChatMemoEdit::setLenDisplayLabelChat(QLabel* label) { + this->lenDisplayLabelchat = 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()) { - //////Render only Memos for selected contacts. Do not render empty Memos //// Render only memos where cid=cid if ( (p.getName() == ui->contactNameMemo->text().trimmed()) && @@ -67,7 +66,8 @@ void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view, QLabel *label) Items->setData(OUTGOING, Qt::UserRole + 1); chat->appendRow(Items); - ui->listChat->setModel(chat); + ui->listChat->setModel(chat); + } else @@ -86,6 +86,8 @@ void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view, QLabel *label) Items1->setData(INCOMING, Qt::UserRole + 1); chat->appendRow(Items1); ui->listChat->setModel(chat); + + } else { @@ -93,5 +95,7 @@ void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view, QLabel *label) ui->listChat->setModel(chat); } } - } -} \ No newline at end of file + } +} + + \ No newline at end of file diff --git a/src/Crypto/FileEncryption.cpp b/src/Crypto/FileEncryption.cpp index 0100585..fae9bbc 100644 --- a/src/Crypto/FileEncryption.cpp +++ b/src/Crypto/FileEncryption.cpp @@ -7,42 +7,48 @@ void FileEncryption::showConfig() 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 buf_out[FILEENCRYPTION_CHUNK_SIZE + crypto_secretstream_xchacha20poly1305_ABYTES]; + unsigned char plain_data[FILEENCRYPTION_CHUNK_SIZE]; + unsigned char cipher_data[FILEENCRYPTION_CHUNK_SIZE + crypto_secretstream_xchacha20poly1305_ABYTES]; unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; - crypto_secretstream_xchacha20poly1305_state st; - FILE *fp_t, *fp_s; - unsigned long long out_len; + crypto_secretstream_xchacha20poly1305_state state; + FILE *target, *source; + unsigned long long cipher_len; size_t rlen; int eof; unsigned char tag; - fp_s = fopen(source_file.toStdString().c_str(), "rb"); - fp_t = fopen(target_file.toStdString().c_str(), "wb"); - crypto_secretstream_xchacha20poly1305_init_push(&st, header, key); - fwrite(header, 1, sizeof header, fp_t); + if(!FileEncryption::exists(source_file.toStdString())) + { + qDebug() << "File not exits" << source_file; + 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 { - rlen = fread(buf_in, 1, sizeof buf_in, fp_s); - eof = feof(fp_s); + rlen = fread(plain_data, 1, sizeof plain_data, source); + eof = feof(source); tag = eof ? crypto_secretstream_xchacha20poly1305_TAG_FINAL : 0; crypto_secretstream_xchacha20poly1305_push( - &st, - buf_out, - &out_len, - buf_in, + &state, + cipher_data, + &cipher_len, + plain_data, rlen, NULL, 0, tag ); - fwrite(buf_out, 1, (size_t) out_len, fp_t); + fwrite(cipher_data, 1, (size_t) cipher_len, target); } while (! eof); - fclose(fp_t); - fclose(fp_s); + fclose(target); + fclose(source); return 0; } @@ -59,6 +65,12 @@ int FileEncryption::decrypt(QString target_file, QString source_file, const unsi int ret = -1; 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_t = fopen(target_file.toStdString().c_str(), "wb"); fread(header, 1, sizeof header, fp_s); diff --git a/src/Crypto/FileEncryption.h b/src/Crypto/FileEncryption.h index 6db8977..c7a09d5 100644 --- a/src/Crypto/FileEncryption.h +++ b/src/Crypto/FileEncryption.h @@ -3,11 +3,17 @@ #include #include #include +#include #define FILEENCRYPTION_CHUNK_SIZE 4096 class FileEncryption { + private: + inline static bool exists (const std::string& name) { + std::ifstream f(name.c_str()); + return f.good(); + } public: static void showConfig(); static int encrypt(QString target_file, QString source_file, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]); diff --git a/src/Crypto/passwd.cpp b/src/Crypto/passwd.cpp new file mode 100644 index 0000000..98996b0 --- /dev/null +++ b/src/Crypto/passwd.cpp @@ -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: " < +#include +#include + +class PASSWD +{ + public: + static void show_hex_buff(unsigned char buf[]); + static const unsigned char* key(QString); +}; + +#endif \ No newline at end of file diff --git a/src/DataStore/ChatDataStore.cpp b/src/DataStore/ChatDataStore.cpp index 21ddef9..7bb3840 100644 --- a/src/DataStore/ChatDataStore.cpp +++ b/src/DataStore/ChatDataStore.cpp @@ -3,6 +3,8 @@ #include "ChatDataStore.h" #include "addressbook.h" +#include "chatmodel.h" + ChatDataStore* ChatDataStore::getInstance() { @@ -53,15 +55,14 @@ std::map ChatDataStore::getAllNewContactRequests() { std::map filteredItems; - for(auto &c: this->data) + for(auto &c: this->data) { if ( (c.second.isOutgoing() == false) && (c.second.getType() == "Cont") && - (c.second.getContact() == "") - - + (c.second.isContact() == false) ) + { filteredItems[c.first] = c.second; } diff --git a/src/FileSystem/FileSystem.cpp b/src/FileSystem/FileSystem.cpp index d560d98..208bfaa 100644 --- a/src/FileSystem/FileSystem.cpp +++ b/src/FileSystem/FileSystem.cpp @@ -1,7 +1,11 @@ -#include "FileSystem.h" +// Copyright 2019-2020 The Hush developers +// GPLv3 +#include "FileSystem.h" #include #include +#include "../Crypto/passwd.h" +#include "addressbook.h" FileSystem::FileSystem() { @@ -98,7 +102,6 @@ QList FileSystem::readContactsOldFormat(QString file) qDebug() << "Detected old addressbook format"; QList> stuff; in >> stuff; - //qDebug() << "Stuff: " << stuff; 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]); diff --git a/src/FileSystem/FileSystem.h b/src/FileSystem/FileSystem.h index 30dd5fc..34fc5fc 100644 --- a/src/FileSystem/FileSystem.h +++ b/src/FileSystem/FileSystem.h @@ -1,3 +1,5 @@ +// Copyright 2019-2020 The Hush developers +// GPLv3 #ifndef FILESYSTEM_H #define FILESYSTEM_H @@ -13,7 +15,7 @@ class FileSystem static bool instanced; static FileSystem* instance; FileSystem(); - + public: static FileSystem* getInstance(); QList readContacts(QString file); diff --git a/src/Model/ChatItem.cpp b/src/Model/ChatItem.cpp index fff8f9a..6a30f56 100644 --- a/src/Model/ChatItem.cpp +++ b/src/Model/ChatItem.cpp @@ -5,7 +5,7 @@ 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; _address = address; @@ -17,9 +17,11 @@ ChatItem::ChatItem(long timestamp, QString address, QString contact, QString mem _txid = txid; _confirmations = confirmations; _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; _address = address; @@ -31,6 +33,9 @@ ChatItem::ChatItem(long timestamp, QString address, QString contact, QString mem _txid = txid; _confirmations = confirmations; _outgoing = outgoing; + _notarize = notarize; + _iscontact = iscontact; + } long ChatItem::getTimestamp() @@ -81,6 +86,16 @@ bool ChatItem::isOutgoing() return _outgoing; } +bool ChatItem::isNotarized() +{ + return _notarize; +} + +bool ChatItem::isContact() +{ + return _iscontact; +} + void ChatItem::setTimestamp(long timestamp) { _timestamp = timestamp; @@ -128,6 +143,15 @@ void ChatItem::toggleOutgo() { _outgoing = true; } +void ChatItem::notarized() +{ + _notarize = false; +} + +void ChatItem::contact(bool iscontact) +{ + _iscontact = iscontact; +} QString ChatItem::toChatLine() @@ -136,14 +160,25 @@ QString ChatItem::toChatLine() QString lock; myDateTime.setTime_t(_timestamp); - if (_confirmations == 0){ + if (_notarize == true) + + { + + lock = " "; + + }else{ + lock = " "; - }else{ + } + if ((_confirmations > 0) && (_notarize == false)) + + { lock = " "; + } + - } - +qDebug()<<_notarize; QString line = QString("") + myDateTime.toString("dd.MM.yyyy hh:mm"); line += QString(lock) + QString(""); line += QString("

") + _memo.toHtmlEscaped() + QString("

"); diff --git a/src/Model/ChatItem.h b/src/Model/ChatItem.h index be8a807..900c994 100644 --- a/src/Model/ChatItem.h +++ b/src/Model/ChatItem.h @@ -20,11 +20,13 @@ class ChatItem QString _txid; int _confirmations; bool _outgoing = false; + bool _notarize = false; + bool _iscontact = false; public: 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 outgoing); + 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, bool notarize, bool iscontact); long getTimestamp(); QString getAddress(); QString getContact(); @@ -35,6 +37,9 @@ class ChatItem QString getTxid(); int getConfirmations(); bool isOutgoing(); + bool isdouble(); + bool isNotarized(); + bool isContact(); void setTimestamp(long timestamp); void setAddress(QString address); void setContact(QString contact); @@ -45,6 +50,8 @@ class ChatItem void setTxid(QString txid); void setConfirmations(int confirmations); void toggleOutgo(); + void notarized(); + void contact(bool iscontact); QString toChatLine(); json toJson(); ~ChatItem(); diff --git a/src/Model/ContactItem.cpp b/src/Model/ContactItem.cpp index d38c1c5..d2321bd 100644 --- a/src/Model/ContactItem.cpp +++ b/src/Model/ContactItem.cpp @@ -1,4 +1,9 @@ +// Copyright 2019-2020 The Hush developers +// GPLv3 #include "ContactItem.h" +#include "chatmodel.h" +#include "Model/ChatItem.h" +#include "controller.h" ContactItem::ContactItem() {} @@ -8,7 +13,7 @@ ContactItem::ContactItem(QString name, QString partnerAddress, QString myAddress _myAddress = myAddress; _partnerAddress = partnerAddress; _cid = cid; - _avatar = avatar; + _avatar = avatar; } QString ContactItem::getName() const diff --git a/src/Model/ContactItem.h b/src/Model/ContactItem.h index f066740..7eda17d 100644 --- a/src/Model/ContactItem.h +++ b/src/Model/ContactItem.h @@ -1,8 +1,11 @@ +// Copyright 2019-2020 The Hush developers +// GPLv3 #ifndef CONTACTITEM_H #define CONTACTITEM_H #include #include +#include "mainwindow.h" using json = nlohmann::json; class ContactItem @@ -13,7 +16,7 @@ private: QString _name; QString _cid; QString _avatar; - + public: ContactItem(); ContactItem(QString name, QString partnerAddress, QString myAddress, QString cid, QString avatar); diff --git a/src/addressbook.cpp b/src/addressbook.cpp index f51e279..808ca40 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -40,7 +40,10 @@ void AddressBookModel::loadData() QSettings().value( "addresstablegeometry" ).toByteArray() + + ); + } void AddressBookModel::addNewLabel(QString label, QString addr, QString myAddr, QString cid, QString avatar) diff --git a/src/addressbook.h b/src/addressbook.h index 8e32fe8..fbd361b 100644 --- a/src/addressbook.h +++ b/src/addressbook.h @@ -23,6 +23,7 @@ public: int columnCount(const QModelIndex &parent) const; QVariant data(const QModelIndex &index, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const; + private: @@ -32,7 +33,8 @@ private: QTableView* parent; //QList> labels; QList labels; - QStringList headers; + QStringList headers; + }; class AddressBook { @@ -63,6 +65,10 @@ public: QString get_avatar_name(); void set_avatar_name(QString avatar_name); + + + + @@ -76,6 +82,7 @@ private: QString writeableFile(); QList allLabels; + static AddressBook* instance; }; diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 91e46d5..ee3fe6d 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -8,7 +8,6 @@ #include "ui_mainwindow.h" #include "ui_requestContactDialog.h" #include "addressbook.h" -#include "ui_memodialog.h" #include "ui_contactrequest.h" #include #include @@ -54,7 +53,6 @@ void ChatModel::clear() void ChatModel::addMessage(ChatItem item) { QString key = ChatIDGenerator::getInstance()->generateID(item); //this->generateChatItemID(item); - // qDebug() << "inserting chatitem with id: " << key; this->chatItems[key] = item; } @@ -74,8 +72,26 @@ 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(){ Ui_requestDialog requestContact; @@ -83,27 +99,53 @@ void MainWindow::renderContactRequest(){ requestContact.setupUi(&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(); for (auto &c : DataStore::getChatDataStore()->getAllNewContactRequests()) + + { - QStandardItem* Items = new QStandardItem(c.second.getAddress()); + QStandardItem* Items = new QStandardItem(QString("Unknown Sender")); contactRequest->appendRow(Items); requestContact.requestContact->setModel(contactRequest); + + Items->setData(QIcon(addnewAddrIcon),Qt::DecorationRole); + requestContact.requestContact->setIconSize(QSize(40,50)); + requestContact.requestContact->setUniformItemSizes(true); requestContact.requestContact->show(); + requestContact.zaddrnew->setVisible(false); + requestContact.zaddrnew->setText(c.second.getAddress()); + } QStandardItemModel* contactRequestOld = new QStandardItemModel(); + for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) for (auto &c : DataStore::getChatDataStore()->getAllOldContactRequests()) { if (p.getPartnerAddress() == c.second.getRequestZaddr()) { - QStandardItem* Items = new QStandardItem(c.second.getAddress()); + QStandardItem* Items = new QStandardItem(p.getName()); contactRequestOld->appendRow(Items); requestContact.requestContactOld->setModel(contactRequestOld); + requestContact.zaddrold->setVisible(false); + requestContact.zaddrold->setText(c.second.getAddress()); requestContact.requestContactOld->show(); }else{} } @@ -116,7 +158,7 @@ void MainWindow::renderContactRequest(){ QString label_contact = index.data(Qt::DisplayRole).toString(); 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, [&] () { for (auto &c : DataStore::getChatDataStore()->getAllRawChatItems()){ - QModelIndex index = requestContact.requestContactOld->currentIndex(); - QString label_contactold = index.data(Qt::DisplayRole).toString(); + /* QModelIndex index = requestContact.requestContactOld->currentIndex(); + QString label_contactold = index.data(Qt::DisplayRole).toString();*/ 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; } +void ChatModel::addconfirmations(QString tx, int confirmation) +{ + this->confirmationsMap[tx] = confirmation; +} + QString ChatModel::getCidByTx(QString tx) { for(auto& pair : this->cidMap) @@ -235,6 +282,21 @@ QString ChatModel::getCidByTx(QString tx) 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) { for(auto& pair : this->requestZaddrMap) @@ -260,6 +322,11 @@ void ChatModel::killrequestZaddrCache() this->requestZaddrMap.clear(); } +void ChatModel::killConfirmationCache() +{ + this->confirmationsMap.clear(); +} + QString MainWindow::createHeaderMemo(QString type, QString cid, QString zaddr, int version=0, int headerNumber=1) { @@ -334,14 +401,12 @@ void MainWindow::sendChat() { // Create a Tx from the values on the send tab. Note that this Tx object // might not be valid yet. - - // Memos can only be used with zAddrs. So check that first - // for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) - + + QString Name = ui->contactNameMemo->text(); + int sizename = Name.size(); + qDebug()<< sizename; 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"), tr("You have selected no Contact from Contactlist,\n") + tr("\nor your Memo is empty"), QMessageBox::Ok, this); @@ -350,6 +415,20 @@ void MainWindow::sendChat() { 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(); QString error = doSendChatTxValidations(tx); @@ -384,10 +463,11 @@ void MainWindow::sendChat() { } 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(); ui->memoTxtChat->clear(); + // And send the Tx rpc->executeTransaction(tx, @@ -396,6 +476,7 @@ void MainWindow::sendChat() { connD->status->setText(tr("Done!")); connD->statusDetail->setText(txid); + QTimer::singleShot(1000, [=]() { d->accept(); @@ -406,7 +487,7 @@ void MainWindow::sendChat() { }); // Force a UI update so we get the unconfirmed Tx - // rpc->refresh(true); + rpc->refresh(true); ui->memoTxtChat->clear(); }, @@ -425,6 +506,8 @@ void MainWindow::sendChat() { QMessageBox::critical(this, QObject::tr("Transaction Error"), errStr, QMessageBox::Ok); } ); + + // rpc->refresh(true); } QString MainWindow::doSendChatTxValidations(Tx tx) { @@ -450,7 +533,7 @@ QString MainWindow::doSendChatTxValidations(Tx tx) { auto available = rpc->getModel()->getAvailableBalance(); 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()); } @@ -499,7 +582,7 @@ void::MainWindow::addContact() }); 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(); @@ -510,96 +593,7 @@ void::MainWindow::addContact() void MainWindow::saveandsendContact() { 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; - } // Create a Tx for a contact Request @@ -647,6 +641,22 @@ void MainWindow::ContactRequest() { 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(); QString error = doSendRequestTxValidations(tx); @@ -681,7 +691,7 @@ void MainWindow::ContactRequest() { } 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(); ui->memoTxtChat->clear(); @@ -701,7 +711,46 @@ void MainWindow::ContactRequest() { 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 // rpc->refresh(true); ui->memoTxtChat->clear(); @@ -750,9 +799,11 @@ QString MainWindow::doSendRequestTxValidations(Tx tx) { auto available = rpc->getModel()->getAvailableBalance(); 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()); } return ""; } + + diff --git a/src/chatmodel.h b/src/chatmodel.h index e8bc3e7..1768b9f 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -20,6 +20,7 @@ #include "Chat/Helper/ChatDelegator.h" #include "Chat/Helper/ChatIDGenerator.h" + namespace Ui { class MainWindow; } @@ -32,7 +33,9 @@ class ChatModel MainWindow* main; std::map cidMap; std::map requestZaddrMap; + std::map confirmationsMap; std::map> sendrequestMap; + std::map AddressbyLabelMap; public: ChatModel() {}; @@ -45,16 +48,21 @@ class ChatModel void triggerRequest(); void showMessages(); void clear(); + void addAddressbylabel(QString addr, QString label); void addMessage(ChatItem item); void addMessage(QString timestamp, ChatItem item); void addCid(QString tx, QString cid); void addrequestZaddr(QString tx, QString requestZaddr); + void addconfirmations(QString tx, int confirmation); void addSendRequest(int i, QString myAddr, QString cid, QString addr ); QString getCidByTx(QString tx); QString getrequestZaddrByTx(QString tx); + QString getConfirmationByTx(QString tx); + QString Addressbylabel(QString addr); void killCidCache(); + void killConfirmationCache(); void killrequestZaddrCache(); - + }; #endif \ No newline at end of file diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index 6f452fa..7f9d097 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -5,11 +5,18 @@ #include "addressbook.h" #include "mainwindow.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) { QStandardItemModel* contact = new QStandardItemModel(); - + for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) { @@ -18,14 +25,119 @@ void ContactModel::renderContactList(QListView* view) QStandardItem* Items1 = new QStandardItem(c.getName()); Items1->setData(QIcon(avatar),Qt::DecorationRole); + contact->appendRow(Items1); view->setModel(contact); view->setIconSize(QSize(60,70)); view->setUniformItemSizes(true); view->setDragDropMode(QAbstractItemView::DropOnly); 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()); + + + + } + +} + -} \ No newline at end of file diff --git a/src/contactmodel.h b/src/contactmodel.h index fcdf7a3..5f79c47 100644 --- a/src/contactmodel.h +++ b/src/contactmodel.h @@ -5,13 +5,17 @@ #include "Model/ContactItem.h" #include +#include "mainwindow.h" class ContactModel + { public: + ContactModel() {} void renderContactList(QListView* view); + }; #endif \ No newline at end of file diff --git a/src/contactrequest.ui b/src/contactrequest.ui index 8667057..1e37ee9 100644 --- a/src/contactrequest.ui +++ b/src/contactrequest.ui @@ -6,7 +6,7 @@ 0 0 - 777 + 780 427 @@ -233,7 +233,7 @@ - + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Insert a memo for your request</span></p></body></html> @@ -318,36 +318,11 @@ - - - - - 152 - 25 - - - - - 100 - 0 - - - - Only add this contact - - - false - - - false - - - - 188 + 300 25 @@ -358,7 +333,7 @@ - Add Contact & send request + Add Contact and send request false diff --git a/src/controller.cpp b/src/controller.cpp index 8007205..83ee2e4 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -237,12 +237,15 @@ void Controller::getInfoThenRefresh(bool force) zrpc->fetchInfo([=] (const json& reply) { prevCallSucceeded = true; int curBlock = reply["latest_block_height"].get(); - int longestchain = reply["longestchain"].get(); - int notarized = reply["notarized"].get(); + bool doUpdate = force || (model->getLatestBlock() != curBlock); int difficulty = reply["difficulty"].get(); int blocks_until_halving= 340000 - curBlock; int halving_days = (blocks_until_halving * 150) / (60*60*24) ; - bool doUpdate = force || (model->getLatestBlock() != curBlock); + int longestchain = reply["longestchain"].get(); + int notarized = reply["notarized"].get(); + + + model->setLatestBlock(curBlock); if ( Settings::getInstance()->get_currency_name() == "EUR" || @@ -258,7 +261,11 @@ void Controller::getInfoThenRefresh(bool force) ); ui->longestchain->setText( "Block: " + QLocale(QLocale::German).toString(longestchain) + ); + + + ui->difficulty->setText( QLocale(QLocale::German).toString(difficulty) ); @@ -540,8 +547,12 @@ void Controller::getInfoThenRefresh(bool force) refreshAddresses(); // This calls refreshZSentTransactions() and refreshReceivedZTrans() refreshTransactions(); } + + int lag = longestchain - notarized ; + this->setLag(lag); }, [=](QString err) { // hushd has probably disappeared. + this->noConnection(); // 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() { if (!zrpc->haveConnection()) @@ -871,12 +896,33 @@ void Controller::refreshTransactions() { CAmount amount = CAmount::fromqint64(-1* o["value"].get()); // 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; if (!o["memo"].is_null()) { memo = QString::fromStdString(o["memo"]); QString cid; + bool isNotarized; + + if (confirmations > getLag()) + { + isNotarized = true; + }else{ + + isNotarized = false; + } + + qDebug()<<"Conf : " << confirmations; ChatItem item = ChatItem( datetime, @@ -888,15 +934,17 @@ void Controller::refreshTransactions() { cid, txid, confirmations, - true + true, + isNotarized, + false ); - // qDebug()<<"Memo : " <setData(ChatIDGenerator::getInstance()->generateID(item), item); - - } - + + + + } + + items.push_back(TransactionItemDetail{address, amount, memo}); total_amount = total_amount + amount; } @@ -944,6 +992,28 @@ void Controller::refreshTransactions() { QString cid; int position; 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()) { @@ -958,7 +1028,8 @@ void Controller::refreshTransactions() { chatModel->addCid(txid, cid); chatModel->addrequestZaddr(txid, requestZaddr); - } + } + if (chatModel->getCidByTx(txid) != QString("0xdeadbeef")){ @@ -973,8 +1044,20 @@ void Controller::refreshTransactions() { requestZaddr = chatModel->getrequestZaddrByTx(txid); }else{ requestZaddr = ""; - } + } + position = it["position"].get(); + + bool isNotarized; + + if (confirmations > getLag()) + { + isNotarized = true; + }else{ + + isNotarized = false; + } + ChatItem item = ChatItem( datetime, address, @@ -985,16 +1068,17 @@ void Controller::refreshTransactions() { cid, txid, confirmations, - false + false, + isNotarized, + isContact ); - // qDebug()<< "Position : " << position; - // qDebug()<<"Confirmation :" << confirmations; - + 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 // shown in the UI so the user can keep track of pending funds diff --git a/src/controller.h b/src/controller.h index b34aeb4..9fd445b 100644 --- a/src/controller.h +++ b/src/controller.h @@ -1,3 +1,6 @@ +// Copyright 2019-2020 The Hush developers +// GPLv3 + #ifndef RPCCLIENT_H #define RPCCLIENT_H @@ -37,7 +40,10 @@ public: Connection* getConnection() { return zrpc->getConnection(); } void setConnection(Connection* c); void refresh(bool force = false); - void refreshAddresses(); + void refreshAddresses(); + int getLag(); + void setLag(int lag); + int _lag; void checkForUpdate(bool silent = true); void refreshZECPrice(); diff --git a/src/encryption.ui b/src/encryption.ui index b4ab606..ae2643b 100644 --- a/src/encryption.ui +++ b/src/encryption.ui @@ -14,65 +14,23 @@ Encrypt Your Wallet - - + + - Qt::Horizontal + Qt::Vertical - + + + 20 + 40 + + + - - - - Encryption Password: - - - - - - - Confirm Password: - - - - - - - QLineEdit::Password - - - - - - - color: red; - - - Passwords don't match - - - Qt::AlignCenter - - - - - - - QLineEdit::Password - - - - - - - Qt::Horizontal - - - - + - WARNING: If you forget your password, the only way to recover the wallet is from the seed phrase. + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> 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!</p></body></html> Qt::AlignCenter @@ -82,6 +40,81 @@ + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + + + + + <html><head/><body><p>16 letters minimum</p></body></html> + + + + + + + color: red; + + + Passphrase don't match + + + Qt::AlignCenter + + + + + + + Encryption Passphrase: + + + + + + + QLineEdit::Password + + + + + + + Confirm Passphrase: + + + + + + + QLineEdit::Password + + + + + + + Qt::Horizontal + + + @@ -95,32 +128,6 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - diff --git a/src/hushrequest.ui b/src/hushrequest.ui new file mode 100644 index 0000000..d0b0ca7 --- /dev/null +++ b/src/hushrequest.ui @@ -0,0 +1,156 @@ + + + hushrequest + + + + 0 + 0 + 663 + 529 + + + + Dialog + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + 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. + + + true + + + + + + + Request From + + + + + + + Qt::Horizontal + + + + 541 + 20 + + + + + + + + zaddr + + + + + + + Amount in + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Amount + + + + + + + Amount USD + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Memo + + + + + + + 0 / 512 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + + + + My Address + + + + + + + The recipient will see this address in the "to" field when they pay your request. + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + MemoEdit + QPlainTextEdit +
memoedit.h
+
+
+ + +
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 0e231f4..7db28cf 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -21,15 +21,36 @@ #include "ui_requestContactDialog.h" #include "chatmodel.h" #include "requestdialog.h" +#include "ui_startupencryption.h" +#include "ui_removeencryption.h" #include "websockets.h" +#include "sodium.h" +#include "sodium/crypto_generichash_blake2b.h" #include +#include "FileSystem/FileSystem.h" +#include "Crypto/passwd.h" +#include "Crypto/FileEncryption.h" 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) : QMainWindow(parent), ui(new Ui::MainWindow) { + // Include css QString theme_name; try @@ -47,12 +68,19 @@ MainWindow::MainWindow(QWidget *parent) : ui->setupUi(this); 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->setPlaceholderText("Send Message"); ui->memoTxtChat->setTextColor(Qt::white); - - - + // Status Bar setupStatusBar(); @@ -180,6 +208,12 @@ MainWindow::MainWindow(QWidget *parent) : createWebsocket(wormholecode); } } + +bool MainWindow::fileExists(QString path) +{ + QFileInfo check_file(path); + return (check_file.exists() && check_file.isFile()); +} void MainWindow::createWebsocket(QString wormholecode) { qDebug() << "Listening for app connections on port 8777"; @@ -234,6 +268,10 @@ void MainWindow::doClose() { closeEvent(nullptr); } +void MainWindow::doClosePw() { + closeEventpw(nullptr); +} + void MainWindow::closeEvent(QCloseEvent* event) { QSettings s; @@ -243,6 +281,78 @@ void MainWindow::closeEvent(QCloseEvent* event) { 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. rpc->shutdownhushd(); @@ -253,124 +363,299 @@ void MainWindow::closeEvent(QCloseEvent* event) { 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); Ui_encryptionDialog ed; ed.setupUi(&d); // Handle edits on the password box + + auto fnPasswordEdited = [=](const QString&) { // Enable the OK button if the passwords match. + QString password = ed.txtPassword->text(); + 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.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); } else { ed.lblPasswordMatch->setText(tr("Passwords don't match")); ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); } + }; QObject::connect(ed.txtConfirmPassword, &QLineEdit::textChanged, fnPasswordEdited); QObject::connect(ed.txtPassword, &QLineEdit::textChanged, fnPasswordEdited); - ed.txtPassword->setText(""); - ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); + if (d.exec() == QDialog::Accepted) + { + QString str = ed.txtPassword->text(); // data comes from user inputs + int length = str.length(); - auto fnShowError = [=](QString title, const json& res) { - QMessageBox::critical(this, title, - tr("Error was:\n") + QString::fromStdString(res.dump()), - QMessageBox::Ok - ); - }; + char *sequence = NULL; + sequence = new char[length+1]; + strncpy(sequence, str.toLocal8Bit(), length +1); - if (d.exec() == QDialog::Accepted) { - rpc->encryptWallet(ed.txtPassword->text(), [=](json res) { - 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); - } - }); + #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); + + QFile filencrypted(dirwalletenc); + QFile wallet(dirwallet); + + if (wallet.size() > 0) + { + + QMessageBox::information(this, tr("Wallet decryption Success"), + QString("Successfully delete the encryption"), + QMessageBox::Ok + ); + + filencrypted.remove(); + + }else{ + + qDebug()<<"verschlüsselung gescheitert "; + + QMessageBox::critical(this, tr("Wallet Encryption Failed"), + QString("False password, please try again"), + QMessageBox::Ok + ); + this->removeWalletEncryption(); + } - // And then refresh the UI - rpc->refresh(true); - } else { - fnShowError(tr("Wallet Encryption Failed"), res); - } - }); } + } -void MainWindow::removeWalletEncryption() { - // Check if wallet is already encrypted - auto encStatus = rpc->getModel()->getEncryptionStatus(); - if (!encStatus.first) { - QMessageBox::information(this, tr("Wallet is not encrypted"), - tr("Your wallet is not encrypted with a password."), +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 ); - return; + this->removeWalletEncryptionStartUp(); + } + + }else{ + + this->doClosePw(); } + +} - bool ok; - QString password = QInputDialog::getText(this, tr("Wallet Password"), - tr("Please enter your wallet password"), QLineEdit::Password, "", &ok); +QString MainWindow::getPassword() +{ - // If cancel was pressed, just return - if (!ok) { - return; - } + return _password; +} - if (password.isEmpty()) { - QMessageBox::critical(this, tr("Wallet Decryption Failed"), - tr("Please enter a password to decrypt your wallet!"), - QMessageBox::Ok - ); - return; - } +void MainWindow::setPassword(QString password) +{ - rpc->removeWalletEncryption(password, [=] (json res) { - if (isJsonResultSuccess(res)) { - // 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()), - QMessageBox::Ok - ); - } - }); - - // And then refresh the UI - rpc->refresh(true); - } else { - QMessageBox::critical(this, tr("Wallet Decryption Failed"), - QString::fromStdString(res["error"].get()), - QMessageBox::Ok - ); - } - }); + _password = password; } void MainWindow::setupStatusBar() { @@ -923,6 +1208,7 @@ void MainWindow::setupTransactionsTab() { ui->listChat->setMinimumSize(200,350); ui->listChat->setItemDelegate(new ListViewDelegate()); ui->listChat->show(); + ui->transactionsTable->setContextMenuPolicy(Qt::CustomContextMenu); // Table right click QObject::connect(ui->transactionsTable, &QTableView::customContextMenuRequested, [=] (QPoint pos) { @@ -1052,9 +1338,6 @@ void MainWindow::setupchatTab() { ui->memoTxtChat->setTextColor("Black"); } - - - QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChat); QObject::connect(ui->safeContactRequest, &QPushButton::clicked, this, &MainWindow::addContact); QObject::connect(ui->pushContact, &QPushButton::clicked, this , &MainWindow::renderContactRequest); @@ -1069,18 +1352,67 @@ void MainWindow::setupchatTab() { for(auto &p : AddressBook::getInstance()->getAllAddressLabels()) if (label_contact == p.getName()) { - // ui->ContactZaddr->setText(p.getPartnerAddress()); - // ui->MyZaddr->setText(p.getMyAddress()); - ui->contactNameMemo->setText(p.getName()); - ui->memoTxtChat->clear(); - - rpc->refresh(true); - // updateChat(); + ui->contactNameMemo->setText(p.getName()); + rpc->refresh(true); + } }); + 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(); + + 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->setLenDisplayLabel(ui->memoSizeChat); +ui->memoTxtChat->setLenDisplayLabelChat(ui->memoSizeChat); } @@ -1089,13 +1421,11 @@ void MainWindow::updateChat() { rpc->refreshChat(ui->listChat,ui->memoSizeChat); rpc->refresh(true); - - } void MainWindow::updateContacts() { - //rpc->refreshContacts(ui->listContactWidget); + } void MainWindow::addNewZaddr(bool sapling) { diff --git a/src/mainwindow.h b/src/mainwindow.h index 85f4feb..56bfbc6 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -51,6 +51,8 @@ public: QString doSendChatTxValidations(Tx tx); QString doSendRequestTxValidations(Tx tx); QString getCid(); + QString getPassword(); + void setPassword(QString Password); void replaceWormholeClient(WormholeClient* newClient); bool isWebsocketListening(); @@ -58,8 +60,9 @@ public: void stopWebsocket(); void saveContact(); void saveandsendContact(); - void setMaxLen(int len); - void updateDisplay(); + void showRequesthush(); + // void setmaxlenChat(int len); + // void updateDisplay(); void balancesReady(); @@ -86,6 +89,7 @@ public: Logger* logger; void doClose(); + void doClosePw(); QString createHeaderMemo(QString type, QString cid, QString zaddr, int version, int headerNumber); public slots: @@ -100,7 +104,9 @@ private slots: private: + bool fileExists(QString path); void closeEvent(QCloseEvent* event); + void closeEventpw(QCloseEvent* event); void setupSendTab(); @@ -119,6 +125,7 @@ private: void setupStatusBar(); void clearSendForm(); + QString _password; Tx createTxFromSendPage(); bool confirmTx(Tx tx, RecurringPaymentInfo* rpi); @@ -129,6 +136,7 @@ private: void encryptWallet(); void removeWalletEncryption(); + void removeWalletEncryptionStartUp(); void cancelButton(); void sendButton(); @@ -192,14 +200,14 @@ class ChatMemoEdit : public QTextEdit public: ChatMemoEdit(QWidget* parent); - void setMaxLen(int len); - void setLenDisplayLabel(QLabel* label); + void setMaxLenChat(int len); + void setLenDisplayLabelChat(QLabel* label); void SetSendChatButton(QPushButton* button); - void updateDisplay(); + void updateDisplayChat(); private: - int maxlen = 512; - QLabel* lenDisplayLabel = nullptr; + int maxlenchat = 512; + QLabel* lenDisplayLabelchat = nullptr; QPushButton* sendChatButton = nullptr; }; diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 2d85bd5..de58411 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1378,7 +1378,10 @@ true - QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked + QAbstractItemView::NoEditTriggers + + + false false @@ -1386,6 +1389,9 @@ QAbstractItemView::SingleSelection + + QAbstractItemView::SelectItems + @@ -1419,10 +1425,16 @@ QTextEdit::AutoNone - QTextEdit::FixedColumnWidth + QTextEdit::FixedPixelWidth - 80 + 600 + + + false + + + Qt::TextEditorInteraction @@ -1505,6 +1517,9 @@ 521 + + The locks shows you the status of the message. Red lock = unconfirmed, green lock = min. 1 confirmations, orange lock = message is notarized + Qt::ScrollBarAsNeeded @@ -1515,7 +1530,7 @@ QAbstractScrollArea::AdjustToContents - QAbstractItemView::AllEditTriggers + QAbstractItemView::NoEditTriggers QListView::Adjust diff --git a/src/memodialog.ui b/src/memodialog.ui index 1c144e0..d365221 100644 --- a/src/memodialog.ui +++ b/src/memodialog.ui @@ -74,7 +74,7 @@ MemoEdit QPlainTextEdit -
memoedit.h
+
memoedit.h
diff --git a/src/removeencryption.ui b/src/removeencryption.ui new file mode 100644 index 0000000..77d7239 --- /dev/null +++ b/src/removeencryption.ui @@ -0,0 +1,197 @@ + + + removeencryption + + + + 0 + 0 + 400 + 300 + + + + Remove your Wallet encryption + + + + + 50 + 260 + 341 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 260 + 170 + 133 + 23 + + + + <html><head/><body><p>16 letters minimum</p></body></html> + + + + + + 10 + 229 + 157 + 25 + + + + Confirm Passphrase: + + + + + + 10 + 164 + 382 + 3 + + + + Qt::Horizontal + + + + + + 173 + 229 + 219 + 25 + + + + QLineEdit::Password + + + + + + 10 + 56 + 382 + 56 + + + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If yo remove your encryption, all your Data is Plaintext on your Disk!</p></body></html> + + + Qt::AlignCenter + + + true + + + + + + 10 + 260 + 382 + 3 + + + + Qt::Horizontal + + + + + + 10 + 198 + 157 + 25 + + + + Encryption Passphrase: + + + + + + 10 + 175 + 243 + 17 + + + + color: red; + + + Passphrase don't match + + + Qt::AlignCenter + + + + + + 173 + 198 + 219 + 25 + + + + QLineEdit::Password + + + + + + + buttonBox + accepted() + removeencryption + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + removeencryption + close() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/requestContactDialog.ui b/src/requestContactDialog.ui index 2eb4bc0..d4420ea 100644 --- a/src/requestContactDialog.ui +++ b/src/requestContactDialog.ui @@ -6,7 +6,7 @@ 0 0 - 812 + 850 495
@@ -27,7 +27,7 @@
- + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Memo of the request</span></p></body></html> @@ -97,12 +97,12 @@ - + 256 - 192 + 190 @@ -119,14 +119,21 @@ - + + + + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Details of the request</span></p></body></html> + + + + Request from : - + @@ -142,14 +149,14 @@ - + My Zaddr : - + @@ -165,24 +172,24 @@ - + Give a Nickname: - + - + <html><head/><body><p align="right">Choose a avatar for your contact :</p></body></html> - + @@ -328,7 +335,7 @@ - + @@ -353,7 +360,7 @@ - + @@ -369,17 +376,24 @@ - - + + + + + + + + + - - + + - <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Details of the request</span></p></body></html> + diff --git a/src/requestdialog.ui b/src/requestdialog.ui index 952f780..e52c475 100644 --- a/src/requestdialog.ui +++ b/src/requestdialog.ui @@ -14,9 +14,124 @@ Payment Request + + + + + + + + + + + Request From + + + + + + + The recipient will see this address in the "to" field when they pay your request. + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + color: red; + + + + + + + + + + Memo + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + 0 / 512 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + + + + Amount USD + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + @@ -41,65 +156,13 @@ - - - - Qt::Horizontal - - - - - + + - Request From + 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. - - - - - - My Address - - - - - - - color: red; - - - - - - - - - - Amount in - - - - - - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - + + true @@ -119,20 +182,20 @@ - - - - Qt::Horizontal + + + + My Address - - - - - 0 - 0 - + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok @@ -146,83 +209,20 @@ - - + + + + Amount in + + + + + Qt::Horizontal - - - - The recipient will see this address in the "to" field when they pay your request. - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - 0 / 512 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Amount USD - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Memo - - - - - - - TextLabel - - - Qt::AlignCenter - - - - - - - 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. - - - true - - - diff --git a/src/sendtab.cpp b/src/sendtab.cpp index de61cf2..ce04a54 100644 --- a/src/sendtab.cpp +++ b/src/sendtab.cpp @@ -937,7 +937,7 @@ QString MainWindow::doSendTxValidations(Tx tx) { auto available = rpc->getModel()->getAvailableBalance(); 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()); } diff --git a/src/startupencryption.ui b/src/startupencryption.ui new file mode 100644 index 0000000..6abdad1 --- /dev/null +++ b/src/startupencryption.ui @@ -0,0 +1,184 @@ + + + startup + + + + 0 + 0 + 400 + 300 + + + + SDL Startup Decryption + + + + + 50 + 260 + 341 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 10 + 229 + 127 + 25 + + + + Confirm Password: + + + + + + 10 + 166 + 382 + 3 + + + + Qt::Horizontal + + + + + + 162 + 229 + 230 + 25 + + + + QLineEdit::Password + + + + + + 10 + 58 + 382 + 56 + + + + <html><head/><body><p>If you have forgotten your password, restore your wallet with your seed!</p></body></html> + + + Qt::AlignCenter + + + true + + + + + + 10 + 260 + 382 + 3 + + + + Qt::Horizontal + + + + + + 10 + 198 + 146 + 25 + + + + Encryption Password: + + + + + + 10 + 175 + 382 + 17 + + + + color: red; + + + Passwords don't match + + + Qt::AlignCenter + + + + + + 162 + 198 + 230 + 25 + + + + QLineEdit::Password + + + + + + + buttonBox + accepted() + startup + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + startup + reject() + + + 316 + 260 + + + 286 + 274 + + + + +