Added AtomicFundDialog ui to make depositing btc for swap easy. Updated AtomicSwap functionality to clean swap and monero-wallet-rpc. Can run swap successfully if nothing goes wrong.

TODO:
This commit is contained in:
twiddle 2024-07-08 14:49:24 -04:00
parent b9fde514af
commit 513d83229f
8 changed files with 365 additions and 41 deletions

View file

@ -0,0 +1,57 @@
// SPDX-License-Identifier: BSD-3-Clause
// SPDX-FileCopyrightText: 2020-2024 The Monero Project
#include "AtomicFundDialog.h"
#include "ui_AtomicFundDialog.h"
#include <QClipboard>
#include <QFileDialog>
#include <QMessageBox>
AtomicFundDialog::AtomicFundDialog(QWidget *parent, QrCode *qrCode, const QString &title, const QString &btc_address)
: WindowModalDialog(parent)
, ui(new Ui::AtomicFundDialog)
, address(btc_address)
{
ui->setupUi(this);
this->setWindowTitle(title);
ui->qrWidget->setQrCode(qrCode);
m_pixmap = qrCode->toPixmap(1).scaled(500, 500, Qt::KeepAspectRatio);
connect(ui->btn_CopyImage, &QPushButton::clicked, this, &AtomicFundDialog::copyImage);
connect(ui->btn_Save, &QPushButton::clicked, this, &AtomicFundDialog::saveImage);
connect(ui->btn_Close, &QPushButton::clicked, [this](){
emit cleanProcs();
accept();
});
this->resize(500, 500);
}
void AtomicFundDialog::copyImage() {
QApplication::clipboard()->setPixmap(m_pixmap);
QMessageBox::information(this, "Information", "QR code copied to clipboard");
}
void AtomicFundDialog::saveImage() {
QString filename = QFileDialog::getSaveFileName(this, "Select where to save file", QDir::current().filePath("qrcode.png"));
if (filename.isEmpty()) {
return;
}
QFile file(filename);
file.open(QIODevice::WriteOnly);
m_pixmap.save(&file, "PNG");
QMessageBox::information(this, "Information", "QR code saved to file");
}
void AtomicFundDialog::copyAddress(){
QApplication::clipboard()->setText(address);
QMessageBox::information(this, "Information", "BTC deposit address copied to clipboard");
}
AtomicFundDialog::~AtomicFundDialog() {
emit cleanProcs();
}

View file

@ -0,0 +1,37 @@
//
// Created by dev on 7/8/24.
//
#ifndef FEATHER_ATOMICFUNDDIALOG_H
#define FEATHER_ATOMICFUNDDIALOG_H
#include <QDialog>
#include "components.h"
#include "qrcode/QrCode.h"
#include "widgets/QrCodeWidget.h"
namespace Ui {
class AtomicFundDialog;
}
class AtomicFundDialog : public WindowModalDialog {
Q_OBJECT
public:
explicit AtomicFundDialog(QWidget *parent, QrCode *qrCode, const QString &title = "Qr Code", const QString &btc_address = "Error Restart swap");
~AtomicFundDialog() override;
signals:
void cleanProcs();
private:
void copyImage();
void saveImage();
void copyAddress();
QScopedPointer<Ui::AtomicFundDialog> ui;
QPixmap m_pixmap;
QString address;
};
#endif //FEATHER_ATOMICFUNDDIALOG_H

View file

@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AtomicFundDialog</class>
<widget class="QDialog" name="AtomicFundDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>520</width>
<height>446</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QrCodeWidget" name="qrWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>150</width>
<height>150</height>
</size>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btn_CopyAddress">
<property name="text">
<string>Copy Address</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_CopyImage">
<property name="text">
<string>Copy Image</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_Save">
<property name="text">
<string>Save</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_Close">
<property name="text">
<string>Cancel</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QrCodeWidget</class>
<extends>QWidget</extends>
<header>widgets/QrCodeWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View file

@ -6,23 +6,45 @@
#include "AtomicSwap.h"
#include "ui_AtomicSwap.h"
#include "AtomicWidget.h"
AtomicSwap::AtomicSwap(QWidget *parent) :
QDialog(parent), ui(new Ui::AtomicSwap) {
WindowModalDialog(parent), ui(new Ui::AtomicSwap) {
ui->setupUi(this);
//ui->debug_log->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
ui->label_status->setTextInteractionFlags(Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse);
this->setContentsMargins(3,3,3,3);
this->adjustSize();
}
AtomicSwap::~AtomicSwap() {
delete ui;
emit cleanProcs();
}
void AtomicSwap::logLine(QString line){
ui->debug_log->setText(ui->debug_log->toPlainText().append(QTime::currentTime().toString() + ":" + line));
//ui->debug_log->setText(ui->debug_log->toPlainText().append(QTime::currentTime().toString() + ":" + line));
this->update();
}
void AtomicSwap::updateStatus(QString status){
ui->label_status->setText(status);
this->update();
}
}
void AtomicSwap::updateXMRConf(int confs) {
ui->label_xmr_cons->setText(QString::number(confs));
this->update();
}
void AtomicSwap::updateBTCConf(int confs) {
ui->label_btc_cons->setText(QString::number(confs));
this->update();
}
void AtomicSwap::setTitle(QString title) {
this->setWindowTitle(title);
this->update();
}

View file

@ -7,13 +7,14 @@
#include <QDialog>
#include <QTime>
#include "components.h"
QT_BEGIN_NAMESPACE
namespace Ui { class AtomicSwap; }
QT_END_NAMESPACE
class AtomicSwap : public QDialog {
class AtomicSwap : public WindowModalDialog {
Q_OBJECT
public:
@ -21,7 +22,11 @@ public:
void updateStatus(QString status);
void logLine(QString line);
~AtomicSwap() override;
void updateBTCConf(int confs);
void updateXMRConf(int confs);
void setTitle(QString title);
signals:
void cleanProcs();
private:
Ui::AtomicSwap *ui;

View file

@ -6,44 +6,113 @@
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
<width>534</width>
<height>200</height>
</rect>
</property>
<property name="windowTitle">
<string>AtomicSwap</string>
</property>
<widget class="QWidget" name="verticalLayoutWidget">
<widget class="QGroupBox" name="verticalGroupBox">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>361</width>
<height>271</height>
<x>30</x>
<y>10</y>
<width>471</width>
<height>151</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_status">
<property name="text">
<string>Connected to peer, swap starting</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout"/>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label">
<widget class="QLabel" name="label_status">
<property name="text">
<string>Debug Log</string>
<string>Btc deposited to wallet, begining swap</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Cancel </string>
</property>
</widget>
</item>
<item>
<widget class="QTextBrowser" name="debug_log"/>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QFrame" name="frame">
<property name="styleSheet">
<string notr="true">border-color: rgb(222, 221, 218);
</string>
</property>
<property name="frameShape">
<enum>QFrame::Shape::Box</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="label">
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string>On chain Confimations</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_btc">
<property name="text">
<string>BTC :</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_btc_cons">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_xmr">
<property name="text">
<string>XMR :</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_xmr_cons">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>

View file

@ -13,7 +13,7 @@
#include "utils/AppData.h"
#include "utils/ColorScheme.h"
#include "utils/WebsocketNotifier.h"
#include "dialog/QrCodeDialog.h"
#include "AtomicFundDialog.h"
AtomicWidget::AtomicWidget(QWidget *parent)
: QWidget(parent)
@ -67,7 +67,6 @@ AtomicWidget::AtomicWidget(QWidget *parent)
//Add proper error checking on ui input after rest of swap is implemented
QString btcChange = ui->change_address->text();
QString xmrReceive = ui->xmr_address->text();
showAtomicSwapDialog();
runSwap(seller,btcChange, xmrReceive);
}
});
@ -84,6 +83,7 @@ AtomicWidget::AtomicWidget(QWidget *parent)
Config::instance()->set(Config::rendezVous,copy);
}
});
connect(swapDialog,&AtomicSwap::cleanProcs, this, [this]{clean();});
this->updateStatus();
@ -106,7 +106,6 @@ void AtomicWidget::showAtomicSwapDialog() {
swapDialog->show();
}
void AtomicWidget::updateStatus() {
}
@ -121,14 +120,26 @@ void AtomicWidget::runSwap(QString seller, QString btcChange, QString xmrReceive
arguments << "-j";
arguments << "buy-xmr";
arguments << "--change-address";
//arguments << "tb1qzndh6u8qgl2ee4k4gl9erg947g67hyx03vvgen";
arguments << btcChange;
arguments << "--receive-address";
//arguments << "78YnzFTp3UUMgtKuAJCP2STcbxRZPDPveJ5YGgfg5doiPahS9suWF1r3JhKqjM1McYBJvu8nhkXExGfXVkU6n5S6AXrg4KP";
arguments << xmrReceive;
arguments << "--seller";
//arguments << "/ip4/127.0.0.1/tcp/9939/p2p/12D3KooWQA4fXDYLNXgxPsVZmnR8kh2wwHUQnkH9e1Wjc8KyJ7p8";
// Remove after testing
//arguments << "--electrum-rpc";
//arguments << "tcp://127.0.0.1:50001";
//arguments << "--bitcoin-target-block";
//arguments << "8";
//arguments << "--monero-daemon-address";
//arguments << "http://127.0.0.1:38083";
// Uncomment after testing
arguments << seller;
arguments << "--tor-socks5-port";
arguments << m_instance->get(Config::socks5Port).toString();
auto *swap = new QProcess();
procList->append(QSharedPointer<QProcess>(swap));
@ -146,15 +157,21 @@ void AtomicWidget::runSwap(QString seller, QString btcChange, QString xmrReceive
qDebug() << "Deposit to btc to segwit address";
QString address = line["fields"]["deposit_address"].toString();
QrCode qrc(address, QrCode::Version::AUTO, QrCode::ErrorCorrectionLevel::HIGH);
swapDialog->updateStatus("Add money to this address\n" + address);
QrCodeDialog dialog(this, &qrc, "Deposit BTC to this address");
dialog.show();
} else{
AtomicFundDialog dialog(qobject_cast<QWidget*>(parent()), &qrc, "Deposit BTC to this address", address);
connect(&dialog,&AtomicFundDialog::cleanProcs, this, [this]{clean();});
connect(this, &AtomicWidget::receivedBTC,&dialog, [this, &dialog]{
disconnect(&dialog, SIGNAL(cleanProcs()), nullptr, nullptr);
dialog.close();});
dialog.exec();
} else if (line["fields"]["message"].toString().startsWith("Received Bitcoin")){
emit receivedBTC(line["fields"]["new_balance"].toString().split(" ")[0].toDouble());
qDebug() << "Spawn atomic swap progress dialog";
showAtomicSwapDialog();
}
//Insert line conditionals here
}
});
swap->start(m_instance->get(Config::swapPath).toString(),arguments);
qDebug() << "process started";
@ -165,8 +182,6 @@ void AtomicWidget::list(QString rendezvous) {
QList<QSharedPointer<OfferEntry>> list;
arguments << "--data-base-dir";
arguments << Config::defaultConfigDir().absolutePath();
// Remove after testing
//arguments << "--testnet";
arguments << "-j";
arguments << "list-sellers";
arguments << "--tor-socks5-port";
@ -208,7 +223,6 @@ void AtomicWidget::list(QString rendezvous) {
qDebug() << entry;
}
}
qDebug() << "next line";
}
qDebug() << "exits fine";
swap->close();
@ -226,6 +240,12 @@ AtomicWidget::~AtomicWidget() {
qDebug()<< "EXiting widget!!";
delete o_model;
delete offerList;
clean();
delete m_instance;
delete procList;
}
void AtomicWidget::clean() {
for (auto proc : *procList){
if(!proc->atEnd())
proc->terminate();
@ -234,7 +254,8 @@ AtomicWidget::~AtomicWidget() {
qDebug() << "Closing monero-wallet-rpc";
(new QProcess)->start("pkill", QStringList{"-f", Config::defaultConfigDir().absolutePath() +
"/mainnet/monero/monero-wallet-rpc"});
(new QProcess)->start("pkill", QStringList{"-f", Config::defaultConfigDir().absolutePath() +
"/testnet/monero/monero-wallet-rpc"});
}
delete m_instance;
delete procList;
};
}

View file

@ -29,11 +29,13 @@ public:
public slots:
void skinChanged();
void clean();
private slots:
void showAtomicConfigureDialog();
void runSwap(QString seller, QString btcChange, QString xmrReceive);
signals:
void receivedBTC(float new_amount);
private:
void updateStatus();