Skip to content

Commit 8a07d91

Browse files
committed
Wire RequestPayment page to PaymentRequest model
- add qml/models/paymentrequest.{h,cpp} - expose WalletQmlModel::currentPaymentRequest - add WalletQmlModel::commitPaymentRequest() - persist receive requests via setAddressReceiveRequest() - register PaymentRequest in qml/bitcoin.cpp - update RequestPayment.qml to bind amount/label/message/address to model - keep create/copy/clear actions model-driven
1 parent 2eb8bb4 commit 8a07d91

6 files changed

Lines changed: 338 additions & 40 deletions

File tree

qml/bitcoin.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include <qml/models/networktraffictower.h>
3434
#include <qml/models/nodemodel.h>
3535
#include <qml/models/options_model.h>
36+
#include <qml/models/paymentrequest.h>
3637
#include <qml/models/peerdetailsmodel.h>
3738
#include <qml/models/peerlistsortproxy.h>
3839
#include <qml/models/peertableqmlmodel.h>
@@ -328,6 +329,7 @@ int QmlGuiMain(int argc, char* argv[])
328329
qmlRegisterType<LineGraph>("org.bitcoincore.qt", 1, 0, "LineGraph");
329330
qmlRegisterUncreatableType<PeerDetailsModel>("org.bitcoincore.qt", 1, 0, "PeerDetailsModel", "");
330331
qmlRegisterType<BitcoinAmount>("org.bitcoincore.qt", 1, 0, "BitcoinAmount");
332+
qmlRegisterType<PaymentRequest>("org.bitcoincore.qt", 1, 0, "PaymentRequest");
331333
qmlRegisterUncreatableType<Transaction>("org.bitcoincore.qt", 1, 0, "Transaction", "");
332334
qmlRegisterUncreatableType<SendRecipient>("org.bitcoincore.qt", 1, 0, "SendRecipient", "");
333335

qml/models/paymentrequest.cpp

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
// Copyright (c) 2024 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <qml/models/paymentrequest.h>
6+
7+
#include <key_io.h>
8+
9+
#include <QString>
10+
11+
PaymentRequest::PaymentRequest(QObject* parent)
12+
: QObject(parent)
13+
{
14+
m_amount = new BitcoinAmount(this);
15+
}
16+
17+
QString PaymentRequest::address() const
18+
{
19+
return QString::fromStdString(EncodeDestination(m_destination));
20+
}
21+
22+
QString PaymentRequest::addressFormatted() const
23+
{
24+
return FormatAddress(address());
25+
}
26+
27+
QString PaymentRequest::label() const
28+
{
29+
return m_label;
30+
}
31+
32+
void PaymentRequest::setLabel(const QString& label)
33+
{
34+
if (m_label == label) {
35+
return;
36+
}
37+
m_label = label;
38+
Q_EMIT labelChanged();
39+
}
40+
41+
QString PaymentRequest::message() const
42+
{
43+
return m_message;
44+
}
45+
46+
void PaymentRequest::setMessage(const QString& message)
47+
{
48+
if (m_message == message) {
49+
return;
50+
}
51+
m_message = message;
52+
Q_EMIT messageChanged();
53+
}
54+
55+
BitcoinAmount* PaymentRequest::amount() const
56+
{
57+
return m_amount;
58+
}
59+
60+
QString PaymentRequest::amountError() const
61+
{
62+
return m_amountError;
63+
}
64+
65+
void PaymentRequest::setAmountError(const QString& error)
66+
{
67+
if (m_amountError == error) {
68+
return;
69+
}
70+
m_amountError = error;
71+
Q_EMIT amountErrorChanged();
72+
}
73+
74+
QString PaymentRequest::id() const
75+
{
76+
return m_id;
77+
}
78+
79+
void PaymentRequest::setId(unsigned int id)
80+
{
81+
const QString new_id = QString::number(id);
82+
if (m_id == new_id) {
83+
return;
84+
}
85+
m_id = new_id;
86+
Q_EMIT idChanged();
87+
}
88+
89+
void PaymentRequest::setDestination(const CTxDestination& destination)
90+
{
91+
m_destination = destination;
92+
Q_EMIT addressChanged();
93+
}
94+
95+
CTxDestination PaymentRequest::destination() const
96+
{
97+
return m_destination;
98+
}
99+
100+
void PaymentRequest::clear()
101+
{
102+
m_destination = CNoDestination();
103+
m_label.clear();
104+
m_message.clear();
105+
m_amount->clear();
106+
m_amountError.clear();
107+
m_id.clear();
108+
Q_EMIT addressChanged();
109+
Q_EMIT labelChanged();
110+
Q_EMIT messageChanged();
111+
Q_EMIT amountErrorChanged();
112+
Q_EMIT idChanged();
113+
}
114+
115+
QString PaymentRequest::FormatAddress(const QString& address)
116+
{
117+
QString formatted;
118+
formatted.reserve(address.length() + address.length() / 4);
119+
for (int i = 0; i < address.length(); ++i) {
120+
if (i > 0 && (i % 4) == 0) {
121+
formatted += QChar(' ');
122+
}
123+
formatted += address[i];
124+
}
125+
return formatted;
126+
}

qml/models/paymentrequest.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright (c) 2024 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_QML_MODELS_PAYMENTREQUEST_H
6+
#define BITCOIN_QML_MODELS_PAYMENTREQUEST_H
7+
8+
#include <qml/bitcoinamount.h>
9+
10+
#include <addresstype.h>
11+
12+
#include <QObject>
13+
#include <QString>
14+
15+
class PaymentRequest : public QObject
16+
{
17+
Q_OBJECT
18+
Q_PROPERTY(QString address READ address NOTIFY addressChanged)
19+
Q_PROPERTY(QString addressFormatted READ addressFormatted NOTIFY addressChanged)
20+
Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY labelChanged)
21+
Q_PROPERTY(QString message READ message WRITE setMessage NOTIFY messageChanged)
22+
Q_PROPERTY(BitcoinAmount* amount READ amount CONSTANT)
23+
Q_PROPERTY(QString amountError READ amountError NOTIFY amountErrorChanged)
24+
Q_PROPERTY(QString id READ id NOTIFY idChanged)
25+
26+
public:
27+
explicit PaymentRequest(QObject* parent = nullptr);
28+
29+
QString address() const;
30+
QString addressFormatted() const;
31+
32+
QString label() const;
33+
void setLabel(const QString& label);
34+
35+
QString message() const;
36+
void setMessage(const QString& message);
37+
38+
BitcoinAmount* amount() const;
39+
QString amountError() const;
40+
void setAmountError(const QString& error);
41+
42+
QString id() const;
43+
void setId(unsigned int id);
44+
45+
void setDestination(const CTxDestination& destination);
46+
CTxDestination destination() const;
47+
48+
Q_INVOKABLE void clear();
49+
50+
Q_SIGNALS:
51+
void addressChanged();
52+
void labelChanged();
53+
void messageChanged();
54+
void amountErrorChanged();
55+
void idChanged();
56+
57+
private:
58+
static QString FormatAddress(const QString& address);
59+
60+
CTxDestination m_destination;
61+
QString m_label;
62+
QString m_message;
63+
QString m_amountError;
64+
BitcoinAmount* m_amount;
65+
QString m_id;
66+
};
67+
68+
#endif // BITCOIN_QML_MODELS_PAYMENTREQUEST_H

qml/models/walletqmlmodel.cpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <qml/models/walletqmlmodel.h>
77

88
#include <qml/models/activitylistmodel.h>
9+
#include <qml/models/paymentrequest.h>
910
#include <qml/models/sendrecipient.h>
1011
#include <qml/models/sendrecipientslistmodel.h>
1112
#include <qml/models/walletqmlmodeltransaction.h>
@@ -18,7 +19,7 @@
1819
#include <wallet/coincontrol.h>
1920
#include <wallet/wallet.h>
2021

21-
#include <QTimer>
22+
unsigned int WalletQmlModel::m_next_payment_request_id{1};
2223

2324
WalletQmlModel::WalletQmlModel(std::unique_ptr<interfaces::Wallet> wallet, QObject *parent)
2425
: QObject(parent)
@@ -27,6 +28,7 @@ WalletQmlModel::WalletQmlModel(std::unique_ptr<interfaces::Wallet> wallet, QObje
2728
m_activity_list_model = new ActivityListModel(this);
2829
m_coins_list_model = new CoinsListModel(this);
2930
m_send_recipients = new SendRecipientsListModel(this);
31+
m_current_payment_request = new PaymentRequest(this);
3032
}
3133

3234
WalletQmlModel::WalletQmlModel(QObject* parent)
@@ -35,13 +37,15 @@ WalletQmlModel::WalletQmlModel(QObject* parent)
3537
m_activity_list_model = new ActivityListModel(this);
3638
m_coins_list_model = new CoinsListModel(this);
3739
m_send_recipients = new SendRecipientsListModel(this);
40+
m_current_payment_request = new PaymentRequest(this);
3841
}
3942

4043
WalletQmlModel::~WalletQmlModel()
4144
{
4245
delete m_activity_list_model;
4346
delete m_coins_list_model;
4447
delete m_send_recipients;
48+
delete m_current_payment_request;
4549
if (m_current_transaction) {
4650
delete m_current_transaction;
4751
}
@@ -81,6 +85,31 @@ QString WalletQmlModel::newAddress(QString label)
8185
return QString::fromStdString(EncodeDestination(dest.value()));
8286
}
8387

88+
void WalletQmlModel::commitPaymentRequest()
89+
{
90+
if (!m_wallet || !m_current_payment_request) {
91+
return;
92+
}
93+
94+
if (m_current_payment_request->id().isEmpty()) {
95+
m_current_payment_request->setId(m_next_payment_request_id++);
96+
}
97+
98+
if (m_current_payment_request->address().isEmpty()) {
99+
const OutputType output_type = m_wallet->getDefaultAddressType();
100+
const auto destination{m_wallet->getNewDestination(output_type, m_current_payment_request->label().toStdString())};
101+
if (!destination) {
102+
return;
103+
}
104+
m_current_payment_request->setDestination(destination.value());
105+
}
106+
107+
m_wallet->setAddressReceiveRequest(
108+
m_current_payment_request->destination(),
109+
m_current_payment_request->id().toStdString(),
110+
m_current_payment_request->message().toStdString());
111+
}
112+
84113
std::set<interfaces::WalletTx> WalletQmlModel::getWalletTxs() const
85114
{
86115
if (!m_wallet) {

qml/models/walletqmlmodel.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <qml/models/activitylistmodel.h>
99
#include <qml/models/coinslistmodel.h>
10+
#include <qml/models/paymentrequest.h>
1011
#include <qml/models/sendrecipient.h>
1112
#include <qml/models/sendrecipientslistmodel.h>
1213
#include <qml/models/walletqmlmodeltransaction.h>
@@ -29,6 +30,7 @@ class WalletQmlModel : public QObject
2930
Q_PROPERTY(ActivityListModel* activityListModel READ activityListModel CONSTANT)
3031
Q_PROPERTY(CoinsListModel* coinsListModel READ coinsListModel CONSTANT)
3132
Q_PROPERTY(SendRecipientsListModel* recipients READ sendRecipientList CONSTANT)
33+
Q_PROPERTY(PaymentRequest* currentPaymentRequest READ currentPaymentRequest CONSTANT)
3234
Q_PROPERTY(WalletQmlModelTransaction* currentTransaction READ currentTransaction NOTIFY currentTransactionChanged)
3335
Q_PROPERTY(unsigned int targetBlocks READ feeTargetBlocks WRITE setFeeTargetBlocks NOTIFY feeTargetBlocksChanged)
3436
Q_PROPERTY(bool isWalletLoaded READ isWalletLoaded NOTIFY walletIsLoadedChanged)
@@ -41,10 +43,12 @@ class WalletQmlModel : public QObject
4143
QString name() const;
4244
QString balance() const;
4345
CAmount balanceSatoshi() const;
46+
Q_INVOKABLE void commitPaymentRequest();
4447

4548
ActivityListModel* activityListModel() const { return m_activity_list_model; }
4649
CoinsListModel* coinsListModel() const { return m_coins_list_model; }
4750
SendRecipientsListModel* sendRecipientList() const { return m_send_recipients; }
51+
PaymentRequest* currentPaymentRequest() const { return m_current_payment_request; }
4852
WalletQmlModelTransaction* currentTransaction() const { return m_current_transaction; }
4953
Q_INVOKABLE bool prepareTransaction();
5054
Q_INVOKABLE void sendTransaction();
@@ -83,10 +87,13 @@ class WalletQmlModel : public QObject
8387
void walletIsLoadedChanged();
8488

8589
private:
90+
static unsigned int m_next_payment_request_id;
91+
8692
std::unique_ptr<interfaces::Wallet> m_wallet;
8793
ActivityListModel* m_activity_list_model{nullptr};
8894
CoinsListModel* m_coins_list_model{nullptr};
8995
SendRecipientsListModel* m_send_recipients{nullptr};
96+
PaymentRequest* m_current_payment_request{nullptr};
9097
WalletQmlModelTransaction* m_current_transaction{nullptr};
9198
wallet::CCoinControl m_coin_control;
9299
bool m_is_wallet_loaded{false};

0 commit comments

Comments
 (0)