}
void MainWindow::showViewOnlyDialog() {
+ if (!this->verifyPassword()) {
+ return;
+ }
+
ViewOnlyDialog dialog{m_wallet, this};
dialog.exec();
}
#include "utils/Utils.h"
#include "WalletManager.h"
-URDialog::URDialog(QWidget *parent, const std::string &data, bool scanOnly)
+URDialog::URDialog(QWidget *parent)
: WindowModalDialog(parent)
, ui(new Ui::URDialog)
{
ui->setupUi(this);
- if (!data.empty()) {
- ui->btn_loadFile->setVisible(false);
- ui->btn_loadClipboard->setVisible(false);
- ui->tabWidget->setTabVisible(1, false);
-
- QScreen *currentScreen = QApplication::screenAt(this->geometry().center());
- if (!currentScreen) {
- currentScreen = QApplication::primaryScreen();
- }
- int availableHeight = currentScreen->availableGeometry().height() - 200;
- this->resize(availableHeight, availableHeight);
-
- ui->widgetUR->setData("xmr-viewonly", data);
- return;
- }
-
connect(ui->btn_loadFile, &QPushButton::clicked, [this]{
QString fn = QFileDialog::getOpenFileName(this, "Load file", QDir::homePath(), "All Files (*)");
if (fn.isEmpty()) {
return;
}
- if (ui->widgetScanner->getURType() == "xmr-viewonly") {
- std::string urData = ui->widgetScanner->getURData();
- while (true) {
- bool ok;
- QString password = QInputDialog::getText(this, "Encrypt view-only details", "Enter one-time password to decrypt view-only details with", QLineEdit::Password, "", &ok);
- if (!ok) {
- break;
- }
-
- QString data = WalletManager::decryptWithPassword(urData, password);
- if (!data.startsWith("Secret view key")) {
- Utils::showError(this, "Unable to load view-only details", "Invalid password");
- continue;
- }
-
- QRegularExpression viewOnlyDetails(
- "Secret view key: (?<key>[0-9a-f]{64})\nAddress: (?<address>\\w+)\nRestore height: (?<restoreheight>\\d+)\nWallet name: (?<walletname>\\w+)\n",
- QRegularExpression::CaseInsensitiveOption | QRegularExpression::DotMatchesEverythingOption);
- QRegularExpressionMatch match = viewOnlyDetails.match(data);
-
- if (!match.hasMatch()) {
- Utils::showError(this, "Unable to load view-only details", "Unexpected data");
- continue;
- }
-
- m_viewOnlyDetails.address = match.captured("address");
- m_viewOnlyDetails.key = match.captured("key").toLower();
- m_viewOnlyDetails.restoreHeight = match.captured("restoreheight").toInt();
- m_viewOnlyDetails.walletName = QString("%1_view_only").arg(match.captured("walletname"));
-
- this->accept();
- return;
- }
- }
-
if (ui->radio_clipboard->isChecked()) {
Utils::copyToClipboard(QString::fromStdString(ui->widgetScanner->getURData()));
Utils::showInfo(this, "Data copied to clipboard");
ui->widgetScanner->reset();
});
- if (scanOnly) {
- ui->tabWidget->setCurrentIndex(1);
- ui->tabWidget->setTabVisible(0, false);
- ui->radio_clipboard->setVisible(false);
- ui->radio_file->setVisible(false);
- return;
- }
-
ui->radio_file->setChecked(true);
ui->tabWidget->setCurrentIndex(0);
this->resize(600, 700);
}
-ViewOnlyDetails URDialog::getViewOnlyDetails() {
- return m_viewOnlyDetails;
-}
-
URDialog::~URDialog() = default;
\ No newline at end of file
class URDialog;
}
-struct ViewOnlyDetails {
- QString address;
- QString key;
- int restoreHeight = 0;
- QString walletName;
-};
-
class URDialog : public WindowModalDialog
{
Q_OBJECT
public:
- explicit URDialog(QWidget *parent, const std::string &data = "", bool scanOnly = false);
+ explicit URDialog(QWidget *parent);
~URDialog() override;
- ViewOnlyDetails getViewOnlyDetails();
-
private:
QScopedPointer<Ui::URDialog> ui;
- ViewOnlyDetails m_viewOnlyDetails;
};
#include "URDialog.h"
#include "utils/Utils.h"
#include "WalletManager.h"
+#include "qrcode/QrCode.h"
+#include "dialog/QrCodeDialog.h"
ViewOnlyDialog::ViewOnlyDialog(Wallet *wallet, QWidget *parent)
: WindowModalDialog(parent)
connect(ui->btn_Copy, &QPushButton::clicked, this, &ViewOnlyDialog::copyToClipboard);
connect(ui->btn_Save, &QPushButton::clicked, this, &ViewOnlyDialog::onWriteViewOnlyWallet);
connect(ui->btn_transmitOverUR, &QPushButton::clicked, [this] {
- bool ok;
- QString password = QInputDialog::getText(this, "Encrypt view-only details", "Enter one-time password to encrypt view-only details with", QLineEdit::Password, "", &ok);
- if (!ok) {
- return;
- }
-
- std::string encrypted = WalletManager::encryptWithPassword(this->toString(), password);
- URDialog dialog{this, encrypted};
+ QrCode qr(this->toJsonString(), QrCode::Version::AUTO, QrCode::ErrorCorrectionLevel::HIGH);
+ QrCodeDialog dialog{this, &qr, "View-Only details"};
dialog.exec();
});
return text;
}
+QString ViewOnlyDialog::toJsonString() {
+ QVariantMap data;
+ data["version"] = 0,
+ data["primaryAddress"] = m_wallet->address(0, 0);
+ data["privateViewKey"] = m_wallet->getSecretViewKey();
+ data["restoreHeight"] = m_wallet->getWalletCreationHeight();
+ data["walletName"] = m_wallet->walletName();
+
+ auto obj = QJsonDocument::fromVariant(data);
+ return obj.toJson(QJsonDocument::Compact);
+}
+
void ViewOnlyDialog::copyToClipboard() {
Utils::copyToClipboard(this->toString());
}
private:
QString toString();
+ QString toJsonString();
void copyToClipboard();
QScopedPointer<Ui::ViewOnlyDialog> ui;
<item>
<widget class="QPushButton" name="btn_transmitOverUR">
<property name="text">
- <string>Transmit over UR</string>
+ <string>Show QR</string>
</property>
</widget>
</item>
this->setWindowTitle("Scan QR code");
ui->widget_scanner->startCapture(scan_ur);
+
+ connect(ui->widget_scanner, &QrCodeScanWidget::finished, [this]{
+ this->accept();
+ });
}
QString QrCodeScanDialog::decodedString() {
#include "constants.h"
#include "dialog/URDialog.h"
#include "libwalletqt/WalletManager.h"
+#include "scanner/QrCodeScanDialog.h"
PageWalletRestoreKeys::PageWalletRestoreKeys(WizardFields *fields, QWidget *parent)
: QWizardPage(parent)
connect(ui->btnOptions, &QPushButton::clicked, this, &PageWalletRestoreKeys::onOptionsClicked);
connect(ui->combo_walletType, &QComboBox::currentTextChanged, this, &PageWalletRestoreKeys::showInputLines);
connect(ui->btn_scanUR, &QPushButton::clicked, [this] {
- URDialog dialog{this, "", true};
+ QrCodeScanDialog dialog{this, false};
dialog.exec();
- ViewOnlyDetails details = dialog.getViewOnlyDetails();
- ui->line_address->setText(details.address);
+
+ QString json = dialog.decodedString();
+ if (json.isEmpty()) {
+ return;
+ }
+
+ QJsonParseError error;
+ auto doc = QJsonDocument::fromJson(json.toUtf8(), &error);
+ if (error.error != QJsonParseError::NoError) {
+ Utils::showError(this, "Unable to load view-only details", QString("Can't parse JSON: %1").arg(error.errorString()));
+ return;
+ }
+
+ ui->line_address->setText(doc["primaryAddress"].toString());
ui->line_address->setCursorPosition(0);
- ui->line_viewkey->setText(details.key);
+ ui->line_viewkey->setText(doc["privateViewKey"].toString());
ui->line_viewkey->setCursorPosition(0);
- m_fields->restoreHeight = details.restoreHeight;
- m_fields->walletName = details.walletName;
+ m_fields->restoreHeight = doc["restoreHeight"].toInt();
+ m_fields->walletName = doc["walletName"].toString() + "_view_only";
});
}
<item>
<widget class="QPushButton" name="btn_scanUR">
<property name="text">
- <string>Scan UR</string>
+ <string>Scan QR</string>
</property>
</widget>
</item>