connect(m_ctx.get(), &AppContext::initiateTransaction, this, &MainWindow::onInitiateTransaction);
connect(m_ctx.get(), &AppContext::endTransaction, this, &MainWindow::onEndTransaction);
connect(m_ctx.get(), &AppContext::customRestoreHeightSet, this, &MainWindow::onCustomRestoreHeightSet);
+ connect(m_ctx.get(), &AppContext::keysCorrupted, this, &MainWindow::onKeysCorrupted);
// Nodes
connect(m_ctx->nodes, &Nodes::updateStatus, this, &MainWindow::onSetStatusText);
this->menuQuitClicked();
}
+void MainWindow::onKeysCorrupted() {
+ if (!m_criticalWarningShown) {
+ m_criticalWarningShown = true;
+ QMessageBox::warning(this, "Critical error", "WARNING!\n\nThe wallet keys are corrupted.\n\nTo prevent LOSS OF FUNDS do NOT continue to use this wallet file.\n\nRestore your wallet from seed.\n\nPlease report this incident to the Feather developers.\n\nWARNING!");
+ m_sendWidget->disableSendButton();
+ }
+}
+
void MainWindow::onExportHistoryCSV(bool checked) {
if (m_ctx->wallet == nullptr)
return;
void onInitiateTransaction();
void onEndTransaction();
void onCustomRestoreHeightSet(int height);
+ void onKeysCorrupted();
// libwalletqt
void onBalanceUpdated(quint64 balance, quint64 spendable);
QTimer m_txTimer;
bool cleanedUp = false;
+ bool m_criticalWarningShown = false;
EventFilter *m_eventFilter = nullptr;
qint64 m_userLastActive = QDateTime::currentSecsSinceEpoch();
}
void SendWidget::onEndTransaction() {
- ui->btnSend->setEnabled(true);
+ if (!m_sendDisabled) {
+ ui->btnSend->setEnabled(true);
+ }
+}
+
+void SendWidget::disableSendButton() {
+ m_sendDisabled = true;
+ ui->btnSend->setEnabled(false);
}
void SendWidget::onDataPasted(const QString &data) {
void onOpenAliasResolveError(const QString &err);
void onOpenAliasResolved(const QString &openAlias, const QString &address, bool dnssecValid);
void onPreferredFiatCurrencyChanged();
+ void disableSendButton();
void onInitiateTransaction();
void onEndTransaction();
void setupComboBox();
double amountDouble();
- QScopedPointer<Ui::SendWidget> ui;
- QSharedPointer<AppContext> m_ctx;
quint64 amount();
double conversionAmount();
+
+ QScopedPointer<Ui::SendWidget> ui;
+ QSharedPointer<AppContext> m_ctx;
+ bool m_sendDisabled = false;
};
#endif // FEATHER_SENDWIDGET_H
void AppContext::refreshModels() {
this->wallet->history()->refresh(this->wallet->currentSubaddressAccount());
- this->wallet->subaddress()->refresh(this->wallet->currentSubaddressAccount());
this->wallet->coins()->refresh(this->wallet->currentSubaddressAccount());
- // Todo: set timer for refreshes
+ bool r = this->wallet->subaddress()->refresh(this->wallet->currentSubaddressAccount());
+
+ if (!r) {
+ // This should only happen if wallet keys got corrupted or were tampered with
+ // The list of subaddresses is wiped to prevent loss of funds
+ // Notify MainWindow to display an error message
+ emit keysCorrupted();
+ }
}
void deviceButtonRequest(quint64 code);
void deviceButtonPressed();
void deviceError(const QString &message);
+ void keysCorrupted();
private:
DaemonRpc *m_rpc;
return r;
}
-void Subaddress::refresh(quint32 accountIndex) const
+bool Subaddress::refresh(quint32 accountIndex) const
{
- m_subaddressImpl->refresh(accountIndex);
+ bool r = m_subaddressImpl->refresh(accountIndex);
getAll();
+ return r;
}
quint64 Subaddress::unusedLookahead() const
bool getRow(int index, std::function<void (Monero::SubaddressRow &row)> callback) const;
bool addRow(quint32 accountIndex, const QString &label) const;
bool setLabel(quint32 accountIndex, quint32 addressIndex, const QString &label) const;
- void refresh(quint32 accountIndex) const;
+ bool refresh(quint32 accountIndex) const;
quint64 unusedLookahead() const;
quint64 count() const;
QString errorString() const;