From 285ce6469a7bfacd854e5ce2b47e63d9754a52cc Mon Sep 17 00:00:00 2001 From: tobtoht Date: Thu, 26 Jan 2023 18:56:09 +0100 Subject: [PATCH] wizard: allow restoring from spendkey --- src/WindowManager.cpp | 49 +++--- src/wizard/PageWalletRestoreKeys.cpp | 81 +++++++--- src/wizard/PageWalletRestoreKeys.h | 8 + src/wizard/PageWalletRestoreKeys.ui | 225 +++++++++++++-------------- 4 files changed, 205 insertions(+), 158 deletions(-) diff --git a/src/WindowManager.cpp b/src/WindowManager.cpp index e6758ad..a987b52 100644 --- a/src/WindowManager.cpp +++ b/src/WindowManager.cpp @@ -163,6 +163,12 @@ void WindowManager::tryOpenWallet(const QString &path, const QString &password) } void WindowManager::onWalletOpened(Wallet *wallet) { + if (!wallet) { + QString err{"Unable to open wallet"}; + this->handleWalletError(err); + return; + } + auto status = wallet->status(); if (status != Wallet::Status_Ok) { QString errMsg = wallet->errorString(); @@ -305,27 +311,34 @@ void WindowManager::tryCreateWalletFromKeys(const QString &path, const QString & return; } - if (!WalletManager::addressValid(address, constants::networkType)) { - auto err = QString("Failed to create wallet. Invalid address provided.").arg(path); - this->handleWalletError(err); - return; + Wallet *wallet; + if (address.isEmpty() && viewkey.isEmpty() && !spendkey.isEmpty()) { + wallet = m_walletManager->createDeterministicWalletFromSpendKey(path, password, constants::seedLanguage, constants::networkType, spendkey, restoreHeight, constants::kdfRounds, "", subaddressLookahead); + } + else { + if (!spendkey.isEmpty() && !WalletManager::keyValid(spendkey, address, false, constants::networkType)) { + auto err = QString("Failed to create wallet. Invalid spendkey provided.").arg(path); + this->handleWalletError(err); + return; + } + + if (!WalletManager::addressValid(address, constants::networkType)) { + auto err = QString("Failed to create wallet. Invalid address provided.").arg(path); + this->handleWalletError(err); + return; + } + + if (!WalletManager::keyValid(viewkey, address, true, constants::networkType)) { + auto err = QString("Failed to create wallet. Invalid viewkey provided.").arg(path); + this->handleWalletError(err); + return; + } + + wallet = m_walletManager->createWalletFromKeys(path, password, constants::seedLanguage, constants::networkType, address, viewkey, spendkey, restoreHeight, constants::kdfRounds, subaddressLookahead); } - if (!WalletManager::keyValid(viewkey, address, true, constants::networkType)) { - auto err = QString("Failed to create wallet. Invalid viewkey provided.").arg(path); - this->handleWalletError(err); - return; - } - - if (!spendkey.isEmpty() && !WalletManager::keyValid(spendkey, address, false, constants::networkType)) { - auto err = QString("Failed to create wallet. Invalid spendkey provided.").arg(path); - this->handleWalletError(err); - return; - } - - Wallet *wallet = m_walletManager->createWalletFromKeys(path, password, constants::seedLanguage, constants::networkType, address, viewkey, spendkey, restoreHeight, constants::kdfRounds, subaddressLookahead); m_openingWallet = true; - m_walletManager->walletOpened(wallet); + this->onWalletOpened(wallet); } void WindowManager::onWalletCreated(Wallet *wallet) { diff --git a/src/wizard/PageWalletRestoreKeys.cpp b/src/wizard/PageWalletRestoreKeys.cpp index 34bdbd4..37eb440 100644 --- a/src/wizard/PageWalletRestoreKeys.cpp +++ b/src/wizard/PageWalletRestoreKeys.cpp @@ -21,9 +21,6 @@ PageWalletRestoreKeys::PageWalletRestoreKeys(WizardFields *fields, QWidget *pare this->setTitle("Restore wallet from keys"); ui->label_errorString->hide(); - QPixmap pixmap = QPixmap(":/assets/images/key.png"); - ui->icon->setPixmap(pixmap.scaledToWidth(32, Qt::SmoothTransformation)); - #ifndef QT_NO_CURSOR QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); QGuiApplication::restoreOverrideCursor(); @@ -35,19 +32,48 @@ PageWalletRestoreKeys::PageWalletRestoreKeys(WizardFields *fields, QWidget *pare ui->line_address->setPlaceholderText("5..."); } + QRegularExpression keyRe(R"([0-9a-fA-F]{64})"); + QValidator *keyValidator = new QRegularExpressionValidator(keyRe, this); + + ui->line_viewkey->setValidator(keyValidator); + ui->line_spendkey->setValidator(keyValidator); + connect(ui->btnOptions, &QPushButton::clicked, this, &PageWalletRestoreKeys::onOptionsClicked); + connect(ui->combo_walletType, &QComboBox::currentTextChanged, this, &PageWalletRestoreKeys::showInputLines); } void PageWalletRestoreKeys::initializePage() { - ui->line_address->setText(""); - ui->line_viewkey->setText(""); - ui->line_spendkey->setText(""); + this->showInputLines(); } int PageWalletRestoreKeys::nextId() const { return WalletWizard::Page_SetRestoreHeight; } +void PageWalletRestoreKeys::showInputLines() { + ui->label_errorString->hide(); + + if (ui->combo_walletType->currentIndex() == walletType::ViewOnly) { + ui->frame_address->show(); + ui->frame_viewKey->show(); + ui->frame_spendKey->hide(); + } + else if (ui->combo_walletType->currentIndex() == walletType::Spendable) { + ui->frame_address->hide(); + ui->frame_viewKey->hide(); + ui->frame_spendKey->show(); + } + else { + ui->frame_address->show(); + ui->frame_viewKey->show(); + ui->frame_spendKey->show(); + } + + ui->line_address->setText(""); + ui->line_viewkey->setText(""); + ui->line_spendkey->setText(""); +} + bool PageWalletRestoreKeys::validatePage() { auto errStyle = "QLineEdit{border: 1px solid red;}"; @@ -59,25 +85,32 @@ bool PageWalletRestoreKeys::validatePage() { QString viewkey = ui->line_viewkey->text().trimmed(); QString spendkey = ui->line_spendkey->text().trimmed(); - if(!WalletManager::addressValid(address, constants::networkType)){ - ui->label_errorString->show(); - ui->label_errorString->setText("Invalid address."); - ui->line_address->setStyleSheet(errStyle); - return false; + if (walletType() == walletType::ViewOnly || walletType() == walletType::Spendable_Nondeterministic) { + if (!WalletManager::addressValid(address, constants::networkType)){ + ui->label_errorString->show(); + ui->label_errorString->setText("Error: Invalid address."); + ui->line_address->setStyleSheet(errStyle); + return false; + } + + if (!WalletManager::keyValid(viewkey, address, true, constants::networkType)) { + ui->label_errorString->show(); + ui->label_errorString->setText("Error: Invalid key."); + ui->line_viewkey->setStyleSheet(errStyle); + return false; + } } - if(!WalletManager::keyValid(viewkey, address, true, constants::networkType)) { - ui->label_errorString->show(); - ui->label_errorString->setText("Invalid key."); - ui->line_viewkey->setStyleSheet(errStyle); - return false; - } + if (walletType() == walletType::Spendable || walletType() == walletType::Spendable_Nondeterministic) { + bool spendKeyValid = (ui->line_spendkey->hasAcceptableInput() && walletType() == walletType::Spendable) + || (WalletManager::keyValid(spendkey, address, false, constants::networkType) && walletType() == walletType::Spendable_Nondeterministic); - if(!spendkey.isEmpty() && !WalletManager::keyValid(spendkey, address, false, constants::networkType)) { - ui->label_errorString->show(); - ui->label_errorString->setText("Invalid key."); - ui->line_viewkey->setStyleSheet(errStyle); - return false; + if (!spendKeyValid) { + ui->label_errorString->show(); + ui->label_errorString->setText("Error: Invalid key."); + ui->line_spendkey->setStyleSheet(errStyle); + return false; + } } m_fields->address = address; @@ -104,4 +137,8 @@ void PageWalletRestoreKeys::onOptionsClicked() { dialog.exec(); m_fields->showSetSubaddressLookaheadPage = check_subaddressLookahead.isChecked(); +} + +int PageWalletRestoreKeys::walletType() { + return ui->combo_walletType->currentIndex(); } \ No newline at end of file diff --git a/src/wizard/PageWalletRestoreKeys.h b/src/wizard/PageWalletRestoreKeys.h index 36febe1..780052b 100644 --- a/src/wizard/PageWalletRestoreKeys.h +++ b/src/wizard/PageWalletRestoreKeys.h @@ -21,14 +21,22 @@ class PageWalletRestoreKeys : public QWizardPage { Q_OBJECT + enum walletType { + ViewOnly = 0, + Spendable = 1, + Spendable_Nondeterministic = 2 + }; + public: explicit PageWalletRestoreKeys(WizardFields *fields, QWidget *parent = nullptr); void initializePage() override; bool validatePage() override; int nextId() const override; + void showInputLines(); private: void onOptionsClicked(); + int walletType(); Ui::PageWalletRestoreKeys *ui; WizardFields *m_fields; diff --git a/src/wizard/PageWalletRestoreKeys.ui b/src/wizard/PageWalletRestoreKeys.ui index 90227c1..21b9f05 100644 --- a/src/wizard/PageWalletRestoreKeys.ui +++ b/src/wizard/PageWalletRestoreKeys.ui @@ -6,134 +6,55 @@ 0 0 - 759 - 460 + 529 + 434 ViewOnlyPage - - - 0 - + - - - QFrame::NoFrame - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - 0 - 0 - - - - icon - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 5 - 20 - - - - - - - - To restore a view-only wallet leave the spend key blank. - - - true - - - - - - - - + + + + + + 0 + 0 + + + + Wallet type: + + + + + + - Primary address + View Only - - - - - - - + + + + Spendable + + + + + Spendable (Non-deterministic) + + + + + - - - QFrame::NoFrame + + + Qt::Horizontal - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Secret view key - - - - - - - @@ -160,7 +81,7 @@ - Secret spend key (optional) + <html><head/><body><p>Secret <span style=" font-weight:600;">spend</span> key</p></body></html> @@ -170,6 +91,74 @@ + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + <html><head/><body><p>Secret <span style=" font-weight:600;">view</span> key</p></body></html> + + + + + + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Primary address + + + + + + + + +