diff --git a/client/src/client.rs b/client/src/client.rs index 2f809a79..08f62f2b 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -1080,6 +1080,27 @@ pub trait RpcApi: Sized { self.call("sendrawtransaction", &[tx.raw_hex().into()]) } + fn send_raw_transaction_advanced( + &self, + tx: R, + maxfeerate: Option, + maxburnamount: Option, + ) -> Result { + let mut params = vec![serde_json::json!(tx.raw_hex())]; + + if let Some(fee_rate) = maxfeerate { + params.push(serde_json::json!(fee_rate)); + } else { + params.push(serde_json::Value::Null); + } + + if let Some(burn_amount) = maxburnamount { + params.push(serde_json::json!(burn_amount)); + } + + self.call("sendrawtransaction", ¶ms) + } + fn estimate_smart_fee( &self, conf_target: u16, diff --git a/integration_test/src/main.rs b/integration_test/src/main.rs index c3236bb9..939e332c 100644 --- a/integration_test/src/main.rs +++ b/integration_test/src/main.rs @@ -176,6 +176,7 @@ fn main() { test_lock_unspent_unlock_unspent(&cl); test_get_block_filter(&cl); test_sign_raw_transaction_with_send_raw_transaction(&cl); + test_send_raw_transaction_advanced(&cl); test_invalidate_block_reconsider_block(&cl); test_key_pool_refill(&cl); test_create_raw_transaction(&cl); @@ -640,6 +641,57 @@ fn test_sign_raw_transaction_with_send_raw_transaction(cl: &Client) { let _ = cl.send_raw_transaction(&res.transaction().unwrap()).unwrap(); } +fn test_send_raw_transaction_advanced(cl: &Client) { + let sk = PrivateKey { + network: Network::Regtest.into(), + inner: secp256k1::SecretKey::new(&mut secp256k1::rand::thread_rng()), + compressed: true, + }; + let pk = CompressedPublicKey::from_private_key(&SECP, &sk).unwrap(); + let addr = Address::p2wpkh(&pk, Network::Regtest); + + let options = json::ListUnspentQueryOptions { + minimum_amount: Some(btc(2)), + ..Default::default() + }; + let unspent = cl.list_unspent(Some(6), None, None, None, Some(options)).unwrap(); + let unspent = unspent.into_iter().nth(0).unwrap(); + + let tx = Transaction { + version: transaction::Version::ONE, + lock_time: LockTime::ZERO, + input: vec![TxIn { + previous_output: OutPoint { + txid: unspent.txid, + vout: unspent.vout, + }, + sequence: Sequence::MAX, + script_sig: ScriptBuf::new(), + witness: Witness::new(), + }], + output: vec![TxOut { + value: (unspent.amount - *FEE), + script_pubkey: addr.script_pubkey(), + }], + }; + + let signed_tx = cl.sign_raw_transaction_with_wallet(&tx, None, None) + .unwrap() + .transaction() + .unwrap(); + + let tx_hex = serialize_hex(&signed_tx); + + let maxfeerate = Some(0.01); + let maxburnamount = Some(0.02); + + let txid = cl.send_raw_transaction_advanced(tx_hex, maxfeerate, maxburnamount).unwrap(); + + assert!(!txid.to_string().is_empty(), "Transaction ID should not be empty"); + + println!("Transaction sent successfully with txid: {}", txid); +} + fn test_invalidate_block_reconsider_block(cl: &Client) { let hash = cl.get_best_block_hash().unwrap(); cl.invalidate_block(&hash).unwrap();