@@ -490,7 +490,7 @@ void SendCoinsDialog::sendButtonClicked([[maybe_unused]] bool checked)
490490 assert (m_current_transaction);
491491
492492 const QString confirmation = tr (" Confirm send coins" );
493- auto confirmationDialog = new SendConfirmationDialog (confirmation, question_string, informative_text, detailed_text, SEND_CONFIRM_DELAY, !model->wallet ().privateKeysDisabled (), model->getOptionsModel ()->getEnablePSBTControls (), this );
493+ auto confirmationDialog = new SendConfirmationDialog (confirmation, question_string, informative_text, detailed_text, SEND_CONFIRM_DELAY, /* enable_send= */ !model->wallet ().privateKeysDisabled () || model-> wallet (). hasExternalSigner (), /* always_show_unsigned= */ model->getOptionsModel ()->getEnablePSBTControls (), this );
494494 confirmationDialog->setAttribute (Qt::WA_DeleteOnClose);
495495 // TODO: Replace QDialog::exec() with safer QDialog::show().
496496 const auto retval = static_cast <QMessageBox::StandardButton>(confirmationDialog->exec ());
@@ -502,19 +502,38 @@ void SendCoinsDialog::sendButtonClicked([[maybe_unused]] bool checked)
502502 }
503503
504504 bool send_failure = false ;
505- if (retval == QMessageBox::Save) {
505+ if (retval == QMessageBox::Save) { // Create Unsigned clicked
506506 CMutableTransaction mtx = CMutableTransaction{*(m_current_transaction->getWtx ())};
507507 PartiallySignedTransaction psbtx (mtx);
508- bool complete = false ;
508+ // Copy PSBT to clipboard and offer to save
509+ presentPSBT (psbtx);
510+ } else { // Send clicked
511+ assert (!model->wallet ().privateKeysDisabled () || model->wallet ().hasExternalSigner ());
512+ bool broadcast = true ;
509513 if (model->wallet ().hasExternalSigner ()) {
514+ CMutableTransaction mtx = CMutableTransaction{*(m_current_transaction->getWtx ())};
515+ PartiallySignedTransaction psbtx (mtx);
516+ bool complete = false ;
510517 send_failure = !signWithExternalSigner (psbtx, mtx, complete);
518+ // Don't broadcast when user rejects it on the device or there's a failure:
519+ broadcast = complete && !send_failure;
520+ if (!send_failure) {
521+ // A transaction signed with an external signer is not always complete,
522+ // e.g. in a multisig wallet.
523+ if (complete) {
524+ // Prepare transaction for broadcast transaction if complete
525+ const CTransactionRef tx = MakeTransactionRef (mtx);
526+ m_current_transaction->setWtx (tx);
527+ } else {
528+ presentPSBT (psbtx);
529+ }
530+ }
511531 }
512532
513- // Broadcast transaction if complete (even with an external signer this
514- // is not always the case, e.g. in a multisig wallet).
515- if (complete) {
516- const CTransactionRef tx = MakeTransactionRef (mtx);
517- m_current_transaction->setWtx (tx);
533+ // Broadcast the transaction, unless an external was used and it
534+ // failed, or more signatures are needed.
535+ if (broadcast) {
536+ // now send the prepared transaction
518537 WalletModel::SendCoinsReturn sendStatus = model->sendCoins (*m_current_transaction);
519538 // process sendStatus and on error generate message shown to user
520539 processSendCoinsReturn (sendStatus);
@@ -524,23 +543,6 @@ void SendCoinsDialog::sendButtonClicked([[maybe_unused]] bool checked)
524543 } else {
525544 send_failure = true ;
526545 }
527- return ;
528- }
529-
530- // Copy PSBT to clipboard and offer to save
531- assert (!complete);
532- presentPSBT (psbtx);
533- } else {
534- assert (!model->wallet ().privateKeysDisabled ());
535- // now send the prepared transaction
536- WalletModel::SendCoinsReturn sendStatus = model->sendCoins (*m_current_transaction);
537- // process sendStatus and on error generate message shown to user
538- processSendCoinsReturn (sendStatus);
539-
540- if (sendStatus.status == WalletModel::OK) {
541- Q_EMIT coinsSent (m_current_transaction->getWtx ()->GetHash ());
542- } else {
543- send_failure = true ;
544546 }
545547 }
546548 if (!send_failure) {
0 commit comments