Skip to content

Commit 46fa4ca

Browse files
Merge #7015: feat(qt): warn when sending to duplicate recipients
e14aaa0 feat(qt): warn when sending to duplicate recipients (UdjinM6) Pull request description: ## Issue being fixed or feature implemented Having duplicated recipients is ok on protocol level, we could be less restrictive in GUI. Inspired by #7012 ## What was done? Handle `DuplicateAddress` as a warning status instead of an error. Show a confirmation dialog when duplicates are detected, allowing the transaction to proceed if the user confirms. <img width="532" height="297" alt="Screenshot 2025-11-27 at 22 34 56" src="https://github.com/user-attachments/assets/b76f7204-9127-456b-ba80-72cbd230b7ec" /> ## How Has This Been Tested? Run dash-qt, send a tx ## Breaking Changes n/a ## Checklist: - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have made corresponding changes to the documentation - [ ] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ ACKs for top commit: PastaPastaPasta: utACK e14aaa0 Tree-SHA512: 72b9cba53a2aaecf691c6236e22075205faa36926bbe084802130316caa9e63d9667a4b9ef4e6a2809c5172aafc0578b91c9bd8b96df7df525eed880f368fafb
2 parents e3d61f2 + e14aaa0 commit 46fa4ca

File tree

2 files changed

+25
-9
lines changed

2 files changed

+25
-9
lines changed

src/qt/sendcoinsdialog.cpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -334,9 +334,26 @@ bool SendCoinsDialog::send(const QList<SendCoinsRecipient>& recipients, QString&
334334
processSendCoinsReturn(prepareStatus,
335335
BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), m_current_transaction->getTransactionFee()));
336336

337-
if(prepareStatus.status != WalletModel::OK) {
337+
// Handle DuplicateAddress as a warning that requires user confirmation
338+
if (prepareStatus.status == WalletModel::DuplicateAddress) {
339+
QMessageBox::StandardButton reply = QMessageBox::question(
340+
this,
341+
tr("Confirm duplicate recipients"),
342+
tr("You are sending to the same address multiple times in a single transaction. "
343+
"This is unusual and may not be what you intended. "
344+
"Are you sure you want to proceed?"),
345+
QMessageBox::Yes | QMessageBox::Cancel,
346+
QMessageBox::Cancel
347+
);
348+
349+
if (reply != QMessageBox::Yes) {
350+
fNewRecipientAllowed = true;
351+
return false;
352+
}
353+
// User confirmed, continue
354+
} else if (prepareStatus.status != WalletModel::OK) {
338355
fNewRecipientAllowed = true;
339-
return false;
356+
return false;
340357
}
341358

342359
QStringList formatted;
@@ -812,9 +829,6 @@ void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn
812829
case WalletModel::AmountWithFeeExceedsBalance:
813830
msgParams.first = tr("The total exceeds your balance when the %1 transaction fee is included.").arg(msgArg);
814831
break;
815-
case WalletModel::DuplicateAddress:
816-
msgParams.first = tr("Duplicate address found: addresses should only be used once each.");
817-
break;
818832
case WalletModel::TransactionCreationFailed:
819833
msgParams.first = tr("Transaction creation failed!");
820834
msgParams.second = CClientUIInterface::MSG_ERROR;
@@ -823,6 +837,7 @@ void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn
823837
msgParams.first = tr("A fee higher than %1 is considered an absurdly high fee.").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), model->wallet().getDefaultMaxTxFee()));
824838
break;
825839
// included to prevent a compiler warning.
840+
case WalletModel::DuplicateAddress:
826841
case WalletModel::OK:
827842
default:
828843
return;

src/qt/walletmodel.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,10 +239,6 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
239239
total += rcp.amount;
240240
}
241241
}
242-
if(setAddress.size() != nAddresses)
243-
{
244-
return DuplicateAddress;
245-
}
246242

247243
CAmount nBalance = m_wallet->getAvailableBalance(coinControl);
248244

@@ -279,6 +275,11 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
279275
return AbsurdFee;
280276
}
281277

278+
// Return warning if duplicate addresses detected, but allow transaction to proceed
279+
if (setAddress.size() != nAddresses) {
280+
return DuplicateAddress;
281+
}
282+
282283
return SendCoinsReturn(OK);
283284
}
284285

0 commit comments

Comments
 (0)