diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 9c8814d..62c880b 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -69,6 +69,7 @@ MainWindow::MainWindow(WindowManager *windowManager, Wallet *wallet, QWidget *pa this->restoreGeo(); this->initStatusBar(); + this->initPlugins(); this->initWidgets(); this->initMenu(); diff --git a/src/plugins/PluginRegistry.h b/src/plugins/PluginRegistry.h index 020d2b2..e63aef4 100644 --- a/src/plugins/PluginRegistry.h +++ b/src/plugins/PluginRegistry.h @@ -6,6 +6,7 @@ #include "Plugin.h" #include "utils/config.h" +#include "constants.h" class PluginRegistry { public: @@ -35,7 +36,7 @@ public: } bool isPluginEnabled(const QString &id) { - if (!pluginMap.contains(id)) { + if (!pluginMap.contains(id) or (QString::compare(id,"atomic")==0 && constants::networkType==NetworkType::TESTNET)) { return false; } diff --git a/src/plugins/atomic/AtomicConfigDialog.cpp b/src/plugins/atomic/AtomicConfigDialog.cpp index c4fc412..c9dbfe5 100644 --- a/src/plugins/atomic/AtomicConfigDialog.cpp +++ b/src/plugins/atomic/AtomicConfigDialog.cpp @@ -90,7 +90,7 @@ void AtomicConfigDialog::extract() { swapPath.append("/swapTool"); QFile binaryFile(swapPath); binaryFile.open(QIODevice::WriteOnly); - auto operatingSystem = Config::instance()->get(Config::operatingSystem).toString().toStdString(); + auto operatingSystem = conf()->get(Config::operatingSystem).toString().toStdString(); if(strcmp("WIN",operatingSystem.c_str()) == 0) { // UNZIP zip *z = zip_open(tempFile.toStdString().c_str(), 0, 0); @@ -114,7 +114,7 @@ void AtomicConfigDialog::extract() { zip_fclose(f); //And close the archive zip_close(z); - Config::instance()->set(Config::swapPath,swapPath); + conf()->set(Config::swapPath,swapPath); } else { struct archive *a; @@ -145,7 +145,7 @@ void AtomicConfigDialog::extract() { archive_write_close(ext); archive_write_free(ext); - Config::instance()->set(Config::swapPath, QString(savePath.c_str())); + conf()->set(Config::swapPath, QString(savePath.c_str())); } qDebug() << "Finished"; binaryFile.close(); diff --git a/src/plugins/atomic/AtomicPlugin.cpp b/src/plugins/atomic/AtomicPlugin.cpp index ddaf240..45fea3c 100644 --- a/src/plugins/atomic/AtomicPlugin.cpp +++ b/src/plugins/atomic/AtomicPlugin.cpp @@ -5,6 +5,7 @@ #include "AtomicConfigDialog.h" #include "plugins/PluginRegistry.h" +#include "constants.h" AtomicPlugin::AtomicPlugin() { @@ -64,7 +65,11 @@ void AtomicPlugin::skinChanged() { } const bool AtomicPlugin::registered = [] { - PluginRegistry::registerPlugin(AtomicPlugin::create()); - PluginRegistry::getInstance().registerPluginCreator(&AtomicPlugin::create); - return true; + if(constants::networkType!=NetworkType::TESTNET) { + PluginRegistry::registerPlugin(AtomicPlugin::create()); + PluginRegistry::getInstance().registerPluginCreator(&AtomicPlugin::create); + return true; + } + + return false; }(); diff --git a/src/plugins/atomic/AtomicRecoverDialog.cpp b/src/plugins/atomic/AtomicRecoverDialog.cpp index 118e00a..fa00416 100644 --- a/src/plugins/atomic/AtomicRecoverDialog.cpp +++ b/src/plugins/atomic/AtomicRecoverDialog.cpp @@ -8,20 +8,27 @@ #include "ui_AtomicRecoverDialog.h" #include "History.h" #include "config.h" +#include "AtomicSwap.h" #include AtomicRecoverDialog::AtomicRecoverDialog(QWidget *parent) : - WindowModalDialog(parent), ui(new Ui::AtomicRecoverDialog) { + WindowModalDialog(parent), ui(new Ui::AtomicRecoverDialog), swapDialog(new AtomicSwap(this)) { ui->setupUi(this); auto model = new QStandardItemModel(); ui->swap_history->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); ui->swap_history->setModel(model); + ui->btn_refund_resume->setVisible(false); + ui->swap_history->setSelectionBehavior(QAbstractItemView::SelectRows); + ui->swap_history->verticalHeader()->setVisible(false); + // Makes it easy to see if button is in refund or resume mode + ui->btn_refund_resume->setProperty("Refund",0); + this->setWindowFlag(Qt::WindowStaysOnTopHint); model->setHorizontalHeaderItem(0, new QStandardItem("Swap-Id")); model->setHorizontalHeaderItem(1, new QStandardItem("Timestamp swap started")); model->setHorizontalHeaderItem(2, new QStandardItem("Status")); QList rowData; - auto data = Config::instance()->get(Config::pendingSwap).value(); + auto data = conf()->get(Config::pendingSwap).value(); for(int i=0; i< data.size(); i++){ auto entry = data[i].value(); qint64 difference = entry.timestamp.secsTo(QDateTime::currentDateTime()); @@ -39,20 +46,47 @@ AtomicRecoverDialog::AtomicRecoverDialog(QWidget *parent) : data.remove(i); } } - Config::instance()->set(Config::pendingSwap,data); + conf()->set(Config::pendingSwap,data); + connect(ui->swap_history, &QAbstractItemView::clicked, this, &AtomicRecoverDialog::updateBtn); + connect(ui->btn_refund_resume, &QPushButton::clicked, this, [this]{ + QStringList arguments; + if (ui->btn_refund_resume->property("Refund").toBool()){ + arguments << "cancel-and-refund"; + } else { + arguments << "resume"; + } + arguments << "--swap-id"; + arguments << ui->swap_history->selectionModel()->selectedRows().at(0).sibling(0,1).data().toString(); + arguments << "--tor-socks5-port"; + arguments << conf()->get(Config::socks5Port).toString(); + swapDialog->runSwap(arguments); + }); +} + +void AtomicRecoverDialog::updateBtn(const QModelIndex &index){ + auto row = index.sibling(index.row(),2).data().toString(); + if (row.startsWith("Ref")){ + ui->btn_refund_resume->setText("Cancel And Refund"); + ui->btn_refund_resume->setProperty("Refund",1); + } else { + ui->btn_refund_resume->setText("Attempt to Resume"); + ui->btn_refund_resume->setProperty("Refund",0); + } + ui->btn_refund_resume->setVisible(true); + } bool AtomicRecoverDialog::historyEmpty(){ - return Config::instance()->get(Config::pendingSwap).value().isEmpty(); + return conf()->get(Config::pendingSwap).value().isEmpty(); } void AtomicRecoverDialog::appendHistory(HistoryEntry entry){ - auto current = Config::instance()->get(Config::pendingSwap).value(); + auto current = conf()->get(Config::pendingSwap).value(); auto var = QVariant(); var.setValue(entry); current.append(var); - Config::instance()->set(Config::pendingSwap, current); + conf()->set(Config::pendingSwap, current); } AtomicRecoverDialog::~AtomicRecoverDialog() { delete ui; diff --git a/src/plugins/atomic/AtomicRecoverDialog.h b/src/plugins/atomic/AtomicRecoverDialog.h index 8e5099e..0558a2f 100644 --- a/src/plugins/atomic/AtomicRecoverDialog.h +++ b/src/plugins/atomic/AtomicRecoverDialog.h @@ -8,6 +8,7 @@ #include #include "components.h" #include "History.h" +#include "AtomicSwap.h" QT_BEGIN_NAMESPACE namespace Ui { class AtomicRecoverDialog; } @@ -22,8 +23,12 @@ public: void appendHistory(HistoryEntry entry); ~AtomicRecoverDialog() override; +private slots: + void updateBtn(const QModelIndex &index); private: Ui::AtomicRecoverDialog *ui; + AtomicSwap *swapDialog; + }; diff --git a/src/plugins/atomic/AtomicRecoverDialog.ui b/src/plugins/atomic/AtomicRecoverDialog.ui index 30d56ff..092a9bb 100644 --- a/src/plugins/atomic/AtomicRecoverDialog.ui +++ b/src/plugins/atomic/AtomicRecoverDialog.ui @@ -6,22 +6,71 @@ 0 0 - 903 - 248 + 936 + 256 AtomicRecoverDialog - + 10 - 20 - 881 - 179 + 10 + 911 + 211 + + + + + There are one or more Atomic Swaps still pending, take action to prevent losing funds! + + + + + + + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + + Resume + + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + diff --git a/src/plugins/atomic/AtomicSwap.cpp b/src/plugins/atomic/AtomicSwap.cpp index 73092dd..7fa80d9 100644 --- a/src/plugins/atomic/AtomicSwap.cpp +++ b/src/plugins/atomic/AtomicSwap.cpp @@ -60,13 +60,21 @@ void AtomicSwap::runSwap(QStringList arguments){ this->updateXMRConf(confs.toInt()); } else if (QString message = line["fields"]["message"].toString(); !QString::compare(message, "Bitcoin transaction status changed")){ qDebug() << "Updating btconfs " + line["fields"]["new_status"].toString().split(" ")[2]; - this->updateBTCConf(line["fields"]["new_status"].toString().split(" ")[2].toInt()); + QString status = line["fields"]["new_status"].toString(); + bool ok; + auto confirmations = status.split(" ")[2].toInt(&ok, 10); + if(ok) { + this->updateBTCConf(confirmations); + } else { + this->updateStatus("Found txid " + line["fields"]["txid"].toString() + " in mempool"); + } + } //Insert line conditionals here } }); - swap->start(Config::instance()->get(Config::swapPath).toString(),arguments); + swap->start(conf()->get(Config::swapPath).toString(),arguments); qDebug() << "process started"; } AtomicSwap::~AtomicSwap() { @@ -74,7 +82,7 @@ AtomicSwap::~AtomicSwap() { for (const auto& proc : *procList){ proc->kill(); } - if(QString::compare("WINDOWS",Config::instance()->get(Config::operatingSystem).toString()) != 0) { + if(QString::compare("WINDOWS",conf()->get(Config::operatingSystem).toString()) != 0) { qDebug() << "Closing monero-wallet-rpc"; (new QProcess)->start("kill", QStringList{"-f", Config::defaultConfigDir().absolutePath() + "/mainnet/monero/monero-wallet-rpc"}); diff --git a/src/plugins/atomic/AtomicWidget.cpp b/src/plugins/atomic/AtomicWidget.cpp index 5c32e06..a31d5fc 100644 --- a/src/plugins/atomic/AtomicWidget.cpp +++ b/src/plugins/atomic/AtomicWidget.cpp @@ -11,6 +11,7 @@ #include "AtomicConfigDialog.h" #include "OfferModel.h" #include "utils/AppData.h" +#include "utils/nodes.h" #include "utils/ColorScheme.h" #include "utils/WebsocketNotifier.h" #include "AtomicFundDialog.h" @@ -18,7 +19,6 @@ AtomicWidget::AtomicWidget(QWidget *parent) : QWidget(parent) , ui(new Ui::AtomicWidget) - , m_instance(Config::instance()) , o_model(new OfferModel(this)) , offerList(new QList>()) , swapDialog(new AtomicSwap(this)) @@ -43,7 +43,7 @@ AtomicWidget::AtomicWidget(QWidget *parent) ui->offerBookTable->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Stretch); ui->btn_configure->setEnabled(true); - if (!m_instance->get(Config::swapPath).toString().isEmpty()) + if (!conf()->get(Config::swapPath).toString().isEmpty()) ui->meta_label->setText("Refresh offer book before swapping to prevent errors"); connect(ui->btn_configure, &QPushButton::clicked, this, &AtomicWidget::showAtomicConfigureDialog); @@ -53,7 +53,7 @@ AtomicWidget::AtomicWidget(QWidget *parent) ui->meta_label->setText("Updating offer book this may take a bit, if no offers appear after a while try refreshing again"); - QStringList pointList = m_instance->get(Config::rendezVous).toStringList(); + QStringList pointList = conf()->get(Config::rendezVous).toStringList(); for(const QString& point :pointList) AtomicWidget::list(point); }); @@ -83,22 +83,21 @@ AtomicWidget::AtomicWidget(QWidget *parent) tr("p2p multi address of rendezvous point"), QLineEdit::Normal, "", &ok); if (ok && !text.isEmpty()) { - QStringList copy = m_instance->get(Config::rendezVous).toStringList(); + QStringList copy = conf()->get(Config::rendezVous).toStringList(); copy.append(text); - m_instance->set(Config::rendezVous,copy); + conf()->set(Config::rendezVous,copy); } }); //Remove after testing - //QVariant var; - //var.setValue(HistoryEntry {QDateTime::currentDateTime(),"test-id"}); - //m_instance->set(Config::pendingSwap, QVariantList{var}); - //auto recd = new AtomicRecoverDialog(); - //if (!recd->historyEmpty()){ - // recd->show(); - //} - this->updateStatus(); + QVariant var; + var.setValue(HistoryEntry {QDateTime::currentDateTime(),"test-id"}); + conf()->set(Config::pendingSwap, QVariantList{var}); + auto recd = new AtomicRecoverDialog(this); + if (!recd->historyEmpty()){ + recd->show(); + } } @@ -111,13 +110,6 @@ void AtomicWidget::showAtomicConfigureDialog() { dialog.exec(); } -void AtomicWidget::showAtomicSwapDialog() { - swapDialog->show(); -} - -void AtomicWidget::updateStatus() { - -} void AtomicWidget::runSwap(const QString& seller, const QString& btcChange, const QString& xmrReceive) { qDebug() << "starting swap"; @@ -125,7 +117,9 @@ void AtomicWidget::runSwap(const QString& seller, const QString& btcChange, cons arguments << "--data-base-dir"; arguments << Config::defaultConfigDir().absolutePath(); // Remove after testing - arguments << "--testnet"; + if (constants::networkType==NetworkType::STAGENET){ + arguments << "--testnet"; + } arguments << "--debug"; arguments << "-j"; arguments << "buy-xmr"; @@ -142,12 +136,24 @@ void AtomicWidget::runSwap(const QString& seller, const QString& btcChange, cons arguments << "tcp://127.0.0.1:50001"; arguments << "--bitcoin-target-block"; arguments << "1"; + auto nodes = conf()->get(Config::nodes).toJsonObject(); + if (nodes.isEmpty()) { + auto jsonData = conf()->get(Config::nodes).toByteArray(); + if (Utils::validateJSON(jsonData)) { + auto doc = QJsonDocument::fromJson(jsonData); + nodes = doc.object(); + } + } + qDebug() << nodes.value("0").toObject()["ws"].toArray()[0]; arguments << "--monero-daemon-address"; - arguments << "node.monerodevs.org:38089"; + //arguments << "node.monerodevs.org:38089"; + arguments << nodes.value("0").toObject()["ws"].toArray()[0].toString(); // Uncomment after testing //arguments << seller; - arguments << "--tor-socks5-port"; - arguments << m_instance->get(Config::socks5Port).toString(); + if(conf()->get(Config::proxy).toInt() != Config::Proxy::None) { + arguments << "--tor-socks5-port"; + arguments << conf()->get(Config::socks5Port).toString(); + } swapDialog->runSwap(arguments); } @@ -156,16 +162,21 @@ void AtomicWidget::list(const QString& rendezvous) { QStringList arguments; arguments << "--data-base-dir"; arguments << Config::defaultConfigDir().absolutePath(); + if (constants::networkType==NetworkType::STAGENET){ + arguments << "--testnet"; + } arguments << "-j"; arguments << "list-sellers"; - arguments << "--tor-socks5-port"; - arguments << m_instance->get(Config::socks5Port).toString(); + if(conf()->get(Config::proxy).toInt() != Config::Proxy::None) { + arguments << "--tor-socks5-port"; + arguments << conf()->get(Config::socks5Port).toString(); + } arguments << "--rendezvous-point"; arguments << rendezvous; auto *swap = new QProcess(); procList->append(QSharedPointer(swap)); swap->setReadChannel(QProcess::StandardError); - //swap->start(m_instance->get(Config::swapPath).toString(), arguments); + //swap->start(conf()->get(Config::swapPath).toString(), arguments); connect(swap, &QProcess::finished, this, [this, swap]{ QJsonDocument parsedLine; QJsonParseError parseError; @@ -203,7 +214,7 @@ void AtomicWidget::list(const QString& rendezvous) { o_model->updateOffers(*offerList); return list; }); - swap->start(m_instance->get(Config::swapPath).toString(), arguments); + swap->start(conf()->get(Config::swapPath).toString(), arguments); //swap->waitForFinished(120000); @@ -216,7 +227,6 @@ AtomicWidget::~AtomicWidget() { delete o_model; delete offerList; clean(); - delete m_instance; delete procList; } @@ -224,7 +234,7 @@ void AtomicWidget::clean() { for (const auto& proc : *procList){ proc->kill(); } - if(QString::compare("WINDOWS",m_instance->get(Config::operatingSystem).toString()) != 0) { + if(QString::compare("WINDOWS",conf()->get(Config::operatingSystem).toString()) != 0) { qDebug() << "Closing monero-wallet-rpc"; (new QProcess)->start("kill", QStringList{"-f", Config::defaultConfigDir().absolutePath() + "/mainnet/monero/monero-wallet-rpc"}); diff --git a/src/plugins/atomic/AtomicWidget.h b/src/plugins/atomic/AtomicWidget.h index 015ea94..c465ced 100644 --- a/src/plugins/atomic/AtomicWidget.h +++ b/src/plugins/atomic/AtomicWidget.h @@ -38,8 +38,6 @@ private slots: void runSwap(const QString& seller, const QString& btcChange, const QString& xmrReceive); private: - void updateStatus(); - QScopedPointer ui; bool m_comboBoxInit = false; QTimer m_statusTimer; @@ -48,10 +46,8 @@ private: AtomicSwap *swapDialog; AtomicFundDialog *fundDialog; AtomicRecoverDialog *recoverDialog; - void showAtomicSwapDialog(); QList> *procList; - Config *m_instance; }; #endif // FEATHER_ATOMICWIDGET_H