Skip to content

Commit 33d165d

Browse files
committed
gui: enable Send for external signer
Before this change the send confirmation dialog would keep the Send option disabled. The Create Unsigned choice would actually send. This is potentially confusing. With this change the Create Unsigned button will not attempt to sign and always produce a PSBT. The Send button will attempt to sign, and only return a PSBT if more signatures are needed. When using an external signer, the Create Unsigned option only appears when PSBT controls are enabled in the wallet settings. Closes #551
1 parent e1c1c61 commit 33d165d

File tree

2 files changed

+25
-25
lines changed

2 files changed

+25
-25
lines changed

src/qt/sendcoinsdialog.cpp

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -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,34 @@ void SendCoinsDialog::sendButtonClicked([[maybe_unused]] bool checked)
502502
}
503503

504504
bool send_failure = false;
505-
if (retval == QMessageBox::Save) {
505+
bool broadcast = true;
506+
if (retval == QMessageBox::Save) { // Create Unsigned clicked
506507
CMutableTransaction mtx = CMutableTransaction{*(m_current_transaction->getWtx())};
507508
PartiallySignedTransaction psbtx(mtx);
508-
bool complete = false;
509+
// Copy PSBT to clipboard and offer to save
510+
presentPSBT(psbtx);
511+
} else { // Send clicked
512+
assert(!model->wallet().privateKeysDisabled() || model->wallet().hasExternalSigner());
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+
// A transaction signed with an external signer is not always complete,
519+
// e.g. in a multisig wallet.
520+
if (complete) {
521+
// Prepare transaction for broadcast transaction if complete
522+
const CTransactionRef tx = MakeTransactionRef(mtx);
523+
m_current_transaction->setWtx(tx);
524+
} else if (!send_failure) {
525+
presentPSBT(psbtx);
526+
broadcast = false;
527+
}
511528
}
512529

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);
530+
// Broadcast the transaction, unless an external was used and it needs more signatures.
531+
if (broadcast) {
532+
// now send the prepared transaction
518533
WalletModel::SendCoinsReturn sendStatus = model->sendCoins(*m_current_transaction);
519534
// process sendStatus and on error generate message shown to user
520535
processSendCoinsReturn(sendStatus);
@@ -524,23 +539,6 @@ void SendCoinsDialog::sendButtonClicked([[maybe_unused]] bool checked)
524539
} else {
525540
send_failure = true;
526541
}
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;
544542
}
545543
}
546544
if (!send_failure) {

src/qt/sendcoinsdialog.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ class SendConfirmationDialog : public QMessageBox
128128

129129
public:
130130
SendConfirmationDialog(const QString& title, const QString& text, const QString& informative_text = "", const QString& detailed_text = "", int secDelay = SEND_CONFIRM_DELAY, bool enable_send = true, bool always_show_unsigned = true, QWidget* parent = nullptr);
131+
/* Returns QMessageBox::Cancel, QMessageBox::Yes when send is
132+
clicked and QMessageBox::Save when Create Unsigned is clicked. */
131133
int exec() override;
132134

133135
private Q_SLOTS:

0 commit comments

Comments
 (0)