@ -74,6 +74,50 @@ static void InterpretFeeEstimationInstructions(const UniValue& conf_target, cons
}
}
}
}
static UniValue FinishTransaction ( const std : : shared_ptr < CWallet > pwallet , const UniValue & options , const CMutableTransaction & rawTx )
{
// Make a blank psbt
PartiallySignedTransaction psbtx ( rawTx ) ;
// First fill transaction with our data without signing,
// so external signers are not asked sign more than once.
bool complete ;
pwallet - > FillPSBT ( psbtx , complete , SIGHASH_DEFAULT , false , true ) ;
const TransactionError err { pwallet - > FillPSBT ( psbtx , complete , SIGHASH_DEFAULT , true , false ) } ;
if ( err ! = TransactionError : : OK ) {
throw JSONRPCTransactionError ( err ) ;
}
CMutableTransaction mtx ;
complete = FinalizeAndExtractPSBT ( psbtx , mtx ) ;
UniValue result ( UniValue : : VOBJ ) ;
const bool psbt_opt_in { options . exists ( " psbt " ) & & options [ " psbt " ] . get_bool ( ) } ;
bool add_to_wallet { options . exists ( " add_to_wallet " ) ? options [ " add_to_wallet " ] . get_bool ( ) : true } ;
if ( psbt_opt_in | | ! complete | | ! add_to_wallet ) {
// Serialize the PSBT
CDataStream ssTx ( SER_NETWORK , PROTOCOL_VERSION ) ;
ssTx < < psbtx ;
result . pushKV ( " psbt " , EncodeBase64 ( ssTx . str ( ) ) ) ;
}
if ( complete ) {
std : : string hex { EncodeHexTx ( CTransaction ( mtx ) ) } ;
CTransactionRef tx ( MakeTransactionRef ( std : : move ( mtx ) ) ) ;
result . pushKV ( " txid " , tx - > GetHash ( ) . GetHex ( ) ) ;
if ( add_to_wallet & & ! psbt_opt_in ) {
pwallet - > CommitTransaction ( tx , { } , { } /* orderForm */ ) ;
} else {
result . pushKV ( " hex " , hex ) ;
}
}
result . pushKV ( " complete " , complete ) ;
return result ;
}
static void PreventOutdatedOptions ( const UniValue & options )
static void PreventOutdatedOptions ( const UniValue & options )
{
{
if ( options . exists ( " feeRate " ) ) {
if ( options . exists ( " feeRate " ) ) {
@ -1174,14 +1218,10 @@ RPCHelpMan send()
InterpretFeeEstimationInstructions ( /*conf_target=*/ request . params [ 1 ] , /*estimate_mode=*/ request . params [ 2 ] , /*fee_rate=*/ request . params [ 3 ] , options ) ;
InterpretFeeEstimationInstructions ( /*conf_target=*/ request . params [ 1 ] , /*estimate_mode=*/ request . params [ 2 ] , /*fee_rate=*/ request . params [ 3 ] , options ) ;
PreventOutdatedOptions ( options ) ;
PreventOutdatedOptions ( options ) ;
const bool psbt_opt_in = options . exists ( " psbt " ) & & options [ " psbt " ] . get_bool ( ) ;
CAmount fee ;
CAmount fee ;
int change_position ;
int change_position ;
bool rbf = pwallet - > m_signal_rbf ;
bool rbf = options . exists ( " replaceable " ) ? options [ " replaceable " ] . get_bool ( ) : pwallet - > m_signal_rbf ;
if ( options . exists ( " replaceable " ) ) {
rbf = options [ " replaceable " ] . get_bool ( ) ;
}
CMutableTransaction rawTx = ConstructTransaction ( options [ " inputs " ] , request . params [ 0 ] , options [ " locktime " ] , rbf ) ;
CMutableTransaction rawTx = ConstructTransaction ( options [ " inputs " ] , request . params [ 0 ] , options [ " locktime " ] , rbf ) ;
CCoinControl coin_control ;
CCoinControl coin_control ;
// Automatically select coins, unless at least one is manually selected. Can
// Automatically select coins, unless at least one is manually selected. Can
@ -1190,49 +1230,7 @@ RPCHelpMan send()
SetOptionsInputWeights ( options [ " inputs " ] , options ) ;
SetOptionsInputWeights ( options [ " inputs " ] , options ) ;
FundTransaction ( * pwallet , rawTx , fee , change_position , options , coin_control , /* override_min_fee */ false ) ;
FundTransaction ( * pwallet , rawTx , fee , change_position , options , coin_control , /* override_min_fee */ false ) ;
bool add_to_wallet = true ;
return FinishTransaction ( pwallet , options , rawTx ) ;
if ( options . exists ( " add_to_wallet " ) ) {
add_to_wallet = options [ " add_to_wallet " ] . get_bool ( ) ;
}
// Make a blank psbt
PartiallySignedTransaction psbtx ( rawTx ) ;
// First fill transaction with our data without signing,
// so external signers are not asked sign more than once.
bool complete ;
pwallet - > FillPSBT ( psbtx , complete , SIGHASH_DEFAULT , false , true ) ;
const TransactionError err = pwallet - > FillPSBT ( psbtx , complete , SIGHASH_DEFAULT , true , false ) ;
if ( err ! = TransactionError : : OK ) {
throw JSONRPCTransactionError ( err ) ;
}
CMutableTransaction mtx ;
complete = FinalizeAndExtractPSBT ( psbtx , mtx ) ;
UniValue result ( UniValue : : VOBJ ) ;
if ( psbt_opt_in | | ! complete | | ! add_to_wallet ) {
// Serialize the PSBT
CDataStream ssTx ( SER_NETWORK , PROTOCOL_VERSION ) ;
ssTx < < psbtx ;
result . pushKV ( " psbt " , EncodeBase64 ( ssTx . str ( ) ) ) ;
}
if ( complete ) {
std : : string err_string ;
std : : string hex = EncodeHexTx ( CTransaction ( mtx ) ) ;
CTransactionRef tx ( MakeTransactionRef ( std : : move ( mtx ) ) ) ;
result . pushKV ( " txid " , tx - > GetHash ( ) . GetHex ( ) ) ;
if ( add_to_wallet & & ! psbt_opt_in ) {
pwallet - > CommitTransaction ( tx , { } , { } /* orderForm */ ) ;
} else {
result . pushKV ( " hex " , hex ) ;
}
}
result . pushKV ( " complete " , complete ) ;
return result ;
}
}
} ;
} ;
}
}