TransactionInfoDialog: add copy spendproof, in/outproof

This commit is contained in:
tobtoht 2020-11-08 12:08:15 +01:00
parent 2c99454565
commit 780a35fabe
14 changed files with 258 additions and 21 deletions

View file

@ -30,7 +30,7 @@ if(DEBUG)
set(CMAKE_VERBOSE_MAKEFILE ON) set(CMAKE_VERBOSE_MAKEFILE ON)
endif() endif()
set(MONERO_HEAD "a6bf6dbb8f1637ccffee1a30d2285324a3ce4d66") set(MONERO_HEAD "9ca5569f40a392b16946c5c3bda312eecfdcc9ab")
set(BUILD_GUI_DEPS ON) set(BUILD_GUI_DEPS ON)
set(ARCH "x86-64") set(ARCH "x86-64")
set(BUILD_64 ON) set(BUILD_64 ON)

2
monero

@ -1 +1 @@
Subproject commit a6bf6dbb8f1637ccffee1a30d2285324a3ce4d66 Subproject commit 9ca5569f40a392b16946c5c3bda312eecfdcc9ab

View file

@ -6,7 +6,9 @@
#include "libwalletqt/CoinsInfo.h" #include "libwalletqt/CoinsInfo.h"
#include "libwalletqt/WalletManager.h" #include "libwalletqt/WalletManager.h"
#include <QDebug> #include "utils.h"
#include <QMessageBox>
TransactionInfoDialog::TransactionInfoDialog(Wallet *wallet, TransactionInfo *txInfo, QWidget *parent) TransactionInfoDialog::TransactionInfoDialog(Wallet *wallet, TransactionInfo *txInfo, QWidget *parent)
: QDialog(parent) : QDialog(parent)
@ -16,6 +18,8 @@ TransactionInfoDialog::TransactionInfoDialog(Wallet *wallet, TransactionInfo *tx
{ {
ui->setupUi(this); ui->setupUi(this);
m_txProofWidget = new TxProofWidget(this, wallet, txInfo);
ui->label_txid->setText(QString(txInfo->hash())); ui->label_txid->setText(QString(txInfo->hash()));
if (txInfo->direction() == TransactionInfo::Direction_In) { if (txInfo->direction() == TransactionInfo::Direction_In) {
@ -48,6 +52,8 @@ TransactionInfoDialog::TransactionInfoDialog(Wallet *wallet, TransactionInfo *tx
ui->destinations->setText(destinations); ui->destinations->setText(destinations);
} }
ui->txProofWidget->addWidget(m_txProofWidget);
this->adjustSize(); this->adjustSize();
} }

View file

@ -9,6 +9,7 @@
#include "libwalletqt/Coins.h" #include "libwalletqt/Coins.h"
#include "libwalletqt/TransactionInfo.h" #include "libwalletqt/TransactionInfo.h"
#include "libwalletqt/Wallet.h" #include "libwalletqt/Wallet.h"
#include "widgets/txproofwidget.h"
namespace Ui { namespace Ui {
class TransactionInfoDialog; class TransactionInfoDialog;
@ -27,6 +28,7 @@ private:
TransactionInfo *m_txInfo; TransactionInfo *m_txInfo;
Wallet *m_wallet; Wallet *m_wallet;
TxProofWidget *m_txProofWidget;
}; };
#endif //FEATHER_TRANSACTIONINFODIALOG_H #endif //FEATHER_TRANSACTIONINFODIALOG_H

View file

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>547</width> <width>829</width>
<height>436</height> <height>570</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -158,6 +158,16 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="Line" name="line_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="txProofWidget"/>
</item>
<item> <item>
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">

View file

@ -28,6 +28,11 @@ bool TransactionInfo::isCoinbase() const
return m_coinbase; return m_coinbase;
} }
quint64 TransactionInfo::balanceDelta() const
{
return m_amount + m_fee;
}
double TransactionInfo::amount() const double TransactionInfo::amount() const
{ {
// there's no unsigned uint64 for JS, so better use double // there's no unsigned uint64 for JS, so better use double
@ -44,6 +49,11 @@ QString TransactionInfo::displayAmount() const
return WalletManager::displayAmount(m_amount); return WalletManager::displayAmount(m_amount);
} }
quint64 TransactionInfo::atomicFee() const
{
return m_fee;
}
QString TransactionInfo::fee() const QString TransactionInfo::fee() const
{ {
if(m_fee == 0) if(m_fee == 0)
@ -127,6 +137,15 @@ QString TransactionInfo::destinations_formatted() const
return destinations; return destinations;
} }
QList<QString> TransactionInfo::destinations() const
{
QList<QString> dests;
for (auto const& t: m_transfers) {
dests.append(t->address());
}
return dests;
}
QString TransactionInfo::rings_formatted() const QString TransactionInfo::rings_formatted() const
{ {
QString rings; QString rings;

View file

@ -52,10 +52,12 @@ public:
bool isPending() const; bool isPending() const;
bool isFailed() const; bool isFailed() const;
bool isCoinbase() const; bool isCoinbase() const;
quint64 balanceDelta() const;
double amount() const; double amount() const;
quint64 atomicAmount() const; quint64 atomicAmount() const;
QString displayAmount() const; QString displayAmount() const;
QString fee() const; QString fee() const;
quint64 atomicFee() const;
quint64 blockHeight() const; quint64 blockHeight() const;
QString description() const; QString description() const;
QSet<quint32> subaddrIndex() const; QSet<quint32> subaddrIndex() const;
@ -72,6 +74,7 @@ public:
QString paymentId() const; QString paymentId() const;
//! only applicable for output transactions //! only applicable for output transactions
//! used in tx details popup //! used in tx details popup
QList<QString> destinations() const;
QString destinations_formatted() const; QString destinations_formatted() const;
QString rings_formatted() const; QString rings_formatted() const;

View file

@ -792,12 +792,10 @@ QString Wallet::checkTxKey(const QString &txid, const QString &tx_key, const QSt
return QString::fromStdString(result); return QString::fromStdString(result);
} }
QString Wallet::getTxProof(const QString &txid, const QString &address, const QString &message) const TxProof Wallet::getTxProof(const QString &txid, const QString &address, const QString &message) const
{ {
std::string result = m_walletImpl->getTxProof(txid.toStdString(), address.toStdString(), message.toStdString()); std::string result = m_walletImpl->getTxProof(txid.toStdString(), address.toStdString(), message.toStdString());
if (result.empty()) return TxProof(QString::fromStdString(result), QString::fromStdString(m_walletImpl->errorString()));
result = "error|" + m_walletImpl->errorString();
return QString::fromStdString(result);
} }
//void Wallet::getTxProofAsync(const QString &txid, const QString &address, const QString &message, const QJSValue &callback) //void Wallet::getTxProofAsync(const QString &txid, const QString &address, const QString &message, const QJSValue &callback)
@ -817,12 +815,10 @@ TxProofResult Wallet::checkTxProof(const QString &txid, const QString &address,
return {success, good, received, in_pool, confirmations}; return {success, good, received, in_pool, confirmations};
} }
Q_INVOKABLE QString Wallet::getSpendProof(const QString &txid, const QString &message) const Q_INVOKABLE TxProof Wallet::getSpendProof(const QString &txid, const QString &message) const
{ {
std::string result = m_walletImpl->getSpendProof(txid.toStdString(), message.toStdString()); std::string result = m_walletImpl->getSpendProof(txid.toStdString(), message.toStdString());
if (result.empty()) return TxProof(QString::fromStdString(result), QString::fromStdString(m_walletImpl->errorString()));
result = "error|" + m_walletImpl->errorString();
return QString::fromStdString(result);
} }
//void Wallet::getSpendProofAsync(const QString &txid, const QString &message, const QJSValue &callback) //void Wallet::getSpendProofAsync(const QString &txid, const QString &message, const QJSValue &callback)

View file

@ -22,6 +22,13 @@ namespace Monero {
struct Wallet; // forward declaration struct Wallet; // forward declaration
} }
struct TxProof {
TxProof(QString proof, QString error = "")
: proof(std::move(proof)), error(std::move(error)){}
QString proof;
QString error;
};
class TransactionHistory; class TransactionHistory;
class TransactionHistoryModel; class TransactionHistoryModel;
@ -336,11 +343,11 @@ public:
Q_INVOKABLE QString getTxKey(const QString &txid) const; Q_INVOKABLE QString getTxKey(const QString &txid) const;
//Q_INVOKABLE void getTxKeyAsync(const QString &txid, const QJSValue &callback); //Q_INVOKABLE void getTxKeyAsync(const QString &txid, const QJSValue &callback);
Q_INVOKABLE QString checkTxKey(const QString &txid, const QString &tx_key, const QString &address); Q_INVOKABLE QString checkTxKey(const QString &txid, const QString &tx_key, const QString &address);
Q_INVOKABLE QString getTxProof(const QString &txid, const QString &address, const QString &message) const; Q_INVOKABLE TxProof getTxProof(const QString &txid, const QString &address, const QString &message) const;
// Q_INVOKABLE void getTxProofAsync(const QString &txid, const QString &address, const QString &message, const QJSValue &callback); // Q_INVOKABLE void getTxProofAsync(const QString &txid, const QString &address, const QString &message, const QJSValue &callback);
//Q_INVOKABLE QString checkTxProof(const QString &txid, const QString &address, const QString &message, const QString &signature); //Q_INVOKABLE QString checkTxProof(const QString &txid, const QString &address, const QString &message, const QString &signature);
Q_INVOKABLE TxProofResult checkTxProof(const QString &txid, const QString &address, const QString &message, const QString &signature); Q_INVOKABLE TxProofResult checkTxProof(const QString &txid, const QString &address, const QString &message, const QString &signature);
Q_INVOKABLE QString getSpendProof(const QString &txid, const QString &message) const; Q_INVOKABLE TxProof getSpendProof(const QString &txid, const QString &message) const;
// Q_INVOKABLE void getSpendProofAsync(const QString &txid, const QString &message, const QJSValue &callback); // Q_INVOKABLE void getSpendProofAsync(const QString &txid, const QString &message, const QJSValue &callback);
Q_INVOKABLE QPair<bool, bool> checkSpendProof(const QString &txid, const QString &message, const QString &signature) const; Q_INVOKABLE QPair<bool, bool> checkSpendProof(const QString &txid, const QString &message, const QString &signature) const;
// Rescan spent outputs // Rescan spent outputs

View file

@ -302,8 +302,8 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) :
// History // History
connect(ui->historyWidget, &HistoryWidget::spendProof, [&](const QString &txid){ connect(ui->historyWidget, &HistoryWidget::spendProof, [&](const QString &txid){
QString spendProof = m_ctx->currentWallet->getSpendProof(txid, ""); TxProof txproof = m_ctx->currentWallet->getSpendProof(txid, "");
Utils::copyToClipboard(spendProof); Utils::copyToClipboard(txproof.proof);
}); });
connect(ui->historyWidget, &HistoryWidget::viewOnBlockExplorer, this, &MainWindow::onViewOnBlockExplorer); connect(ui->historyWidget, &HistoryWidget::viewOnBlockExplorer, this, &MainWindow::onViewOnBlockExplorer);

View file

@ -119,7 +119,7 @@ QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const
case Column::FiatAmount: case Column::FiatAmount:
case Column::Amount: case Column::Amount:
{ {
if (tInfo.direction() == TransactionInfo::Direction_Out && tInfo.amount() > 0) { if (tInfo.direction() == TransactionInfo::Direction_Out) {
result = QVariant(QColor("#BC1E1E")); result = QVariant(QColor("#BC1E1E"));
} }
} }
@ -152,8 +152,8 @@ QVariant TransactionHistoryModel::parseTransactionInfo(const TransactionInfo &tI
} }
case Column::Amount: case Column::Amount:
{ {
QString amount = QString::number(tInfo.atomicAmount() / globals::cdiv, 'f', 4); QString amount = QString::number(tInfo.balanceDelta() / globals::cdiv, 'f', 4);
amount = (tInfo.direction() == TransactionInfo::Direction_Out && tInfo.amount() > 0) ? "-" + amount : "+" + amount; amount = (tInfo.direction() == TransactionInfo::Direction_Out) ? "-" + amount : "+" + amount;
return amount; return amount;
} }
case Column::TxID: case Column::TxID:
@ -164,7 +164,7 @@ QVariant TransactionHistoryModel::parseTransactionInfo(const TransactionInfo &tI
if (usd_price == 0.0) if (usd_price == 0.0)
return QVariant("?"); return QVariant("?");
double usd_amount = usd_price * tInfo.amount(); double usd_amount = usd_price * (tInfo.balanceDelta() / globals::cdiv);
if(this->preferredFiatSymbol != "USD") if(this->preferredFiatSymbol != "USD")
usd_amount = AppContext::prices->convert("USD", this->preferredFiatSymbol, usd_amount); usd_amount = AppContext::prices->convert("USD", this->preferredFiatSymbol, usd_amount);
double fiat_rounded = ceil(Utils::roundSignificant(usd_amount, 3) * 100.0) / 100.0; double fiat_rounded = ceil(Utils::roundSignificant(usd_amount, 3) * 100.0) / 100.0;

View file

@ -0,0 +1,61 @@
#include "txproofwidget.h"
#include "ui_txproofwidget.h"
#include <QMessageBox>
#include <utility>
#include "utils/utils.h"
TxProofWidget::TxProofWidget(QWidget *parent, Wallet *wallet, TransactionInfo *txInfo)
: QWidget(parent)
, ui(new Ui::TxProofWidget)
, m_wallet(wallet)
, m_txid(txInfo->hash())
{
ui->setupUi(this);
if (txInfo->direction() == TransactionInfo::Direction_Out) {
for (auto const &d: txInfo->destinations()) {
ui->comboBox_TxProofAddresses->addItem(d);
}
} else {
ui->btn_copySpendProof->setEnabled(false);
for (auto const &s: txInfo->subaddrIndex()) {
ui->comboBox_TxProofAddresses->addItem(wallet->address(txInfo->subaddrAccount(), s));
}
}
if (ui->comboBox_TxProofAddresses->count() == 0) {
ui->btn_copyTxProof->setEnabled(false);
}
connect(ui->btn_copySpendProof, &QPushButton::clicked, this, &TxProofWidget::copySpendProof);
connect(ui->btn_copyTxProof, &QPushButton::clicked, this, &TxProofWidget::copyTxProof);
}
void TxProofWidget::copySpendProof() {
auto txproof = m_wallet->getSpendProof(m_txid, "");
if (!txproof.error.isEmpty()) {
QMessageBox::warning(this, "Copy SpendProof", QString("Failed to copy SpendProof").arg(txproof.error));
return;
}
Utils::copyToClipboard(txproof.proof);
QMessageBox::information(this, "Copy SpendProof", "SpendProof copied to clipboard");
}
void TxProofWidget::copyTxProof() {
auto txproof = m_wallet->getTxProof(m_txid, ui->comboBox_TxProofAddresses->currentText(), "");
if (!txproof.error.isEmpty()) {
QMessageBox::warning(this, "Copy Transaction Proof", QString("Failed to copy transaction proof: %1").arg(txproof.error));
return;
}
Utils::copyToClipboard(txproof.proof);
QMessageBox::information(this, "Copy Transaction Proof", "Transaction proof copied to clipboard");
}
TxProofWidget::~TxProofWidget() {
delete ui;
}

View file

@ -0,0 +1,30 @@
#ifndef FEATHER_TXPROOFWIDGET_H
#define FEATHER_TXPROOFWIDGET_H
#include <QWidget>
#include "libwalletqt/Wallet.h"
#include "libwalletqt/TransactionInfo.h"
namespace Ui {
class TxProofWidget;
}
class TxProofWidget : public QWidget
{
Q_OBJECT
public:
explicit TxProofWidget(QWidget *parent, Wallet *wallet, TransactionInfo *txid);
~TxProofWidget() override;
private:
void copySpendProof();
void copyTxProof();
Ui::TxProofWidget *ui;
QString m_txid;
Wallet *m_wallet;
};
#endif //FEATHER_TXPROOFWIDGET_H

View file

@ -0,0 +1,103 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TxProofWidget</class>
<widget class="QWidget" name="TxProofWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>647</width>
<height>79</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="btn_copySpendProof">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Copy</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>SpendProof</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="btn_copyTxProof">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Copy</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>In/OutProof</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_TxProofAddresses">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>