@ -21,11 +21,12 @@
# include <chainparams.h>
# include <interfaces/node.h>
# include <key_io.h>
# include <wallet/coincontrol.h>
# include <ui_interface.h>
# include <txmempool.h>
# include <policy/fees.h>
# include <txmempool.h>
# include <ui_interface.h>
# include <wallet/coincontrol.h>
# include <wallet/fees.h>
# include <wallet/psbtwallet.h>
# include <QFontMetrics>
# include <QScrollBar>
@ -186,6 +187,11 @@ void SendCoinsDialog::setModel(WalletModel *_model)
// set default rbf checkbox state
ui - > optInRBF - > setCheckState ( Qt : : Checked ) ;
if ( model - > privateKeysDisabled ( ) ) {
ui - > sendButton - > setText ( tr ( " Cr&eate Unsigned " ) ) ;
ui - > sendButton - > setToolTip ( tr ( " Creates a Partially Signed Bitcoin Transaction (PSBT) for use with e.g. an offline %1 wallet, or a PSBT-compatible hardware wallet. " ) . arg ( PACKAGE_NAME ) ) ;
}
// set the smartfee-sliders default value (wallets default conf.target or last stored value)
QSettings settings ;
if ( settings . value ( " nSmartFeeSliderPosition " ) . toInt ( ) ! = 0 ) {
@ -305,9 +311,19 @@ void SendCoinsDialog::on_sendButton_clicked()
formatted . append ( recipientElement ) ;
}
QString questionString = tr ( " Are you sure you want to send? " ) ;
QString questionString ;
if ( model - > privateKeysDisabled ( ) ) {
questionString . append ( tr ( " Do you want to draft this transaction? " ) ) ;
} else {
questionString . append ( tr ( " Are you sure you want to send? " ) ) ;
}
questionString . append ( " <br /><span style='font-size:10pt;'> " ) ;
if ( model - > privateKeysDisabled ( ) ) {
questionString . append ( tr ( " Please, review your transaction proposal. This will produce a Partially Signed Bitcoin Transaction (PSBT) which you can copy and then sign with e.g. an offline %1 wallet, or a PSBT-compatible hardware wallet. " ) . arg ( PACKAGE_NAME ) ) ;
} else {
questionString . append ( tr ( " Please, review your transaction. " ) ) ;
}
questionString . append ( " </span>%1 " ) ;
if ( txFee > 0 )
@ -358,8 +374,9 @@ void SendCoinsDialog::on_sendButton_clicked()
} else {
questionString = questionString . arg ( " <br /><br /> " + formatted . at ( 0 ) ) ;
}
SendConfirmationDialog confirmationDialog ( tr ( " Confirm send coins " ) , questionString , informative_text , detailed_text , SEND_CONFIRM_DELAY , this ) ;
const QString confirmation = model - > privateKeysDisabled ( ) ? tr ( " Confirm transaction proposal " ) : tr ( " Confirm send coins " ) ;
const QString confirmButtonText = model - > privateKeysDisabled ( ) ? tr ( " Copy PSBT to clipboard " ) : tr ( " Send " ) ;
SendConfirmationDialog confirmationDialog ( confirmation , questionString , informative_text , detailed_text , SEND_CONFIRM_DELAY , confirmButtonText , this ) ;
confirmationDialog . exec ( ) ;
QMessageBox : : StandardButton retval = static_cast < QMessageBox : : StandardButton > ( confirmationDialog . result ( ) ) ;
@ -369,17 +386,35 @@ void SendCoinsDialog::on_sendButton_clicked()
return ;
}
bool send_failure = false ;
if ( model - > privateKeysDisabled ( ) ) {
CMutableTransaction mtx = CMutableTransaction { * ( currentTransaction . getWtx ( ) ) } ;
PartiallySignedTransaction psbtx ( mtx ) ;
bool complete = false ;
const TransactionError err = model - > wallet ( ) . fillPSBT ( psbtx , complete , SIGHASH_ALL , false /* sign */ , true /* bip32derivs */ ) ;
assert ( ! complete ) ;
assert ( err = = TransactionError : : OK ) ;
// Serialize the PSBT
CDataStream ssTx ( SER_NETWORK , PROTOCOL_VERSION ) ;
ssTx < < psbtx ;
GUIUtil : : setClipboard ( EncodeBase64 ( ssTx . str ( ) ) . c_str ( ) ) ;
Q_EMIT message ( tr ( " PSBT copied " ) , " Copied to clipboard " , CClientUIInterface : : MSG_INFORMATION ) ;
} else {
// now send the prepared transaction
WalletModel : : SendCoinsReturn sendStatus = model - > sendCoins ( currentTransaction ) ;
// process sendStatus and on error generate message shown to user
processSendCoinsReturn ( sendStatus ) ;
if ( sendStatus . status = = WalletModel : : OK )
{
if ( sendStatus . status = = WalletModel : : OK ) {
Q_EMIT coinsSent ( currentTransaction . getWtx ( ) - > GetHash ( ) ) ;
} else {
send_failure = true ;
}
}
if ( ! send_failure ) {
accept ( ) ;
CoinControlDialog : : coinControl ( ) - > UnSelectAll ( ) ;
coinControlUpdateLabels ( ) ;
Q_EMIT coinsSent ( currentTransaction . getWtx ( ) - > GetHash ( ) ) ;
}
fNewRecipientAllowed = true ;
}
@ -875,8 +910,8 @@ void SendCoinsDialog::coinControlUpdateLabels()
}
}
SendConfirmationDialog : : SendConfirmationDialog ( const QString & title , const QString & text , const QString & informative_text , const QString & detailed_text , int _secDelay , QWidget * parent )
: QMessageBox ( parent ) , secDelay ( _secDelay )
SendConfirmationDialog : : SendConfirmationDialog ( const QString & title , const QString & text , const QString & informative_text , const QString & detailed_text , int _secDelay , const QString & _confirmButtonText , QWidget * parent )
: QMessageBox ( parent ) , secDelay ( _secDelay ) , confirmButtonText ( _confirmButtonText )
{
setIcon ( QMessageBox : : Question ) ;
setWindowTitle ( title ) ; // On macOS, the window title is ignored (as required by the macOS Guidelines).
@ -913,11 +948,11 @@ void SendConfirmationDialog::updateYesButton()
if ( secDelay > 0 )
{
yesButton - > setEnabled ( false ) ;
yesButton - > setText ( tr( " Send " ) + " ( " + QString : : number ( secDelay ) + " ) " ) ;
yesButton - > setText ( confirmButtonText + " ( " + QString : : number ( secDelay ) + " ) " ) ;
}
else
{
yesButton - > setEnabled ( true ) ;
yesButton - > setText ( tr( " Send " ) ) ;
yesButton - > setText ( confirmButtonText ) ;
}
}