@@ -447,6 +447,39 @@ void SendCoinsDialog::presentPSBT(PartiallySignedTransaction& psbtx)
447447 } // msgBox.exec()
448448}
449449
450+ bool SendCoinsDialog::signWithExternalSigner (PartiallySignedTransaction& psbtx, CMutableTransaction& mtx, bool & complete) {
451+ // Always fill without signing first. This prevents an external signer
452+ // from being called prematurely and is not expensive.
453+ TransactionError err = model->wallet ().fillPSBT (SIGHASH_ALL, false /* sign */ , true /* bip32derivs */ , nullptr , psbtx, complete);
454+ assert (!complete);
455+ assert (err == TransactionError::OK);
456+
457+ try {
458+ err = model->wallet ().fillPSBT (SIGHASH_ALL, true /* sign */ , true /* bip32derivs */ , nullptr , psbtx, complete);
459+ } catch (const std::runtime_error& e) {
460+ QMessageBox::critical (nullptr , tr (" Sign failed" ), e.what ());
461+ return false ;
462+ }
463+ if (err == TransactionError::EXTERNAL_SIGNER_NOT_FOUND) {
464+ // : "External signer" means using devices such as hardware wallets.
465+ QMessageBox::critical (nullptr , tr (" External signer not found" ), " External signer not found" );
466+ return false ;
467+ }
468+ if (err == TransactionError::EXTERNAL_SIGNER_FAILED) {
469+ // : "External signer" means using devices such as hardware wallets.
470+ QMessageBox::critical (nullptr , tr (" External signer failure" ), " External signer failure" );
471+ return false ;
472+ }
473+ if (err != TransactionError::OK) {
474+ tfm::format (std::cerr, " Failed to sign PSBT" );
475+ processSendCoinsReturn (WalletModel::TransactionCreationFailed);
476+ return false ;
477+ }
478+ // fillPSBT does not always properly finalize
479+ complete = FinalizeAndExtractPSBT (psbtx, mtx);
480+ return true ;
481+ }
482+
450483void SendCoinsDialog::sendButtonClicked ([[maybe_unused]] bool checked)
451484{
452485 if (!model || !model->getOptionsModel ())
@@ -473,39 +506,8 @@ void SendCoinsDialog::sendButtonClicked([[maybe_unused]] bool checked)
473506 CMutableTransaction mtx = CMutableTransaction{*(m_current_transaction->getWtx ())};
474507 PartiallySignedTransaction psbtx (mtx);
475508 bool complete = false ;
476- // Always fill without signing first. This prevents an external signer
477- // from being called prematurely and is not expensive.
478- TransactionError err = model->wallet ().fillPSBT (SIGHASH_ALL, false /* sign */ , true /* bip32derivs */ , nullptr , psbtx, complete);
479- assert (!complete);
480- assert (err == TransactionError::OK);
481509 if (model->wallet ().hasExternalSigner ()) {
482- try {
483- err = model->wallet ().fillPSBT (SIGHASH_ALL, true /* sign */ , true /* bip32derivs */ , nullptr , psbtx, complete);
484- } catch (const std::runtime_error& e) {
485- QMessageBox::critical (nullptr , tr (" Sign failed" ), e.what ());
486- send_failure = true ;
487- return ;
488- }
489- if (err == TransactionError::EXTERNAL_SIGNER_NOT_FOUND) {
490- // : "External signer" means using devices such as hardware wallets.
491- QMessageBox::critical (nullptr , tr (" External signer not found" ), " External signer not found" );
492- send_failure = true ;
493- return ;
494- }
495- if (err == TransactionError::EXTERNAL_SIGNER_FAILED) {
496- // : "External signer" means using devices such as hardware wallets.
497- QMessageBox::critical (nullptr , tr (" External signer failure" ), " External signer failure" );
498- send_failure = true ;
499- return ;
500- }
501- if (err != TransactionError::OK) {
502- tfm::format (std::cerr, " Failed to sign PSBT" );
503- processSendCoinsReturn (WalletModel::TransactionCreationFailed);
504- send_failure = true ;
505- return ;
506- }
507- // fillPSBT does not always properly finalize
508- complete = FinalizeAndExtractPSBT (psbtx, mtx);
510+ send_failure = !signWithExternalSigner (psbtx, mtx, complete);
509511 }
510512
511513 // Broadcast transaction if complete (even with an external signer this
0 commit comments