From 6ac2d60815c8245b6d9c523027971aca7884ddaf Mon Sep 17 00:00:00 2001 From: aiwe Date: Sat, 11 May 2024 12:29:11 -0500 Subject: [PATCH] Improve wallet import dialogues --- CMakeLists.txt | 2 +- src/gui/ImportKeyDialog.cpp | 44 ++++- src/gui/ImportKeyDialog.h | 8 +- src/gui/ImportKeysDialog.cpp | 62 ++++++- src/gui/ImportKeysDialog.h | 8 +- src/gui/ImportTrackingKeyDialog.cpp | 82 +++++++++- src/gui/ImportTrackingKeyDialog.h | 8 +- src/gui/MainWindow.cpp | 173 ++++---------------- src/gui/RestoreFromMnemonicSeedDialog.cpp | 37 ++++- src/gui/RestoreFromMnemonicSeedDialog.h | 6 +- src/gui/ui/importkeydialog.ui | 19 ++- src/gui/ui/importkeysdialog.ui | 139 +++++++++++----- src/gui/ui/importtrackingkeydialog.ui | 19 ++- src/gui/ui/restorefrommnemonicseeddialog.ui | 2 +- 14 files changed, 413 insertions(+), 196 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 65b8ea241..26de22294 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -318,9 +318,9 @@ if (WIN32) add_definitions(/D_CRT_SECURE_NO_WARNINGS /D_WIN32_WINNT=0x0600 /DSTATICLIB) add_subdirectory(cryptonote/external/zstd EXCLUDE_FROM_ALL) + add_subdirectory(cryptonote/external/snappy EXCLUDE_FROM_ALL) add_subdirectory(cryptonote/external/rocksdb EXCLUDE_FROM_ALL) add_subdirectory(cryptonote/external/leveldb EXCLUDE_FROM_ALL) - add_subdirectory(cryptonote/external/snappy EXCLUDE_FROM_ALL) set_property(TARGET rocksdb leveldb snappy zstd PROPERTY FOLDER "external") include_directories(cryptonote/src/platform/msc) diff --git a/src/gui/ImportKeyDialog.cpp b/src/gui/ImportKeyDialog.cpp index 370b5e2d2..cbcdeda10 100644 --- a/src/gui/ImportKeyDialog.cpp +++ b/src/gui/ImportKeyDialog.cpp @@ -1,13 +1,19 @@ // Copyright (c) 2011-2016 The Cryptonote developers // Copyright (c) 2015-2016 XDN developers -// Copyright (c) 2016-2018 The Karbowanec developers +// Copyright (c) 2016-2022 The Karbowanec developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include +#include #include +#include "Common/Base58.h" +#include "Common/StringTools.h" +#include "CryptoNoteCore/CryptoNoteTools.h" +#include "CurrencyAdapter.h" + #include "ImportKeyDialog.h" #include "ui_importkeydialog.h" @@ -16,6 +22,7 @@ namespace WalletGui { ImportKeyDialog::ImportKeyDialog(QWidget* _parent) : QDialog(_parent), m_ui(new Ui::ImportKeyDialog) { m_ui->setupUi(this); + m_ui->m_okButton->setEnabled(false); } ImportKeyDialog::~ImportKeyDialog() { @@ -33,6 +40,10 @@ quint32 ImportKeyDialog::getSyncHeight() const { return m_ui->m_syncHeight->value(); } +CryptoNote::AccountKeys ImportKeyDialog::getAccountKeys() const { + return m_keys; +} + void ImportKeyDialog::selectPathClicked() { QString filePath = QFileDialog::getSaveFileName(this, tr("Wallet file"), #ifdef Q_OS_WIN @@ -51,4 +62,35 @@ void ImportKeyDialog::selectPathClicked() { m_ui->m_pathEdit->setText(filePath); } +void ImportKeyDialog::onTextChanged() { + if (getKeyString().isEmpty() || getKeyString().size() != 183) { + m_ui->m_okButton->setEnabled(false); + } else { + m_ui->m_okButton->setEnabled(true); + } +} + +void ImportKeyDialog::onAccept() { + uint64_t addressPrefix; + std::string data; + QString keyString = getKeyString().trimmed(); + if (!keyString.isEmpty() && Tools::Base58::decode_addr(keyString.toStdString(), addressPrefix, data) && addressPrefix == CurrencyAdapter::instance().getAddressPrefix() && data.size() == sizeof(m_keys)) { + if (!CryptoNote::fromBinaryArray(m_keys, Common::asBinaryArray(data))) { + QMessageBox::warning(nullptr, tr("Wallet keys are not valid"), tr("Failed to parse account keys"), QMessageBox::Ok); + return; + } + } else { + QMessageBox::warning(nullptr, tr("Wallet keys are not valid"), tr("The private keys you entered are not valid."), QMessageBox::Ok); + return; + } + + QString filePath = getFilePath(); + if (filePath.isEmpty()) { + QMessageBox::critical(nullptr, tr("File path is empty"), tr("Please enter the path where to save the wallet file and its name."), QMessageBox::Ok); + return; + } + + accept(); +} + } diff --git a/src/gui/ImportKeyDialog.h b/src/gui/ImportKeyDialog.h index e38861306..387255e17 100644 --- a/src/gui/ImportKeyDialog.h +++ b/src/gui/ImportKeyDialog.h @@ -1,12 +1,13 @@ // Copyright (c) 2011-2016 The Cryptonote developers // Copyright (c) 2015-2016 XDN developers -// Copyright (c) 2016-2017 The Karbowanec developers +// Copyright (c) 2016-2022 The Karbowanec developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #pragma once #include +#include namespace Ui { class ImportKeyDialog; @@ -24,11 +25,16 @@ class ImportKeyDialog : public QDialog { QString getKeyString() const; QString getFilePath() const; quint32 getSyncHeight() const; + CryptoNote::AccountKeys getAccountKeys() const; private: QScopedPointer m_ui; + CryptoNote::AccountKeys m_keys; + Q_SLOT void selectPathClicked(); + Q_SLOT void onTextChanged(); + Q_SLOT void onAccept(); }; } diff --git a/src/gui/ImportKeysDialog.cpp b/src/gui/ImportKeysDialog.cpp index 43a9e4370..441271202 100644 --- a/src/gui/ImportKeysDialog.cpp +++ b/src/gui/ImportKeysDialog.cpp @@ -1,13 +1,18 @@ // Copyright (c) 2011-2016 The Cryptonote developers // Copyright (c) 2015-2016 XDN developers -// Copyright (c) 2016-2019 The Karbowanec developers +// Copyright (c) 2016-2022 The Karbowanec developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include +#include #include +#include "Common/StringTools.h" +#include "CryptoNoteCore/CryptoNoteTools.h" +#include "CurrencyAdapter.h" + #include "ImportKeysDialog.h" #include "ui_importkeysdialog.h" @@ -16,6 +21,7 @@ namespace WalletGui { ImportKeysDialog::ImportKeysDialog(QWidget* _parent) : QDialog(_parent), m_ui(new Ui::ImportKeysDialog) { m_ui->setupUi(this); + m_ui->m_okButton->setEnabled(false); } ImportKeysDialog::~ImportKeysDialog() { @@ -37,6 +43,10 @@ quint32 ImportKeysDialog::getSyncHeight() const { return m_ui->m_syncHeight->value(); } +CryptoNote::AccountKeys ImportKeysDialog::getAccountKeys() const { + return m_keys; +} + void ImportKeysDialog::selectPathClicked() { QString filePath = QFileDialog::getSaveFileName(this, tr("Wallet file"), #ifdef Q_OS_WIN @@ -55,4 +65,54 @@ void ImportKeysDialog::selectPathClicked() { m_ui->m_pathEdit->setText(filePath); } +void ImportKeysDialog::onTextChanged(QString _text) { + Q_UNUSED(_text); + if (getViewKeyString().isEmpty() || getSpendKeyString().isEmpty() || getViewKeyString().size() != 64 || getSpendKeyString().size() != 64) { + m_ui->m_okButton->setEnabled(false); + } else { + m_ui->m_okButton->setEnabled(true); + } +} + +void ImportKeysDialog::onAccept() { + QString viewKeyString = getViewKeyString().trimmed(); + QString spendKeyString = getSpendKeyString().trimmed(); + + if (viewKeyString.isEmpty() || spendKeyString.isEmpty()) { + return; // no error message, it's obvious + } + + uint64_t addressPrefix; + std::string data; + + std::string private_spend_key_string = spendKeyString.toStdString(); + std::string private_view_key_string = viewKeyString.toStdString(); + + Crypto::Hash private_spend_key_hash; + Crypto::Hash private_view_key_hash; + + size_t size; + if (!Common::fromHex(private_spend_key_string, &private_spend_key_hash, sizeof(private_spend_key_hash), size) || size != sizeof(private_spend_key_hash)) { + QMessageBox::warning(this, tr("Key is not valid"), tr("The private spend key you entered is not valid."), QMessageBox::Ok); + return; + } + if (!Common::fromHex(private_view_key_string, &private_view_key_hash, sizeof(private_view_key_hash), size) || size != sizeof(private_view_key_hash)) { + QMessageBox::warning(this, tr("Key is not valid"), tr("The private view key you entered is not valid."), QMessageBox::Ok); + return; + } + + m_keys.spendSecretKey = *(struct Crypto::SecretKey *) &private_spend_key_hash; + m_keys.viewSecretKey = *(struct Crypto::SecretKey *) &private_view_key_hash; + + Crypto::secret_key_to_public_key(m_keys.spendSecretKey, m_keys.address.spendPublicKey); + Crypto::secret_key_to_public_key(m_keys.viewSecretKey, m_keys.address.viewPublicKey); + + if (getFilePath().isEmpty()) { + QMessageBox::critical(nullptr, tr("File path is empty"), tr("Please enter the path where to save the wallet file and its name."), QMessageBox::Ok); + return; + } + + accept(); +} + } diff --git a/src/gui/ImportKeysDialog.h b/src/gui/ImportKeysDialog.h index ec540d395..639181f2e 100644 --- a/src/gui/ImportKeysDialog.h +++ b/src/gui/ImportKeysDialog.h @@ -1,12 +1,13 @@ // Copyright (c) 2011-2016 The Cryptonote developers // Copyright (c) 2015-2016 XDN developers -// Copyright (c) 2016-2019 The Karbowanec developers +// Copyright (c) 2016-2022 The Karbowanec developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #pragma once #include +#include namespace Ui { class ImportKeysDialog; @@ -25,11 +26,16 @@ class ImportKeysDialog : public QDialog { QString getSpendKeyString() const; QString getFilePath() const; quint32 getSyncHeight() const; + CryptoNote::AccountKeys getAccountKeys() const; private: QScopedPointer m_ui; + CryptoNote::AccountKeys m_keys; + Q_SLOT void selectPathClicked(); + Q_SLOT void onTextChanged(QString _text); + Q_SLOT void onAccept(); }; } diff --git a/src/gui/ImportTrackingKeyDialog.cpp b/src/gui/ImportTrackingKeyDialog.cpp index 2d03a0845..9e4679ac5 100644 --- a/src/gui/ImportTrackingKeyDialog.cpp +++ b/src/gui/ImportTrackingKeyDialog.cpp @@ -1,13 +1,18 @@ // Copyright (c) 2011-2016 The Cryptonote developers // Copyright (c) 2015-2016 XDN developers -// Copyright (c) 2016-2018 The Karbowanec developers +// Copyright (c) 2016-2022 The Karbowanec developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include +#include #include +#include "Common/StringTools.h" +#include "CryptoNoteCore/CryptoNoteTools.h" +#include "CurrencyAdapter.h" + #include "ImportTrackingKeyDialog.h" #include "ui_importtrackingkeydialog.h" @@ -16,6 +21,7 @@ namespace WalletGui { ImportTrackingKeyDialog::ImportTrackingKeyDialog(QWidget* _parent) : QDialog(_parent), m_ui(new Ui::ImportTrackingKeyDialog) { m_ui->setupUi(this); + m_ui->m_okButton->setEnabled(false); } ImportTrackingKeyDialog::~ImportTrackingKeyDialog() { @@ -33,6 +39,10 @@ quint32 ImportTrackingKeyDialog::getSyncHeight() const { return m_ui->m_syncHeight->value(); } +CryptoNote::AccountKeys ImportTrackingKeyDialog::getAccountKeys() const { + return m_keys; +} + void ImportTrackingKeyDialog::selectPathClicked() { QString filePath = QFileDialog::getSaveFileName(this, tr("Tracking wallet file"), #ifdef Q_OS_WIN @@ -51,4 +61,74 @@ void ImportTrackingKeyDialog::selectPathClicked() { m_ui->m_pathEdit->setText(filePath); } +void ImportTrackingKeyDialog::onTextChanged() { + if (getKeyString().isEmpty() || getKeyString().size() != 256) { + m_ui->m_okButton->setEnabled(false); + } else { + m_ui->m_okButton->setEnabled(true); + } +} + +void ImportTrackingKeyDialog::onAccept() { + QString keyString = getKeyString().trimmed(); + if (keyString.isEmpty() || keyString.size() != 256) { + QMessageBox::warning(this, tr("Tracking key is not valid"), tr("The tracking key you entered is not valid."), QMessageBox::Ok); + return; + } + + // XDN style tracking key import + // uint64_t addressPrefix; + // std::string data; + + // if (Tools::Base58::decode_addr(keyString.toStdString(), addressPrefix, data) && addressPrefix == CurrencyAdapter::instance().getAddressPrefix() && + // data.size() == sizeof(keys)) { + // std::memcpy(&keys, data.data(), sizeof(keys)); + + // To prevent confusing with import of private key / paperwallet lets use Bytecoin style tracking keys, they look different + std::string public_spend_key_string = keyString.mid(0,64).toStdString(); + std::string public_view_key_string = keyString.mid(64,64).toStdString(); + std::string private_spend_key_string = keyString.mid(128,64).toStdString(); + std::string private_view_key_string = keyString.mid(192,64).toStdString(); + + Crypto::Hash public_spend_key_hash; + Crypto::Hash public_view_key_hash; + Crypto::Hash private_spend_key_hash; + Crypto::Hash private_view_key_hash; + + size_t size; + if (!Common::fromHex(public_spend_key_string, &public_spend_key_hash, sizeof(public_spend_key_hash), size) || size != sizeof(public_spend_key_hash)) { + QMessageBox::warning(this, tr("Key is not valid"), tr("The public spend key you entered is not valid."), QMessageBox::Ok); + return; + } + if (!Common::fromHex(public_view_key_string, &public_view_key_hash, sizeof(public_view_key_hash), size) || size != sizeof(public_view_key_hash)) { + QMessageBox::warning(this, tr("Key is not valid"), tr("The public view key you entered is not valid."), QMessageBox::Ok); + return; + } + if (!Common::fromHex(private_spend_key_string, &private_spend_key_hash, sizeof(private_spend_key_hash), size) || size != sizeof(private_spend_key_hash)) { + QMessageBox::warning(this, tr("Key is not valid"), tr("The private spend key you entered is not valid."), QMessageBox::Ok); + return; + } + if (!Common::fromHex(private_view_key_string, &private_view_key_hash, sizeof(private_view_key_hash), size) || size != sizeof(private_view_key_hash)) { + QMessageBox::warning(this, tr("Key is not valid"), tr("The private view key you entered is not valid."), QMessageBox::Ok); + return; + } + + Crypto::PublicKey public_spend_key = *(struct Crypto::PublicKey *) &public_spend_key_hash; + Crypto::PublicKey public_view_key = *(struct Crypto::PublicKey *) &public_view_key_hash; + Crypto::SecretKey private_spend_key = *(struct Crypto::SecretKey *) &private_spend_key_hash; + Crypto::SecretKey private_view_key = *(struct Crypto::SecretKey *) &private_view_key_hash; + + m_keys.address.spendPublicKey = public_spend_key; + m_keys.address.viewPublicKey = public_view_key; + m_keys.spendSecretKey = private_spend_key; + m_keys.viewSecretKey = private_view_key; + + if (getFilePath().isEmpty()) { + QMessageBox::critical(nullptr, tr("File path is empty"), tr("Please enter the path where to save the wallet file and its name."), QMessageBox::Ok); + return; + } + + accept(); +} + } diff --git a/src/gui/ImportTrackingKeyDialog.h b/src/gui/ImportTrackingKeyDialog.h index c542f478d..cb36430fe 100644 --- a/src/gui/ImportTrackingKeyDialog.h +++ b/src/gui/ImportTrackingKeyDialog.h @@ -1,12 +1,13 @@ // Copyright (c) 2011-2016 The Cryptonote developers // Copyright (c) 2015-2016 XDN developers -// Copyright (c) 2016-2017 The Karbowanec developers +// Copyright (c) 2016-2022 The Karbowanec developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #pragma once #include +#include namespace Ui { class ImportTrackingKeyDialog; @@ -24,11 +25,16 @@ class ImportTrackingKeyDialog : public QDialog { QString getKeyString() const; QString getFilePath() const; quint32 getSyncHeight() const; + CryptoNote::AccountKeys getAccountKeys() const; private: QScopedPointer m_ui; + CryptoNote::AccountKeys m_keys; + Q_SLOT void selectPathClicked(); + Q_SLOT void onTextChanged(); + Q_SLOT void onAccept(); }; } diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 0c7190744..30c0dcf3e 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2011-2016 The Cryptonote developers // Copyright (c) 2011-2013 The Bitcoin Core developers // Copyright (c) 2015-2016 XDN developers -// Copyright (c) 2016-2022 The Karbo developers +// Copyright (c) 2016-2024 The Karbo developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -60,14 +60,6 @@ #include "macdockiconhandler.h" #endif -#include "Mnemonics/electrum-words.h" - -extern "C" -{ -#include "crypto/keccak.h" -#include "crypto/crypto-ops.h" -} - namespace WalletGui { MainWindow* MainWindow::m_instance = nullptr; @@ -472,9 +464,8 @@ void MainWindow::openRecent(){ void MainWindow::importKey() { ImportKeyDialog dlg(this); if (dlg.exec() == QDialog::Accepted) { - QString keyString = dlg.getKeyString().trimmed(); QString filePath = dlg.getFilePath(); - if (keyString.isEmpty() || filePath.isEmpty()) { + if (filePath.isEmpty()) { return; } @@ -482,28 +473,18 @@ void MainWindow::importKey() { filePath.append(".wallet"); } - uint64_t addressPrefix; - std::string data; - CryptoNote::AccountKeys keys; - if (Tools::Base58::decode_addr(keyString.toStdString(), addressPrefix, data) && addressPrefix == CurrencyAdapter::instance().getAddressPrefix() && - data.size() == sizeof(keys)) { - if (!fromBinaryArray(keys, Common::asBinaryArray(data))) { - QMessageBox::warning(this, tr("Wallet keys are not valid"), tr("Failed to parse account keys"), QMessageBox::Ok); - } - if (WalletAdapter::instance().isOpen()) { - WalletAdapter::instance().close(); - } - WalletAdapter::instance().setWalletFile(filePath); + CryptoNote::AccountKeys keys = dlg.getAccountKeys(); - quint32 syncHeight = dlg.getSyncHeight(); - if (syncHeight != 0) { - WalletAdapter::instance().createWithKeys(keys, syncHeight); - } else { - WalletAdapter::instance().createWithKeys(keys); - } + if (WalletAdapter::instance().isOpen()) { + WalletAdapter::instance().close(); + } + WalletAdapter::instance().setWalletFile(filePath); + quint32 syncHeight = dlg.getSyncHeight(); + if (syncHeight != 0) { + WalletAdapter::instance().createWithKeys(keys, syncHeight); } else { - QMessageBox::warning(this, tr("Wallet keys are not valid"), tr("The private keys you entered are not valid."), QMessageBox::Ok); + WalletAdapter::instance().createWithKeys(keys); } } } @@ -511,10 +492,8 @@ void MainWindow::importKey() { void MainWindow::importKeys() { ImportKeysDialog dlg(this); if (dlg.exec() == QDialog::Accepted) { - QString viewKeyString = dlg.getViewKeyString().trimmed(); - QString spendKeyString = dlg.getSpendKeyString().trimmed(); QString filePath = dlg.getFilePath(); - if (viewKeyString.isEmpty() || spendKeyString.isEmpty() || filePath.isEmpty()) { + if (filePath.isEmpty()) { return; } @@ -522,31 +501,7 @@ void MainWindow::importKeys() { filePath.append(".wallet"); } - uint64_t addressPrefix; - std::string data; - CryptoNote::AccountKeys keys; - - std::string private_spend_key_string = spendKeyString.toStdString(); - std::string private_view_key_string = viewKeyString.toStdString(); - - Crypto::Hash private_spend_key_hash; - Crypto::Hash private_view_key_hash; - - size_t size; - if (!Common::fromHex(private_spend_key_string, &private_spend_key_hash, sizeof(private_spend_key_hash), size) || size != sizeof(private_spend_key_hash)) { - QMessageBox::warning(this, tr("Key is not valid"), tr("The private spend key you entered is not valid."), QMessageBox::Ok); - return; - } - if (!Common::fromHex(private_view_key_string, &private_view_key_hash, sizeof(private_view_key_hash), size) || size != sizeof(private_view_key_hash)) { - QMessageBox::warning(this, tr("Key is not valid"), tr("The private view key you entered is not valid."), QMessageBox::Ok); - return; - } - - keys.spendSecretKey = *(struct Crypto::SecretKey *) &private_spend_key_hash; - keys.viewSecretKey = *(struct Crypto::SecretKey *) &private_view_key_hash; - - Crypto::secret_key_to_public_key(keys.spendSecretKey, keys.address.spendPublicKey); - Crypto::secret_key_to_public_key(keys.viewSecretKey, keys.address.viewPublicKey); + CryptoNote::AccountKeys keys = dlg.getAccountKeys(); if (WalletAdapter::instance().isOpen()) { WalletAdapter::instance().close(); @@ -579,69 +534,20 @@ void MainWindow::importTrackingKey() { filePath.append(".wallet"); } - CryptoNote::AccountKeys keys; - - // XDN style tracking key import - // uint64_t addressPrefix; - // std::string data; - - // if (Tools::Base58::decode_addr(keyString.toStdString(), addressPrefix, data) && addressPrefix == CurrencyAdapter::instance().getAddressPrefix() && - // data.size() == sizeof(keys)) { - // std::memcpy(&keys, data.data(), sizeof(keys)); - - // To prevent confusing with import of private key / paperwallet lets use Bytecoin style tracking keys, they look different - std::string public_spend_key_string = keyString.mid(0,64).toStdString(); - std::string public_view_key_string = keyString.mid(64,64).toStdString(); - std::string private_spend_key_string = keyString.mid(128,64).toStdString(); - std::string private_view_key_string = keyString.mid(192,64).toStdString(); - - Crypto::Hash public_spend_key_hash; - Crypto::Hash public_view_key_hash; - Crypto::Hash private_spend_key_hash; - Crypto::Hash private_view_key_hash; + CryptoNote::AccountKeys keys = dlg.getAccountKeys(); - size_t size; - if (!Common::fromHex(public_spend_key_string, &public_spend_key_hash, sizeof(public_spend_key_hash), size) || size != sizeof(public_spend_key_hash)) { - QMessageBox::warning(this, tr("Key is not valid"), tr("The public spend key you entered is not valid."), QMessageBox::Ok); - return; - } - if (!Common::fromHex(public_view_key_string, &public_view_key_hash, sizeof(public_view_key_hash), size) || size != sizeof(public_view_key_hash)) { - QMessageBox::warning(this, tr("Key is not valid"), tr("The public view key you entered is not valid."), QMessageBox::Ok); - return; - } - if (!Common::fromHex(private_spend_key_string, &private_spend_key_hash, sizeof(private_spend_key_hash), size) || size != sizeof(private_spend_key_hash)) { - QMessageBox::warning(this, tr("Key is not valid"), tr("The private spend key you entered is not valid."), QMessageBox::Ok); - return; - } - if (!Common::fromHex(private_view_key_string, &private_view_key_hash, sizeof(private_view_key_hash), size) || size != sizeof(private_view_key_hash)) { - QMessageBox::warning(this, tr("Key is not valid"), tr("The private view key you entered is not valid."), QMessageBox::Ok); - return; + if (WalletAdapter::instance().isOpen()) { + WalletAdapter::instance().close(); } + Settings::instance().setTrackingMode(true); + WalletAdapter::instance().setWalletFile(filePath); - Crypto::PublicKey public_spend_key = *(struct Crypto::PublicKey *) &public_spend_key_hash; - Crypto::PublicKey public_view_key = *(struct Crypto::PublicKey *) &public_view_key_hash; - Crypto::SecretKey private_spend_key = *(struct Crypto::SecretKey *) &private_spend_key_hash; - Crypto::SecretKey private_view_key = *(struct Crypto::SecretKey *) &private_view_key_hash; - - keys.address.spendPublicKey = public_spend_key; - keys.address.viewPublicKey = public_view_key; - keys.spendSecretKey = private_spend_key; - keys.viewSecretKey = private_view_key; - - if (WalletAdapter::instance().isOpen()) { - WalletAdapter::instance().close(); - } - Settings::instance().setTrackingMode(true); - WalletAdapter::instance().setWalletFile(filePath); - - quint32 syncHeight = dlg.getSyncHeight(); - if (syncHeight != 0) { - WalletAdapter::instance().createWithKeys(keys, syncHeight); - } else { - WalletAdapter::instance().createWithKeys(keys); - } - - // } + quint32 syncHeight = dlg.getSyncHeight(); + if (syncHeight != 0) { + WalletAdapter::instance().createWithKeys(keys, syncHeight); + } else { + WalletAdapter::instance().createWithKeys(keys); + } } } @@ -659,9 +565,8 @@ void MainWindow::isTrackingMode() { void MainWindow::restoreFromMnemonicSeed() { RestoreFromMnemonicSeedDialog dlg(this); if (dlg.exec() == QDialog::Accepted) { - QString mnemonicString = dlg.getSeedString().trimmed(); QString filePath = dlg.getFilePath(); - if (mnemonicString.isEmpty() || filePath.isEmpty()) { + if (filePath.isEmpty()) { return; } @@ -669,28 +574,18 @@ void MainWindow::restoreFromMnemonicSeed() { filePath.append(".wallet"); } - CryptoNote::AccountKeys keys; - std::string seed_language = "English"; - if(Crypto::ElectrumWords::words_to_bytes(mnemonicString.toStdString(), keys.spendSecretKey, seed_language)) { - Crypto::secret_key_to_public_key(keys.spendSecretKey,keys.address.spendPublicKey); - Crypto::SecretKey second; - keccak((uint8_t *)&keys.spendSecretKey, sizeof(Crypto::SecretKey), (uint8_t *)&second, sizeof(Crypto::SecretKey)); - Crypto::generate_deterministic_keys(keys.address.viewPublicKey,keys.viewSecretKey,second); + CryptoNote::AccountKeys keys = dlg.getAccountKeys(); - if (WalletAdapter::instance().isOpen()) { - WalletAdapter::instance().close(); - } - WalletAdapter::instance().setWalletFile(filePath); + if (WalletAdapter::instance().isOpen()) { + WalletAdapter::instance().close(); + } + WalletAdapter::instance().setWalletFile(filePath); - quint32 syncHeight = dlg.getSyncHeight(); - if (syncHeight != 0) { - WalletAdapter::instance().createWithKeys(keys, syncHeight); - } else { - WalletAdapter::instance().createWithKeys(keys); - } + quint32 syncHeight = dlg.getSyncHeight(); + if (syncHeight != 0) { + WalletAdapter::instance().createWithKeys(keys, syncHeight); } else { - QMessageBox::critical(nullptr, tr("Mnemonic seed is not correct"), tr("There must be an error in mnemonic seed. Make sure you entered it correctly."), QMessageBox::Ok); - return; + WalletAdapter::instance().createWithKeys(keys); } } } diff --git a/src/gui/RestoreFromMnemonicSeedDialog.cpp b/src/gui/RestoreFromMnemonicSeedDialog.cpp index a50aa7064..dc1bfdb3f 100644 --- a/src/gui/RestoreFromMnemonicSeedDialog.cpp +++ b/src/gui/RestoreFromMnemonicSeedDialog.cpp @@ -1,19 +1,29 @@ // Copyright (c) 2011-2016 The Cryptonote developers // Copyright (c) 2015-2016 XDN developers -// Copyright (c) 2016-2018 The Karbowanec developers +// Copyright (c) 2016-2022 The Karbowanec developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include +#include #include #include "RestoreFromMnemonicSeedDialog.h" +#include "Mnemonics/electrum-words.h" + +extern "C" +{ +#include "crypto/keccak.h" +#include "crypto/crypto-ops.h" +} + #include "ui_restorefrommnemonicseeddialog.h" namespace WalletGui { RestoreFromMnemonicSeedDialog::RestoreFromMnemonicSeedDialog(QWidget* _parent) : QDialog(_parent), m_ui(new Ui::RestoreFromMnemonicSeedDialog) { m_ui->setupUi(this); + m_ui->m_okButton->setEnabled(false); } RestoreFromMnemonicSeedDialog::~RestoreFromMnemonicSeedDialog() { @@ -31,6 +41,10 @@ quint32 RestoreFromMnemonicSeedDialog::getSyncHeight() const { return m_ui->m_syncHeight->value(); } +CryptoNote::AccountKeys RestoreFromMnemonicSeedDialog::getAccountKeys() const { + return m_keys; +} + void RestoreFromMnemonicSeedDialog::selectPathClicked() { QString filePath = QFileDialog::getSaveFileName(this, tr("Wallet file"), #ifdef Q_OS_WIN @@ -64,4 +78,25 @@ void RestoreFromMnemonicSeedDialog::onTextChanged() { } } +void RestoreFromMnemonicSeedDialog::onAccept() { + std::string seed_language = ""; + QString seedString = getSeedString(); + if (!Crypto::ElectrumWords::words_to_bytes(seedString.toStdString(), m_keys.spendSecretKey, seed_language)) { + QMessageBox::critical(nullptr, tr("Mnemonic seed is not correct"), tr("There must be an error in mnemonic seed. Make sure you entered it correctly."), QMessageBox::Ok); + return; + } else { + Crypto::secret_key_to_public_key(m_keys.spendSecretKey,m_keys.address.spendPublicKey); + Crypto::SecretKey second; + keccak((uint8_t *)&m_keys.spendSecretKey, sizeof(Crypto::SecretKey), (uint8_t *)&second, sizeof(Crypto::SecretKey)); + Crypto::generate_deterministic_keys(m_keys.address.viewPublicKey,m_keys.viewSecretKey,second); + } + + if (getFilePath().isEmpty()) { + QMessageBox::critical(nullptr, tr("File path is empty"), tr("Please enter the path where to save the wallet file and its name."), QMessageBox::Ok); + return; + } + + accept(); +} + } diff --git a/src/gui/RestoreFromMnemonicSeedDialog.h b/src/gui/RestoreFromMnemonicSeedDialog.h index 4c5396222..d9467694d 100644 --- a/src/gui/RestoreFromMnemonicSeedDialog.h +++ b/src/gui/RestoreFromMnemonicSeedDialog.h @@ -1,12 +1,13 @@ // Copyright (c) 2011-2016 The Cryptonote developers // Copyright (c) 2015-2016 XDN developers -// Copyright (c) 2016-2017 The Karbowanec developers +// Copyright (c) 2016-2022 The Karbowanec developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #pragma once #include +#include namespace Ui { class RestoreFromMnemonicSeedDialog; @@ -24,14 +25,17 @@ class RestoreFromMnemonicSeedDialog : public QDialog { QString getSeedString() const; QString getFilePath() const; quint32 getSyncHeight() const; + CryptoNote::AccountKeys getAccountKeys() const; private: QScopedPointer m_ui; int wordCount = 0; + CryptoNote::AccountKeys m_keys; Q_SLOT void selectPathClicked(); Q_SLOT void onTextChanged(); + Q_SLOT void onAccept(); }; } diff --git a/src/gui/ui/importkeydialog.ui b/src/gui/ui/importkeydialog.ui index 522f5988d..27f3f5d28 100644 --- a/src/gui/ui/importkeydialog.ui +++ b/src/gui/ui/importkeydialog.ui @@ -125,7 +125,7 @@ m_okButton clicked() ImportKeyDialog - accept() + onAccept() 594 @@ -153,8 +153,25 @@ + + m_keyEdit + textChanged() + ImportKeyDialog + onTextChanged() + + + 323 + 93 + + + 323 + 138 + + + selectPathClicked() + onTextChanged() diff --git a/src/gui/ui/importkeysdialog.ui b/src/gui/ui/importkeysdialog.ui index 7ed37a135..f3a0c595c 100644 --- a/src/gui/ui/importkeysdialog.ui +++ b/src/gui/ui/importkeysdialog.ui @@ -20,54 +20,21 @@ Import private keys - - - - - - - Select folder - - - - + 999999999 - - - - + Where to save new wallet file: - - - - - - - Cancel - - - false - - - - - - - Spend Secret Key: - - - - + Qt::Horizontal @@ -80,21 +47,17 @@ - - - - View Secret Key: - - + + - + Start synchronization from this height (leave empty if unsure): - + OK @@ -107,6 +70,59 @@ + + + + Cancel + + + false + + + + + + + + + + Spend Secret Key: + + + + + + + Select folder + + + + + + + View Secret Key: + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 10 + 40 + + + + @@ -131,7 +147,7 @@ m_okButton clicked() ImportKeysDialog - accept() + onAccept() 594 @@ -159,8 +175,41 @@ + + m_spendKeyEdit + textEdited(QString) + ImportKeysDialog + onTextChanged(QString) + + + 323 + 45 + + + 323 + 141 + + + + + m_viewKeyEdit + textEdited(QString) + ImportKeysDialog + onTextChanged(QString) + + + 323 + 99 + + + 323 + 141 + + + selectPathClicked() + onTextChanged(QString) diff --git a/src/gui/ui/importtrackingkeydialog.ui b/src/gui/ui/importtrackingkeydialog.ui index 7177eaf26..2e0b06336 100644 --- a/src/gui/ui/importtrackingkeydialog.ui +++ b/src/gui/ui/importtrackingkeydialog.ui @@ -128,7 +128,7 @@ m_okButton clicked() ImportTrackingKeyDialog - accept() + onAccept() 594 @@ -156,8 +156,25 @@ + + m_keyEdit + textChanged() + ImportTrackingKeyDialog + onTextChanged() + + + 323 + 62 + + + 323 + 118 + + + selectPathClicked() + onTextChanged() diff --git a/src/gui/ui/restorefrommnemonicseeddialog.ui b/src/gui/ui/restorefrommnemonicseeddialog.ui index babd20368..dee87cda9 100644 --- a/src/gui/ui/restorefrommnemonicseeddialog.ui +++ b/src/gui/ui/restorefrommnemonicseeddialog.ui @@ -132,7 +132,7 @@ m_okButton clicked() RestoreFromMnemonicSeedDialog - accept() + onAccept() 594