@@ -268,6 +268,8 @@ bool SendCoinsDialog::PrepareSendText(QString& question_string, QString& informa
268268 }
269269
270270 // prepare transaction for getting txFee earlier
271+ // Create unsigned transaction to support creating unsigned PSBTs.
272+ // Signing is deferred until the user clicks "Send".
271273 m_current_transaction = std::make_unique<WalletModelTransaction>(recipients);
272274 WalletModel::SendCoinsReturn prepareStatus;
273275
@@ -344,7 +346,7 @@ bool SendCoinsDialog::PrepareSendText(QString& question_string, QString& informa
344346
345347 // append transaction size
346348 // : When reviewing a newly created PSBT (via Send flow), the transaction fee is shown, with "virtual size" of the transaction displayed for context
347- question_string.append (" (" + tr (" %1 kvB" , " PSBT transaction creation" ).arg ((double )m_current_transaction->getTransactionSize () / 1000 , 0 , ' g' , 3 ) + " ): " );
349+ question_string.append (" (" + tr (" %1 kvB (unsigned) " , " PSBT transaction creation" ).arg ((double )m_current_transaction->getTransactionSize () / 1000 , 0 , ' g' , 3 ) + " ): " );
348350
349351 // append transaction fee value
350352 question_string.append (" <span style='color:#aa0000; font-weight:bold;'>" );
@@ -497,6 +499,12 @@ void SendCoinsDialog::sendButtonClicked([[maybe_unused]] bool checked)
497499 presentPSBT (psbtx);
498500 } else {
499501 // "Send" clicked
502+ WalletModel::UnlockContext ctx (model->requestUnlock ());
503+ if (!ctx.isValid ()) {
504+ fNewRecipientAllowed = true ;
505+ return ;
506+ }
507+
500508 assert (!model->wallet ().privateKeysDisabled () || model->wallet ().hasExternalSigner ());
501509 bool broadcast = true ;
502510 if (model->wallet ().hasExternalSigner ()) {
@@ -522,6 +530,21 @@ void SendCoinsDialog::sendButtonClicked([[maybe_unused]] bool checked)
522530 presentPSBT (psbtx);
523531 }
524532 }
533+ } else {
534+ // Sign the transaction now that the user has confirmed they want to send.
535+ CMutableTransaction mtx = CMutableTransaction{*(m_current_transaction->getWtx ())};
536+ PartiallySignedTransaction psbtx (mtx);
537+ bool complete = false ;
538+ const auto err{model->wallet ().fillPSBT ({.sign = true , .bip32_derivs = false }, /* n_signed=*/ nullptr , psbtx, complete)};
539+ if (err || !complete) {
540+ Q_EMIT message (tr (" Send Coins" ), tr (" Failed to sign transaction." ),
541+ CClientUIInterface::MSG_ERROR );
542+ send_failure = true ;
543+ broadcast = false ;
544+ } else {
545+ CHECK_NONFATAL (FinalizeAndExtractPSBT (psbtx, mtx));
546+ m_current_transaction->setWtx (MakeTransactionRef (mtx));
547+ }
525548 }
526549
527550 // Broadcast the transaction, unless an external signer was used and it
0 commit comments