Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

qt: Add addressList field to SendCoinsRecipient for multiple addresses #857

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions src/qt/guiutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
11 changes: 11 additions & 0 deletions src/qt/paymentserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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("<br />")) {
recipient.addressList = recipient.address;
// Keep only the first address in the address field
int brPos = recipient.address.indexOf("<br />");
if (brPos > 0) {
recipient.address = recipient.address.left(brPos);
}
}
}
Q_EMIT message(tr("URI handling"), QString::fromStdString(error_msg),
CClientUIInterface::MSG_ERROR);
Expand Down
27 changes: 24 additions & 3 deletions src/qt/receiverequestdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,14 @@ void ReceiveRequestDialog::setInfo(const SendCoinsRecipient &_info)
#endif

ui->uri_content->setText("<a href=\"" + uri + "\">" + GUIUtil::HtmlEscape(uri) + "</a>");
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();
Expand Down Expand Up @@ -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("<br />");
if (brPos > 0) {
firstAddress = firstAddress.left(brPos);
}
model->displayAddress(firstAddress.toStdString());
} else {
model->displayAddress(info.address.toStdString());
}
});
}

Expand All @@ -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);
}
}
12 changes: 9 additions & 3 deletions src/qt/sendcoinsrecipient.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@ class SendCoinsRecipient
// the addresses, e.g. address-A<br />address-B<br />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
Expand All @@ -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));
}
};

Expand Down