Skip to content

Commit 4f0d8b8

Browse files
UdjinM6claude
andcommitted
feat(qt): warn when sending to duplicate recipients
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. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 199ac79 commit 4f0d8b8

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)