refactor: remove appcontext, cleanup Wallet

This commit is contained in:
tobtoht 2023-03-01 03:05:56 +01:00
parent b057f750a5
commit 402bea3fd6
No known key found for this signature in database
GPG key ID: E45B10DD027D2472
82 changed files with 1626 additions and 2340 deletions

2
monero

@ -1 +1 @@
Subproject commit f7705c2c6740699a3fa47895473f79c006624559
Subproject commit 772d207026dac31f927efa733fda3f73b103e71a

View file

@ -9,11 +9,12 @@
#include "dialog/OutputInfoDialog.h"
#include "dialog/OutputSweepDialog.h"
#include "utils/Icons.h"
#include "utils/Utils.h"
CoinsWidget::CoinsWidget(QSharedPointer<AppContext> ctx, QWidget *parent)
CoinsWidget::CoinsWidget(Wallet *wallet, QWidget *parent)
: QWidget(parent)
, ui(new Ui::CoinsWidget)
, m_ctx(std::move(ctx))
, m_wallet(wallet)
, m_headerMenu(new QMenu(this))
, m_copyMenu(new QMenu("Copy",this))
{
@ -71,7 +72,7 @@ CoinsWidget::CoinsWidget(QSharedPointer<AppContext> ctx, QWidget *parent)
connect(ui->search, &QLineEdit::textChanged, this, &CoinsWidget::setSearchFilter);
connect(m_ctx.get(), &AppContext::selectedInputsChanged, this, &CoinsWidget::selectCoins);
connect(m_wallet, &Wallet::selectedInputsChanged, this, &CoinsWidget::selectCoins);
}
void CoinsWidget::setModel(CoinsModel * model, Coins * coins) {
@ -84,7 +85,7 @@ void CoinsWidget::setModel(CoinsModel * model, Coins * coins) {
ui->coins->setColumnHidden(CoinsModel::SpentHeight, true);
ui->coins->setColumnHidden(CoinsModel::Frozen, true);
if (!m_ctx->wallet->viewOnly()) {
if (!m_wallet->viewOnly()) {
ui->coins->setColumnHidden(CoinsModel::KeyImageKnown, true);
} else {
ui->coins->setColumnHidden(CoinsModel::KeyImageKnown, false);
@ -188,7 +189,7 @@ void CoinsWidget::spendSelected() {
keyimages << m_model->entryFromIndex(m_proxyModel->mapToSource(index))->keyImage();
}
m_ctx->setSelectedInputs(keyimages);
m_wallet->setSelectedInputs(keyimages);
this->selectCoins(keyimages);
}
@ -239,7 +240,7 @@ void CoinsWidget::onSweepOutputs() {
int ret = dialog.exec();
if (!ret) return;
m_ctx->onSweepOutputs(keyImages, dialog.address(), dialog.churn(), dialog.outputs());
m_wallet->sweepOutputs(keyImages, dialog.address(), dialog.churn(), dialog.outputs());
}
void CoinsWidget::copy(copyField field) {
@ -298,18 +299,18 @@ QVector<CoinsInfo*> CoinsWidget::currentEntries() {
void CoinsWidget::freezeCoins(QStringList &pubkeys) {
for (auto &pubkey : pubkeys) {
m_ctx->wallet->coins()->freeze(pubkey);
m_wallet->coins()->freeze(pubkey);
}
m_ctx->wallet->coins()->refresh(m_ctx->wallet->currentSubaddressAccount());
m_ctx->updateBalance();
m_wallet->coins()->refresh(m_wallet->currentSubaddressAccount());
m_wallet->updateBalance();
}
void CoinsWidget::thawCoins(QStringList &pubkeys) {
for (auto &pubkey : pubkeys) {
m_ctx->wallet->coins()->thaw(pubkey);
m_wallet->coins()->thaw(pubkey);
}
m_ctx->wallet->coins()->refresh(m_ctx->wallet->currentSubaddressAccount());
m_ctx->updateBalance();
m_wallet->coins()->refresh(m_wallet->currentSubaddressAccount());
m_wallet->updateBalance();
}
void CoinsWidget::selectCoins(const QStringList &keyimages) {

View file

@ -8,10 +8,10 @@
#include <QWidget>
#include <QSvgWidget>
#include "appcontext.h"
#include "model/CoinsModel.h"
#include "model/CoinsProxyModel.h"
#include "libwalletqt/Coins.h"
#include "libwalletqt/Wallet.h"
namespace Ui {
class CoinsWidget;
@ -22,7 +22,7 @@ class CoinsWidget : public QWidget
Q_OBJECT
public:
explicit CoinsWidget(QSharedPointer<AppContext> ctx, QWidget *parent = nullptr);
explicit CoinsWidget(Wallet *wallet, QWidget *parent = nullptr);
void setModel(CoinsModel * model, Coins * coins);
~CoinsWidget() override;
@ -62,7 +62,7 @@ private:
};
QScopedPointer<Ui::CoinsWidget> ui;
QSharedPointer<AppContext> m_ctx;
Wallet *m_wallet;
QMenu *m_contextMenu;
QMenu *m_headerMenu;

View file

@ -8,13 +8,14 @@
#include "dialog/ContactsDialog.h"
#include "libwalletqt/AddressBook.h"
#include "libwalletqt/WalletManager.h"
#include "model/ModelUtils.h"
#include "utils/Icons.h"
ContactsWidget::ContactsWidget(QSharedPointer<AppContext> ctx, QWidget *parent)
ContactsWidget::ContactsWidget(Wallet *wallet, QWidget *parent)
: QWidget(parent)
, ui(new Ui::ContactsWidget)
, m_ctx(std::move(ctx))
, m_wallet(wallet)
{
ui->setupUi(this);
@ -23,7 +24,7 @@ ContactsWidget::ContactsWidget(QSharedPointer<AppContext> ctx, QWidget *parent)
ui->searchLayout->addWidget(m_btn_addContact, 0, Qt::AlignRight);
connect(m_btn_addContact, &QPushButton::clicked, [this]{this->newContact();});
m_model = m_ctx->wallet->addressBookModel();
m_model = m_wallet->addressBookModel();
m_proxyModel = new AddressBookProxyModel;
m_proxyModel->setSourceModel(m_model);
ui->contacts->setModel(m_proxyModel);
@ -124,17 +125,17 @@ void ContactsWidget::newContact(QString address, QString name)
address = dialog.getAddress();
name = dialog.getName();
bool addressValid = WalletManager::addressValid(address, m_ctx->wallet->nettype());
bool addressValid = WalletManager::addressValid(address, m_wallet->nettype());
if (!addressValid) {
QMessageBox::warning(this, "Invalid address", "Invalid address");
return;
}
int num_addresses = m_ctx->wallet->addressBook()->count();
int num_addresses = m_wallet->addressBook()->count();
QString address_entry;
QString name_entry;
for (int i=0; i<num_addresses; i++) {
m_ctx->wallet->addressBook()->getRow(i, [&address_entry, &name_entry](const AddressBookInfo &entry){
m_wallet->addressBook()->getRow(i, [&address_entry, &name_entry](const AddressBookInfo &entry){
address_entry = entry.address();
name_entry = entry.description();
});
@ -151,7 +152,7 @@ void ContactsWidget::newContact(QString address, QString name)
}
}
m_ctx->wallet->addressBook()->addRow(address, "", name);
m_wallet->addressBook()->addRow(address, "", name);
}
void ContactsWidget::deleteContact()

View file

@ -8,9 +8,9 @@
#include <QWidget>
#include <QMenu>
#include "appcontext.h"
#include "model/AddressBookModel.h"
#include "model/AddressBookProxyModel.h"
#include "libwalletqt/Wallet.h"
namespace Ui {
class ContactsWidget;
@ -21,7 +21,7 @@ class ContactsWidget : public QWidget
Q_OBJECT
public:
explicit ContactsWidget(QSharedPointer<AppContext> ctx, QWidget *parent = nullptr);
explicit ContactsWidget(Wallet *wallet, QWidget *parent = nullptr);
~ContactsWidget() override;
void setSearchbarVisible(bool visible);
@ -44,7 +44,7 @@ private slots:
private:
QScopedPointer<Ui::ContactsWidget> ui;
QSharedPointer<AppContext> m_ctx;
Wallet *m_wallet;
QAction *m_showFullAddressesAction;
QMenu *m_rowMenu;

View file

@ -6,20 +6,20 @@
#include <QMessageBox>
#include "appcontext.h"
#include "dialog/TxInfoDialog.h"
#include "dialog/TxProofDialog.h"
#include "libwalletqt/WalletManager.h"
#include "utils/config.h"
#include "utils/Icons.h"
#include "WebsocketNotifier.h"
HistoryWidget::HistoryWidget(QSharedPointer<AppContext> ctx, QWidget *parent)
HistoryWidget::HistoryWidget(Wallet *wallet, QWidget *parent)
: QWidget(parent)
, ui(new Ui::HistoryWidget)
, m_ctx(std::move(ctx))
, m_wallet(wallet)
, m_contextMenu(new QMenu(this))
, m_copyMenu(new QMenu("Copy", this))
, m_model(m_ctx->wallet->historyModel())
, m_model(wallet->historyModel())
{
ui->setupUi(this);
m_contextMenu->addMenu(m_copyMenu);
@ -49,7 +49,7 @@ HistoryWidget::HistoryWidget(QSharedPointer<AppContext> ctx, QWidget *parent)
ui->syncNotice->hide();
});
connect(m_ctx.get(), &AppContext::walletRefreshed, this, &HistoryWidget::onWalletRefreshed);
connect(m_wallet, &Wallet::walletRefreshed, this, &HistoryWidget::onWalletRefreshed);
ui->syncNotice->setVisible(config()->get(Config::showHistorySyncNotice).toBool());
ui->history->setHistoryModel(m_model);
@ -119,7 +119,7 @@ void HistoryWidget::showTxDetails() {
auto *tx = ui->history->currentEntry();
if (!tx) return;
auto *dialog = new TxInfoDialog(m_ctx, tx, this);
auto *dialog = new TxInfoDialog(m_wallet, tx, this);
connect(dialog, &TxInfoDialog::resendTranscation, [this](const QString &txid){
emit resendTransaction(txid);
});
@ -148,7 +148,7 @@ void HistoryWidget::createTxProof() {
auto *tx = ui->history->currentEntry();
if (!tx) return;
TxProofDialog dialog{this, m_ctx, tx};
TxProofDialog dialog{this, m_wallet, tx};
dialog.getTxKey();
dialog.exec();
}

View file

@ -7,7 +7,6 @@
#include <QWidget>
#include <QMenu>
#include "appcontext.h"
#include "libwalletqt/Coins.h"
#include "libwalletqt/Wallet.h"
#include "model/TransactionHistoryModel.h"
@ -22,7 +21,7 @@ class HistoryWidget : public QWidget
Q_OBJECT
public:
explicit HistoryWidget(QSharedPointer<AppContext> ctx, QWidget *parent = nullptr);
explicit HistoryWidget(Wallet *wallet, QWidget *parent = nullptr);
~HistoryWidget() override;
void setSearchbarVisible(bool visible);
@ -58,7 +57,7 @@ private:
void showSyncNoticeMsg();
QScopedPointer<Ui::HistoryWidget> ui;
QSharedPointer<AppContext> m_ctx;
Wallet *m_wallet;
QMenu *m_contextMenu;
QMenu *m_copyMenu;
TransactionHistoryProxyModel *m_model;

View file

@ -43,7 +43,9 @@ MainWindow::MainWindow(WindowManager *windowManager, Wallet *wallet, QWidget *pa
: QMainWindow(parent)
, ui(new Ui::MainWindow)
, m_windowManager(windowManager)
, m_ctx(new AppContext(wallet))
, m_wallet(wallet)
, m_nodes(new Nodes(this, wallet))
, m_rpc(new DaemonRpc(this, ""))
{
ui->setupUi(this);
@ -55,7 +57,7 @@ MainWindow::MainWindow(WindowManager *windowManager, Wallet *wallet, QWidget *pa
m_windowCalc = new CalcWindow(this);
m_splashDialog = new SplashDialog(this);
m_accountSwitcherDialog = new AccountSwitcherDialog(m_ctx, this);
m_accountSwitcherDialog = new AccountSwitcherDialog(m_wallet, this);
m_updater = QSharedPointer<Updater>(new Updater(this));
@ -81,18 +83,9 @@ MainWindow::MainWindow(WindowManager *windowManager, Wallet *wallet, QWidget *pa
connect(m_windowManager, &WindowManager::websocketStatusChanged, this, &MainWindow::onWebsocketStatusChanged);
this->onWebsocketStatusChanged(!config()->get(Config::disableWebsocket).toBool());
connect(m_windowManager, &WindowManager::proxySettingsChanged, [this]{
m_ctx->onProxySettingsChanged();
this->onProxySettingsChanged();
});
connect(m_windowManager, &WindowManager::updateBalance, m_ctx.data(), &AppContext::updateBalance);
connect(m_windowManager, &WindowManager::offlineMode, [this](bool offline){
if (!m_ctx->wallet) {
return;
}
m_ctx->wallet->setOffline(offline);
this->onConnectionStatusChanged(Wallet::ConnectionStatus_Disconnected);
});
connect(m_windowManager, &WindowManager::proxySettingsChanged, this, &MainWindow::onProxySettingsChanged);
connect(m_windowManager, &WindowManager::updateBalance, m_wallet, &Wallet::updateBalance);
connect(m_windowManager, &WindowManager::offlineMode, this, &MainWindow::onOfflineMode);
connect(torManager(), &TorManager::connectionStateChanged, this, &MainWindow::onTorConnectionStateChanged);
this->onTorConnectionStateChanged(torManager()->torConnected);
@ -191,20 +184,20 @@ void MainWindow::initWidgets() {
ui->tabHomeWidget->setCurrentIndex(TabsHome(homeWidget));
// [History]
m_historyWidget = new HistoryWidget(m_ctx, this);
m_historyWidget = new HistoryWidget(m_wallet, this);
ui->historyWidgetLayout->addWidget(m_historyWidget);
connect(m_historyWidget, &HistoryWidget::viewOnBlockExplorer, this, &MainWindow::onViewOnBlockExplorer);
connect(m_historyWidget, &HistoryWidget::resendTransaction, this, &MainWindow::onResendTransaction);
// [Send]
m_sendWidget = new SendWidget(m_ctx, this);
m_sendWidget = new SendWidget(m_wallet, this);
ui->sendWidgetLayout->addWidget(m_sendWidget);
// --------------
m_contactsWidget = new ContactsWidget(m_ctx, this);
m_contactsWidget = new ContactsWidget(m_wallet, this);
ui->contactsWidgetLayout->addWidget(m_contactsWidget);
// [Receive]
m_receiveWidget = new ReceiveWidget(m_ctx, this);
m_receiveWidget = new ReceiveWidget(m_wallet, this);
ui->receiveWidgetLayout->addWidget(m_receiveWidget);
connect(m_receiveWidget, &ReceiveWidget::showTransactions, [this](const QString &text) {
m_historyWidget->setSearchText(text);
@ -213,18 +206,18 @@ void MainWindow::initWidgets() {
connect(m_contactsWidget, &ContactsWidget::fillAddress, m_sendWidget, &SendWidget::fillAddress);
// [Coins]
m_coinsWidget = new CoinsWidget(m_ctx, this);
m_coinsWidget = new CoinsWidget(m_wallet, this);
ui->coinsWidgetLayout->addWidget(m_coinsWidget);
#ifdef HAS_LOCALMONERO
m_localMoneroWidget = new LocalMoneroWidget(this, m_ctx);
m_localMoneroWidget = new LocalMoneroWidget(this, m_wallet);
ui->localMoneroLayout->addWidget(m_localMoneroWidget);
#else
ui->tabWidgetExchanges->setTabVisible(0, false);
#endif
#ifdef HAS_XMRIG
m_xmrig = new XMRigWidget(m_ctx, this);
m_xmrig = new XMRigWidget(m_wallet, this);
ui->xmrRigLayout->addWidget(m_xmrig);
connect(m_xmrig, &XMRigWidget::miningStarted, [this]{ this->updateTitle(); });
@ -239,7 +232,7 @@ void MainWindow::initWidgets() {
ui->frame_coinControl->setVisible(false);
connect(ui->btn_resetCoinControl, &QPushButton::clicked, [this]{
m_ctx->setSelectedInputs({});
m_wallet->setSelectedInputs({});
});
m_walletUnlockWidget = new WalletUnlockWidget(this);
@ -276,8 +269,8 @@ void MainWindow::initMenu() {
// [Wallet] -> [Advanced]
connect(ui->actionStore_wallet, &QAction::triggered, this, &MainWindow::tryStoreWallet);
connect(ui->actionUpdate_balance, &QAction::triggered, [this]{m_ctx->updateBalance();});
connect(ui->actionRefresh_tabs, &QAction::triggered, [this]{m_ctx->refreshModels();});
connect(ui->actionUpdate_balance, &QAction::triggered, [this]{m_wallet->updateBalance();});
connect(ui->actionRefresh_tabs, &QAction::triggered, [this]{m_wallet->refreshModels();});
connect(ui->actionRescan_spent, &QAction::triggered, this, &MainWindow::rescanSpent);
connect(ui->actionWallet_cache_debug, &QAction::triggered, this, &MainWindow::showWalletCacheDebugDialog);
@ -399,14 +392,14 @@ void MainWindow::initMenu() {
void MainWindow::initHome() {
// Ticker widgets
m_tickerWidgets.append(new PriceTickerWidget(this, m_ctx, "XMR"));
m_tickerWidgets.append(new PriceTickerWidget(this, m_ctx, "BTC"));
m_tickerWidgets.append(new RatioTickerWidget(this, m_ctx, "XMR", "BTC"));
m_tickerWidgets.append(new PriceTickerWidget(this, m_wallet, "XMR"));
m_tickerWidgets.append(new PriceTickerWidget(this, m_wallet, "BTC"));
m_tickerWidgets.append(new RatioTickerWidget(this, m_wallet, "XMR", "BTC"));
for (const auto &widget : m_tickerWidgets) {
ui->tickerLayout->addWidget(widget);
}
m_balanceTickerWidget = new BalanceTickerWidget(this, m_ctx, false);
m_balanceTickerWidget = new BalanceTickerWidget(this, m_wallet, false);
ui->fiatTickerLayout->addWidget(m_balanceTickerWidget);
connect(ui->ccsWidget, &CCSWidget::selected, this, &MainWindow::showSendScreen);
@ -419,29 +412,56 @@ void MainWindow::initHome() {
}
void MainWindow::initWalletContext() {
connect(m_ctx.get(), &AppContext::balanceUpdated, this, &MainWindow::onBalanceUpdated);
connect(m_ctx.get(), &AppContext::synchronized, this, &MainWindow::onSynchronized);
connect(m_ctx.get(), &AppContext::blockchainSync, this, &MainWindow::onBlockchainSync);
connect(m_ctx.get(), &AppContext::refreshSync, this, &MainWindow::onRefreshSync);
connect(m_ctx.get(), &AppContext::createTransactionError, this, &MainWindow::onCreateTransactionError);
connect(m_ctx.get(), &AppContext::createTransactionSuccess, this, &MainWindow::onCreateTransactionSuccess);
connect(m_ctx.get(), &AppContext::transactionCommitted, this, &MainWindow::onTransactionCommitted);
connect(m_ctx.get(), &AppContext::deviceError, this, &MainWindow::onDeviceError);
connect(m_ctx.get(), &AppContext::deviceButtonRequest, this, &MainWindow::onDeviceButtonRequest);
connect(m_ctx.get(), &AppContext::deviceButtonPressed, this, &MainWindow::onDeviceButtonPressed);
connect(m_ctx.get(), &AppContext::initiateTransaction, this, &MainWindow::onInitiateTransaction);
connect(m_ctx.get(), &AppContext::endTransaction, this, &MainWindow::onEndTransaction);
connect(m_ctx.get(), &AppContext::keysCorrupted, this, &MainWindow::onKeysCorrupted);
connect(m_ctx.get(), &AppContext::selectedInputsChanged, this, &MainWindow::onSelectedInputsChanged);
connect(m_wallet, &Wallet::balanceUpdated, this, &MainWindow::onBalanceUpdated);
connect(m_wallet, &Wallet::synchronized, this, &MainWindow::onSynchronized); //TODO
connect(m_wallet, &Wallet::blockchainSync, this, &MainWindow::onBlockchainSync);
connect(m_wallet, &Wallet::refreshSync, this, &MainWindow::onRefreshSync);
connect(m_wallet, &Wallet::createTransactionError, this, &MainWindow::onCreateTransactionError);
connect(m_wallet, &Wallet::createTransactionSuccess, this, &MainWindow::onCreateTransactionSuccess);
connect(m_wallet, &Wallet::transactionCommitted, this, &MainWindow::onTransactionCommitted);
connect(m_wallet, &Wallet::initiateTransaction, this, &MainWindow::onInitiateTransaction);
connect(m_wallet, &Wallet::endTransaction, this, &MainWindow::onEndTransaction);
connect(m_wallet, &Wallet::keysCorrupted, this, &MainWindow::onKeysCorrupted);
connect(m_wallet, &Wallet::selectedInputsChanged, this, &MainWindow::onSelectedInputsChanged);
// Wallet
connect(m_ctx->wallet, &Wallet::connectionStatusChanged, [this](int status){
connect(m_wallet, &Wallet::connectionStatusChanged, [this](int status){
// Order is important, first inform UI about a potential disconnect, then reconnect
this->onConnectionStatusChanged(status);
this->m_ctx->nodes->autoConnect();
m_nodes->autoConnect();
});
connect(m_wallet, &Wallet::currentSubaddressAccountChanged, this, &MainWindow::updateTitle);
connect(m_wallet, &Wallet::walletPassphraseNeeded, this, &MainWindow::onWalletPassphraseNeeded);
connect(m_wallet, &Wallet::unconfirmedMoneyReceived, this, [this](const QString &txId, uint64_t amount){
if (m_wallet->isSynchronized()) {
auto notify = QString("%1 XMR (pending)").arg(WalletManager::displayAmount(amount, false));
Utils::desktopNotify("Payment received", notify, 5000);
}
});
// Device
connect(m_wallet, &Wallet::deviceButtonRequest, this, &MainWindow::onDeviceButtonRequest);
connect(m_wallet, &Wallet::deviceButtonPressed, this, &MainWindow::onDeviceButtonPressed);
connect(m_wallet, &Wallet::deviceError, this, &MainWindow::onDeviceError);
connect(m_wallet, &Wallet::donationSent, this, []{
config()->set(Config::donateBeg, -1);
});
connect(m_wallet, &Wallet::multiBroadcast, this, [this](PendingTransaction *tx){
quint64 count = tx->txCount();
for (quint64 i = 0; i < count; i++) {
QString txData = tx->signedTxToHex(i);
for (const auto& node: m_nodes->nodes()) {
QString address = node.toURL();
qDebug() << QString("Relaying %1 to: %2").arg(tx->txid()[i], address);
m_rpc->setDaemonAddress(address);
m_rpc->sendRawTransaction(txData);
}
}
});
connect(m_ctx->wallet, &Wallet::currentSubaddressAccountChanged, this, &MainWindow::updateTitle);
connect(m_ctx->wallet, &Wallet::walletPassphraseNeeded, this, &MainWindow::onWalletPassphraseNeeded);
}
void MainWindow::menuToggleTabVisible(const QString &key){
@ -459,15 +479,15 @@ void MainWindow::menuClearHistoryClicked() {
}
QString MainWindow::walletName() {
return QFileInfo(m_ctx->wallet->cachePath()).fileName();
return QFileInfo(m_wallet->cachePath()).fileName();
}
QString MainWindow::walletCachePath() {
return m_ctx->wallet->cachePath();
return m_wallet->cachePath();
}
QString MainWindow::walletKeysPath() {
return m_ctx->wallet->keysPath();
return m_wallet->keysPath();
}
void MainWindow::displayWalletErrorMsg(const QString &err) {
@ -497,10 +517,10 @@ void MainWindow::onWalletOpened() {
qDebug() << Q_FUNC_INFO;
m_splashDialog->hide();
m_ctx->wallet->setRingDatabase(Utils::ringDatabasePath());
m_wallet->setRingDatabase(Utils::ringDatabasePath());
m_ctx->updateBalance();
if (m_ctx->wallet->isHwBacked()) {
m_wallet->updateBalance();
if (m_wallet->isHwBacked()) {
m_statusBtnHwDevice->show();
}
@ -508,38 +528,39 @@ void MainWindow::onWalletOpened() {
this->setEnabled(true);
// receive page
m_ctx->wallet->subaddress()->refresh(m_ctx->wallet->currentSubaddressAccount());
if (m_ctx->wallet->subaddress()->count() == 1) {
m_wallet->subaddress()->refresh(m_wallet->currentSubaddressAccount());
if (m_wallet->subaddress()->count() == 1) {
for (int i = 0; i < 10; i++) {
m_ctx->wallet->subaddress()->addRow(m_ctx->wallet->currentSubaddressAccount(), "");
m_wallet->subaddress()->addRow(m_wallet->currentSubaddressAccount(), "");
}
}
m_ctx->wallet->subaddressModel()->setCurrentSubaddressAccount(m_ctx->wallet->currentSubaddressAccount());
m_wallet->subaddressModel()->setCurrentSubaddressAccount(m_wallet->currentSubaddressAccount());
// history page
m_ctx->wallet->history()->refresh(m_ctx->wallet->currentSubaddressAccount());
m_wallet->history()->refresh(m_wallet->currentSubaddressAccount());
// coins page
m_ctx->wallet->coins()->refresh(m_ctx->wallet->currentSubaddressAccount());
m_coinsWidget->setModel(m_ctx->wallet->coinsModel(), m_ctx->wallet->coins());
m_ctx->wallet->coinsModel()->setCurrentSubaddressAccount(m_ctx->wallet->currentSubaddressAccount());
m_wallet->coins()->refresh(m_wallet->currentSubaddressAccount());
m_coinsWidget->setModel(m_wallet->coinsModel(), m_wallet->coins());
m_wallet->coinsModel()->setCurrentSubaddressAccount(m_wallet->currentSubaddressAccount());
// Coin labeling uses set_tx_note, so we need to refresh history too
connect(m_ctx->wallet->coins(), &Coins::descriptionChanged, [this] {
m_ctx->wallet->history()->refresh(m_ctx->wallet->currentSubaddressAccount());
connect(m_wallet->coins(), &Coins::descriptionChanged, [this] {
m_wallet->history()->refresh(m_wallet->currentSubaddressAccount());
});
// Vice versa
connect(m_ctx->wallet->history(), &TransactionHistory::txNoteChanged, [this] {
m_ctx->wallet->coins()->refresh(m_ctx->wallet->currentSubaddressAccount());
connect(m_wallet->history(), &TransactionHistory::txNoteChanged, [this] {
m_wallet->coins()->refresh(m_wallet->currentSubaddressAccount());
});
this->updatePasswordIcon();
this->updateTitle();
m_ctx->nodes->connectToNode();
m_nodes->allowConnection();
m_nodes->connectToNode();
m_updateBytes.start(250);
if (config()->get(Config::writeRecentlyOpenedWallets).toBool()) {
this->addToRecentlyOpened(m_ctx->wallet->cachePath());
this->addToRecentlyOpened(m_wallet->cachePath());
}
}
@ -587,13 +608,13 @@ void MainWindow::setStatusText(const QString &text, bool override, int timeout)
}
void MainWindow::tryStoreWallet() {
if (m_ctx->wallet->connectionStatus() == Wallet::ConnectionStatus::ConnectionStatus_Synchronizing) {
if (m_wallet->connectionStatus() == Wallet::ConnectionStatus::ConnectionStatus_Synchronizing) {
QMessageBox::warning(this, "Save wallet", "Unable to save wallet during synchronization.\n\n"
"Wait until synchronization is finished and try again.");
return;
}
m_ctx->wallet->store();
m_wallet->store();
}
void MainWindow::onWebsocketStatusChanged(bool enabled) {
@ -614,6 +635,8 @@ void MainWindow::onWebsocketStatusChanged(bool enabled) {
}
void MainWindow::onProxySettingsChanged() {
m_nodes->connectToNode();
int proxy = config()->get(Config::proxy).toInt();
if (proxy == Config::Proxy::Tor) {
@ -631,6 +654,14 @@ void MainWindow::onProxySettingsChanged() {
m_statusBtnProxySettings->hide();
}
void MainWindow::onOfflineMode(bool offline) {
if (!m_wallet) {
return;
}
m_wallet->setOffline(offline);
this->onConnectionStatusChanged(Wallet::ConnectionStatus_Disconnected);
}
void MainWindow::onSynchronized() {
this->updateNetStats();
this->setStatusText("Synchronized");
@ -693,13 +724,13 @@ void MainWindow::onCreateTransactionSuccess(PendingTransaction *tx, const QVecto
QString tx_err = tx->errorString();
qCritical() << tx_err;
if (m_ctx->wallet->connectionStatus() == Wallet::ConnectionStatus_WrongVersion)
if (m_wallet->connectionStatus() == Wallet::ConnectionStatus_WrongVersion)
err = QString("%1 Wrong node version: %2").arg(err, tx_err);
else
err = QString("%1 %2").arg(err, tx_err);
if (tx_err.contains("Node response did not include the requested real output")) {
QString currentNode = m_ctx->nodes->connection().toAddress();
QString currentNode = m_nodes->connection().toAddress();
err += QString("\nYou are currently connected to: %1\n\n"
"This node may be acting maliciously. You are strongly recommended to disconnect from this node."
@ -708,21 +739,21 @@ void MainWindow::onCreateTransactionSuccess(PendingTransaction *tx, const QVecto
qDebug() << Q_FUNC_INFO << err;
this->displayWalletErrorMsg(err);
m_ctx->wallet->disposeTransaction(tx);
m_wallet->disposeTransaction(tx);
return;
}
else if (tx->txCount() == 0) {
err = QString("%1 %2").arg(err, "No unmixable outputs to sweep.");
qDebug() << Q_FUNC_INFO << err;
this->displayWalletErrorMsg(err);
m_ctx->wallet->disposeTransaction(tx);
m_wallet->disposeTransaction(tx);
return;
}
else if (tx->txCount() > 1) {
err = QString("%1 %2").arg(err, "Split transactions are not supported. Try sending a smaller amount.");
qDebug() << Q_FUNC_INFO << err;
this->displayWalletErrorMsg(err);
m_ctx->wallet->disposeTransaction(tx);
m_wallet->disposeTransaction(tx);
return;
}
@ -743,35 +774,36 @@ void MainWindow::onCreateTransactionSuccess(PendingTransaction *tx, const QVecto
err = QString("%1 %2").arg(err, "Constructed transaction doesn't appear to send to (all) specified destination address(es). Try creating the transaction again.");
qDebug() << Q_FUNC_INFO << err;
this->displayWalletErrorMsg(err);
m_ctx->wallet->disposeTransaction(tx);
m_wallet->disposeTransaction(tx);
return;
}
m_ctx->addCacheTransaction(tx->txid()[0], tx->signedTxToHex(0));
m_wallet->addCacheTransaction(tx->txid()[0], tx->signedTxToHex(0));
// Show advanced dialog on multi-destination transactions
if (address.size() > 1 || m_ctx->wallet->viewOnly()) {
TxConfAdvDialog dialog_adv{m_ctx, m_ctx->tmpTxDescription, this};
dialog_adv.setTransaction(tx, !m_ctx->wallet->viewOnly());
if (address.size() > 1 || m_wallet->viewOnly()) {
TxConfAdvDialog dialog_adv{m_wallet, m_wallet->tmpTxDescription, this};
dialog_adv.setTransaction(tx, !m_wallet->viewOnly());
dialog_adv.exec();
return;
}
TxConfDialog dialog{m_ctx, tx, address[0], m_ctx->tmpTxDescription, this};
TxConfDialog dialog{m_wallet, tx, address[0], m_wallet->tmpTxDescription, this};
switch (dialog.exec()) {
case QDialog::Rejected:
{
if (!dialog.showAdvanced)
m_ctx->onCancelTransaction(tx, address);
if (!dialog.showAdvanced) {
m_wallet->disposeTransaction(tx);
}
break;
}
case QDialog::Accepted:
m_ctx->commitTransaction(tx, m_ctx->tmpTxDescription);
m_wallet->commitTransaction(tx, m_wallet->tmpTxDescription);
break;
}
if (dialog.showAdvanced) {
TxConfAdvDialog dialog_adv{m_ctx, m_ctx->tmpTxDescription, this};
TxConfAdvDialog dialog_adv{m_wallet, m_wallet->tmpTxDescription, this};
dialog_adv.setTransaction(tx);
dialog_adv.exec();
}
@ -789,8 +821,8 @@ void MainWindow::onTransactionCommitted(bool status, PendingTransaction *tx, con
msgBox.exec();
if (msgBox.clickedButton() == showDetailsButton) {
this->showHistoryTab();
TransactionInfo *txInfo = m_ctx->wallet->history()->transaction(txid.first());
auto *dialog = new TxInfoDialog(m_ctx, txInfo, this);
TransactionInfo *txInfo = m_wallet->history()->transaction(txid.first());
auto *dialog = new TxInfoDialog(m_wallet, txInfo, this);
connect(dialog, &TxInfoDialog::resendTranscation, this, &MainWindow::onResendTransaction);
dialog->show();
dialog->setAttribute(Qt::WA_DeleteOnClose);
@ -815,22 +847,22 @@ void MainWindow::onCreateTransactionError(const QString &message) {
}
void MainWindow::showWalletInfoDialog() {
WalletInfoDialog dialog{m_ctx, this};
WalletInfoDialog dialog{m_wallet, this};
dialog.exec();
}
void MainWindow::showSeedDialog() {
if (m_ctx->wallet->isHwBacked()) {
if (m_wallet->isHwBacked()) {
QMessageBox::information(this, "Information", "Seed unavailable: Wallet keys are stored on hardware device.");
return;
}
if (m_ctx->wallet->viewOnly()) {
if (m_wallet->viewOnly()) {
QMessageBox::information(this, "Information", "Wallet is view-only and has no seed.\n\nTo obtain wallet keys go to Wallet -> View-Only");
return;
}
if (!m_ctx->wallet->isDeterministic()) {
if (!m_wallet->isDeterministic()) {
QMessageBox::information(this, "Information", "Wallet is non-deterministic and has no seed.\n\nTo obtain wallet keys go to Wallet -> Keys");
return;
}
@ -839,18 +871,18 @@ void MainWindow::showSeedDialog() {
return;
}
SeedDialog dialog{m_ctx, this};
SeedDialog dialog{m_wallet, this};
dialog.exec();
}
void MainWindow::showPasswordDialog() {
PasswordChangeDialog dialog{this, m_ctx->wallet};
PasswordChangeDialog dialog{this, m_wallet};
dialog.exec();
this->updatePasswordIcon();
}
void MainWindow::updatePasswordIcon() {
bool emptyPassword = m_ctx->wallet->verifyPassword("");
bool emptyPassword = m_wallet->verifyPassword("");
QIcon icon = emptyPassword ? icons()->icon("unlock.svg") : icons()->icon("lock.svg");
m_statusBtnPassword->setIcon(icon);
}
@ -860,12 +892,12 @@ void MainWindow::showKeysDialog() {
return;
}
KeysDialog dialog{m_ctx, this};
KeysDialog dialog{m_wallet, this};
dialog.exec();
}
void MainWindow::showViewOnlyDialog() {
ViewOnlyDialog dialog{m_ctx, this};
ViewOnlyDialog dialog{m_wallet, this};
dialog.exec();
}
@ -900,16 +932,16 @@ void MainWindow::menuAboutClicked() {
}
void MainWindow::menuSettingsClicked(bool showProxyTab) {
m_windowManager->showSettings(m_ctx, this, showProxyTab);
m_windowManager->showSettings(m_nodes, this, showProxyTab);
}
void MainWindow::menuSignVerifyClicked() {
SignVerifyDialog dialog{m_ctx->wallet, this};
SignVerifyDialog dialog{m_wallet, this};
dialog.exec();
}
void MainWindow::menuVerifyTxProof() {
VerifyProofDialog dialog{m_ctx->wallet, this};
VerifyProofDialog dialog{m_wallet, this};
dialog.exec();
}
@ -936,18 +968,18 @@ void MainWindow::updateWidgetIcons() {
QIcon MainWindow::hardwareDevicePairedIcon() {
QString filename;
if (m_ctx->wallet->isLedger())
if (m_wallet->isLedger())
filename = "ledger.png";
else if (m_ctx->wallet->isTrezor())
else if (m_wallet->isTrezor())
filename = ColorScheme::darkScheme ? "trezor_white.png" : "trezor.png";
return icons()->icon(filename);
}
QIcon MainWindow::hardwareDeviceUnpairedIcon() {
QString filename;
if (m_ctx->wallet->isLedger())
if (m_wallet->isLedger())
filename = "ledger_unpaired.png";
else if (m_ctx->wallet->isTrezor())
else if (m_wallet->isTrezor())
filename = ColorScheme::darkScheme ? "trezor_unpaired_white.png" : "trezor_unpaired.png";
return icons()->icon(filename);
}
@ -964,10 +996,10 @@ void MainWindow::closeEvent(QCloseEvent *event) {
m_updateBytes.stop();
m_txTimer.stop();
m_ctx->stopTimers();
// Wallet signal may fire after AppContext is gone, causing segv
m_ctx->wallet->disconnect();
m_wallet->disconnect();
this->disconnect();
this->saveGeo();
m_windowManager->closeWindow(this);
@ -1031,16 +1063,16 @@ void MainWindow::onViewOnBlockExplorer(const QString &txid) {
}
void MainWindow::onResendTransaction(const QString &txid) {
QString txHex = m_ctx->getCacheTransaction(txid);
QString txHex = m_wallet->getCacheTransaction(txid);
if (txHex.isEmpty()) {
QMessageBox::warning(this, "Unable to resend transaction", "Transaction was not found in transaction cache. Unable to resend.");
return;
}
// Connect to a different node so chances of successful relay are higher
m_ctx->nodes->autoConnect(true);
m_nodes->autoConnect(true);
TxBroadcastDialog dialog{this, m_ctx, txHex};
TxBroadcastDialog dialog{this, m_nodes, txHex};
dialog.exec();
}
@ -1048,14 +1080,14 @@ void MainWindow::importContacts() {
const QString targetFile = QFileDialog::getOpenFileName(this, "Import CSV file", QDir::homePath(), "CSV Files (*.csv)");
if(targetFile.isEmpty()) return;
auto *model = m_ctx->wallet->addressBookModel();
auto *model = m_wallet->addressBookModel();
QMapIterator<QString, QString> i(model->readCSV(targetFile));
int inserts = 0;
while (i.hasNext()) {
i.next();
bool addressValid = WalletManager::addressValid(i.value(), m_ctx->wallet->nettype());
bool addressValid = WalletManager::addressValid(i.value(), m_wallet->nettype());
if(addressValid) {
m_ctx->wallet->addressBook()->addRow(i.value(), "", i.key());
m_wallet->addressBook()->addRow(i.value(), "", i.key());
inserts++;
}
}
@ -1075,7 +1107,7 @@ void MainWindow::restoreGeo() {
}
void MainWindow::showDebugInfo() {
DebugInfoDialog dialog{m_ctx, this};
DebugInfoDialog dialog{m_wallet, m_nodes, this};
dialog.exec();
}
@ -1084,7 +1116,7 @@ void MainWindow::showWalletCacheDebugDialog() {
return;
}
WalletCacheDebugDialog dialog{m_ctx, this};
WalletCacheDebugDialog dialog{m_wallet, this};
dialog.exec();
}
@ -1103,7 +1135,7 @@ void MainWindow::showAddressChecker() {
return;
}
SubaddressIndex index = m_ctx->wallet->subaddressIndex(address);
SubaddressIndex index = m_wallet->subaddressIndex(address);
if (!index.isValid()) {
// TODO: probably mention lookahead here
QMessageBox::warning(this, "Address Checker", "This address does not belong to this wallet.");
@ -1117,9 +1149,9 @@ void MainWindow::exportKeyImages() {
QString fn = QFileDialog::getSaveFileName(this, "Save key images to file", QString("%1/%2_%3").arg(QDir::homePath(), this->walletName(), QString::number(QDateTime::currentSecsSinceEpoch())), "Key Images (*_keyImages)");
if (fn.isEmpty()) return;
if (!fn.endsWith("_keyImages")) fn += "_keyImages";
bool r = m_ctx->wallet->exportKeyImages(fn, true);
bool r = m_wallet->exportKeyImages(fn, true);
if (!r) {
QMessageBox::warning(this, "Key image export", QString("Failed to export key images.\nReason: %1").arg(m_ctx->wallet->errorString()));
QMessageBox::warning(this, "Key image export", QString("Failed to export key images.\nReason: %1").arg(m_wallet->errorString()));
} else {
QMessageBox::information(this, "Key image export", "Successfully exported key images.");
}
@ -1128,12 +1160,12 @@ void MainWindow::exportKeyImages() {
void MainWindow::importKeyImages() {
QString fn = QFileDialog::getOpenFileName(this, "Import key image file", QDir::homePath(), "Key Images (*_keyImages)");
if (fn.isEmpty()) return;
bool r = m_ctx->wallet->importKeyImages(fn);
bool r = m_wallet->importKeyImages(fn);
if (!r) {
QMessageBox::warning(this, "Key image import", QString("Failed to import key images.\n\n%1").arg(m_ctx->wallet->errorString()));
QMessageBox::warning(this, "Key image import", QString("Failed to import key images.\n\n%1").arg(m_wallet->errorString()));
} else {
QMessageBox::information(this, "Key image import", "Successfully imported key images");
m_ctx->refreshModels();
m_wallet->refreshModels();
}
}
@ -1141,9 +1173,9 @@ void MainWindow::exportOutputs() {
QString fn = QFileDialog::getSaveFileName(this, "Save outputs to file", QString("%1/%2_%3").arg(QDir::homePath(), this->walletName(), QString::number(QDateTime::currentSecsSinceEpoch())), "Outputs (*_outputs)");
if (fn.isEmpty()) return;
if (!fn.endsWith("_outputs")) fn += "_outputs";
bool r = m_ctx->wallet->exportOutputs(fn, true);
bool r = m_wallet->exportOutputs(fn, true);
if (!r) {
QMessageBox::warning(this, "Outputs export", QString("Failed to export outputs.\nReason: %1").arg(m_ctx->wallet->errorString()));
QMessageBox::warning(this, "Outputs export", QString("Failed to export outputs.\nReason: %1").arg(m_wallet->errorString()));
} else {
QMessageBox::information(this, "Outputs export", "Successfully exported outputs.");
}
@ -1152,20 +1184,20 @@ void MainWindow::exportOutputs() {
void MainWindow::importOutputs() {
QString fn = QFileDialog::getOpenFileName(this, "Import outputs file", QDir::homePath(), "Outputs (*_outputs)");
if (fn.isEmpty()) return;
bool r = m_ctx->wallet->importOutputs(fn);
bool r = m_wallet->importOutputs(fn);
if (!r) {
QMessageBox::warning(this, "Outputs import", QString("Failed to import outputs.\n\n%1").arg(m_ctx->wallet->errorString()));
QMessageBox::warning(this, "Outputs import", QString("Failed to import outputs.\n\n%1").arg(m_wallet->errorString()));
} else {
QMessageBox::information(this, "Outputs import", "Successfully imported outputs");
m_ctx->refreshModels();
m_wallet->refreshModels();
}
}
void MainWindow::loadUnsignedTx() {
QString fn = QFileDialog::getOpenFileName(this, "Select transaction to load", QDir::homePath(), "Transaction (*unsigned_monero_tx)");
if (fn.isEmpty()) return;
UnsignedTransaction *tx = m_ctx->wallet->loadTxFile(fn);
auto err = m_ctx->wallet->errorString();
UnsignedTransaction *tx = m_wallet->loadTxFile(fn);
auto err = m_wallet->errorString();
if (!err.isEmpty()) {
QMessageBox::warning(this, "Load transaction from file", QString("Failed to load transaction.\n\n%1").arg(err));
return;
@ -1180,8 +1212,8 @@ void MainWindow::loadUnsignedTxFromClipboard() {
QMessageBox::warning(this, "Load unsigned transaction from clipboard", "Clipboard is empty");
return;
}
UnsignedTransaction *tx = m_ctx->wallet->loadTxFromBase64Str(unsigned_tx);
auto err = m_ctx->wallet->errorString();
UnsignedTransaction *tx = m_wallet->loadTxFromBase64Str(unsigned_tx);
auto err = m_wallet->errorString();
if (!err.isEmpty()) {
QMessageBox::warning(this, "Load unsigned transaction from clipboard", QString("Failed to load transaction.\n\n%1").arg(err));
return;
@ -1193,25 +1225,25 @@ void MainWindow::loadUnsignedTxFromClipboard() {
void MainWindow::loadSignedTx() {
QString fn = QFileDialog::getOpenFileName(this, "Select transaction to load", QDir::homePath(), "Transaction (*signed_monero_tx)");
if (fn.isEmpty()) return;
PendingTransaction *tx = m_ctx->wallet->loadSignedTxFile(fn);
auto err = m_ctx->wallet->errorString();
PendingTransaction *tx = m_wallet->loadSignedTxFile(fn);
auto err = m_wallet->errorString();
if (!err.isEmpty()) {
QMessageBox::warning(this, "Load signed transaction from file", err);
return;
}
TxConfAdvDialog dialog{m_ctx, "", this};
TxConfAdvDialog dialog{m_wallet, "", this};
dialog.setTransaction(tx);
dialog.exec();
}
void MainWindow::loadSignedTxFromText() {
TxBroadcastDialog dialog{this, m_ctx};
TxBroadcastDialog dialog{this, m_nodes};
dialog.exec();
}
void MainWindow::createUnsignedTxDialog(UnsignedTransaction *tx) {
TxConfAdvDialog dialog{m_ctx, "", this};
TxConfAdvDialog dialog{m_wallet, "", this};
dialog.setUnsignedTransaction(tx);
dialog.exec();
}
@ -1229,11 +1261,13 @@ void MainWindow::importTransaction() {
}
}
TxImportDialog dialog(this, m_ctx);
TxImportDialog dialog(this, m_wallet);
dialog.exec();
}
void MainWindow::onDeviceError(const QString &error) {
qCritical() << "Device error: " << error;
if (m_showDeviceError) {
return;
}
@ -1243,7 +1277,7 @@ void MainWindow::onDeviceError(const QString &error) {
m_showDeviceError = true;
auto result = QMessageBox::question(this, "Hardware device", "Lost connection to hardware device. Attempt to reconnect?");
if (result == QMessageBox::Yes) {
bool r = m_ctx->wallet->reconnectDevice();
bool r = m_wallet->reconnectDevice();
if (r) {
break;
}
@ -1254,14 +1288,14 @@ void MainWindow::onDeviceError(const QString &error) {
}
}
m_statusBtnHwDevice->setIcon(this->hardwareDevicePairedIcon());
m_ctx->wallet->startRefresh();
m_wallet->startRefresh();
m_showDeviceError = false;
}
void MainWindow::onDeviceButtonRequest(quint64 code) {
qDebug() << "DeviceButtonRequest, code: " << code;
if (m_ctx->wallet->isTrezor()) {
if (m_wallet->isTrezor()) {
switch (code) {
case 1:
{
@ -1306,41 +1340,41 @@ void MainWindow::onWalletPassphraseNeeded(bool on_device) {
"the hardware wallet for better security.",
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
if (button == QMessageBox::Yes) {
m_ctx->wallet->onPassphraseEntered("", true, false);
m_wallet->onPassphraseEntered("", true, false);
return;
}
bool ok;
QString passphrase = QInputDialog::getText(nullptr, "Wallet Passphrase Needed", "Enter passphrase:", QLineEdit::EchoMode::Password, "", &ok);
if (ok) {
m_ctx->wallet->onPassphraseEntered(passphrase, false, false);
m_wallet->onPassphraseEntered(passphrase, false, false);
} else {
m_ctx->wallet->onPassphraseEntered(passphrase, false, true);
m_wallet->onPassphraseEntered(passphrase, false, true);
}
}
void MainWindow::updateNetStats() {
if (!m_ctx->wallet || m_ctx->wallet->connectionStatus() == Wallet::ConnectionStatus_Disconnected
|| m_ctx->wallet->connectionStatus() == Wallet::ConnectionStatus_Synchronized)
if (!m_wallet || m_wallet->connectionStatus() == Wallet::ConnectionStatus_Disconnected
|| m_wallet->connectionStatus() == Wallet::ConnectionStatus_Synchronized)
{
m_statusLabelNetStats->hide();
return;
}
m_statusLabelNetStats->show();
m_statusLabelNetStats->setText(QString("(D: %1)").arg(Utils::formatBytes(m_ctx->wallet->getBytesReceived())));
m_statusLabelNetStats->setText(QString("(D: %1)").arg(Utils::formatBytes(m_wallet->getBytesReceived())));
}
void MainWindow::rescanSpent() {
if (!m_ctx->wallet->rescanSpent()) {
QMessageBox::warning(this, "Rescan spent", m_ctx->wallet->errorString());
if (!m_wallet->rescanSpent()) {
QMessageBox::warning(this, "Rescan spent", m_wallet->errorString());
} else {
QMessageBox::information(this, "Rescan spent", "Successfully rescanned spent outputs.");
}
}
void MainWindow::showBalanceDialog() {
BalanceDialog dialog{this, m_ctx->wallet};
BalanceDialog dialog{this, m_wallet};
dialog.exec();
}
@ -1420,7 +1454,7 @@ void MainWindow::onInitiateTransaction() {
m_constructingTransaction = true;
m_txTimer.start(1000);
if (m_ctx->wallet->isHwBacked()) {
if (m_wallet->isHwBacked()) {
QString message = "Constructing transaction: action may be required on device.";
m_splashDialog->setMessage(message);
m_splashDialog->setIcon(QPixmap(":/assets/images/unconfirmed.png"));
@ -1435,7 +1469,7 @@ void MainWindow::onEndTransaction() {
m_txTimer.stop();
this->setStatusText(m_statusText);
if (m_ctx->wallet->isHwBacked()) {
if (m_wallet->isHwBacked()) {
m_splashDialog->hide();
}
}
@ -1456,7 +1490,7 @@ void MainWindow::onSelectedInputsChanged(const QStringList &selectedInputs) {
if (numInputs > 0) {
quint64 totalAmount = 0;
auto coins = m_ctx->wallet->coins()->coinsFromKeyImage(selectedInputs);
auto coins = m_wallet->coins()->coinsFromKeyImage(selectedInputs);
for (const auto coin : coins) {
totalAmount += coin->amount();
}
@ -1467,20 +1501,20 @@ void MainWindow::onSelectedInputsChanged(const QStringList &selectedInputs) {
}
void MainWindow::onExportHistoryCSV(bool checked) {
if (m_ctx->wallet == nullptr)
if (m_wallet == nullptr)
return;
QString fn = QFileDialog::getSaveFileName(this, "Save CSV file", QDir::homePath(), "CSV (*.csv)");
if (fn.isEmpty())
return;
if (!fn.endsWith(".csv"))
fn += ".csv";
m_ctx->wallet->history()->writeCSV(fn);
m_wallet->history()->writeCSV(fn);
QMessageBox::information(this, "CSV export", QString("Transaction history exported to %1").arg(fn));
}
void MainWindow::onExportContactsCSV(bool checked) {
if (m_ctx->wallet == nullptr) return;
auto *model = m_ctx->wallet->addressBookModel();
if (m_wallet == nullptr) return;
auto *model = m_wallet->addressBookModel();
if (model->rowCount() <= 0){
QMessageBox::warning(this, "Error", "Addressbook empty");
return;
@ -1540,19 +1574,19 @@ QString MainWindow::getPlatformTag() {
}
QString MainWindow::getHardwareDevice() {
if (!m_ctx->wallet->isHwBacked())
if (!m_wallet->isHwBacked())
return "";
if (m_ctx->wallet->isTrezor())
if (m_wallet->isTrezor())
return "Trezor";
if (m_ctx->wallet->isLedger())
if (m_wallet->isLedger())
return "Ledger";
return "Unknown";
}
void MainWindow::updateTitle() {
QString title = QString("%1 (#%2)").arg(this->walletName(), QString::number(m_ctx->wallet->currentSubaddressAccount()));
QString title = QString("%1 (#%2)").arg(this->walletName(), QString::number(m_wallet->currentSubaddressAccount()));
if (m_ctx->wallet->viewOnly())
if (m_wallet->viewOnly())
title += " [view-only]";
#ifdef HAS_XMRIG
if (m_xmrig->isMining())
@ -1565,13 +1599,13 @@ void MainWindow::updateTitle() {
}
void MainWindow::donationNag() {
if (m_ctx->networkType != NetworkType::Type::MAINNET)
if (m_wallet->nettype() != NetworkType::Type::MAINNET)
return;
if (m_ctx->wallet->viewOnly())
if (m_wallet->viewOnly())
return;
if (m_ctx->wallet->balanceAll() == 0)
if (m_wallet->balanceAll() == 0)
return;
auto donationCounter = config()->get(Config::donateBeg).toInt();
@ -1640,7 +1674,7 @@ bool MainWindow::verifyPassword(bool sensitive) {
return false;
}
if (!m_ctx->wallet->verifyPassword(passwordDialog.password)) {
if (!m_wallet->verifyPassword(passwordDialog.password)) {
incorrectPassword = true;
continue;
}
@ -1707,7 +1741,7 @@ void MainWindow::unlockWallet(const QString &password) {
return;
}
if (!m_ctx->wallet->verifyPassword(password)) {
if (!m_wallet->verifyPassword(password)) {
m_walletUnlockWidget->incorrectPassword();
return;
}
@ -1742,4 +1776,6 @@ void MainWindow::toggleSearchbar(bool visible) {
m_coinsWidget->focusSearchbar();
}
MainWindow::~MainWindow() = default;
MainWindow::~MainWindow() {
qDebug() << "~MainWindow";
};

View file

@ -8,7 +8,6 @@
#include <QSystemTrayIcon>
#include <QMenu>
#include "appcontext.h"
#include "components.h"
#include "CalcWindow.h"
#include "SettingsDialog.h"
@ -30,6 +29,7 @@
#include "model/CoinsProxyModel.h"
#include "utils/networking.h"
#include "utils/config.h"
#include "utils/daemonrpc.h"
#include "utils/EventFilter.h"
#include "utils/Updater.h"
#include "widgets/CCSWidget.h"
@ -192,6 +192,7 @@ private slots:
void onWebsocketStatusChanged(bool enabled);
void showUpdateNotification();
void onProxySettingsChanged();
void onOfflineMode(bool offline);
private:
friend WindowManager;
@ -235,7 +236,9 @@ private:
QScopedPointer<Ui::MainWindow> ui;
WindowManager *m_windowManager;
QSharedPointer<AppContext> m_ctx;
Wallet *m_wallet = nullptr;
Nodes *m_nodes;
DaemonRpc *m_rpc;
CalcWindow *m_windowCalc = nullptr;
SplashDialog *m_splashDialog = nullptr;

View file

@ -12,15 +12,15 @@
#include "model/ModelUtils.h"
#include "utils/Icons.h"
ReceiveWidget::ReceiveWidget(QSharedPointer<AppContext> ctx, QWidget *parent)
ReceiveWidget::ReceiveWidget(Wallet *wallet, QWidget *parent)
: QWidget(parent)
, ui(new Ui::ReceiveWidget)
, m_ctx(std::move(ctx))
, m_wallet(wallet)
{
ui->setupUi(this);
m_model = m_ctx->wallet->subaddressModel();
m_proxyModel = new SubaddressProxyModel(this, m_ctx->wallet->subaddress());
m_model = m_wallet->subaddressModel();
m_proxyModel = new SubaddressProxyModel(this, m_wallet->subaddress());
m_proxyModel->setSourceModel(m_model);
m_proxyModel->setHiddenAddresses(this->getHiddenAddresses());
@ -112,7 +112,7 @@ void ReceiveWidget::showContextMenu(const QPoint &point) {
menu->addAction("Hide address", this, &ReceiveWidget::hideAddress);
}
if (m_ctx->wallet->isHwBacked()) {
if (m_wallet->isHwBacked()) {
menu->addAction("Show on device", this, &ReceiveWidget::showOnDevice);
}
@ -127,7 +127,7 @@ void ReceiveWidget::createPaymentRequest() {
QString address = index.model()->data(index.siblingAtColumn(SubaddressModel::Address), Qt::UserRole).toString();
PaymentRequestDialog dialog{this, m_ctx, address};
PaymentRequestDialog dialog{this, m_wallet, address};
dialog.exec();
}
@ -189,13 +189,13 @@ void ReceiveWidget::showAddress()
void ReceiveWidget::showOnDevice() {
Monero::SubaddressRow* row = this->currentEntry();
if (!row) return;
m_ctx->wallet->deviceShowAddressAsync(m_ctx->wallet->currentSubaddressAccount(), row->getRowId(), "");
m_wallet->deviceShowAddressAsync(m_wallet->currentSubaddressAccount(), row->getRowId(), "");
}
void ReceiveWidget::generateSubaddress() {
bool r = m_ctx->wallet->subaddress()->addRow(m_ctx->wallet->currentSubaddressAccount(), "");
bool r = m_wallet->subaddress()->addRow(m_wallet->currentSubaddressAccount(), "");
if (!r) {
QMessageBox::warning(this, "Warning", QString("Failed to generate subaddress:\n\n%1").arg(m_ctx->wallet->subaddress()->errorString()));
QMessageBox::warning(this, "Warning", QString("Failed to generate subaddress:\n\n%1").arg(m_wallet->subaddress()->errorString()));
}
}
@ -229,7 +229,7 @@ void ReceiveWidget::showQrCodeDialog() {
}
QStringList ReceiveWidget::getHiddenAddresses() {
QString data = m_ctx->wallet->getCacheAttribute("feather.hiddenaddresses");
QString data = m_wallet->getCacheAttribute("feather.hiddenaddresses");
return data.split(",");
}
@ -239,14 +239,14 @@ void ReceiveWidget::addHiddenAddress(const QString& address) {
hiddenAddresses.append(address);
}
QString data = hiddenAddresses.join(",");
m_ctx->wallet->setCacheAttribute("feather.hiddenaddresses", data);
m_wallet->setCacheAttribute("feather.hiddenaddresses", data);
}
void ReceiveWidget::removeHiddenAddress(const QString &address) {
QStringList hiddenAddresses = this->getHiddenAddresses();
hiddenAddresses.removeAll(address);
QString data = hiddenAddresses.join(",");
m_ctx->wallet->setCacheAttribute("feather.hiddenaddresses", data);
m_wallet->setCacheAttribute("feather.hiddenaddresses", data);
}
Monero::SubaddressRow* ReceiveWidget::currentEntry() {

View file

@ -8,8 +8,8 @@
#include <QWidget>
#include <QSvgWidget>
#include "appcontext.h"
#include "libwalletqt/Subaddress.h"
#include "libwalletqt/Wallet.h"
#include "model/SubaddressProxyModel.h"
#include "model/SubaddressModel.h"
#include "qrcode/QrCode.h"
@ -23,7 +23,7 @@ class ReceiveWidget : public QWidget
Q_OBJECT
public:
explicit ReceiveWidget(QSharedPointer<AppContext> ctx, QWidget *parent = nullptr);
explicit ReceiveWidget(Wallet *wallet, QWidget *parent = nullptr);
~ReceiveWidget() override;
void setSearchbarVisible(bool visible);
@ -53,7 +53,7 @@ private slots:
private:
QScopedPointer<Ui::ReceiveWidget> ui;
QSharedPointer<AppContext> m_ctx;
Wallet *m_wallet;
QMenu *m_headerMenu;
QAction *m_showFullAddressesAction;
QAction *m_showUsedAddressesAction;

View file

@ -9,7 +9,9 @@
#include "ColorScheme.h"
#include "constants.h"
#include "utils/AppData.h"
#include "utils/config.h"
#include "Icons.h"
#include "libwalletqt/WalletManager.h"
#if defined(WITH_SCANNER) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
#include "qrcode_scanner/QrCodeScanDialog.h"
@ -19,10 +21,10 @@
#include <QMediaDevices>
#endif
SendWidget::SendWidget(QSharedPointer<AppContext> ctx, QWidget *parent)
SendWidget::SendWidget(Wallet *wallet, QWidget *parent)
: QWidget(parent)
, ui(new Ui::SendWidget)
, m_ctx(std::move(ctx))
, m_wallet(wallet)
{
ui->setupUi(this);
@ -32,8 +34,8 @@ SendWidget::SendWidget(QSharedPointer<AppContext> ctx, QWidget *parent)
QValidator *validator = new QRegularExpressionValidator(rx, this);
ui->lineAmount->setValidator(validator);
connect(m_ctx.get(), &AppContext::initiateTransaction, this, &SendWidget::onInitiateTransaction);
connect(m_ctx.get(), &AppContext::endTransaction, this, &SendWidget::onEndTransaction);
connect(m_wallet, &Wallet::initiateTransaction, this, &SendWidget::onInitiateTransaction);
connect(m_wallet, &Wallet::endTransaction, this, &SendWidget::onEndTransaction);
connect(WalletManager::instance(), &WalletManager::openAliasResolved, this, &SendWidget::onOpenAliasResolved);
@ -143,14 +145,14 @@ void SendWidget::scanClicked() {
}
void SendWidget::sendClicked() {
if (!m_ctx->wallet->isConnected()) {
if (!m_wallet->isConnected()) {
QMessageBox::warning(this, "Error", "Unable to create transaction:\n\n"
"Wallet is not connected to a node.\n"
"Go to File -> Settings -> Node to manually connect to a node.");
return;
}
if (!m_ctx->wallet->isSynchronized()) {
if (!m_wallet->isSynchronized()) {
QMessageBox::warning(this, "Error", "Wallet is not synchronized, unable to create transaction.\n\n"
"Wait for synchronization to complete.");
return;
@ -189,7 +191,7 @@ void SendWidget::sendClicked() {
amounts.push_back(output.amount);
}
m_ctx->onCreateTransactionMultiDest(addresses, amounts, description);
m_wallet->createTransactionMultiDest(addresses, amounts, description);
return;
}
@ -207,7 +209,7 @@ void SendWidget::sendClicked() {
amount = WalletManager::amountFromDouble(this->conversionAmount());
}
m_ctx->onCreateTransaction(recipient, amount, description, sendAll);
m_wallet->createTransaction(recipient, amount, description, sendAll);
}
void SendWidget::aliasClicked() {
@ -347,7 +349,7 @@ void SendWidget::setWebsocketEnabled(bool enabled) {
void SendWidget::onDataPasted(const QString &data) {
if (!data.isEmpty()) {
QVariantMap uriData = m_ctx->wallet->parse_uri_to_object(data);
QVariantMap uriData = m_wallet->parse_uri_to_object(data);
if (!uriData.contains("error")) {
ui->lineAddress->setText(uriData.value("address").toString());
ui->lineDescription->setText(uriData.value("tx_description").toString());

View file

@ -6,7 +6,7 @@
#include <QWidget>
#include "appcontext.h"
#include "libwalletqt/Wallet.h"
#include "widgets/CCSWidget.h"
namespace Ui {
@ -18,7 +18,7 @@ class SendWidget : public QWidget
Q_OBJECT
public:
explicit SendWidget(QSharedPointer<AppContext> ctx, QWidget *parent = nullptr);
explicit SendWidget(Wallet *wallet, QWidget *parent = nullptr);
void fill(const QString &address, const QString &description, double amount = 0);
void fill(double amount);
void clearFields();
@ -57,7 +57,7 @@ private:
double conversionAmount();
QScopedPointer<Ui::SendWidget> ui;
QSharedPointer<AppContext> m_ctx;
Wallet *m_wallet;
bool m_sendDisabled = false;
};

View file

@ -9,14 +9,16 @@
#include <QFileDialog>
#include <QMessageBox>
#include "libwalletqt/WalletManager.h"
#include "utils/AppData.h"
#include "utils/Icons.h"
#include "utils/WebsocketNotifier.h"
#include "widgets/NetworkProxyWidget.h"
Settings::Settings(QSharedPointer<AppContext> ctx, QWidget *parent)
Settings::Settings(Nodes *nodes, QWidget *parent)
: QDialog(parent)
, ui(new Ui::Settings)
, m_ctx(std::move(ctx))
, m_nodes(nodes)
{
ui->setupUi(this);
@ -150,12 +152,12 @@ void Settings::setupAppearanceTab() {
void Settings::setupNetworkTab() {
// Node
if (m_ctx) {
ui->nodeWidget->setupUI(m_ctx->nodes);
connect(ui->nodeWidget, &NodeWidget::nodeSourceChanged, m_ctx->nodes, &Nodes::onNodeSourceChanged);
connect(ui->nodeWidget, &NodeWidget::connectToNode, m_ctx->nodes, QOverload<const FeatherNode&>::of(&Nodes::connectToNode));
if (m_nodes) {
ui->nodeWidget->setupUI(m_nodes);
connect(ui->nodeWidget, &NodeWidget::nodeSourceChanged, m_nodes, &Nodes::onNodeSourceChanged);
connect(ui->nodeWidget, &NodeWidget::connectToNode, m_nodes, QOverload<const FeatherNode&>::of(&Nodes::connectToNode));
} else {
m_nodes = new Nodes(this);
m_nodes = new Nodes(this, nullptr);
ui->nodeWidget->setupUI(m_nodes);
ui->nodeWidget->setCanConnect(false);
}

View file

@ -9,7 +9,6 @@
#include <QDialog>
#include <QSettings>
#include "appcontext.h"
#include "widgets/NodeWidget.h"
namespace Ui {
@ -21,7 +20,7 @@ class Settings : public QDialog
Q_OBJECT
public:
explicit Settings(QSharedPointer<AppContext> ctx, QWidget *parent = nullptr);
explicit Settings(Nodes *nodes, QWidget *parent = nullptr);
~Settings() override;
void showNetworkProxyTab();
@ -67,7 +66,6 @@ private:
void enableWebsocket(bool enabled);
QScopedPointer<Ui::Settings> ui;
QSharedPointer<AppContext> m_ctx;
Nodes *m_nodes = nullptr;
QStringList m_themes{"Native", "QDarkStyle", "Breeze/Dark", "Breeze/Light"};

View file

@ -13,11 +13,13 @@
#include "utils/Icons.h"
#include "utils/NetworkManager.h"
#include "utils/os/tails.h"
#include "utils/os/whonix.h"
#include "utils/TorManager.h"
#include "utils/WebsocketNotifier.h"
WindowManager::WindowManager(EventFilter *eventFilter)
: eventFilter(eventFilter)
WindowManager::WindowManager(QObject *parent, EventFilter *eventFilter)
: QObject(parent)
, eventFilter(eventFilter)
{
m_walletManager = WalletManager::instance();
m_splashDialog = new SplashDialog;
@ -83,12 +85,15 @@ void WindowManager::close() {
}
void WindowManager::closeWindow(MainWindow *window) {
qDebug() << "closing Window";
m_windows.removeOne(window);
// Move Wallet to a different thread for cleanup so it doesn't block GUI thread
window->m_ctx->wallet->moveToThread(m_cleanupThread);
// Move Wallet to a different thread for cleanup, so it doesn't block GUI thread
window->m_wallet->moveToThread(m_cleanupThread);
m_cleanupThread->start();
window->m_ctx->wallet->deleteLater();
window->m_wallet->deleteLater();
window->deleteLater();
}
void WindowManager::restartApplication(const QString &binaryFilename) {
@ -138,8 +143,8 @@ void WindowManager::raise() {
// ######################## SETTINGS ########################
void WindowManager::showSettings(QSharedPointer<AppContext> ctx, QWidget *parent, bool showProxyTab) {
Settings settings{ctx, parent};
void WindowManager::showSettings(Nodes *nodes, QWidget *parent, bool showProxyTab) {
Settings settings{nodes, parent};
connect(&settings, &Settings::preferredFiatCurrencyChanged, [this]{
for (const auto &window : m_windows) {
@ -301,6 +306,7 @@ void WindowManager::tryCreateWallet(Seed seed, const QString &path, const QStrin
wallet->setCacheAttribute("feather.seed", seed.mnemonic.join(" "));
wallet->setCacheAttribute("feather.seedoffset", seedOffset);
wallet->setNewWallet();
this->onWalletOpened(wallet);
}
@ -359,6 +365,7 @@ void WindowManager::onWalletCreated(Wallet *wallet) {
// Currently only called when a wallet is created from device.
auto state = wallet->status();
if (state != Wallet::Status_Ok) {
wallet->setNewWallet();
qDebug() << Q_FUNC_INFO << QString("Wallet open error: %1").arg(wallet->errorString());
this->displayWalletErrorMessage(wallet->errorString());
m_splashDialog->hide();

View file

@ -10,6 +10,7 @@
#include "libwalletqt/WalletManager.h"
#include "libwalletqt/Wallet.h"
#include "MainWindow.h"
#include "utils/nodes.h"
#include "wizard/WalletWizard.h"
class MainWindow;
@ -17,7 +18,7 @@ class WindowManager : public QObject {
Q_OBJECT
public:
explicit WindowManager(EventFilter *eventFilter);
explicit WindowManager(QObject *parent, EventFilter *eventFilter);
~WindowManager() override;
void wizardOpenWallet();
@ -27,7 +28,7 @@ public:
void restartApplication(const QString &binaryFilename);
void raise();
void showSettings(QSharedPointer<AppContext> ctx, QWidget *parent, bool showProxyTab = false);
void showSettings(Nodes *nodes, QWidget *parent, bool showProxyTab = false);
EventFilter *eventFilter;

View file

@ -1,343 +0,0 @@
// SPDX-License-Identifier: BSD-3-Clause
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
#include <QDir>
#include "appcontext.h"
#include "constants.h"
// libwalletqt
#include "libwalletqt/TransactionHistory.h"
#include "libwalletqt/Subaddress.h"
#include "libwalletqt/Coins.h"
#include "model/TransactionHistoryModel.h"
#include "model/SubaddressModel.h"
#include "utils/NetworkManager.h"
#include "utils/WebsocketClient.h"
#include "utils/WebsocketNotifier.h"
// This class serves as a business logic layer between MainWindow and libwalletqt.
// This way we don't clutter the GUI with wallet logic,
// and keep libwalletqt (mostly) clean of Feather specific implementation details
AppContext::AppContext(Wallet *wallet)
: wallet(wallet)
, nodes(new Nodes(this))
, networkType(constants::networkType)
, m_rpc(new DaemonRpc{this, ""})
{
connect(this->wallet, &Wallet::moneySpent, this, &AppContext::onMoneySpent);
connect(this->wallet, &Wallet::moneyReceived, this, &AppContext::onMoneyReceived);
connect(this->wallet, &Wallet::unconfirmedMoneyReceived, this, &AppContext::onUnconfirmedMoneyReceived);
connect(this->wallet, &Wallet::newBlock, this, &AppContext::onWalletNewBlock);
connect(this->wallet, &Wallet::updated, this, &AppContext::onWalletUpdate);
connect(this->wallet, &Wallet::refreshed, this, &AppContext::onWalletRefreshed);
connect(this->wallet, &Wallet::transactionCommitted, this, &AppContext::onTransactionCommitted);
connect(this->wallet, &Wallet::heightRefreshed, this, &AppContext::onHeightRefreshed);
connect(this->wallet, &Wallet::transactionCreated, this, &AppContext::onTransactionCreated);
connect(this->wallet, &Wallet::deviceError, this, &AppContext::onDeviceError);
connect(this->wallet, &Wallet::deviceButtonRequest, this, &AppContext::onDeviceButtonRequest);
connect(this->wallet, &Wallet::deviceButtonPressed, this, &AppContext::onDeviceButtonPressed);
connect(this->wallet, &Wallet::currentSubaddressAccountChanged, [this]{
this->updateBalance();
});
connect(this, &AppContext::createTransactionError, this, &AppContext::onCreateTransactionError);
nodes->setContext(this);
// Store the wallet every 2 minutes
m_storeTimer.start(2 * 60 * 1000);
connect(&m_storeTimer, &QTimer::timeout, [this](){
this->storeWallet();
});
this->updateBalance();
connect(this->wallet->history(), &TransactionHistory::txNoteChanged, [this]{
this->wallet->history()->refresh(this->wallet->currentSubaddressAccount());
});
}
// ################## Transaction creation ##################
void AppContext::onCreateTransaction(const QString &address, quint64 amount, const QString &description, bool all) {
this->tmpTxDescription = description;
if (!all && amount == 0) {
emit createTransactionError("Cannot send nothing");
return;
}
quint64 unlocked_balance = this->wallet->unlockedBalance();
if (!all && amount > unlocked_balance) {
emit createTransactionError(QString("Not enough money to spend.\n\n"
"Spendable balance: %1").arg(WalletManager::displayAmount(unlocked_balance)));
return;
} else if (unlocked_balance == 0) {
emit createTransactionError("No money to spend");
return;
}
qInfo() << "Creating transaction";
if (all)
this->wallet->createTransactionAllAsync(address, "", constants::mixin, this->tx_priority, m_selectedInputs);
else
this->wallet->createTransactionAsync(address, "", amount, constants::mixin, this->tx_priority, m_selectedInputs);
emit initiateTransaction();
}
void AppContext::onCreateTransactionMultiDest(const QVector<QString> &addresses, const QVector<quint64> &amounts, const QString &description) {
this->tmpTxDescription = description;
quint64 total_amount = 0;
for (auto &amount : amounts) {
total_amount += amount;
}
auto unlocked_balance = this->wallet->unlockedBalance();
if (total_amount > unlocked_balance) {
emit createTransactionError("Not enough money to spend");
}
qInfo() << "Creating transaction";
this->wallet->createTransactionMultiDestAsync(addresses, amounts, this->tx_priority, m_selectedInputs);
emit initiateTransaction();
}
void AppContext::onSweepOutputs(const QVector<QString> &keyImages, QString address, bool churn, int outputs) {
if (churn) {
address = this->wallet->address(0, 0);
}
qInfo() << "Creating transaction";
this->wallet->createTransactionSelectedAsync(keyImages, address, outputs, this->tx_priority);
emit initiateTransaction();
}
void AppContext::onCreateTransactionError(const QString &msg) {
this->tmpTxDescription = "";
emit endTransaction();
}
void AppContext::onCancelTransaction(PendingTransaction *tx, const QVector<QString> &address) {
// tx cancelled by user
emit createTransactionCancelled(address, tx->amount());
this->wallet->disposeTransaction(tx);
}
void AppContext::commitTransaction(PendingTransaction *tx, const QString &description) {
// Clear list of selected transfers
this->setSelectedInputs({});
// Nodes - even well-connected, properly configured ones - consistently fail to relay transactions
// To mitigate transactions failing we just send the transaction to every node we know about over Tor
if (config()->get(Config::multiBroadcast).toBool()) {
this->onMultiBroadcast(tx);
}
this->wallet->commitTransactionAsync(tx, description);
}
void AppContext::onMultiBroadcast(PendingTransaction *tx) {
quint64 count = tx->txCount();
for (quint64 i = 0; i < count; i++) {
QString txData = tx->signedTxToHex(i);
for (const auto& node: this->nodes->nodes()) {
QString address = node.toURL();
qDebug() << QString("Relaying %1 to: %2").arg(tx->txid()[i], address);
m_rpc->setDaemonAddress(address);
m_rpc->sendRawTransaction(txData);
}
}
}
void AppContext::addCacheTransaction(const QString &txid, const QString &txHex) const {
this->wallet->setCacheAttribute(QString("tx:%1").arg(txid), txHex);
}
QString AppContext::getCacheTransaction(const QString &txid) const {
QString txHex = this->wallet->getCacheAttribute(QString("tx:%1").arg(txid));
return txHex;
}
// ################## Device ##################
void AppContext::onDeviceButtonRequest(quint64 code) {
emit deviceButtonRequest(code);
}
void AppContext::onDeviceButtonPressed() {
emit deviceButtonPressed();
}
void AppContext::onDeviceError(const QString &message) {
qCritical() << "Device error: " << message;
emit deviceError(message);
}
// ################## Misc ##################
void AppContext::setSelectedInputs(const QStringList &selectedInputs) {
m_selectedInputs = selectedInputs;
emit selectedInputsChanged(selectedInputs);
}
void AppContext::onProxySettingsChanged() {
if (Utils::isTorsocks()) {
return;
}
this->nodes->connectToNode();
}
void AppContext::stopTimers() {
m_storeTimer.stop();
}
// ########################################## LIBWALLET QT SIGNALS ####################################################
void AppContext::onMoneySpent(const QString &txId, quint64 amount) {
// Outgoing tx included in a block
qDebug() << Q_FUNC_INFO << txId << " " << WalletManager::displayAmount(amount);
}
void AppContext::onMoneyReceived(const QString &txId, quint64 amount) {
// Incoming tx included in a block.
qDebug() << Q_FUNC_INFO << txId << " " << WalletManager::displayAmount(amount);
}
void AppContext::onUnconfirmedMoneyReceived(const QString &txId, quint64 amount) {
// Incoming tx in pool
qDebug() << Q_FUNC_INFO << txId << " " << WalletManager::displayAmount(amount);
if (this->wallet->synchronized()) {
auto notify = QString("%1 XMR (pending)").arg(WalletManager::displayAmount(amount, false));
Utils::desktopNotify("Payment received", notify, 5000);
}
}
void AppContext::onWalletUpdate() {
if (this->wallet->synchronized()) {
this->refreshModels();
this->storeWallet();
}
this->updateBalance();
}
void AppContext::onWalletRefreshed(bool success, const QString &message) {
if (!success) {
// Something went wrong during refresh, in some cases we need to notify the user
qCritical() << "Exception during refresh: " << message; // Can't use ->errorString() here, other SLOT might snipe it first
return;
}
if (!this->refreshed) {
refreshModels();
this->refreshed = true;
emit walletRefreshed();
// store wallet immediately upon finishing synchronization
this->wallet->store();
}
}
void AppContext::onWalletNewBlock(quint64 blockheight, quint64 targetHeight) {
// Called whenever a new block gets scanned by the wallet
this->syncStatusUpdated(blockheight, targetHeight);
if (this->wallet->isSynchronized()) {
this->wallet->coins()->refreshUnlocked();
this->wallet->history()->refresh(this->wallet->currentSubaddressAccount());
// Todo: only refresh tx confirmations
}
}
void AppContext::onHeightRefreshed(quint64 walletHeight, quint64 daemonHeight, quint64 targetHeight) {
if (this->wallet->connectionStatus() == Wallet::ConnectionStatus_Disconnected)
return;
if (daemonHeight < targetHeight) {
emit blockchainSync(daemonHeight, targetHeight);
}
else {
this->syncStatusUpdated(walletHeight, daemonHeight);
}
}
void AppContext::onTransactionCreated(PendingTransaction *tx, const QVector<QString> &address) {
qDebug() << Q_FUNC_INFO;
for (auto &addr : address) {
if (addr == constants::donationAddress) {
this->donationSending = true;
}
}
// Let UI know that the transaction was constructed
emit endTransaction();
// tx created, but not sent yet. ask user to verify first.
emit createTransactionSuccess(tx, address);
}
void AppContext::onTransactionCommitted(bool status, PendingTransaction *tx, const QStringList& txid){
// Store wallet immediately so we don't risk losing tx key if wallet crashes
this->wallet->store();
this->wallet->history()->refresh(this->wallet->currentSubaddressAccount());
this->wallet->coins()->refresh(this->wallet->currentSubaddressAccount());
this->updateBalance();
// this tx was a donation to Feather, stop our nagging
if (this->donationSending) {
this->donationSending = false;
config()->set(Config::donateBeg, -1);
}
emit transactionCommitted(status, tx, txid);
}
void AppContext::storeWallet() {
// Do not store a synchronizing wallet: store() is NOT thread safe and may crash the wallet
if (!this->wallet->isSynchronized())
return;
qDebug() << "Storing wallet";
this->wallet->store();
}
void AppContext::updateBalance() {
quint64 balance = this->wallet->balance();
quint64 spendable = this->wallet->unlockedBalance();
emit balanceUpdated(balance, spendable);
}
void AppContext::syncStatusUpdated(quint64 height, quint64 target) {
if (height < (target - 1)) {
emit refreshSync(height, target);
}
else {
this->updateBalance();
emit synchronized();
}
}
void AppContext::refreshModels() {
this->wallet->history()->refresh(this->wallet->currentSubaddressAccount());
this->wallet->coins()->refresh(this->wallet->currentSubaddressAccount());
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();
}
}

View file

@ -1,103 +0,0 @@
// SPDX-License-Identifier: BSD-3-Clause
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
#ifndef FEATHER_APPCONTEXT_H
#define FEATHER_APPCONTEXT_H
#include <QObject>
#include <QTimer>
#include "utils/os/whonix.h"
#include "utils/networking.h"
#include "utils/Seed.h"
#include "utils/daemonrpc.h"
#include "utils/RestoreHeightLookup.h"
#include "utils/nodes.h"
#include "libwalletqt/WalletManager.h"
#include "PendingTransaction.h"
class AppContext : public QObject
{
Q_OBJECT
public:
explicit AppContext(Wallet *wallet);
Wallet *wallet;
Nodes *nodes;
bool donationSending = false;
QString tmpTxDescription; // TODO: remove the need for this var
NetworkType::Type networkType;
PendingTransaction::Priority tx_priority = PendingTransaction::Priority::Priority_Low;
// libwalletqt
bool refreshed = false;
void commitTransaction(PendingTransaction *tx, const QString &description="");
void syncStatusUpdated(quint64 height, quint64 target);
void updateBalance();
void refreshModels();
void storeWallet();
void stopTimers();
void addCacheTransaction(const QString &txid, const QString &txHex) const;
QString getCacheTransaction(const QString &txid) const;
void setSelectedInputs(const QStringList &selectedInputs);
public slots:
void onCreateTransaction(const QString &address, quint64 amount, const QString &description, bool all);
void onCreateTransactionMultiDest(const QVector<QString> &addresses, const QVector<quint64> &amounts, const QString &description);
void onCancelTransaction(PendingTransaction *tx, const QVector<QString> &address);
void onSweepOutputs(const QVector<QString> &keyImages, QString address, bool churn, int outputs);
void onCreateTransactionError(const QString &msg);
void onMultiBroadcast(PendingTransaction *tx);
void onDeviceButtonRequest(quint64 code);
void onDeviceButtonPressed();
void onDeviceError(const QString &message);
void onProxySettingsChanged(); // should not be here
private slots:
void onMoneySpent(const QString &txId, quint64 amount);
void onMoneyReceived(const QString &txId, quint64 amount);
void onUnconfirmedMoneyReceived(const QString &txId, quint64 amount);
void onWalletUpdate();
void onWalletRefreshed(bool success, const QString &message);
void onWalletNewBlock(quint64 blockheight, quint64 targetHeight);
void onHeightRefreshed(quint64 walletHeight, quint64 daemonHeight, quint64 targetHeight);
void onTransactionCreated(PendingTransaction *tx, const QVector<QString> &address);
void onTransactionCommitted(bool status, PendingTransaction *t, const QStringList& txid);
signals:
void balanceUpdated(quint64 balance, quint64 spendable);
void blockchainSync(int height, int target);
void refreshSync(int height, int target);
void synchronized();
void walletRefreshed();
void transactionCommitted(bool status, PendingTransaction *tx, const QStringList& txid);
void createTransactionError(QString message);
void createTransactionCancelled(const QVector<QString> &address, quint64 amount);
void createTransactionSuccess(PendingTransaction *tx, const QVector<QString> &address);
void initiateTransaction();
void endTransaction();
void deviceButtonRequest(quint64 code);
void deviceButtonPressed();
void deviceError(const QString &message);
void keysCorrupted();
void selectedInputsChanged(const QStringList &selectedInputs);
private:
DaemonRpc *m_rpc;
QTimer m_storeTimer;
QStringList m_selectedInputs;
};
#endif //FEATHER_APPCONTEXT_H

BIN
src/assets/tor2/tor Executable file

Binary file not shown.

View file

@ -7,23 +7,25 @@
#include <QMenu>
#include "libwalletqt/SubaddressAccount.h"
#include "libwalletqt/WalletManager.h"
#include "model/ModelUtils.h"
#include "utils/Icons.h"
#include "utils/Utils.h"
AccountSwitcherDialog::AccountSwitcherDialog(QSharedPointer<AppContext> ctx, QWidget *parent)
AccountSwitcherDialog::AccountSwitcherDialog(Wallet *wallet, QWidget *parent)
: WindowModalDialog(parent)
, ui(new Ui::AccountSwitcherDialog)
, m_ctx(std::move(ctx))
, m_model(m_ctx->wallet->subaddressAccountModel())
, m_wallet(wallet)
, m_model(wallet->subaddressAccountModel())
, m_proxyModel(new SubaddressAccountProxyModel(this))
{
ui->setupUi(this);
m_ctx->wallet->subaddressAccount()->refresh();
m_wallet->subaddressAccount()->refresh();
m_proxyModel->setSourceModel(m_model);
ui->label_totalBalance->setFont(ModelUtils::getMonospaceFont());
ui->label_totalBalance->setText(WalletManager::displayAmount(m_ctx->wallet->balanceAll()));
ui->label_totalBalance->setText(WalletManager::displayAmount(m_wallet->balanceAll()));
this->setWindowModality(Qt::WindowModal);
@ -43,12 +45,12 @@ AccountSwitcherDialog::AccountSwitcherDialog(QSharedPointer<AppContext> ctx, QWi
connect(ui->accounts, &QTreeView::customContextMenuRequested, this, &AccountSwitcherDialog::showContextMenu);
connect(ui->btn_newAccount, &QPushButton::clicked, [this]{
m_ctx->wallet->addSubaddressAccount("New account");
m_ctx->wallet->subaddressAccount()->refresh();
m_wallet->addSubaddressAccount("New account");
m_wallet->subaddressAccount()->refresh();
});
connect(m_ctx->wallet, &Wallet::currentSubaddressAccountChanged, this, &AccountSwitcherDialog::updateSelection);
connect(m_ctx->wallet->subaddressAccount(), &SubaddressAccount::refreshFinished, this, &AccountSwitcherDialog::updateSelection);
connect(m_wallet, &Wallet::currentSubaddressAccountChanged, this, &AccountSwitcherDialog::updateSelection);
connect(m_wallet->subaddressAccount(), &SubaddressAccount::refreshFinished, this, &AccountSwitcherDialog::updateSelection);
this->updateSelection();
}
@ -59,7 +61,7 @@ void AccountSwitcherDialog::switchAccount() {
return;
}
m_ctx->wallet->switchSubaddressAccount(row->getRowId());
m_wallet->switchSubaddressAccount(row->getRowId());
}
void AccountSwitcherDialog::copyLabel() {
@ -81,13 +83,13 @@ void AccountSwitcherDialog::copyBalance() {
}
void AccountSwitcherDialog::editLabel() {
QModelIndex index = ui->accounts->currentIndex().siblingAtColumn(m_ctx->wallet->subaddressAccountModel()->Column::Label);
QModelIndex index = ui->accounts->currentIndex().siblingAtColumn(m_wallet->subaddressAccountModel()->Column::Label);
ui->accounts->setCurrentIndex(index);
ui->accounts->edit(index);
}
void AccountSwitcherDialog::updateSelection() {
QModelIndex index = m_model->index(m_ctx->wallet->currentSubaddressAccount(), 0);
QModelIndex index = m_model->index(m_wallet->currentSubaddressAccount(), 0);
ui->accounts->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
}
@ -108,7 +110,7 @@ void AccountSwitcherDialog::showContextMenu(const QPoint &point) {
Monero::SubaddressAccountRow* AccountSwitcherDialog::currentEntry() {
QModelIndex index = m_proxyModel->mapToSource(ui->accounts->currentIndex());
return m_ctx->wallet->subaddressAccountModel()->entryFromIndex(index);
return m_wallet->subaddressAccountModel()->entryFromIndex(index);
}
AccountSwitcherDialog::~AccountSwitcherDialog() = default;

View file

@ -6,7 +6,7 @@
#include <QDialog>
#include "appcontext.h"
#include "libwalletqt/Wallet.h"
#include "components.h"
#include "model/SubaddressAccountModel.h"
@ -19,7 +19,7 @@ class AccountSwitcherDialog : public WindowModalDialog
Q_OBJECT
public:
explicit AccountSwitcherDialog(QSharedPointer<AppContext> ctx, QWidget *parent = nullptr);
explicit AccountSwitcherDialog(Wallet *wallet, QWidget *parent = nullptr);
~AccountSwitcherDialog() override;
private slots:
@ -35,7 +35,7 @@ private:
Monero::SubaddressAccountRow* currentEntry();
QScopedPointer<Ui::AccountSwitcherDialog> ui;
QSharedPointer<AppContext> m_ctx;
Wallet *m_wallet;
SubaddressAccountModel *m_model;
SubaddressAccountProxyModel *m_proxyModel;
};

View file

@ -5,15 +5,18 @@
#include "ui_DebugInfoDialog.h"
#include "config-feather.h"
#include "utils/AppData.h"
#include "utils/os/tails.h"
#include "utils/os/whonix.h"
#include "utils/TorManager.h"
#include "utils/WebsocketClient.h"
#include "utils/WebsocketNotifier.h"
DebugInfoDialog::DebugInfoDialog(QSharedPointer<AppContext> ctx, QWidget *parent)
DebugInfoDialog::DebugInfoDialog(Wallet *wallet, Nodes *nodes, QWidget *parent)
: WindowModalDialog(parent)
, ui(new Ui::DebugInfoDialog)
, m_ctx(std::move(ctx))
, m_wallet(wallet)
, m_nodes(nodes)
{
ui->setupUi(this);
@ -47,16 +50,16 @@ void DebugInfoDialog::updateInfo() {
ui->label_featherVersion->setText(QString("%1-%2").arg(FEATHER_VERSION, FEATHER_COMMIT));
ui->label_walletHeight->setText(QString::number(m_ctx->wallet->blockChainHeight()));
ui->label_daemonHeight->setText(QString::number(m_ctx->wallet->daemonBlockChainHeight()));
ui->label_targetHeight->setText(QString::number(m_ctx->wallet->daemonBlockChainTargetHeight()));
QDateTime restoreDate = appData()->restoreHeights[constants::networkType]->heightToDate(m_ctx->wallet->getWalletCreationHeight());
ui->label_restoreHeight->setText(QString("%1 (%2)").arg(QString::number(m_ctx->wallet->getWalletCreationHeight()), restoreDate.toString("yyyy-MM-dd")));
ui->label_synchronized->setText(m_ctx->wallet->isSynchronized() ? "True" : "False");
ui->label_walletHeight->setText(QString::number(m_wallet->blockChainHeight()));
ui->label_daemonHeight->setText(QString::number(m_wallet->daemonBlockChainHeight()));
ui->label_targetHeight->setText(QString::number(m_wallet->daemonBlockChainTargetHeight()));
QDateTime restoreDate = appData()->restoreHeights[constants::networkType]->heightToDate(m_wallet->getWalletCreationHeight());
ui->label_restoreHeight->setText(QString("%1 (%2)").arg(QString::number(m_wallet->getWalletCreationHeight()), restoreDate.toString("yyyy-MM-dd")));
ui->label_synchronized->setText(m_wallet->isSynchronized() ? "True" : "False");
auto node = m_ctx->nodes->connection();
auto node = m_nodes->connection();
ui->label_remoteNode->setText(node.toAddress());
ui->label_walletStatus->setText(this->statusToString(m_ctx->wallet->connectionStatus()));
ui->label_walletStatus->setText(this->statusToString(m_wallet->connectionStatus()));
QString websocketStatus = Utils::QtEnumToString(websocketNotifier()->websocketClient.webSocket.state()).remove("State");
if (config()->get(Config::disableWebsocket).toBool()) {
websocketStatus = "Disabled";
@ -66,16 +69,16 @@ void DebugInfoDialog::updateInfo() {
ui->label_torLevel->setText(config()->get(Config::torPrivacyLevel).toString());
QString seedType = [this](){
if (m_ctx->wallet->isHwBacked())
if (m_wallet->isHwBacked())
return QString("Hardware");
return QString("%1 word").arg(m_ctx->wallet->seedLength());
return QString("%1 word").arg(m_wallet->seedLength());
}();
QString deviceType = [this](){
if (m_ctx->wallet->isHwBacked()) {
if (m_ctx->wallet->isLedger())
if (m_wallet->isHwBacked()) {
if (m_wallet->isLedger())
return "Ledger";
else if (m_ctx->wallet->isTrezor())
else if (m_wallet->isTrezor())
return "Trezor";
else
return "Unknown";
@ -85,15 +88,15 @@ void DebugInfoDialog::updateInfo() {
}
}();
QString networkType = Utils::QtEnumToString(m_ctx->wallet->nettype());
QString networkType = Utils::QtEnumToString(m_wallet->nettype());
if (config()->get(Config::offlineMode).toBool()) {
networkType += " (offline)";
}
ui->label_netType->setText(networkType);
ui->label_seedType->setText(seedType);
ui->label_deviceType->setText(deviceType);
ui->label_viewOnly->setText(m_ctx->wallet->viewOnly() ? "True" : "False");
ui->label_primaryOnly->setText(m_ctx->wallet->balance(0) == m_ctx->wallet->balanceAll() ? "True" : "False");
ui->label_viewOnly->setText(m_wallet->viewOnly() ? "True" : "False");
ui->label_primaryOnly->setText(m_wallet->balance(0) == m_wallet->balanceAll() ? "True" : "False");
QString os = QSysInfo::prettyProductName();
if (TailsOS::detect()) {

View file

@ -6,9 +6,9 @@
#include <QDialog>
#include "appcontext.h"
#include "components.h"
#include "libwalletqt/Wallet.h"
#include "utils/nodes.h"
namespace Ui {
class DebugInfoDialog;
@ -19,7 +19,7 @@ class DebugInfoDialog : public WindowModalDialog
Q_OBJECT
public:
explicit DebugInfoDialog(QSharedPointer<AppContext> ctx, QWidget *parent = nullptr);
explicit DebugInfoDialog(Wallet *wallet, Nodes *nodes, QWidget *parent = nullptr);
~DebugInfoDialog() override;
private:
@ -28,7 +28,8 @@ private:
void updateInfo();
QScopedPointer<Ui::DebugInfoDialog> ui;
QSharedPointer<AppContext> m_ctx;
Wallet *m_wallet;
Nodes *m_nodes;
QTimer m_updateTimer;
};

View file

@ -4,7 +4,7 @@
#include "KeysDialog.h"
#include "ui_KeysDialog.h"
KeysDialog::KeysDialog(QSharedPointer<AppContext> ctx, QWidget *parent)
KeysDialog::KeysDialog(Wallet *wallet, QWidget *parent)
: WindowModalDialog(parent)
, ui(new Ui::KeysDialog)
{
@ -12,12 +12,12 @@ KeysDialog::KeysDialog(QSharedPointer<AppContext> ctx, QWidget *parent)
QString unavailable = "Unavailable: Key is stored on hardware device";
ui->label_restoreHeight->setText(QString::number(ctx->wallet->getWalletCreationHeight()));
ui->label_primaryAddress->setText(ctx->wallet->address(0, 0));
ui->label_secretSpendKey->setText(ctx->wallet->isHwBacked() ? unavailable : ctx->wallet->getSecretSpendKey());
ui->label_secretViewKey->setText(ctx->wallet->getSecretViewKey());
ui->label_publicSpendKey->setText(ctx->wallet->getPublicSpendKey());
ui->label_publicViewKey->setText(ctx->wallet->getPublicViewKey());
ui->label_restoreHeight->setText(QString::number(wallet->getWalletCreationHeight()));
ui->label_primaryAddress->setText(wallet->address(0, 0));
ui->label_secretSpendKey->setText(wallet->isHwBacked() ? unavailable : wallet->getSecretSpendKey());
ui->label_secretViewKey->setText(wallet->getSecretViewKey());
ui->label_publicSpendKey->setText(wallet->getPublicSpendKey());
ui->label_publicViewKey->setText(wallet->getPublicViewKey());
this->adjustSize();
}

View file

@ -6,8 +6,8 @@
#include <QDialog>
#include "appcontext.h"
#include "components.h"
#include "libwalletqt/Wallet.h"
namespace Ui {
class KeysDialog;
@ -18,7 +18,7 @@ class KeysDialog : public WindowModalDialog
Q_OBJECT
public:
explicit KeysDialog(QSharedPointer<AppContext> ctx, QWidget *parent = nullptr);
explicit KeysDialog(Wallet *wallet, QWidget *parent = nullptr);
~KeysDialog() override;
private:

View file

@ -10,11 +10,12 @@
#include <QRegularExpressionValidator>
#include "WalletManager.h"
#include "utils/Utils.h"
PaymentRequestDialog::PaymentRequestDialog(QWidget *parent, QSharedPointer<AppContext> ctx, QString address)
PaymentRequestDialog::PaymentRequestDialog(QWidget *parent, Wallet *wallet, QString address)
: WindowModalDialog(parent)
, ui(new Ui::PaymentRequestDialog)
, m_ctx(std::move(ctx))
, m_wallet(wallet)
, m_address(std::move(address))
{
ui->setupUi(this);
@ -45,7 +46,7 @@ void PaymentRequestDialog::updatePaymentRequest() {
QString recipient = ui->line_recipient->text();
quint64 amount = WalletManager::amountFromString(ui->line_amountXMR->text());
QString uri = m_ctx->wallet->make_uri(m_address, amount, description, recipient);
QString uri = m_wallet->make_uri(m_address, amount, description, recipient);
ui->line_paymentRequestUri->setText(uri);
ui->line_paymentRequestUri->setCursorPosition(0);

View file

@ -6,8 +6,8 @@
#include <QDialog>
#include "appcontext.h"
#include "components.h"
#include "libwalletqt/Wallet.h"
#include "qrcode/QrCode.h"
namespace Ui {
@ -19,7 +19,7 @@ class PaymentRequestDialog : public WindowModalDialog
Q_OBJECT
public:
explicit PaymentRequestDialog(QWidget *parent, QSharedPointer<AppContext> ctx, QString address);
explicit PaymentRequestDialog(QWidget *parent, Wallet *wallet, QString address);
~PaymentRequestDialog() override;
private slots:
@ -30,7 +30,7 @@ private slots:
private:
QScopedPointer<Ui::PaymentRequestDialog> ui;
QSharedPointer<AppContext> m_ctx;
Wallet *m_wallet;
QString m_address;
QrCode *m_qrCode;
};

View file

@ -6,26 +6,26 @@
#include "constants.h"
SeedDialog::SeedDialog(QSharedPointer<AppContext> ctx, QWidget *parent)
SeedDialog::SeedDialog(Wallet *wallet, QWidget *parent)
: WindowModalDialog(parent)
, ui(new Ui::SeedDialog)
, m_ctx(std::move(ctx))
, m_wallet(wallet)
{
ui->setupUi(this);
ui->label_seedIcon->setPixmap(QPixmap(":/assets/images/seed.png").scaledToWidth(64, Qt::SmoothTransformation));
ui->label_restoreHeight->setText(QString::number(m_ctx->wallet->getWalletCreationHeight()));
ui->label_restoreHeight->setText(QString::number(m_wallet->getWalletCreationHeight()));
if (m_ctx->wallet->getSeedLanguage().isEmpty()) {
if (m_wallet->getSeedLanguage().isEmpty()) {
qDebug() << "No seed language set, using default";
m_ctx->wallet->setSeedLanguage(constants::seedLanguage);
m_wallet->setSeedLanguage(constants::seedLanguage);
}
QString seedOffset = m_ctx->wallet->getCacheAttribute("feather.seedoffset");
QString seed = m_ctx->wallet->getCacheAttribute("feather.seed");
auto seedLength = m_ctx->wallet->seedLength();
QString seedOffset = m_wallet->getCacheAttribute("feather.seedoffset");
QString seed = m_wallet->getCacheAttribute("feather.seed");
auto seedLength = m_wallet->seedLength();
QString seed_25_words = m_ctx->wallet->getSeed(seedOffset);
QString seed_25_words = m_wallet->getSeed(seedOffset);
if (seedLength >= 24) {
ui->check_toggleSeedType->hide();

View file

@ -6,8 +6,8 @@
#include <QDialog>
#include "appcontext.h"
#include "components.h"
#include "libwalletqt/Wallet.h"
namespace Ui {
class SeedDialog;
@ -18,14 +18,14 @@ class SeedDialog : public WindowModalDialog
Q_OBJECT
public:
explicit SeedDialog(QSharedPointer<AppContext> ctx, QWidget *parent = nullptr);
explicit SeedDialog(Wallet *wallet, QWidget *parent = nullptr);
~SeedDialog() override;
private:
void setSeed(const QString &seed);
QScopedPointer<Ui::SeedDialog> ui;
QSharedPointer<AppContext> m_ctx;
Wallet *m_wallet;
};

View file

@ -8,14 +8,14 @@
#include "utils/NetworkManager.h"
TxBroadcastDialog::TxBroadcastDialog(QWidget *parent, QSharedPointer<AppContext> ctx, const QString &transactionHex)
TxBroadcastDialog::TxBroadcastDialog(QWidget *parent, Nodes *nodes, const QString &transactionHex)
: WindowModalDialog(parent)
, ui(new Ui::TxBroadcastDialog)
, m_ctx(std::move(ctx))
, m_nodes(nodes)
{
ui->setupUi(this);
auto node = m_ctx->nodes->connection();
auto node = m_nodes->connection();
m_rpc = new DaemonRpc(this, node.toAddress());
connect(ui->btn_Broadcast, &QPushButton::clicked, this, &TxBroadcastDialog::broadcastTx);
@ -33,7 +33,7 @@ TxBroadcastDialog::TxBroadcastDialog(QWidget *parent, QSharedPointer<AppContext>
void TxBroadcastDialog::broadcastTx() {
QString tx = ui->transaction->toPlainText();
FeatherNode node = ui->radio_useCustom->isChecked() ? FeatherNode(ui->customNode->text()) : m_ctx->nodes->connection();
FeatherNode node = ui->radio_useCustom->isChecked() ? FeatherNode(ui->customNode->text()) : m_nodes->connection();
m_rpc->setDaemonAddress(node.toURL());
m_rpc->sendRawTransaction(tx);

View file

@ -6,9 +6,9 @@
#include <QDialog>
#include "appcontext.h"
#include "components.h"
#include "utils/daemonrpc.h"
#include "utils/nodes.h"
namespace Ui {
class TxBroadcastDialog;
@ -19,7 +19,7 @@ class TxBroadcastDialog : public WindowModalDialog
Q_OBJECT
public:
explicit TxBroadcastDialog(QWidget *parent, QSharedPointer<AppContext> ctx, const QString &transactionHex = "");
explicit TxBroadcastDialog(QWidget *parent, Nodes *nodes, const QString &transactionHex = "");
~TxBroadcastDialog() override;
private slots:
@ -28,7 +28,7 @@ private slots:
private:
QScopedPointer<Ui::TxBroadcastDialog> ui;
QSharedPointer<AppContext> m_ctx;
Nodes *m_nodes;
DaemonRpc *m_rpc;
};

View file

@ -11,13 +11,17 @@
#include "dialog/QrCodeDialog.h"
#include "libwalletqt/Input.h"
#include "libwalletqt/Transfer.h"
#include "libwalletqt/WalletManager.h"
#include "model/ModelUtils.h"
#include "qrcode/QrCode.h"
#include "utils/AppData.h"
#include "utils/config.h"
#include "utils/Utils.h"
TxConfAdvDialog::TxConfAdvDialog(QSharedPointer<AppContext> ctx, const QString &description, QWidget *parent)
TxConfAdvDialog::TxConfAdvDialog(Wallet *wallet, const QString &description, QWidget *parent)
: WindowModalDialog(parent)
, ui(new Ui::TxConfAdvDialog)
, m_ctx(std::move(ctx))
, m_wallet(wallet)
, m_exportUnsignedMenu(new QMenu(this))
, m_exportSignedMenu(new QMenu(this))
, m_exportTxKeyMenu(new QMenu(this))
@ -65,7 +69,7 @@ void TxConfAdvDialog::setTransaction(PendingTransaction *tx, bool isSigned) {
PendingTransactionInfo *ptx = m_tx->transaction(0); //Todo: support split transactions
// TODO: implement hasTxKey()
if (!m_ctx->wallet->isHwBacked() && m_tx->transaction(0)->txKey() == "0100000000000000000000000000000000000000000000000000000000000000") {
if (!m_wallet->isHwBacked() && m_tx->transaction(0)->txKey() == "0100000000000000000000000000000000000000000000000000000000000000") {
ui->btn_exportTxKey->hide();
}
@ -148,7 +152,7 @@ void TxConfAdvDialog::setupConstructionData(ConstructionInfo *ci) {
for (const auto& o: outputs) {
auto address = o->address();
auto amount = WalletManager::displayAmount(o->amount());
auto index = m_ctx->wallet->subaddressIndex(address);
auto index = m_wallet->subaddressIndex(address);
cursor.insertText(address, Utils::addressTextFormat(index, o->amount()));
cursor.insertText(QString(" %1").arg(amount), QTextCharFormat());
cursor.insertBlock();
@ -205,7 +209,7 @@ void TxConfAdvDialog::signedCopy() {
}
void TxConfAdvDialog::txKeyCopy() {
if (m_ctx->wallet->isHwBacked()) {
if (m_wallet->isHwBacked()) {
QMessageBox::warning(this, "Unable to get tx private key", "Unable to get tx secret key: wallet is backed by hardware device");
return;
}
@ -218,15 +222,15 @@ void TxConfAdvDialog::signedQrCode() {
void TxConfAdvDialog::broadcastTransaction() {
if (m_tx == nullptr) return;
m_ctx->commitTransaction(m_tx, ui->line_description->text());
m_wallet->commitTransaction(m_tx, ui->line_description->text());
QDialog::accept();
}
void TxConfAdvDialog::closeDialog() {
if (m_tx != nullptr)
m_ctx->wallet->disposeTransaction(m_tx);
m_wallet->disposeTransaction(m_tx);
if (m_utx != nullptr)
m_ctx->wallet->disposeTransaction(m_utx);
m_wallet->disposeTransaction(m_utx);
QDialog::reject();
}

View file

@ -9,9 +9,9 @@
#include <QStandardItemModel>
#include <QTextCharFormat>
#include "appcontext.h"
#include "components.h"
#include "libwalletqt/PendingTransaction.h"
#include "libwalletqt/Wallet.h"
namespace Ui {
class TxConfAdvDialog;
@ -22,7 +22,7 @@ class TxConfAdvDialog : public WindowModalDialog
Q_OBJECT
public:
explicit TxConfAdvDialog(QSharedPointer<AppContext> ctx, const QString &description, QWidget *parent = nullptr);
explicit TxConfAdvDialog(Wallet *wallet, const QString &description, QWidget *parent = nullptr);
~TxConfAdvDialog() override;
void setTransaction(PendingTransaction *tx, bool isSigned = true); // #TODO: have libwallet return a UnsignedTransaction, this is just dumb
@ -46,7 +46,7 @@ private:
void txKeyCopy();
QScopedPointer<Ui::TxConfAdvDialog> ui;
QSharedPointer<AppContext> m_ctx;
Wallet *m_wallet;
PendingTransaction *m_tx = nullptr;
UnsignedTransaction *m_utx = nullptr;
QMenu *m_exportUnsignedMenu;

View file

@ -11,11 +11,12 @@
#include "TxConfAdvDialog.h"
#include "utils/AppData.h"
#include "utils/ColorScheme.h"
#include "utils/config.h"
TxConfDialog::TxConfDialog(QSharedPointer<AppContext> ctx, PendingTransaction *tx, const QString &address, const QString &description, QWidget *parent)
TxConfDialog::TxConfDialog(Wallet *wallet, PendingTransaction *tx, const QString &address, const QString &description, QWidget *parent)
: WindowModalDialog(parent)
, ui(new Ui::TxConfDialog)
, m_ctx(std::move(ctx))
, m_wallet(wallet)
, m_tx(tx)
, m_address(address)
, m_description(description)
@ -53,7 +54,7 @@ TxConfDialog::TxConfDialog(QSharedPointer<AppContext> ctx, PendingTransaction *t
ui->label_fee->setText(QString("%1 (%2 %3)").arg(amounts[1], amounts_fiat[1], preferredCur));
ui->label_total->setText(QString("%1 (%2 %3)").arg(amounts[2], amounts_fiat[2], preferredCur));
auto subaddressIndex = m_ctx->wallet->subaddressIndex(address);
auto subaddressIndex = m_wallet->subaddressIndex(address);
QString addressExtra;
ui->label_address->setText(ModelUtils::displayAddress(address, 2));

View file

@ -6,10 +6,10 @@
#include <QDialog>
#include "appcontext.h"
#include "components.h"
#include "libwalletqt/PendingTransaction.h"
#include "libwalletqt/WalletManager.h"
#include "libwalletqt/Wallet.h"
namespace Ui {
class TxConfDialog;
@ -20,7 +20,7 @@ class TxConfDialog : public WindowModalDialog
Q_OBJECT
public:
explicit TxConfDialog(QSharedPointer<AppContext> ctx, PendingTransaction *tx, const QString &address, const QString &description, QWidget *parent = nullptr);
explicit TxConfDialog(Wallet *wallet, PendingTransaction *tx, const QString &address, const QString &description, QWidget *parent = nullptr);
~TxConfDialog() override;
bool showAdvanced = false;
@ -29,7 +29,7 @@ private:
void setShowAdvanced();
QScopedPointer<Ui::TxConfDialog> ui;
QSharedPointer<AppContext> m_ctx;
Wallet *m_wallet;
PendingTransaction *m_tx;
QString m_address;
QString m_description;

View file

@ -8,10 +8,10 @@
#include "utils/NetworkManager.h"
TxImportDialog::TxImportDialog(QWidget *parent, QSharedPointer<AppContext> ctx)
TxImportDialog::TxImportDialog(QWidget *parent, Wallet *wallet)
: WindowModalDialog(parent)
, ui(new Ui::TxImportDialog)
, m_ctx(std::move(ctx))
, m_wallet(wallet)
{
ui->setupUi(this);
@ -23,15 +23,15 @@ TxImportDialog::TxImportDialog(QWidget *parent, QSharedPointer<AppContext> ctx)
void TxImportDialog::onImport() {
QString txid = ui->line_txid->text();
if (m_ctx->wallet->haveTransaction(txid)) {
if (m_wallet->haveTransaction(txid)) {
QMessageBox::warning(this, "Warning", "This transaction already exists in the wallet. "
"If you can't find it in your history, "
"check if it belongs to a different account (Wallet -> Account)");
return;
}
if (m_ctx->wallet->importTransaction(txid)) {
if (!m_ctx->wallet->haveTransaction(txid)) {
if (m_wallet->importTransaction(txid)) {
if (!m_wallet->haveTransaction(txid)) {
QMessageBox::warning(this, "Import transaction", "This transaction does not belong to this wallet.");
return;
}
@ -39,7 +39,7 @@ void TxImportDialog::onImport() {
} else {
QMessageBox::warning(this, "Import transaction", "Transaction import failed.");
}
m_ctx->refreshModels();
m_wallet->refreshModels();
}
TxImportDialog::~TxImportDialog() = default;

View file

@ -6,9 +6,9 @@
#include <QDialog>
#include "appcontext.h"
#include "components.h"
#include "utils/daemonrpc.h"
#include "libwalletqt/Wallet.h"
namespace Ui {
class TxImportDialog;
@ -19,7 +19,7 @@ class TxImportDialog : public WindowModalDialog
Q_OBJECT
public:
explicit TxImportDialog(QWidget *parent, QSharedPointer<AppContext> ctx);
explicit TxImportDialog(QWidget *parent, Wallet *wallet);
~TxImportDialog() override;
private slots:
@ -27,7 +27,7 @@ private slots:
private:
QScopedPointer<Ui::TxImportDialog> ui;
QSharedPointer<AppContext> m_ctx;
Wallet *m_wallet;
};

View file

@ -7,7 +7,6 @@
#include <QMessageBox>
#include <QScrollBar>
#include "appcontext.h"
#include "config.h"
#include "constants.h"
#include "libwalletqt/Coins.h"
@ -19,12 +18,12 @@
#include "Utils.h"
#include "utils/Icons.h"
TxInfoDialog::TxInfoDialog(QSharedPointer<AppContext> ctx, TransactionInfo *txInfo, QWidget *parent)
TxInfoDialog::TxInfoDialog(Wallet *wallet, TransactionInfo *txInfo, QWidget *parent)
: QDialog(parent)
, ui(new Ui::TxInfoDialog)
, m_ctx(std::move(ctx))
, m_wallet(wallet)
, m_txInfo(txInfo)
, m_txProofDialog(new TxProofDialog(this, m_ctx, txInfo))
, m_txProofDialog(new TxProofDialog(this, wallet, txInfo))
{
ui->setupUi(this);
@ -39,7 +38,7 @@ TxInfoDialog::TxInfoDialog(QSharedPointer<AppContext> ctx, TransactionInfo *txIn
connect(ui->btn_CopyTxKey, &QPushButton::clicked, this, &TxInfoDialog::copyTxKey);
connect(ui->btn_createTxProof, &QPushButton::clicked, this, &TxInfoDialog::createTxProof);
connect(m_ctx->wallet, &Wallet::newBlock, this, &TxInfoDialog::updateData);
connect(m_wallet, &Wallet::newBlock, this, &TxInfoDialog::updateData);
this->setData(txInfo);
@ -79,7 +78,7 @@ TxInfoDialog::TxInfoDialog(QSharedPointer<AppContext> ctx, TransactionInfo *txIn
for (const auto& transfer : transfers) {
auto address = transfer->address();
auto amount = WalletManager::displayAmount(transfer->amount());
auto index = m_ctx->wallet->subaddressIndex(address);
auto index = m_wallet->subaddressIndex(address);
cursor.insertText(address, Utils::addressTextFormat(index, transfer->amount()));
cursor.insertText(QString(" %1").arg(amount), QTextCharFormat());
cursor.insertBlock();
@ -151,7 +150,7 @@ void TxInfoDialog::setData(TransactionInfo *tx) {
}
void TxInfoDialog::updateData() {
TransactionInfo *tx = m_ctx->wallet->history()->transaction(m_txid);
TransactionInfo *tx = m_wallet->history()->transaction(m_txid);
if (!tx) return;
this->setData(tx);
}
@ -161,12 +160,12 @@ void TxInfoDialog::copyTxID() {
}
void TxInfoDialog::copyTxKey() {
if (m_ctx->wallet->isHwBacked()) {
if (m_wallet->isHwBacked()) {
QMessageBox::warning(this, "Unable to get tx private key", "Unable to get tx secret key: wallet is backed by hardware device");
return;
}
m_ctx->wallet->getTxKeyAsync(m_txid, [this](QVariantMap map){
m_wallet->getTxKeyAsync(m_txid, [this](QVariantMap map){
QString txKey = map.value("tx_key").toString();
if (txKey.isEmpty()) {
QMessageBox::warning(this, "Unable to copy transaction key", "Transaction key unknown");

View file

@ -9,7 +9,6 @@
#include <QTextEdit>
#include <QSvgWidget>
#include "appcontext.h"
#include "dialog/TxProofDialog.h"
namespace Ui {
@ -21,7 +20,7 @@ class TxInfoDialog : public QDialog
Q_OBJECT
public:
explicit TxInfoDialog(QSharedPointer<AppContext> ctx, TransactionInfo *txInfo, QWidget *parent = nullptr);
explicit TxInfoDialog(Wallet *wallet, TransactionInfo *txInfo, QWidget *parent = nullptr);
~TxInfoDialog() override;
signals:
@ -37,7 +36,7 @@ private:
void viewOnBlockExplorer();
QScopedPointer<Ui::TxInfoDialog> ui;
QSharedPointer<AppContext> m_ctx;
Wallet *m_wallet;
TransactionInfo *m_txInfo;
TxProofDialog *m_txProofDialog;
QString m_txid;

View file

@ -10,10 +10,10 @@
#include "utils/Icons.h"
#include "utils/Utils.h"
TxProofDialog::TxProofDialog(QWidget *parent, QSharedPointer<AppContext> ctx, TransactionInfo *txInfo)
TxProofDialog::TxProofDialog(QWidget *parent, Wallet *wallet, TransactionInfo *txInfo)
: WindowModalDialog(parent)
, ui(new Ui::TxProofDialog)
, m_ctx(std::move(ctx))
, m_wallet(wallet)
{
ui->setupUi(this);
@ -26,7 +26,7 @@ TxProofDialog::TxProofDialog(QWidget *parent, QSharedPointer<AppContext> ctx, Tr
}
for (auto const &s: txInfo->subaddrIndex()) {
m_InDestinations.push_back(m_ctx->wallet->address(txInfo->subaddrAccount(), s));
m_InDestinations.push_back(m_wallet->address(txInfo->subaddrAccount(), s));
}
// Due to some logic in core we can't create OutProofs
@ -57,7 +57,7 @@ TxProofDialog::TxProofDialog(QWidget *parent, QSharedPointer<AppContext> ctx, Tr
void TxProofDialog::getTxKey() {
if (!m_txKey.isEmpty()) return;
m_ctx->wallet->getTxKeyAsync(m_txid, [this](QVariantMap map){
m_wallet->getTxKeyAsync(m_txid, [this](QVariantMap map){
m_txKey = map.value("tx_key").toString();
});
}
@ -75,7 +75,7 @@ void TxProofDialog::selectSpendProof() {
return;
}
if (m_ctx->wallet->isHwBacked()) {
if (m_wallet->isHwBacked()) {
this->showWarning("SpendProof creation is not supported on this hardware device.");
return;
}
@ -150,7 +150,7 @@ void TxProofDialog::showWarning(const QString &message) {
void TxProofDialog::getFormattedProof() {
QString message = ui->message->toPlainText();
QString address = ui->combo_address->currentText();
QString nettype = Utils::QtEnumToString(m_ctx->wallet->nettype()).toLower();
QString nettype = Utils::QtEnumToString(m_wallet->nettype()).toLower();
nettype = nettype.replace(0, 1, nettype[0].toUpper()); // Capitalize first letter
TxProof proof = this->getProof();
@ -231,12 +231,12 @@ TxProof TxProofDialog::getProof() {
TxProof proof = [this, message, address]{
switch (m_mode) {
case Mode::SpendProof: {
return m_ctx->wallet->getSpendProof(m_txid, message);
return m_wallet->getSpendProof(m_txid, message);
}
case Mode::OutProof:
case Mode::InProof:
default: { // Todo: split this into separate functions
return m_ctx->wallet->getTxProof(m_txid, address, message);
return m_wallet->getTxProof(m_txid, address, message);
}
}
}();

View file

@ -6,9 +6,9 @@
#include <QDialog>
#include "appcontext.h"
#include "components.h"
#include "libwalletqt/TransactionInfo.h"
#include "libwalletqt/Wallet.h"
namespace Ui {
class TxProofDialog;
@ -19,7 +19,7 @@ class TxProofDialog : public WindowModalDialog
Q_OBJECT
public:
explicit TxProofDialog(QWidget *parent, QSharedPointer<AppContext> ctx, TransactionInfo *txid);
explicit TxProofDialog(QWidget *parent, Wallet *wallet, TransactionInfo *txid);
~TxProofDialog() override;
void setTxId(const QString &txid);
void getTxKey();
@ -45,7 +45,7 @@ private:
void showWarning(const QString &message);
QScopedPointer<Ui::TxProofDialog> ui;
QSharedPointer<AppContext> m_ctx;
Wallet *m_wallet;
QStringList m_OutDestinations;
QStringList m_InDestinations;

View file

@ -8,21 +8,23 @@
#include <QInputDialog>
#include <QMessageBox>
ViewOnlyDialog::ViewOnlyDialog(QSharedPointer<AppContext> ctx, QWidget *parent)
#include "utils/Utils.h"
ViewOnlyDialog::ViewOnlyDialog(Wallet *wallet, QWidget *parent)
: WindowModalDialog(parent)
, ui(new Ui::ViewOnlyDialog)
, m_ctx(std::move(ctx))
, m_wallet(wallet)
{
ui->setupUi(this);
ui->label_restoreHeight->setText(QString::number(m_ctx->wallet->getWalletCreationHeight()));
ui->label_primaryAddress->setText(m_ctx->wallet->address(0, 0));
ui->label_secretViewKey->setText(m_ctx->wallet->getSecretViewKey());
ui->label_restoreHeight->setText(QString::number(m_wallet->getWalletCreationHeight()));
ui->label_primaryAddress->setText(m_wallet->address(0, 0));
ui->label_secretViewKey->setText(m_wallet->getSecretViewKey());
connect(ui->btn_Copy, &QPushButton::clicked, this, &ViewOnlyDialog::copyToClipboard);
connect(ui->btn_Save, &QPushButton::clicked, this, &ViewOnlyDialog::onWriteViewOnlyWallet);
if (m_ctx->wallet->viewOnly()) {
if (m_wallet->viewOnly()) {
ui->btn_Save->setEnabled(false);
ui->btn_Save->setToolTip("Wallet is already view-only");
}
@ -45,7 +47,7 @@ void ViewOnlyDialog::onWriteViewOnlyWallet(){
if((bool)passwordDialog.exec())
passwd = passwordDialog.textValue();
m_ctx->wallet->createViewOnly(fn, passwd);
m_wallet->createViewOnly(fn, passwd);
QMessageBox::information(this, "Information", "View-only wallet successfully written to disk.");
}

View file

@ -6,8 +6,8 @@
#include <QDialog>
#include "appcontext.h"
#include "components.h"
#include "libwalletqt/Wallet.h"
namespace Ui {
class ViewOnlyDialog;
@ -18,7 +18,7 @@ class ViewOnlyDialog : public WindowModalDialog
Q_OBJECT
public:
explicit ViewOnlyDialog(QSharedPointer<AppContext> ctx, QWidget *parent = nullptr);
explicit ViewOnlyDialog(Wallet *wallet, QWidget *parent = nullptr);
~ViewOnlyDialog() override;
private slots:
@ -28,7 +28,7 @@ private:
void copyToClipboard();
QScopedPointer<Ui::ViewOnlyDialog> ui;
QSharedPointer<AppContext> m_ctx;
Wallet *m_wallet;
};

View file

@ -8,81 +8,81 @@
#include "model/ModelUtils.h"
WalletCacheDebugDialog::WalletCacheDebugDialog(QSharedPointer<AppContext> ctx, QWidget *parent)
WalletCacheDebugDialog::WalletCacheDebugDialog(Wallet *wallet, QWidget *parent)
: WindowModalDialog(parent)
, ui(new Ui::WalletCacheDebugDialog)
, m_ctx(std::move(ctx))
, m_wallet(wallet)
{
ui->setupUi(this);
ui->output->setFont(ModelUtils::getMonospaceFont());
connect(ui->m_blockchain, &QRadioButton::pressed, [this]{
this->setOutput(m_ctx->wallet->printBlockchain());
this->setOutput(m_wallet->printBlockchain());
});
connect(ui->m_transfers, &QRadioButton::pressed, [this]{
this->setOutput(m_ctx->wallet->printTransfers());
this->setOutput(m_wallet->printTransfers());
});
connect(ui->m_unconfirmed_payments, &QRadioButton::pressed, [this]{
this->setOutput(m_ctx->wallet->printUnconfirmedPayments());
this->setOutput(m_wallet->printUnconfirmedPayments());
});
connect(ui->m_confirmed_txs, &QRadioButton::pressed, [this]{
this->setOutput(m_ctx->wallet->printConfirmedTransferDetails());
this->setOutput(m_wallet->printConfirmedTransferDetails());
});
connect(ui->m_unconfirmed_txs, &QRadioButton::pressed, [this]{
this->setOutput(m_ctx->wallet->printUnconfirmedTransferDetails());
this->setOutput(m_wallet->printUnconfirmedTransferDetails());
});
connect(ui->m_payments, &QRadioButton::pressed, [this]{
this->setOutput(m_ctx->wallet->printPayments());
this->setOutput(m_wallet->printPayments());
});
connect(ui->m_pub_keys, &QRadioButton::pressed, [this]{
this->setOutput(m_ctx->wallet->printPubKeys());
this->setOutput(m_wallet->printPubKeys());
});
connect(ui->m_tx_notes, &QRadioButton::pressed, [this]{
this->setOutput(m_ctx->wallet->printTxNotes());
this->setOutput(m_wallet->printTxNotes());
});
connect(ui->m_subaddresses, &QRadioButton::pressed, [this]{
this->setOutput(m_ctx->wallet->printSubaddresses());
this->setOutput(m_wallet->printSubaddresses());
});
connect(ui->m_subaddress_labels, &QRadioButton::pressed, [this]{
this->setOutput(m_ctx->wallet->printSubaddressLabels());
this->setOutput(m_wallet->printSubaddressLabels());
});
connect(ui->m_additional_tx_keys, &QRadioButton::pressed, [this]{
this->setOutput(m_ctx->wallet->printAdditionalTxKeys());
this->setOutput(m_wallet->printAdditionalTxKeys());
});
connect(ui->m_attributes, &QRadioButton::pressed, [this]{
this->setOutput(m_ctx->wallet->printAttributes());
this->setOutput(m_wallet->printAttributes());
});
connect(ui->m_key_images, &QRadioButton::pressed, [this]{
this->setOutput(m_ctx->wallet->printKeyImages());
this->setOutput(m_wallet->printKeyImages());
});
connect(ui->m_account_tags, &QRadioButton::pressed, [this]{
this->setOutput(m_ctx->wallet->printAccountTags());
this->setOutput(m_wallet->printAccountTags());
});
connect(ui->m_tx_keys, &QRadioButton::pressed, [this]{
this->setOutput(m_ctx->wallet->printTxKeys());
this->setOutput(m_wallet->printTxKeys());
});
connect(ui->m_address_book, &QRadioButton::pressed, [this]{
this->setOutput(m_ctx->wallet->printAddressBook());
this->setOutput(m_wallet->printAddressBook());
});
connect(ui->m_scanned_pool_txs, &QRadioButton::pressed, [this]{
this->setOutput(m_ctx->wallet->printScannedPoolTxs());
this->setOutput(m_wallet->printScannedPoolTxs());
});
this->adjustSize();

View file

@ -6,8 +6,8 @@
#include <QDialog>
#include "appcontext.h"
#include "components.h"
#include "libwalletqt/Wallet.h"
namespace Ui {
class WalletCacheDebugDialog;
@ -18,14 +18,14 @@ class WalletCacheDebugDialog : public WindowModalDialog
Q_OBJECT
public:
explicit WalletCacheDebugDialog(QSharedPointer<AppContext> ctx, QWidget *parent = nullptr);
explicit WalletCacheDebugDialog(Wallet *wallet, QWidget *parent = nullptr);
~WalletCacheDebugDialog() override;
private:
void setOutput(const QString &output);
QScopedPointer<Ui::WalletCacheDebugDialog> ui;
QSharedPointer<AppContext> m_ctx;
Wallet *m_wallet;
};

View file

@ -6,22 +6,24 @@
#include <QDesktopServices>
WalletInfoDialog::WalletInfoDialog(QSharedPointer<AppContext> ctx, QWidget *parent)
#include "utils/Utils.h"
WalletInfoDialog::WalletInfoDialog(Wallet *wallet, QWidget *parent)
: WindowModalDialog(parent)
, ui(new Ui::WalletInfoDialog)
, m_ctx(std::move(ctx))
, m_wallet(wallet)
{
ui->setupUi(this);
QFileInfo cache(m_ctx->wallet->cachePath());
QFileInfo cache(m_wallet->cachePath());
ui->label_walletName->setText(QFileInfo(m_ctx->wallet->cachePath()).fileName());
ui->label_netType->setText(Utils::QtEnumToString(m_ctx->wallet->nettype()));
ui->label_seedType->setText(QString("%1 word").arg(m_ctx->wallet->seedLength()));
ui->label_viewOnly->setText(m_ctx->wallet->viewOnly() ? "True" : "False");
ui->label_subaddressLookahead->setText(m_ctx->wallet->getSubaddressLookahead());
ui->label_keysFile->setText(m_ctx->wallet->keysPath());
ui->label_cacheFile->setText(m_ctx->wallet->cachePath());
ui->label_walletName->setText(QFileInfo(m_wallet->cachePath()).fileName());
ui->label_netType->setText(Utils::QtEnumToString(m_wallet->nettype()));
ui->label_seedType->setText(QString("%1 word").arg(m_wallet->seedLength()));
ui->label_viewOnly->setText(m_wallet->viewOnly() ? "True" : "False");
ui->label_subaddressLookahead->setText(m_wallet->getSubaddressLookahead());
ui->label_keysFile->setText(m_wallet->keysPath());
ui->label_cacheFile->setText(m_wallet->cachePath());
ui->label_cacheSize->setText(QString("%1 MB").arg(QString::number(cache.size() / 1e6, 'f', 2)));
connect(ui->btn_openWalletDir, &QPushButton::clicked, this, &WalletInfoDialog::openWalletDir);
@ -40,7 +42,7 @@ WalletInfoDialog::WalletInfoDialog(QSharedPointer<AppContext> ctx, QWidget *pare
}
void WalletInfoDialog::openWalletDir() {
QFileInfo file(m_ctx->wallet->keysPath());
QFileInfo file(m_wallet->keysPath());
QDesktopServices::openUrl(QUrl::fromLocalFile(file.absolutePath()));
}

View file

@ -6,8 +6,8 @@
#include <QDialog>
#include "appcontext.h"
#include "components.h"
#include "libwalletqt/Wallet.h"
namespace Ui {
class WalletInfoDialog;
@ -18,14 +18,14 @@ class WalletInfoDialog : public WindowModalDialog
Q_OBJECT
public:
explicit WalletInfoDialog(QSharedPointer<AppContext> ctx, QWidget *parent = nullptr);
explicit WalletInfoDialog(Wallet *wallet, QWidget *parent = nullptr);
~WalletInfoDialog() override;
private:
void openWalletDir();
QScopedPointer<Ui::WalletInfoDialog> ui;
QSharedPointer<AppContext> m_ctx;
Wallet *m_wallet;
};
#endif //FEATHER_WALLETINFODIALOG_H

File diff suppressed because it is too large Load diff

View file

@ -10,9 +10,9 @@
#include <QList>
#include <QtConcurrent/QtConcurrent>
#include "wallet/api/wallet2_api.h" // we need to have an access to the Monero::Wallet::Status enum here;
#include "wallet/api/wallet2_api.h"
#include "utils/scheduler.h"
#include "PendingTransaction.h" // we need to have an access to the PendingTransaction::Priority enum here;
#include "PendingTransaction.h"
#include "UnsignedTransaction.h"
#include "utils/networktype.h"
#include "PassphraseHelper.h"
@ -86,8 +86,7 @@ class Wallet : public QObject, public PassphrasePrompter
Q_OBJECT
public:
explicit Wallet(QObject *parent = nullptr);
explicit Wallet(Monero::Wallet *w, QObject * parent = nullptr);
explicit Wallet(Monero::Wallet *w, QObject *parent = nullptr);
~Wallet() override;
enum Status {
@ -109,9 +108,64 @@ public:
Q_ENUM(ConnectionStatus)
// ##### Status #####
//! returns last operation's status
Status status() const;
//! return connection status
ConnectionStatus connectionStatus() const;
//! returns true if wallet is currently synchronized
bool isSynchronized() const;
//! return true if wallet is connected to a node
bool isConnected() const;
//! returns last operation's error message
QString errorString() const;
//! returns network type of the wallet.
NetworkType::Type nettype() const;
//! returns if view only wallet
bool viewOnly() const;
//! return true if deterministic keys
bool isDeterministic() const;
// ##### Balance #####
//! returns balance
quint64 balance() const;
quint64 balance(quint32 accountIndex) const;
quint64 balanceAll() const;
//! returns unlocked balance
quint64 unlockedBalance() const;
quint64 unlockedBalance(quint32 accountIndex) const;
quint64 unlockedBalanceAll() const;
void updateBalance();
// ##### Subaddresses and Accounts #####
//! returns wallet's public address
QString address(quint32 accountIndex, quint32 addressIndex) const;
//! returns the subaddress index of the address
SubaddressIndex subaddressIndex(const QString &address) const;
quint32 currentSubaddressAccount() const;
void switchSubaddressAccount(quint32 accountIndex);
void addSubaddressAccount(const QString& label);
quint32 numSubaddressAccounts() const;
quint32 numSubaddresses(quint32 accountIndex) const;
void addSubaddress(const QString& label);
QString getSubaddressLabel(quint32 accountIndex, quint32 addressIndex) const;
void setSubaddressLabel(quint32 accountIndex, quint32 addressIndex, const QString &label);
void deviceShowAddressAsync(quint32 accountIndex, quint32 addressIndex, const QString &paymentId);
QString getSubaddressLookahead() const;
// ##### Seed #####
//! returns mnemonic seed
QString getSeed(const QString &seedOffset) const;
@ -123,115 +177,64 @@ public:
//! set seed language
void setSeedLanguage(const QString &lang);
//! returns last operation's status
Status status() const;
//! Get wallet keys
QString getSecretViewKey() const {return QString::fromStdString(m_walletImpl->secretViewKey());}
QString getPublicViewKey() const {return QString::fromStdString(m_walletImpl->publicViewKey());}
QString getSecretSpendKey() const {return QString::fromStdString(m_walletImpl->secretSpendKey());}
QString getPublicSpendKey() const {return QString::fromStdString(m_walletImpl->publicSpendKey());}
//! returns network type of the wallet.
NetworkType::Type nettype() const;
//! returns true if wallet was ever synchronized
bool synchronized() const;
//! returns true if wallet is currently synchronized
bool isSynchronized() const;
//! return true if wallet is connected to a node
bool isConnected() const;
// ##### Node connection #####
void setOffline(bool offline) const;
//! returns last operation's error message
QString errorString() const;
//! changes the password using existing parameters (path, seed, seed lang)
bool setPassword(const QString &oldPassword, const QString &newPassword);
//! verify wallet password
bool verifyPassword(const QString &password);
//! returns wallet's public address
QString address(quint32 accountIndex, quint32 addressIndex) const;
//! returns the subaddress index of the address
SubaddressIndex subaddressIndex(const QString &address) const;
//! returns wallet cache file path
QString cachePath() const;
//! returns wallet keys file path
QString keysPath() const;
//! saves wallet to the file by given path
//! empty path stores in current location
void store();
// void storeAsync(const QJSValue &callback, const QString &path = "");
//! initializes wallet asynchronously
void initAsync(
const QString &daemonAddress,
bool trustedDaemon = false,
quint64 upperTransactionLimit = 0,
bool isRecovering = false,
bool isRecoveringFromDevice = false,
quint64 restoreHeight = 0,
const QString &proxyAddress = "");
bool setDaemon(const QString &daemonAddress);
// Set daemon rpc user/pass
void setDaemonLogin(const QString &daemonUsername = "", const QString &daemonPassword = "");
//! create a view only wallet
bool createViewOnly(const QString &path, const QString &password) const;
//! connects to daemon
bool connectToDaemon();
//! indicates if daemon is trusted
void setTrustedDaemon(bool arg);
//! indicates if ssl should be used to connect to daemon
void setUseSSL(bool ssl);
//! returns balance
quint64 balance() const;
quint64 balance(quint32 accountIndex) const;
quint64 balanceAll() const;
//! Set daemon rpc user/pass
void setDaemonLogin(const QString &daemonUsername = "", const QString &daemonPassword = "");
//! returns unlocked balance
quint64 unlockedBalance() const;
quint64 unlockedBalance(quint32 accountIndex) const;
quint64 unlockedBalanceAll() const;
//! initializes wallet asynchronously
void initAsync(const QString &daemonAddress,
bool trustedDaemon = false,
quint64 upperTransactionLimit = 0,
const QString &proxyAddress = "");
//! account/address management
quint32 currentSubaddressAccount() const;
void switchSubaddressAccount(quint32 accountIndex);
void addSubaddressAccount(const QString& label);
quint32 numSubaddressAccounts() const;
quint32 numSubaddresses(quint32 accountIndex) const;
void addSubaddress(const QString& label);
QString getSubaddressLabel(quint32 accountIndex, quint32 addressIndex) const;
void setSubaddressLabel(quint32 accountIndex, quint32 addressIndex, const QString &label);
void deviceShowAddressAsync(quint32 accountIndex, quint32 addressIndex, const QString &paymentId);
QString getSubaddressLookahead() const;
// ##### Synchronization (Refresh) #####
void startRefresh();
void pauseRefresh();
//! hw-device backed wallets
//! returns current wallet's block height
//! (can be less than daemon's blockchain height when wallet sync in progress)
quint64 blockChainHeight() const;
//! returns daemon's blockchain height
quint64 daemonBlockChainHeight() const;
//! returns daemon's blockchain target height
quint64 daemonBlockChainTargetHeight() const;
void syncStatusUpdated(quint64 height, quint64 target);
void refreshModels();
// ##### Hardware wallet #####
bool isHwBacked() const;
bool isLedger() const;
bool isTrezor() const;
bool isDeviceConnected() const;
//! attempt to reconnect to hw-device
bool reconnectDevice();
//! returns if view only wallet
bool viewOnly() const;
//! return true if deterministic keys
bool isDeterministic() const;
//! refresh daemon blockchain and target height
bool refreshHeights();
// Passphrase entry for hardware wallets
void onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort=false);
void onWalletPassphraseNeeded(bool on_device) override;
// ##### Import / Export #####
//! export/import key images
bool exportKeyImages(const QString& path, bool all = false);
bool importKeyImages(const QString& path);
@ -243,6 +246,35 @@ public:
//! import a transaction
bool importTransaction(const QString& txid);
// ##### Wallet cache #####
//! saves wallet to the file by given path
//! empty path stores in current location
void store();
void storeSafer();
//! returns wallet cache file path
QString cachePath() const;
//! returns wallet keys file path
QString keysPath() const;
//! changes the password using existing parameters (path, seed, seed lang)
bool setPassword(const QString &oldPassword, const QString &newPassword);
//! verify wallet password
bool verifyPassword(const QString &password);
//! Namespace your cacheAttribute keys to avoid collisions
bool cacheAttributeExists(const QString &key);
bool setCacheAttribute(const QString &key, const QString &val);
QString getCacheAttribute(const QString &key) const;
void addCacheTransaction(const QString &txid, const QString &txHex);
QString getCacheTransaction(const QString &txid) const;
bool setUserNote(const QString &txid, const QString &note);
QString getUserNote(const QString &txid) const;
QString printBlockchain();
QString printTransfers();
QString printPayments();
@ -261,78 +293,26 @@ public:
QString printAddressBook();
QString printScannedPoolTxs();
// ##### Transactions #####
void setSelectedInputs(const QStringList &selected);
void createTransaction(const QString &address, quint64 amount, const QString &description, bool all);
void createTransactionMultiDest(const QVector<QString> &addresses, const QVector<quint64> &amounts, const QString &description);
void sweepOutputs(const QVector<QString> &keyImages, QString address, bool churn, int outputs);
void onCreateTransactionError(const QString &msg);
void commitTransaction(PendingTransaction *tx, const QString &description="");
//! deletes transaction and frees memory
void disposeTransaction(PendingTransaction * t);
//! deletes unsigned transaction and frees memory
void disposeTransaction(UnsignedTransaction * t);
// ##### Transaction import #####
//! does wallet have txid
bool haveTransaction(const QString &txid);
//! refreshes the wallet
bool refresh(bool historyAndSubaddresses = false);
// pause/resume refresh
void startRefresh();
void pauseRefresh();
//! returns current wallet's block height
//! (can be less than daemon's blockchain height when wallet sync in progress)
quint64 blockChainHeight() const;
//! returns daemon's blockchain height
quint64 daemonBlockChainHeight() const;
//! returns daemon's blockchain target height
quint64 daemonBlockChainTargetHeight() const;
//! creates transaction
PendingTransaction * createTransaction(const QString &dst_addr, const QString &payment_id,
quint64 amount, quint32 mixin_count,
PendingTransaction::Priority priority,
const QStringList &preferredInputs);
//! creates async transaction
void createTransactionAsync(const QString &dst_addr, const QString &payment_id,
quint64 amount, quint32 mixin_count,
PendingTransaction::Priority priority, const QStringList &preferredInputs);
//! creates multi-destination transaction
PendingTransaction * createTransactionMultiDest(const QVector<QString> &dst_addr, const QVector<quint64> &amount,
PendingTransaction::Priority priority, const QStringList &preferredInputs);
//! creates async multi-destination transaction
void createTransactionMultiDestAsync(const QVector<QString> &dst_addr, const QVector<quint64> &amount,
PendingTransaction::Priority priority, const QStringList &preferredInputs);
//! creates transaction with all outputs
PendingTransaction * createTransactionAll(const QString &dst_addr, const QString &payment_id,
quint32 mixin_count, PendingTransaction::Priority priority,
const QStringList &preferredInputs);
//! creates async transaction with all outputs
void createTransactionAllAsync(const QString &dst_addr, const QString &payment_id,
quint32 mixin_count, PendingTransaction::Priority priority,
const QStringList &preferredInputs);
//! creates transaction with single input
PendingTransaction * createTransactionSingle(const QString &key_image, const QString &dst_addr,
size_t outputs, PendingTransaction::Priority priority);
//! creates async transaction with single input
void createTransactionSingleAsync(const QString &key_image, const QString &dst_addr,
size_t outputs, PendingTransaction::Priority priority);
//! creates transaction with selected inputs
PendingTransaction * createTransactionSelected(const QVector<QString> &key_images, const QString &dst_addr,
size_t outputs, PendingTransaction::Priority priority);
//! creates async transaction with selected inputs
void createTransactionSelectedAsync(const QVector<QString> &key_images, const QString &dst_addr,
size_t outputs, PendingTransaction::Priority priority);
//! creates sweep unmixable transaction
PendingTransaction * createSweepUnmixableTransaction();
//! creates async sweep unmixable transaction
void createSweepUnmixableTransactionAsync();
//! Sign a transfer from file
UnsignedTransaction * loadTxFile(const QString &fileName);
@ -345,136 +325,73 @@ public:
//! Submit a transfer from file
bool submitTxFile(const QString &fileName) const;
//! asynchronous transaction commit
void commitTransactionAsync(PendingTransaction * t, const QString &description="");
// ##### Models #####
TransactionHistory* history() const;
TransactionHistoryProxyModel* historyModel();
TransactionHistoryModel* transactionHistoryModel() const;
AddressBook* addressBook() const;
AddressBookModel* addressBookModel() const;
Subaddress* subaddress() const;
SubaddressModel* subaddressModel() const;
SubaddressAccount* subaddressAccount() const;
SubaddressAccountModel* subaddressAccountModel() const;
Coins* coins() const;
CoinsModel* coinsModel() const;
//! deletes transaction and frees memory
void disposeTransaction(PendingTransaction * t);
// ##### Transaction proofs #####
//! deletes unsigned transaction and frees memory
void disposeTransaction(UnsignedTransaction * t);
QString getTxKey(const QString &txid) const;
void getTxKeyAsync(const QString &txid, const std::function<void (QVariantMap)> &callback);
// void estimateTransactionFeeAsync(const QString &destination,
// quint64 amount,
// PendingTransaction::Priority priority,
// const QJSValue &callback);
//! returns transaction history
TransactionHistory * history() const;
//! returns transaction history model
TransactionHistoryProxyModel *historyModel() const;
//! returns transaction history model (the real one)
TransactionHistoryModel *transactionHistoryModel() const;
//! returns Address book
AddressBook *addressBook() const;
//! returns address book model
AddressBookModel *addressBookModel() const;
//! returns subaddress
Subaddress *subaddress();
//! returns subaddress model
SubaddressModel *subaddressModel();
//! returns subaddress account
SubaddressAccount *subaddressAccount() const;
//! returns subaddress account model
SubaddressAccountModel *subaddressAccountModel() const;
//! returns coins
Coins *coins() const;
//! return coins model
CoinsModel *coinsModel() const;
//! generate payment id
QString generatePaymentId() const;
//! integrated address
QString integratedAddress(const QString &paymentId) const;
TxKeyResult checkTxKey(const QString &txid, const QString &tx_key, const QString &address);
TxProof getTxProof(const QString &txid, const QString &address, const QString &message) const;
TxProofResult checkTxProof(const QString &txid, const QString &address, const QString &message, const QString &signature);
void checkTxProofAsync(const QString &txid, const QString &address, const QString &message, const QString &signature);
TxProof getSpendProof(const QString &txid, const QString &message) const;
QPair<bool, bool> checkSpendProof(const QString &txid, const QString &message, const QString &signature) const;
void checkSpendProofAsync(const QString &txid, const QString &message, const QString &signature);
// ##### Sign / Verify message #####
//! signing a message
QString signMessage(const QString &message, bool filename = false, const QString &address = "") const;
//! verify a signed message
bool verifySignedMessage(const QString &message, const QString &address, const QString &signature, bool filename = false) const;
//! Parse URI
// ##### URI Parsing #####
bool parse_uri(const QString &uri, QString &address, QString &payment_id, uint64_t &amount, QString &tx_description, QString &recipient_name, QVector<QString> &unknown_parameters, QString &error) const;
QVariantMap parse_uri_to_object(const QString &uri) const;
QString make_uri(const QString &address, quint64 &amount, const QString &description, const QString &recipient) const;
//! Namespace your cacheAttribute keys to avoid collisions
bool cacheAttributeExists(const QString &key);
bool setCacheAttribute(const QString &key, const QString &val);
QString getCacheAttribute(const QString &key) const;
bool setUserNote(const QString &txid, const QString &note);
QString getUserNote(const QString &txid) const;
QString getTxKey(const QString &txid) const;
void getTxKeyAsync(const QString &txid, const std::function<void (QVariantMap)> &callback);
TxKeyResult checkTxKey(const QString &txid, const QString &tx_key, const QString &address);
TxProof getTxProof(const QString &txid, const QString &address, const QString &message) const;
// void getTxProofAsync(const QString &txid, const QString &address, const QString &message, const QJSValue &callback);
//QString checkTxProof(const QString &txid, const QString &address, const QString &message, const QString &signature);
TxProofResult checkTxProof(const QString &txid, const QString &address, const QString &message, const QString &signature);
void checkTxProofAsync(const QString &txid, const QString &address, const QString &message, const QString &signature);
TxProof getSpendProof(const QString &txid, const QString &message) const;
// void getSpendProofAsync(const QString &txid, const QString &message, const QJSValue &callback);
QPair<bool, bool> checkSpendProof(const QString &txid, const QString &message, const QString &signature) const;
void checkSpendProofAsync(const QString &txid, const QString &message, const QString &signature);
// Rescan spent outputs
bool rescanSpent();
// check if fork rules should be used
bool useForkRules(quint8 version, quint64 earlyBlocks = 0) const;
//! Get wallet keys
QString getSecretViewKey() const {return QString::fromStdString(m_walletImpl->secretViewKey());}
QString getPublicViewKey() const {return QString::fromStdString(m_walletImpl->publicViewKey());}
QString getSecretSpendKey() const {return QString::fromStdString(m_walletImpl->secretSpendKey());}
QString getPublicSpendKey() const {return QString::fromStdString(m_walletImpl->publicSpendKey());}
quint64 getWalletCreationHeight() const {return m_walletImpl->getRefreshFromBlockHeight();}
void setWalletCreationHeight(quint64 height);
QString getDaemonLogPath() const;
// Blackballed outputs
bool blackballOutput(const QString &amount, const QString &offset);
bool blackballOutputs(const QList<QString> &outputs, bool add);
bool blackballOutputs(const QString &filename, bool add);
bool unblackballOutput(const QString &amount, const QString &offset);
// Rings
QString getRing(const QString &key_image);
QString getRings(const QString &txid);
bool setRing(const QString &key_image, const QString &ring, bool relative);
// key reuse mitigation options
void segregatePreForkOutputs(bool segregate);
void segregationHeight(quint64 height);
void keyReuseMitigation2(bool mitigation);
// Passphrase entry for hardware wallets
void onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort=false);
void onWalletPassphraseNeeded(bool on_device) override;
// ##### Misc / Unused #####
quint64 getBytesReceived() const;
quint64 getBytesSent() const;
bool isDeviceConnected() const;
QString getDaemonLogPath() const;
bool setRingDatabase(const QString &path);
// TODO: setListener() when it implemented in API
quint64 getWalletCreationHeight() const {return m_walletImpl->getRefreshFromBlockHeight();}
void setWalletCreationHeight(quint64 height);
//! Rescan spent outputs
bool rescanSpent();
//! Indicates that the wallet is new
void setNewWallet();
//! create a view only wallet
bool createViewOnly(const QString &path, const QString &password) const;
PendingTransaction::Priority tx_priority = PendingTransaction::Priority::Priority_Low;
QString tmpTxDescription; // TODO: remove the need for this var
bool refreshedOnce = false;
void onHeightsRefreshed(bool success, quint64 daemonHeight, quint64 targetHeight);
signals:
// emitted on every event happened with wallet
// (money sent/received, new block)
@ -488,15 +405,12 @@ signals:
void moneyReceived(const QString &txId, quint64 amount);
void unconfirmedMoneyReceived(const QString &txId, quint64 amount);
void newBlock(quint64 height, quint64 targetHeight);
void addressBookChanged() const;
void historyModelChanged() const;
void walletCreationHeightChanged();
void deviceButtonRequest(quint64 buttonCode);
void deviceButtonPressed();
void deviceError(const QString &message);
void walletPassphraseNeeded(bool onDevice);
void transactionCommitted(bool status, PendingTransaction *t, const QStringList& txid);
void heightRefreshed(quint64 walletHeight, quint64 daemonHeight, quint64 targetHeight) const;
void deviceShowAddressShowed();
void transactionProofVerified(TxProofResult result);
void spendProofVerified(QPair<bool, bool> result);
@ -506,72 +420,82 @@ signals:
void connectionStatusChanged(int status) const;
void currentSubaddressAccountChanged() const;
void disconnectedChanged() const;
void proxyAddressChanged() const;
void refreshingChanged() const;
void refreshSync(int height, int target);
void blockchainSync(int height, int target);
void synchronized();
void balanceUpdated(quint64 balance, quint64 spendable);
void keysCorrupted();
void endTransaction();
void createTransactionSuccess(PendingTransaction *tx, const QVector<QString> &address);
void donationSent();
void walletRefreshed();
void initiateTransaction();
void createTransactionError(QString message);
void selectedInputsChanged(const QStringList &selectedInputs);
void multiBroadcast(PendingTransaction *tx);
void heightsRefreshed(bool success, quint64 daemonHeight, quint64 targetHeight);
private:
//! initializes wallet
bool init(
const QString &daemonAddress,
bool trustedDaemon,
quint64 upperTransactionLimit,
bool isRecovering,
bool isRecoveringFromDevice,
quint64 restoreHeight,
const QString& proxyAddress);
bool disconnected() const;
bool refreshing() const;
void refreshingSet(bool value);
void onRefreshed(bool success);
// ###### Status ######
void setConnectionStatus(ConnectionStatus value);
QString getProxyAddress() const;
void setProxyAddress(QString address);
void startRefreshThread();
// ##### Synchronization (Refresh) #####
void startRefreshThread();
void onNewBlock(uint64_t height);
void onUpdated();
void onRefreshed(bool success, const QString &message);
// ##### Transactions #####
void onTransactionCreated(PendingTransaction *tx, const QVector<QString> &address);
private:
friend class WalletManager;
friend class WalletListenerImpl;
//! libwallet's
Monero::Wallet * m_walletImpl;
// history lifetime managed by wallet;
TransactionHistory * m_history;
// Used for UI history view
mutable TransactionHistoryModel * m_historyModel;
mutable TransactionHistoryProxyModel * m_historySortFilterModel;
QString m_paymentId;
AddressBook * m_addressBook;
mutable AddressBookModel * m_addressBookModel;
mutable quint64 m_daemonBlockChainHeight;
mutable quint64 m_daemonBlockChainTargetHeight;
mutable ConnectionStatus m_connectionStatus;
Monero::Wallet *m_walletImpl;
TransactionHistory *m_history;
TransactionHistoryModel *m_historyModel;
TransactionHistoryProxyModel *m_historySortFilterModel;
AddressBook *m_addressBook;
AddressBookModel *m_addressBookModel;
quint64 m_daemonBlockChainHeight;
quint64 m_daemonBlockChainTargetHeight;
ConnectionStatus m_connectionStatus;
bool m_disconnected;
mutable bool m_initialized;
uint32_t m_currentSubaddressAccount;
Subaddress * m_subaddress;
mutable SubaddressModel * m_subaddressModel;
SubaddressAccount * m_subaddressAccount;
mutable SubaddressAccountModel * m_subaddressAccountModel;
Coins * m_coins;
mutable CoinsModel * m_coinsModel;
Subaddress *m_subaddress;
SubaddressModel *m_subaddressModel;
SubaddressAccount *m_subaddressAccount;
SubaddressAccountModel *m_subaddressAccountModel;
Coins *m_coins;
CoinsModel *m_coinsModel;
QMutex m_asyncMutex;
QString m_daemonUsername;
QString m_daemonPassword;
QString m_proxyAddress;
mutable QMutex m_proxyMutex;
QMutex m_proxyMutex;
std::atomic<bool> m_refreshNow;
std::atomic<bool> m_refreshEnabled;
std::atomic<bool> m_refreshing;
WalletListenerImpl *m_walletListener;
FutureScheduler m_scheduler;
int m_connectionTimeout = 30;
bool m_useSSL;
bool donationSending = false;
bool m_newWallet = false;
QTimer *m_storeTimer = nullptr;
std::set<std::string> m_selectedInputs;
};

View file

@ -3,6 +3,7 @@
#include "WalletListenerImpl.h"
#include "Wallet.h"
#include "WalletManager.h"
WalletListenerImpl::WalletListenerImpl(Wallet * w)
: m_wallet(w)
@ -11,28 +12,40 @@ WalletListenerImpl::WalletListenerImpl(Wallet * w)
}
// Beware!
// Do not call non-signal m_wallet functions here
// Nothing here runs in the GUI thread
void WalletListenerImpl::moneySpent(const std::string &txId, uint64_t amount)
{
qDebug() << __FUNCTION__;
emit m_wallet->moneySpent(QString::fromStdString(txId), amount);
// Outgoing tx included in a block
QString qTxId = QString::fromStdString(txId);
qDebug() << Q_FUNC_INFO << qTxId << " " << WalletManager::displayAmount(amount);
emit m_wallet->moneySpent(qTxId, amount);
}
void WalletListenerImpl::moneyReceived(const std::string &txId, uint64_t amount)
{
qDebug() << __FUNCTION__;
emit m_wallet->moneyReceived(QString::fromStdString(txId), amount);
// Incoming tx included in a block.
QString qTxId = QString::fromStdString(txId);
qDebug() << Q_FUNC_INFO << qTxId << " " << WalletManager::displayAmount(amount);
emit m_wallet->moneyReceived(qTxId, amount);
}
void WalletListenerImpl::unconfirmedMoneyReceived(const std::string &txId, uint64_t amount)
{
qDebug() << __FUNCTION__;
emit m_wallet->unconfirmedMoneyReceived(QString::fromStdString(txId), amount);
// Incoming tx in pool
QString qTxId = QString::fromStdString(txId);
qDebug() << Q_FUNC_INFO << qTxId << " " << WalletManager::displayAmount(amount);
emit m_wallet->unconfirmedMoneyReceived(qTxId, amount);
}
void WalletListenerImpl::newBlock(uint64_t height)
{
// qDebug() << __FUNCTION__;
m_wallet->onNewBlock(height);
// Called whenever a new block gets scanned by the wallet
emit m_wallet->newBlock(height, m_wallet->daemonBlockChainTargetHeight());
}
@ -45,7 +58,6 @@ void WalletListenerImpl::updated()
void WalletListenerImpl::refreshed(bool success)
{
QString message = m_wallet->errorString();
m_wallet->onRefreshed(success);
emit m_wallet->refreshed(success, message);
}

View file

@ -232,7 +232,7 @@ if (AttachConsole(ATTACH_PARENT_PROCESS)) {
EventFilter filter;
app.installEventFilter(&filter);
WindowManager windowManager(&filter);
WindowManager windowManager(QCoreApplication::instance(), &filter);
QObject::connect(&app, &SingleApplication::instanceStarted, [&windowManager]() {
windowManager.raise();

View file

@ -7,9 +7,10 @@
#include <QDesktopServices>
#include <QRegularExpression>
#include "utils/config.h"
#include "utils/Utils.h"
#include "utils/os/tails.h"
#include "appcontext.h"
#include "utils/os/whonix.h"
#include "config-feather.h"
TorManager::TorManager(QObject *parent)
@ -313,4 +314,8 @@ TorManager* TorManager::instance()
}
return m_instance;
}
}
TorManager::~TorManager() {
qDebug() << "~TorManager";
}

View file

@ -18,6 +18,7 @@ Q_OBJECT
public:
explicit TorManager(QObject *parent = nullptr);
~TorManager() override;
void init();
void start();

View file

@ -4,9 +4,10 @@
#include <QObject>
#include "nodes.h"
#include "utils/AppData.h"
#include "utils/Utils.h"
#include "utils/os/tails.h"
#include "appcontext.h"
#include "utils/os/whonix.h"
#include "constants.h"
#include "utils/WebsocketNotifier.h"
#include "utils/TorManager.h"
@ -94,21 +95,21 @@ void NodeList::ensureStructure(QJsonObject &obj, NetworkType::Type networkType)
obj[networkTypeStr] = netTypeObj;
}
Nodes::Nodes(QObject *parent)
Nodes::Nodes(QObject *parent, Wallet *wallet)
: QObject(parent)
, modelWebsocket(new NodeModel(NodeSource::websocket, this))
, modelCustom(new NodeModel(NodeSource::custom, this))
, m_connection(FeatherNode())
, m_wallet(wallet)
{
// TODO: This class is in desperate need of refactoring
this->loadConfig();
connect(websocketNotifier(), &WebsocketNotifier::NodesReceived, this, &Nodes::onWSNodesReceived);
}
void Nodes::setContext(AppContext *ctx) {
m_ctx = ctx;
connect(m_ctx, &AppContext::walletRefreshed, this, &Nodes::onWalletRefreshed);
if (m_wallet) {
connect(m_wallet, &Wallet::walletRefreshed, this, &Nodes::onWalletRefreshed);
}
}
void Nodes::loadConfig() {
@ -195,7 +196,11 @@ void Nodes::connectToNode() {
}
void Nodes::connectToNode(const FeatherNode &node) {
if (!m_ctx) {
if (!m_wallet) {
return;
}
if (!m_allowConnection) {
return;
}
@ -217,11 +222,11 @@ void Nodes::connectToNode(const FeatherNode &node) {
qInfo() << QString("Attempting to connect to %1 (%2)").arg(node.toAddress(), node.custom ? "custom" : "ws");
if (!node.url.userName().isEmpty() && !node.url.password().isEmpty()) {
m_ctx->wallet->setDaemonLogin(node.url.userName(), node.url.password());
m_wallet->setDaemonLogin(node.url.userName(), node.url.password());
}
// Don't use SSL over Tor/i2p
m_ctx->wallet->setUseSSL(!node.isAnonymityNetwork());
m_wallet->setUseSSL(!node.isAnonymityNetwork());
QString proxyAddress;
if (useSocks5Proxy(node)) {
@ -233,7 +238,7 @@ void Nodes::connectToNode(const FeatherNode &node) {
}
}
m_ctx->wallet->initAsync(node.toAddress(), true, 0, false, false, 0, proxyAddress);
m_wallet->initAsync(node.toAddress(), true, 0, proxyAddress);
m_connection = node;
m_connection.isActive = false;
@ -244,16 +249,16 @@ void Nodes::connectToNode(const FeatherNode &node) {
}
void Nodes::autoConnect(bool forceReconnect) {
if (!m_ctx) {
if (!m_wallet) {
return;
}
// this function is responsible for automatically connecting to a daemon.
if (m_ctx->wallet == nullptr || !m_enableAutoconnect) {
if (m_wallet == nullptr || !m_enableAutoconnect) {
return;
}
Wallet::ConnectionStatus status = m_ctx->wallet->connectionStatus();
Wallet::ConnectionStatus status = m_wallet->connectionStatus();
bool wsMode = (this->source() == NodeSource::websocket);
if (wsMode && !m_wsNodesReceived && websocketNodes().count() == 0) {
@ -423,7 +428,7 @@ bool Nodes::useOnionNodes() {
}
if (privacyLevel == Config::allTorExceptInitSync) {
if (m_ctx && m_ctx->refreshed) {
if (m_wallet && m_wallet->refreshedOnce) {
return true;
}
@ -431,7 +436,7 @@ bool Nodes::useOnionNodes() {
int initSyncThreshold = config()->get(Config::initSyncThreshold).toInt();
int networkHeight = appData()->heights[constants::networkType];
if (m_ctx && m_ctx->wallet->blockChainHeight() > (networkHeight - initSyncThreshold)) {
if (m_wallet && m_wallet->blockChainHeight() > (networkHeight - initSyncThreshold)) {
return true;
}
}
@ -584,4 +589,12 @@ int Nodes::modeHeight(const QList<FeatherNode> &nodes) {
}
return mode_height;
}
}
void Nodes::allowConnection() {
m_allowConnection = true;
}
Nodes::~Nodes() {
qDebug() << "~Nodes";
}

View file

@ -118,9 +118,11 @@ class Nodes : public QObject {
Q_OBJECT
public:
explicit Nodes(QObject *parent = nullptr);
void setContext(AppContext *ctx);
explicit Nodes(QObject *parent, Wallet *wallet);
~Nodes() override;
void loadConfig();
void allowConnection();
NodeSource source();
FeatherNode connection();
@ -144,7 +146,7 @@ private slots:
void onWalletRefreshed();
private:
AppContext *m_ctx = nullptr;
Wallet *m_wallet = nullptr;
QJsonObject m_configJson;
NodeList m_nodes;
@ -159,6 +161,8 @@ private:
bool m_wsNodesReceived = false;
bool m_enableAutoconnect = true;
bool m_allowConnection = false;
FeatherNode pickEligibleNode();
bool useOnionNodes();

View file

@ -4,10 +4,10 @@
#include <QScreen>
#include <QDesktopServices>
#include "utils/config.h"
#include "utils/Utils.h"
#include "utils/xmrig.h"
#include "utils/TorManager.h"
#include "appcontext.h"
XmRig::XmRig(const QString &configDir, QObject *parent)
: QObject(parent)

View file

@ -9,6 +9,7 @@
#include <QTableWidget>
#include "CCSProgressDelegate.h"
#include "utils/Utils.h"
CCSWidget::CCSWidget(QWidget *parent)
: QWidget(parent)
@ -37,8 +38,9 @@ void CCSWidget::linkClicked() {
QModelIndex index = ui->tableView->currentIndex();
auto entry = m_model->entry(index.row());
if (entry)
if (entry) {
Utils::externalLinkWarning(this, entry->url);
}
}
void CCSWidget::donateClicked() {

View file

@ -10,7 +10,6 @@
#include <QProgressBar>
#include <QWidget>
#include "appcontext.h"
#include "model/CCSModel.h"
#include "widgets/CCSEntry.h"

View file

@ -13,10 +13,10 @@
#include "utils/NetworkManager.h"
#include "utils/WebsocketNotifier.h"
LocalMoneroWidget::LocalMoneroWidget(QWidget *parent, QSharedPointer<AppContext> ctx)
LocalMoneroWidget::LocalMoneroWidget(QWidget *parent, Wallet *wallet)
: QWidget(parent)
, ui(new Ui::LocalMoneroWidget)
, m_ctx(std::move(ctx))
, m_wallet(wallet)
{
ui->setupUi(this);

View file

@ -7,8 +7,8 @@
#include <QWidget>
#include "api/LocalMoneroApi.h"
#include "appcontext.h"
#include "model/LocalMoneroModel.h"
#include "libwalletqt/Wallet.h"
namespace Ui {
class LocalMoneroWidget;
@ -19,7 +19,7 @@ class LocalMoneroWidget : public QWidget
Q_OBJECT
public:
explicit LocalMoneroWidget(QWidget *parent, QSharedPointer<AppContext> ctx);
explicit LocalMoneroWidget(QWidget *parent, Wallet *wallet);
~LocalMoneroWidget() override;
public slots:
@ -42,7 +42,7 @@ private:
void updatePaymentMethods();
QScopedPointer<Ui::LocalMoneroWidget> ui;
QSharedPointer<AppContext> m_ctx;
Wallet *m_wallet;
int m_currentPage = 0;

View file

@ -8,7 +8,6 @@
#include <QTreeView>
#include <QWidget>
#include "appcontext.h"
#include "model/NodeModel.h"
#include "utils/nodes.h"

View file

@ -6,11 +6,12 @@
#include "constants.h"
#include "utils/AppData.h"
#include "utils/config.h"
TickerWidgetBase::TickerWidgetBase(QWidget *parent, QSharedPointer<AppContext> ctx)
TickerWidgetBase::TickerWidgetBase(QWidget *parent, Wallet *wallet)
: QWidget(parent)
, ui(new Ui::TickerWidget)
, m_ctx(std::move(ctx))
, m_wallet(wallet)
{
ui->setupUi(this);
@ -53,8 +54,8 @@ void TickerWidgetBase::setDisplayText(const QString &text) {
}
// BalanceTickerWidget
BalanceTickerWidget::BalanceTickerWidget(QWidget *parent, QSharedPointer<AppContext> ctx, bool totalBalance)
: TickerWidgetBase(parent, std::move(ctx))
BalanceTickerWidget::BalanceTickerWidget(QWidget *parent, Wallet *wallet, bool totalBalance)
: TickerWidgetBase(parent, wallet)
, m_totalBalance(totalBalance)
{
if (totalBalance)
@ -64,13 +65,13 @@ BalanceTickerWidget::BalanceTickerWidget(QWidget *parent, QSharedPointer<AppCont
this->setPercentageVisible(false);
connect(m_ctx.get(), &AppContext::balanceUpdated, this, &BalanceTickerWidget::updateDisplay);
connect(m_wallet, &Wallet::balanceUpdated, this, &BalanceTickerWidget::updateDisplay);
connect(&appData()->prices, &Prices::fiatPricesUpdated, this, &BalanceTickerWidget::updateDisplay);
connect(&appData()->prices, &Prices::fiatPricesUpdated, this, &BalanceTickerWidget::updateDisplay);
}
void BalanceTickerWidget::updateDisplay() {
double balance = (m_totalBalance ? m_ctx->wallet->balanceAll() : m_ctx->wallet->balance()) / constants::cdiv;
double balance = (m_totalBalance ? m_wallet->balanceAll() : m_wallet->balance()) / constants::cdiv;
QString fiatCurrency = config()->get(Config::preferredFiatCurrency).toString();
double balanceFiatAmount = appData()->prices.convert("XMR", fiatCurrency, balance);
if (balanceFiatAmount < 0)
@ -79,8 +80,8 @@ void BalanceTickerWidget::updateDisplay() {
}
// PriceTickerWidget
PriceTickerWidget::PriceTickerWidget(QWidget *parent, QSharedPointer<AppContext> ctx, QString symbol)
: TickerWidgetBase(parent, std::move(ctx))
PriceTickerWidget::PriceTickerWidget(QWidget *parent, Wallet *wallet, QString symbol)
: TickerWidgetBase(parent, wallet)
, m_symbol(std::move(symbol))
{
this->setTitle(m_symbol);
@ -107,8 +108,8 @@ void PriceTickerWidget::updateDisplay() {
}
//RatioTickerWidget
RatioTickerWidget::RatioTickerWidget(QWidget *parent, QSharedPointer<AppContext> ctx, QString symbol1, QString symbol2)
: TickerWidgetBase(parent, std::move(ctx))
RatioTickerWidget::RatioTickerWidget(QWidget *parent, Wallet *wallet, QString symbol1, QString symbol2)
: TickerWidgetBase(parent, wallet)
, m_symbol1(std::move(symbol1))
, m_symbol2(std::move(symbol2))
{

View file

@ -6,7 +6,7 @@
#include <QWidget>
#include "appcontext.h"
#include "libwalletqt/Wallet.h"
namespace Ui {
class TickerWidget;
@ -17,7 +17,7 @@ class TickerWidgetBase : public QWidget
Q_OBJECT
public:
explicit TickerWidgetBase(QWidget *parent, QSharedPointer<AppContext> ctx);
explicit TickerWidgetBase(QWidget *parent, Wallet *wallet);
~TickerWidgetBase() override;
void setTitle(const QString &title);
@ -34,7 +34,7 @@ private:
QScopedPointer<Ui::TickerWidget> ui;
protected:
QSharedPointer<AppContext> m_ctx;
Wallet *m_wallet;
};
class BalanceTickerWidget : public TickerWidgetBase
@ -42,7 +42,7 @@ class BalanceTickerWidget : public TickerWidgetBase
Q_OBJECT
public:
explicit BalanceTickerWidget(QWidget *parent, QSharedPointer<AppContext> ctx, bool totalBalance);
explicit BalanceTickerWidget(QWidget *parent, Wallet *wallet, bool totalBalance);
public slots:
void updateDisplay() override;
@ -56,7 +56,7 @@ class PriceTickerWidget : public TickerWidgetBase
Q_OBJECT
public:
explicit PriceTickerWidget(QWidget *parent, QSharedPointer<AppContext> ctx, QString symbol);
explicit PriceTickerWidget(QWidget *parent, Wallet *wallet, QString symbol);
public slots:
void updateDisplay() override;
@ -70,7 +70,7 @@ class RatioTickerWidget : public TickerWidgetBase
Q_OBJECT
public:
explicit RatioTickerWidget(QWidget *parent, QSharedPointer<AppContext> ctx, QString symbol1, QString symbol2);
explicit RatioTickerWidget(QWidget *parent, Wallet *wallet, QString symbol1, QString symbol2);
public slots:
void updateDisplay() override;

View file

@ -13,11 +13,12 @@
#include <QTableWidget>
#include "utils/Icons.h"
#include "utils/Utils.h"
XMRigWidget::XMRigWidget(QSharedPointer<AppContext> ctx, QWidget *parent)
XMRigWidget::XMRigWidget(Wallet *wallet, QWidget *parent)
: QWidget(parent)
, ui(new Ui::XMRigWidget)
, m_ctx(std::move(ctx))
, m_wallet(wallet)
, m_XMRig(new XmRig(Config::defaultConfigDir().path()))
, m_model(new QStandardItemModel(this))
, m_contextMenu(new QMenu(this))
@ -96,25 +97,25 @@ XMRigWidget::XMRigWidget(QSharedPointer<AppContext> ctx, QWidget *parent)
ui->relayTor->setChecked(config()->get(Config::xmrigNetworkTor).toBool());
// Receiving address
auto username = m_ctx->wallet->getCacheAttribute("feather.xmrig_username");
auto username = m_wallet->getCacheAttribute("feather.xmrig_username");
if (!username.isEmpty()) {
ui->lineEdit_address->setText(username);
}
connect(ui->lineEdit_address, &QLineEdit::textChanged, [=]() {
m_ctx->wallet->setCacheAttribute("feather.xmrig_username", ui->lineEdit_address->text());
m_wallet->setCacheAttribute("feather.xmrig_username", ui->lineEdit_address->text());
});
connect(ui->btn_fillPrimaryAddress, &QPushButton::clicked, this, &XMRigWidget::onUsePrimaryAddressClicked);
// Password
auto password = m_ctx->wallet->getCacheAttribute("feather.xmrig_password");
auto password = m_wallet->getCacheAttribute("feather.xmrig_password");
if (!password.isEmpty()) {
ui->lineEdit_password->setText(password);
} else {
ui->lineEdit_password->setText("featherwallet");
m_ctx->wallet->setCacheAttribute("feather.xmrig_password", ui->lineEdit_password->text());
m_wallet->setCacheAttribute("feather.xmrig_password", ui->lineEdit_password->text());
}
connect(ui->lineEdit_password, &QLineEdit::textChanged, [=]() {
m_ctx->wallet->setCacheAttribute("feather.xmrig_password", ui->lineEdit_password->text());
m_wallet->setCacheAttribute("feather.xmrig_password", ui->lineEdit_password->text());
});
// [Status] tab
@ -171,7 +172,7 @@ void XMRigWidget::onClearClicked() {
}
void XMRigWidget::onUsePrimaryAddressClicked() {
ui->lineEdit_address->setText(m_ctx->wallet->address(0, 0));
ui->lineEdit_address->setText(m_wallet->address(0, 0));
}
void XMRigWidget::onStartClicked() {
@ -193,8 +194,8 @@ void XMRigWidget::onStartClicked() {
}
// username is receiving address usually
auto username = m_ctx->wallet->getCacheAttribute("feather.xmrig_username");
auto password = m_ctx->wallet->getCacheAttribute("feather.xmrig_password");
auto username = m_wallet->getCacheAttribute("feather.xmrig_username");
auto password = m_wallet->getCacheAttribute("feather.xmrig_password");
if (username.isEmpty()) {
ui->console->appendPlainText("Please specify a receiving address on the Settings screen.");
@ -203,7 +204,7 @@ void XMRigWidget::onStartClicked() {
if (address.contains("cryptonote.social") && !username.contains(".")) {
// cryptonote social requires <addr>.<username>, we'll just grab a few chars from primary addy
username = QString("%1.%2").arg(username, m_ctx->wallet->address(0, 0).mid(0, 6));
username = QString("%1.%2").arg(username, m_wallet->address(0, 0).mid(0, 6));
}
int threads = ui->threadSlider->value();

View file

@ -7,10 +7,11 @@
#include <QMenu>
#include <QWidget>
#include <QItemSelection>
#include <QStandardItemModel>
#include "appcontext.h"
#include "utils/xmrig.h"
#include "utils/config.h"
#include "libwalletqt/Wallet.h"
namespace Ui {
class XMRigWidget;
@ -21,7 +22,7 @@ class XMRigWidget : public QWidget
Q_OBJECT
public:
explicit XMRigWidget(QSharedPointer<AppContext> ctx, QWidget *parent = nullptr);
explicit XMRigWidget(Wallet *wallet, QWidget *parent = nullptr);
~XMRigWidget() override;
QStandardItemModel *model();
@ -63,7 +64,7 @@ private:
bool checkXMRigPath();
QScopedPointer<Ui::XMRigWidget> ui;
QSharedPointer<AppContext> m_ctx;
Wallet *m_wallet;
XmRig *m_XMRig;
QStandardItemModel *m_model;
QMenu *m_contextMenu;

View file

@ -9,7 +9,6 @@
#include <QWidget>
#include <QDir>
#include "appcontext.h"
#include "WalletWizard.h"
namespace Ui {

View file

@ -8,8 +8,6 @@
#include <QWizardPage>
#include <QWidget>
#include "appcontext.h"
namespace Ui {
class PageMenu;
}

View file

@ -8,7 +8,6 @@
#include <QWizardPage>
#include <QWidget>
#include "appcontext.h"
#include "utils/nodes.h"
namespace Ui {

View file

@ -6,8 +6,6 @@
#include <QWizardPage>
#include "appcontext.h"
namespace Ui {
class PageNetworkProxy;
}

View file

@ -6,8 +6,6 @@
#include <QWizardPage>
#include "appcontext.h"
namespace Ui {
class PageNetworkWebsocket;
}

View file

@ -5,10 +5,10 @@
#define FEATHER_OPENWALLET_H
#include <QLabel>
#include <QStandardItemModel>
#include <QWizardPage>
#include <QWidget>
#include "appcontext.h"
#include "model/WalletKeysFilesModel.h"
namespace Ui {

View file

@ -7,7 +7,6 @@
#include <QWizardPage>
#include <QWidget>
#include "appcontext.h"
#include "WalletWizard.h"
namespace Ui {

View file

@ -7,7 +7,6 @@
#include <QWizardPage>
#include <QWidget>
#include "appcontext.h"
#include "WalletWizard.h"
namespace Ui {

View file

@ -7,7 +7,6 @@
#include <QWizardPage>
#include <QWidget>
#include "appcontext.h"
#include "WalletWizard.h"
namespace Ui {

View file

@ -7,7 +7,6 @@
#include <QWizardPage>
#include <QWidget>
#include "appcontext.h"
#include "WalletWizard.h"
namespace Ui {

View file

@ -9,8 +9,6 @@
#include <QWidget>
#include <QDir>
#include "appcontext.h"
namespace Ui {
class PageWalletFile;
}

View file

@ -11,6 +11,7 @@
#include "WalletWizard.h"
#include "constants.h"
#include "libwalletqt/WalletManager.h"
PageWalletRestoreKeys::PageWalletRestoreKeys(WizardFields *fields, QWidget *parent)
: QWizardPage(parent)

View file

@ -10,7 +10,6 @@
#include <QTextEdit>
#include <QCompleter>
#include "appcontext.h"
#include "WalletWizard.h"
namespace Ui {

View file

@ -11,7 +11,6 @@
#include <QCompleter>
#include "utils/textedit.h"
#include "appcontext.h"
namespace Ui {
class PageWalletRestoreSeed;

View file

@ -8,10 +8,10 @@
#include <QLabel>
#include <QRadioButton>
#include "appcontext.h"
#include "model/WalletKeysFilesModel.h"
#include "utils/RestoreHeightLookup.h"
#include "utils/config.h"
#include "utils/Seed.h"
#include "constants.h"
enum WizardMode {