mirror of
https://github.com/feather-wallet/feather.git
synced 2025-01-09 20:39:58 +00:00
Version v1.0
Everything should be working, tested on ubuntu.
This commit is contained in:
parent
12bbc76e26
commit
441aa24996
11 changed files with 96 additions and 67 deletions
|
@ -51,7 +51,9 @@ void AtomicFundDialog::copyAddress(){
|
|||
QMessageBox::information(this, "Information", "BTC deposit address copied to clipboard");
|
||||
}
|
||||
|
||||
|
||||
void AtomicFundDialog::updateMin(QString min){
|
||||
ui->label_status->setText("Deposit at least " + min + " BTC to cover fee");
|
||||
}
|
||||
|
||||
AtomicFundDialog::~AtomicFundDialog() {
|
||||
emit cleanProcs();
|
||||
|
|
|
@ -22,6 +22,7 @@ class AtomicFundDialog : public WindowModalDialog {
|
|||
public:
|
||||
explicit AtomicFundDialog(QWidget *parent, const QString &title = "Qr Code", const QString &btc_address = "Error Restart swap");
|
||||
~AtomicFundDialog() override;
|
||||
void updateMin(QString min);
|
||||
signals:
|
||||
void cleanProcs();
|
||||
private:
|
||||
|
|
|
@ -14,6 +14,13 @@
|
|||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_status">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QrCodeWidget" name="qrWidget" native="true">
|
||||
<property name="sizePolicy">
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
|
||||
#include "AtomicRecoverDialog.h"
|
||||
#include "ui_AtomicRecoverDialog.h"
|
||||
#include "History.h"
|
||||
#include "config.h"
|
||||
#include "AtomicSwap.h"
|
||||
#include "Utils.h"
|
||||
#include "constants.h"
|
||||
#include <QStandardItemModel>
|
||||
|
||||
AtomicRecoverDialog::AtomicRecoverDialog(QWidget *parent) :
|
||||
|
@ -17,27 +17,33 @@ AtomicRecoverDialog::AtomicRecoverDialog(QWidget *parent) :
|
|||
ui->setupUi(this);
|
||||
auto model = new QStandardItemModel();
|
||||
ui->swap_history->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
||||
ui->swap_history->setModel(model);
|
||||
ui->swap_history->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
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);
|
||||
this->raise();
|
||||
model->setHorizontalHeaderItem(0, new QStandardItem("Swap-Id"));
|
||||
model->setHorizontalHeaderItem(1, new QStandardItem("Timestamp swap started"));
|
||||
model->setHorizontalHeaderItem(2, new QStandardItem("Status"));
|
||||
|
||||
QList<QStandardItem*> rowData;
|
||||
auto data = conf()->get(Config::pendingSwap).value<QVariantList>();
|
||||
qDebug() << conf()->get(Config::pendingSwap);
|
||||
QStringList data = conf()->get(Config::pendingSwap).toStringList();
|
||||
qDebug() << data;
|
||||
for(int i=0; i< data.size(); i++){
|
||||
auto entry = data[i].value<HistoryEntry>();
|
||||
qint64 difference = entry.timestamp.secsTo(QDateTime::currentDateTime());
|
||||
QStringList entry = data[i].split(":");
|
||||
qDebug() << "Swap-id - " + entry[0];
|
||||
QString id = entry[0];
|
||||
QDateTime timestamp = QDateTime::fromString(entry[1],"dd.MM.yyyy.hh.mm.ss");
|
||||
qint64 difference = timestamp.secsTo(QDateTime::currentDateTime());
|
||||
|
||||
if (difference < 86400) {
|
||||
rowData.clear();
|
||||
rowData << new QStandardItem(entry.id);
|
||||
rowData << new QStandardItem(entry.timestamp.toString("MM-dd-yyyy hh:mm"));
|
||||
rowData << new QStandardItem(id);
|
||||
rowData << new QStandardItem(timestamp.toString("MM-dd-yyyy hh:mm"));
|
||||
if (difference > 43200){
|
||||
rowData << new QStandardItem("Refundable");
|
||||
} else
|
||||
|
@ -47,27 +53,26 @@ AtomicRecoverDialog::AtomicRecoverDialog(QWidget *parent) :
|
|||
data.remove(i);
|
||||
}
|
||||
}
|
||||
ui->swap_history->setModel(model);
|
||||
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 (constants::networkType==NetworkType::STAGENET) {
|
||||
arguments << "--testnet";
|
||||
}
|
||||
arguments << "-j";
|
||||
arguments << "--debug";
|
||||
arguments << "-d";
|
||||
arguments << Config::defaultConfigDir().absolutePath();
|
||||
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 << "--monero-daemon-address";
|
||||
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();
|
||||
}
|
||||
}
|
||||
arguments << nodes.value("0").toObject()["ws"].toArray()[0].toString();
|
||||
auto row = ui->swap_history->selectionModel()->selectedRows().at(0);
|
||||
arguments << row.sibling(row.row(),0).data().toString();
|
||||
if(conf()->get(Config::proxy).toInt() != Config::Proxy::None) {
|
||||
arguments << "--tor-socks5-port";
|
||||
arguments << conf()->get(Config::socks5Port).toString();
|
||||
|
@ -94,11 +99,9 @@ bool AtomicRecoverDialog::historyEmpty(){
|
|||
}
|
||||
|
||||
|
||||
void AtomicRecoverDialog::appendHistory(HistoryEntry entry){
|
||||
void AtomicRecoverDialog::appendHistory(QString entry){
|
||||
auto current = conf()->get(Config::pendingSwap).value<QVariantList>();
|
||||
auto var = QVariant();
|
||||
var.setValue(entry);
|
||||
current.append(var);
|
||||
current.append(entry);
|
||||
conf()->set(Config::pendingSwap, current);
|
||||
}
|
||||
AtomicRecoverDialog::~AtomicRecoverDialog() {
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
#include <QDialog>
|
||||
#include "components.h"
|
||||
#include "History.h"
|
||||
#include "AtomicSwap.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
@ -20,7 +19,7 @@ Q_OBJECT
|
|||
public:
|
||||
explicit AtomicRecoverDialog(QWidget *parent = nullptr);
|
||||
bool historyEmpty();
|
||||
void appendHistory(HistoryEntry entry);
|
||||
void appendHistory(QString entry);
|
||||
~AtomicRecoverDialog() override;
|
||||
|
||||
private slots:
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include <qt6/QtWidgets/QMessageBox>
|
||||
#include "ui_AtomicSwap.h"
|
||||
#include "AtomicWidget.h"
|
||||
#include "constants.h"
|
||||
#include "networktype.h"
|
||||
|
||||
|
||||
AtomicSwap::AtomicSwap(QWidget *parent) :
|
||||
|
@ -20,7 +22,7 @@ AtomicSwap::AtomicSwap(QWidget *parent) :
|
|||
int size=20;
|
||||
pixmapTarget = pixmapTarget.scaled(size-5, size-5, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
ui->btc_hint->setPixmap(pixmapTarget);
|
||||
ui->btc_hint->setToolTip("Alice is expected to send monero lock after one btc confirmation,\nswap is cancelable after 72 btc confirmations,\nyou will lose your funds if you don't refund before 144 confirmations");
|
||||
ui->btc_hint->setToolTip("Alice is expected to send monero lock after one btc confirmation,\nswap is cancelable after 72 btc confirmations,\nyou will lose your funds if you don't refund before 144 confirmations\n\nResumed swaps may not have accurate numbers for confirmations!!!");
|
||||
this->setContentsMargins(3,3,3,3);
|
||||
this->adjustSize();
|
||||
connect(ui->btn_cancel, &QPushButton::clicked, this, &AtomicSwap::cancel);
|
||||
|
@ -38,21 +40,25 @@ void AtomicSwap::runSwap(QStringList arguments){
|
|||
QJsonDocument line = QJsonDocument::fromJson(rawline, &err);
|
||||
qDebug() << rawline;
|
||||
bool check;
|
||||
if (line["fields"]["message"].toString().contains("Connected to Alice")){
|
||||
QString message = line["fields"]["message"].toString();
|
||||
if (message.contains("Connected to Alice")){
|
||||
qDebug() << "Successfully connected";
|
||||
this->logLine(line["fields"].toString());
|
||||
} else if (!line["fields"]["deposit_address"].toString().isEmpty()){
|
||||
qDebug() << "Deposit to btc to segwit address";
|
||||
QString address = line["fields"]["deposit_address"].toString();
|
||||
fundDialog = new AtomicFundDialog(this, "Deposit BTC to this address", address);
|
||||
fundDialog->updateMin(min);
|
||||
fundDialog->update();
|
||||
//dialog->setModal(true);
|
||||
fundDialog->show();
|
||||
} else if (line["fields"]["message"].toString().startsWith("Received Bitcoin")){
|
||||
} else if (message.startsWith("Received Bitcoin")){
|
||||
this->updateStatus(line["fields"]["new_balance"].toString().split(" ")[0] + " BTC received, starting swap");
|
||||
QVariant var;
|
||||
var.setValue(HistoryEntry {QDateTime::currentDateTime(),line["span"]["swap_id"].toString()});
|
||||
QString entry = line["span"]["swap_id"].toString() + ":" + QDateTime::currentDateTime().toString("dd.MM.yyyy.hh.mm.ss");
|
||||
qDebug() << "Swap logged as ";
|
||||
qDebug() << entry;
|
||||
QVariantList past = conf()->get(Config::pendingSwap).toList();
|
||||
past.append(var);
|
||||
past.append(entry);
|
||||
conf()->set(Config::pendingSwap,past);
|
||||
fundDialog->close();
|
||||
qDebug() << "Spawn atomic swap progress dialog";
|
||||
|
@ -60,40 +66,46 @@ void AtomicSwap::runSwap(QStringList arguments){
|
|||
} else if ( QString confs = line["fields"]["seen_confirmations"].toString(); !confs.isEmpty()){
|
||||
qDebug() << "Updating xmrconfs " + confs;
|
||||
this->updateXMRConf(confs.toInt());
|
||||
} else if (QString message = line["fields"]["message"].toString(); QString::compare(message, "Bitcoin transaction status changed")==0){
|
||||
qDebug() << "Updating btconfs " + line["fields"]["new_status"].toString().split(" ")[2];
|
||||
} else if (QString::compare(message, "Bitcoin transaction status changed")==0){
|
||||
QString status = line["fields"]["new_status"].toString();
|
||||
bool ok;
|
||||
auto confirmations = status.split(" ")[2].toInt(&ok, 10);
|
||||
if(ok) {
|
||||
this->updateBTCConf(confirmations);
|
||||
} else {
|
||||
auto parts = status.split(" ");
|
||||
if (parts.length() == 2){
|
||||
this->updateStatus("Found txid " + line["fields"]["txid"].toString() + " in mempool");
|
||||
|
||||
}else {
|
||||
auto confirmations = parts[2].toInt();
|
||||
this->updateBTCConf(confirmations);
|
||||
}
|
||||
} else if (QString message = line["fields"]["message"].toString(); message.startsWith("Swap completed")){
|
||||
} else if (message.startsWith("Swap completed")){
|
||||
QVariantList past = conf()->get(Config::pendingSwap).toList();
|
||||
past.removeLast();
|
||||
conf()->set(Config::pendingSwap, past);
|
||||
this->updateStatus("Swap has successfully completed you can close this window now");
|
||||
} else if (QString message = line["fields"]["message"].toString(); QString::compare(message,"Advancing state")==0){
|
||||
} else if (QString::compare(message,"Advancing state")==0){
|
||||
this->updateStatus("State of swap has advanced to " + line["fields"]["state"].toString());
|
||||
} else if (QString refund = line["fields"]["kind"].toString(); QString::compare(refund,"refund")==0){
|
||||
QString txid = line["fields"]["txid"].toString();
|
||||
QString id = line["span"]["swap_id"].toString();
|
||||
QVariantList past = conf()->get(Config::pendingSwap).toList();
|
||||
QStringList past = conf()->get(Config::pendingSwap).toStringList();
|
||||
for(int i=0;i<past.length();i++){
|
||||
if(QString::compare(past[i].value<HistoryEntry>().id,id)==0) {
|
||||
if(QString::compare(past[i].split(":")[0],id)==0) {
|
||||
past.remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
conf()->set(Config::pendingSwap, past);
|
||||
QMessageBox::information(this,"Cancel and Refund","Swap refunded succesfully with txid " + txid);
|
||||
} else if (QString message = line["fields"]["message"].toString(); QString::compare(message, "API call resulted in an error")==0){
|
||||
} else if ( QString::compare(message, "API call resulted in an error")==0){
|
||||
QString err = line["fields"]["err"].toString().split("\n")[0].split(":")[1];
|
||||
QMessageBox::warning(this, "Cancel and Refund", "Time lock hasn't expired yet so cancel failed. Try again in " + err + "blocks");
|
||||
} else if (QString message = line["fields"]["latest_version"].toString(); !message.isEmpty()){
|
||||
conf()->set(Config::swapVersion,message);
|
||||
} else if (QString latest_version = line["fields"]["latest_version"].toString(); !latest_version.isEmpty()){
|
||||
QMessageBox::warning(this, "Outdated swap version","A newer version of COMIT xmr-btc swap tool is available, delete current binary and re auto install to upgrade");
|
||||
conf()->set(Config::swapVersion,latest_version);
|
||||
} else if (message.startsWith("Acquiring swap lock") && QString::compare("Resume",line["span"]["method_name"].toString())==0){
|
||||
updateStatus("Beginning resumption of previous swap");
|
||||
this->show();
|
||||
} else if (message.startsWith("Deposit at least")){
|
||||
min = message.split(" ")[3];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -106,6 +118,16 @@ AtomicSwap::~AtomicSwap() {
|
|||
for (const auto& proc : *procList){
|
||||
proc->kill();
|
||||
}
|
||||
if(conf()->get(Config::operatingSystem)=="WINDOWS"){
|
||||
(new QProcess)->start("tskill", QStringList{"monero-wallet-rpc"});
|
||||
}else {
|
||||
if (constants::networkType==NetworkType::STAGENET){
|
||||
(new QProcess)->start("pkill", QStringList{"-f", Config::defaultConfigDir().absolutePath() +"/testnet/monero/monero-wallet-rpc"});
|
||||
} else {
|
||||
(new QProcess)->start("pkill", QStringList{"-f", Config::defaultConfigDir().absolutePath() +
|
||||
"/mainnet/monero/monero-wallet-rpc"});
|
||||
}
|
||||
}
|
||||
}
|
||||
void AtomicSwap::logLine(QString line){
|
||||
this->update();
|
||||
|
|
|
@ -34,6 +34,7 @@ signals:
|
|||
private:
|
||||
Ui::AtomicSwap *ui;
|
||||
QString id;
|
||||
QString min;
|
||||
AtomicFundDialog* fundDialog;
|
||||
QList<QSharedPointer<QProcess>>* procList;
|
||||
int btc_confs;
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#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"
|
||||
|
@ -137,7 +136,6 @@ void AtomicWidget::runSwap(const QString& seller, const QString& btcChange, cons
|
|||
QStringList arguments;
|
||||
arguments << "--data-base-dir";
|
||||
arguments << Config::defaultConfigDir().absolutePath();
|
||||
// Remove after testing
|
||||
if (constants::networkType==NetworkType::STAGENET){
|
||||
arguments << "--testnet";
|
||||
}
|
||||
|
@ -149,6 +147,8 @@ void AtomicWidget::runSwap(const QString& seller, const QString& btcChange, cons
|
|||
arguments << "--receive-address";
|
||||
arguments << xmrReceive;
|
||||
|
||||
//Doesn't work cause wallet rpc
|
||||
/*
|
||||
auto nodes = conf()->get(Config::nodes).toJsonObject();
|
||||
if (nodes.isEmpty()) {
|
||||
auto jsonData = conf()->get(Config::nodes).toByteArray();
|
||||
|
@ -159,6 +159,7 @@ void AtomicWidget::runSwap(const QString& seller, const QString& btcChange, cons
|
|||
}
|
||||
arguments << "--monero-daemon-address";
|
||||
arguments << nodes.value("0").toObject()["ws"].toArray()[0].toString();
|
||||
*/
|
||||
arguments << "--seller";
|
||||
arguments << seller;
|
||||
if(conf()->get(Config::proxy).toInt() != Config::Proxy::None) {
|
||||
|
@ -235,6 +236,16 @@ void AtomicWidget::clean() {
|
|||
for (const auto& proc : *procList){
|
||||
proc->kill();
|
||||
}
|
||||
if(conf()->get(Config::operatingSystem)=="WINDOWS"){
|
||||
(new QProcess)->start("tskill", QStringList{"monero-wallet-rpc"});
|
||||
}else {
|
||||
if (constants::networkType==NetworkType::STAGENET){
|
||||
(new QProcess)->start("pkill", QStringList{"-f", Config::defaultConfigDir().absolutePath() +"/testnet/monero/monero-wallet-rpc"});
|
||||
} else {
|
||||
(new QProcess)->start("pkill", QStringList{"-f", Config::defaultConfigDir().absolutePath() +
|
||||
"/mainnet/monero/monero-wallet-rpc"});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<item>
|
||||
<widget class="QLineEdit" name="change_address">
|
||||
<property name="text">
|
||||
<string>bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq</string>
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -49,7 +49,7 @@
|
|||
<item>
|
||||
<widget class="QLineEdit" name="xmr_address">
|
||||
<property name="text">
|
||||
<string>888tNkZrPN6JsEgekjMnABU4TBzc2Dt29EPAvkRxbANsAnjyPbb3iQ1YBRk1UXcdRsiKc9dhwMVgN5S9cQUiyoogDavup3H</string>
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
//
|
||||
// Created by dev on 7/29/24.
|
||||
//
|
||||
|
||||
#ifndef FEATHER_HISTORY_H
|
||||
#define FEATHER_HISTORY_H
|
||||
|
||||
#include <QString>
|
||||
#include <QDateTime>
|
||||
|
||||
struct HistoryEntry {
|
||||
QDateTime timestamp;
|
||||
QString id;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(HistoryEntry);
|
||||
#endif //FEATHER_HISTORY_H
|
|
@ -149,7 +149,7 @@ static const QHash<Config::ConfigKey, ConfigDirective> configStrings = {
|
|||
"/dns4/swap.sethforprivacy.com/tcp/8888/p2p/12D3KooWCULyZKuV9YEkb6BX8FuwajdvktSzmMg4U5ZX2uYZjHeu"}}},
|
||||
{Config::swapPath, {QS("swapPath"), ""}},
|
||||
{Config::operatingSystem, {QS("operatingSystem"), OS}},
|
||||
{Config::pendingSwap, {QS("pendingSwap"), QVariantList{}}},
|
||||
{Config::pendingSwap, {QS("pendingSwap"), QStringList{}}},
|
||||
{Config::swapVersion, {QS("swapVersion"), "0.13.4"}},
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue