@@ -9,6 +9,7 @@ use bitcoin::{
9
9
} ;
10
10
use bitcoincore_rpc:: {
11
11
bitcoin:: { BlockHash , Transaction } ,
12
+ json,
12
13
json:: { EstimateMode , TestMempoolAcceptResult } ,
13
14
jsonrpc:: { error:: RpcError , Error as JsonRpcError } ,
14
15
Auth , Client , Error as BitcoinError , RpcApi ,
@@ -181,6 +182,20 @@ pub struct BumpFeeResult {
181
182
pub errors : Vec < String > ,
182
183
}
183
184
185
+ #[ derive( Deserialize , Clone , Debug ) ]
186
+ #[ serde( rename_all = "camelCase" ) ]
187
+ pub struct PsbtBumpFeeResult {
188
+ /// The base64-encoded unsigned PSBT of the new transaction. Only returned when wallet private
189
+ /// keys are disabled.
190
+ pub psbt : Option < String > ,
191
+ /// The fee of the original transaction (before bumping), denominated in BTC.
192
+ pub origfee : f64 ,
193
+ /// The fee of the newly created bumped transaction, denominated in BTC.
194
+ pub fee : f64 ,
195
+ /// Errors encountered during processing.
196
+ pub errors : Vec < String > ,
197
+ }
198
+
184
199
impl From < RpcError > for BitcoinRpcError {
185
200
fn from ( err : RpcError ) -> Self {
186
201
match num:: FromPrimitive :: from_i32 ( err. code ) {
@@ -216,6 +231,8 @@ pub enum Error {
216
231
InvalidRecipient ,
217
232
#[ error( "Hex decoding error: {0}" ) ]
218
233
HexDecodeError ( #[ from] hex:: FromHexError ) ,
234
+ #[ error( "Finalized PSBT did not return a raw transaction hex" ) ]
235
+ MissingRawTxHex ,
219
236
}
220
237
221
238
#[ derive( Clone ) ]
@@ -454,6 +471,54 @@ impl BitcoinClient {
454
471
Err ( err) => Err ( err. into ( ) ) , // Handle the case where the RPC call fails
455
472
}
456
473
}
474
+
475
+ pub fn psbt_bump_fee (
476
+ & self ,
477
+ txid : & Txid ,
478
+ options : Option < & BumpFeeOptions > ,
479
+ ) -> Result < PsbtBumpFeeResult , Error > {
480
+ // Serialize options if provided
481
+ let opts = match options {
482
+ Some ( options) => Some ( options. to_serializable ( self . rpc . version ( ) ?) ) ,
483
+ None => None ,
484
+ } ;
485
+
486
+ // Prepare arguments
487
+ let args = vec ! [ serde_json:: to_value( txid) ?, serde_json:: to_value( opts) ?] ;
488
+
489
+ // Call the "psbtbumpfee" RPC method
490
+ let result = self . rpc . call ( "psbtbumpfee" , & args) ;
491
+
492
+ // Handle the result
493
+ match result {
494
+ Ok ( result_value) => {
495
+ let result: Result < PsbtBumpFeeResult , _ > = serde_json:: from_value ( result_value) ;
496
+ match result {
497
+ Ok ( bump_fee_result) => Ok ( bump_fee_result) ,
498
+ Err ( err) => {
499
+ println ! ( "Failed to deserialize into PsbtBumpFeeResult" ) ;
500
+ Err ( err. into ( ) )
501
+ }
502
+ }
503
+ }
504
+ Err ( err) => Err ( err. into ( ) ) ,
505
+ }
506
+ }
507
+
508
+ pub fn sign_and_finalize_psbt (
509
+ & self ,
510
+ psbt : & str ,
511
+ sign : Option < bool > ,
512
+ sighash_type : Option < json:: SigHashType > ,
513
+ bip32derivs : Option < bool > ,
514
+ ) -> Result < Transaction , Error > {
515
+ let wallet_process_psbt =
516
+ self . rpc . wallet_process_psbt ( psbt, sign, sighash_type, bip32derivs) ?;
517
+ let finalized = self . rpc . finalize_psbt ( & wallet_process_psbt. psbt , Some ( true ) ) ?;
518
+ let tx_bytes = finalized. hex . ok_or ( Error :: MissingRawTxHex ) ?;
519
+ let tx: Transaction = consensus:: deserialize ( & tx_bytes) ?;
520
+ Ok ( tx)
521
+ }
457
522
}
458
523
459
524
fn merklize ( left : Sha256dHash , right : Sha256dHash ) -> Sha256dHash {
0 commit comments