]> Nutra Git (v1) - gamesguru/feather.git/commitdiff
wizard: allow restoring from spendkey
authortobtoht <tob@featherwallet.org>
Thu, 26 Jan 2023 17:56:09 +0000 (18:56 +0100)
committertobtoht <tob@featherwallet.org>
Mon, 30 Jan 2023 15:55:39 +0000 (16:55 +0100)
src/WindowManager.cpp
src/wizard/PageWalletRestoreKeys.cpp
src/wizard/PageWalletRestoreKeys.h
src/wizard/PageWalletRestoreKeys.ui

index e6758ad081e44a80bbda5c9db78473724bb26719..a987b527431504645e5f1b7d217d2ee6697edf16 100644 (file)
@@ -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::keyValid(viewkey, address, true, constants::networkType)) {
-        auto err = QString("Failed to create wallet. Invalid viewkey 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 (!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::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);
     }
 
-    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) {
index 34bdbd40bd29edbcdc292c7a680d5a58fef947b3..37eb4404af1cf05eac3bbcdb2cf7b560ff9ce99d 100644 (file)
@@ -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
index 36febe119566e73b3f23437c7bd7c8213f9cd382..780052b6c1556d994e12c5853856a9b3cdebd39e 100644 (file)
@@ -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;
index 90227c1ef9e5dea5d21fe53ce3902c283fa38af4..21b9f05698372384b7302efa626b96334d075b79 100644 (file)
@@ -6,26 +6,66 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>759</width>
-    <height>460</height>
+    <width>529</width>
+    <height>434</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>ViewOnlyPage</string>
   </property>
-  <layout class="QVBoxLayout" name="verticalLayout_3">
-   <property name="topMargin">
-    <number>0</number>
-   </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
    <item>
-    <widget class="QFrame" name="frame_address">
+    <layout class="QHBoxLayout" name="horizontalLayout_3">
+     <item>
+      <widget class="QLabel" name="label_5">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="text">
+        <string>Wallet type:</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QComboBox" name="combo_walletType">
+       <item>
+        <property name="text">
+         <string>View Only</string>
+        </property>
+       </item>
+       <item>
+        <property name="text">
+         <string>Spendable</string>
+        </property>
+       </item>
+       <item>
+        <property name="text">
+         <string>Spendable (Non-deterministic)</string>
+        </property>
+       </item>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="Line" name="line">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QFrame" name="frame_spendKey">
      <property name="frameShape">
       <enum>QFrame::NoFrame</enum>
      </property>
      <property name="frameShadow">
       <enum>QFrame::Raised</enum>
      </property>
-     <layout class="QVBoxLayout" name="verticalLayout_4">
+     <layout class="QVBoxLayout" name="verticalLayout_6">
       <property name="leftMargin">
        <number>0</number>
       </property>
        <number>0</number>
       </property>
       <item>
-       <widget class="QFrame" name="frame">
-        <property name="frameShape">
-         <enum>QFrame::StyledPanel</enum>
-        </property>
-        <property name="frameShadow">
-         <enum>QFrame::Raised</enum>
-        </property>
-        <layout class="QHBoxLayout" name="horizontalLayout">
-         <item>
-          <widget class="QLabel" name="icon">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="text">
-            <string>icon</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <spacer name="horizontalSpacer">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Fixed</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>5</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-         <item>
-          <widget class="QLabel" name="label_4">
-           <property name="text">
-            <string>To restore a view-only wallet leave the spend key blank.</string>
-           </property>
-           <property name="wordWrap">
-            <bool>true</bool>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </widget>
-      </item>
-      <item>
-       <widget class="QLabel" name="label">
+       <widget class="QLabel" name="label_3">
         <property name="text">
-         <string>Primary address</string>
+         <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Secret &lt;span style=&quot; font-weight:600;&quot;&gt;spend&lt;/span&gt; key&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
         </property>
        </widget>
       </item>
       <item>
-       <widget class="QLineEdit" name="line_address"/>
+       <widget class="QLineEdit" name="line_spendkey"/>
       </item>
      </layout>
     </widget>
        <number>0</number>
       </property>
       <item>
-       <widget class="QLabel" name="label_2">
+       <widget class="QLabel" name="label_viewKey">
         <property name="text">
-         <string>Secret view key</string>
+         <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Secret &lt;span style=&quot; font-weight:600;&quot;&gt;view&lt;/span&gt; key&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
         </property>
        </widget>
       </item>
     </widget>
    </item>
    <item>
-    <widget class="QFrame" name="frame_spendKey">
+    <widget class="QFrame" name="frame_address">
      <property name="frameShape">
       <enum>QFrame::NoFrame</enum>
      </property>
      <property name="frameShadow">
       <enum>QFrame::Raised</enum>
      </property>
-     <layout class="QVBoxLayout" name="verticalLayout_6">
+     <layout class="QVBoxLayout" name="verticalLayout_4">
       <property name="leftMargin">
        <number>0</number>
       </property>
        <number>0</number>
       </property>
       <item>
-       <widget class="QLabel" name="label_3">
+       <widget class="QLabel" name="label">
         <property name="text">
-         <string>Secret spend key (optional)</string>
+         <string>Primary address</string>
         </property>
        </widget>
       </item>
       <item>
-       <widget class="QLineEdit" name="line_spendkey"/>
+       <widget class="QLineEdit" name="line_address"/>
       </item>
      </layout>
     </widget>