From 99501f697901e24ee1d5bfadff76b10443c6ebc9 Mon Sep 17 00:00:00 2001 From: VolodymyrBg Date: Tue, 11 Mar 2025 20:34:22 +0200 Subject: [PATCH 1/4] Update guiutil.cpp --- src/qt/guiutil.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 2369f6b6312..9f90396a10a 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -174,26 +174,31 @@ bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out) if (i->first == "label") { rv.label = i->second; - fShouldReturnFalse = false; } - if (i->first == "message") + else if (i->first == "message") { rv.message = i->second; - fShouldReturnFalse = false; } else if (i->first == "amount") { if(!i->second.isEmpty()) { - if (!BitcoinUnits::parse(BitcoinUnit::BTC, i->second, &rv.amount)) { + if(!BitcoinUnits::parse(BitcoinUnits::BTC, i->second, &rv.amount)) + { return false; } } - fShouldReturnFalse = false; } - - if (fShouldReturnFalse) + else if (i->first == "addresses") + { + // Handle multiple addresses for unauthenticated payment requests + // Store them in the new addressList field + rv.addressList = i->second; + } + else if (fShouldReturnFalse) + { return false; + } } if(out) { From 01944a589000e5f78b4bdebe3dab7340e928ac01 Mon Sep 17 00:00:00 2001 From: VolodymyrBg Date: Tue, 11 Mar 2025 20:34:47 +0200 Subject: [PATCH 2/4] Update paymentserver.cpp --- src/qt/paymentserver.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index d4c325b7b1c..fa6b851aa0f 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -212,6 +212,17 @@ void PaymentServer::handleURIOrFile(const QString& s) "Due to widespread security flaws in BIP70 it's strongly recommended that any merchant instructions to switch wallets be ignored.\n" "If you are receiving this error you should request the merchant provide a BIP21 compatible URI."), CClientUIInterface::ICON_WARNING); + + // For unauthenticated payment requests with multiple addresses, + // store the addresses in the addressList field instead of abusing the address field + if (recipient.address.contains("
")) { + recipient.addressList = recipient.address; + // Keep only the first address in the address field + int brPos = recipient.address.indexOf("
"); + if (brPos > 0) { + recipient.address = recipient.address.left(brPos); + } + } } Q_EMIT message(tr("URI handling"), QString::fromStdString(error_msg), CClientUIInterface::MSG_ERROR); From 0a8fa64ae865df64a9f8f6f01d9bde5352e5c761 Mon Sep 17 00:00:00 2001 From: VolodymyrBg Date: Tue, 11 Mar 2025 20:35:20 +0200 Subject: [PATCH 3/4] Update receiverequestdialog.cpp --- src/qt/receiverequestdialog.cpp | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index a5ee6583e00..0aee6643a04 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -58,7 +58,14 @@ void ReceiveRequestDialog::setInfo(const SendCoinsRecipient &_info) #endif ui->uri_content->setText("" + GUIUtil::HtmlEscape(uri) + ""); - ui->address_content->setText(info.address); + + // Use addressList if available (for unauthenticated payment requests with multiple addresses) + // Otherwise use the single address + if (!info.addressList.isEmpty()) { + ui->address_content->setText(info.addressList); + } else { + ui->address_content->setText(info.address); + } if (!info.amount) { ui->amount_tag->hide(); @@ -90,7 +97,17 @@ void ReceiveRequestDialog::setInfo(const SendCoinsRecipient &_info) ui->btnVerify->setVisible(model->wallet().hasExternalSigner()); connect(ui->btnVerify, &QPushButton::clicked, [this] { - model->displayAddress(info.address.toStdString()); + // If we have a list of addresses, use the first one for verification + if (!info.addressList.isEmpty()) { + QString firstAddress = info.addressList; + int brPos = firstAddress.indexOf("
"); + if (brPos > 0) { + firstAddress = firstAddress.left(brPos); + } + model->displayAddress(firstAddress.toStdString()); + } else { + model->displayAddress(info.address.toStdString()); + } }); } @@ -107,5 +124,9 @@ void ReceiveRequestDialog::on_btnCopyURI_clicked() void ReceiveRequestDialog::on_btnCopyAddress_clicked() { - GUIUtil::setClipboard(info.address); + if (!info.addressList.isEmpty()) { + GUIUtil::setClipboard(info.addressList); + } else { + GUIUtil::setClipboard(info.address); + } } From ac1b3bddd3df6474fc7e00d1afa90f319395efab Mon Sep 17 00:00:00 2001 From: VolodymyrBg Date: Tue, 11 Mar 2025 20:35:47 +0200 Subject: [PATCH 4/4] Update sendcoinsrecipient.h --- src/qt/sendcoinsrecipient.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/qt/sendcoinsrecipient.h b/src/qt/sendcoinsrecipient.h index aa2ea0498e8..56a449725a5 100644 --- a/src/qt/sendcoinsrecipient.h +++ b/src/qt/sendcoinsrecipient.h @@ -23,8 +23,12 @@ class SendCoinsRecipient // the addresses, e.g. address-A
address-B
address-C. // Info: As we don't need to process addresses in here when using // payment requests, we can abuse it for displaying an address list. - // Todo: This is a hack, should be replaced with a cleaner solution! QString address; + + // Separate field for storing multiple addresses from unauthenticated payment requests + // This replaces the hack mentioned in the TODO comment + QString addressList; + QString label; CAmount amount; // If from a payment request, this is used for storing the memo @@ -42,19 +46,21 @@ class SendCoinsRecipient SERIALIZE_METHODS(SendCoinsRecipient, obj) { - std::string address_str, label_str, message_str, auth_merchant_str; + std::string address_str, label_str, message_str, auth_merchant_str, address_list_str; SER_WRITE(obj, address_str = obj.address.toStdString()); SER_WRITE(obj, label_str = obj.label.toStdString()); SER_WRITE(obj, message_str = obj.message.toStdString()); SER_WRITE(obj, auth_merchant_str = obj.authenticatedMerchant.toStdString()); + SER_WRITE(obj, address_list_str = obj.addressList.toStdString()); - READWRITE(obj.nVersion, address_str, label_str, obj.amount, message_str, obj.sPaymentRequest, auth_merchant_str); + READWRITE(obj.nVersion, address_str, label_str, obj.amount, message_str, obj.sPaymentRequest, auth_merchant_str, address_list_str); SER_READ(obj, obj.address = QString::fromStdString(address_str)); SER_READ(obj, obj.label = QString::fromStdString(label_str)); SER_READ(obj, obj.message = QString::fromStdString(message_str)); SER_READ(obj, obj.authenticatedMerchant = QString::fromStdString(auth_merchant_str)); + SER_READ(obj, obj.addressList = QString::fromStdString(address_list_str)); } };