From 9f903932dc59e1cc955112492b699330b8806d93 Mon Sep 17 00:00:00 2001 From: Steve Myers Date: Mon, 2 May 2022 19:23:47 -0700 Subject: [PATCH 1/3] Add BumpFeeTxBuilder --- CHANGELOG.md | 1 + src/bdk.udl | 9 +++++++ src/lib.rs | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 85 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73fd99e..713c56e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - Update BDK to version 0.18.0 +- Add BumpFeeTxBuilder to bump the fee on an unconfirmed tx created by the Wallet ## [v0.5.0] diff --git a/src/bdk.udl b/src/bdk.udl index 5429127..b722f09 100644 --- a/src/bdk.udl +++ b/src/bdk.udl @@ -158,6 +158,15 @@ interface TxBuilder { PartiallySignedBitcoinTransaction build([ByRef] Wallet wallet); }; +interface BumpFeeTxBuilder { + constructor(string txid, float new_fee_rate); + BumpFeeTxBuilder allow_shrinking(string address); + BumpFeeTxBuilder enable_rbf(); + BumpFeeTxBuilder enable_rbf_with_sequence(u32 nsequence); + [Throws=BdkError] + PartiallySignedBitcoinTransaction build([ByRef] Wallet wallet); +}; + dictionary ExtendedKeyInfo { string mnemonic; string xprv; diff --git a/src/lib.rs b/src/lib.rs index caa1396..22d99bd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ use bdk::bitcoin::hashes::hex::ToHex; use bdk::bitcoin::secp256k1::Secp256k1; use bdk::bitcoin::util::psbt::PartiallySignedTransaction; -use bdk::bitcoin::{Address, Network, Script}; +use bdk::bitcoin::{Address, Network, Script, Txid}; use bdk::blockchain::any::{AnyBlockchain, AnyBlockchainConfig}; use bdk::blockchain::{ electrum::ElectrumBlockchainConfig, esplora::EsploraBlockchainConfig, ConfigurableBlockchain, @@ -440,4 +440,78 @@ impl TxBuilder { } } +struct BumpFeeTxBuilder { + txid: String, + fee_rate: f32, + rbf: Option, + allow_shrinking: Option, +} + +impl BumpFeeTxBuilder { + fn new(txid: String, fee_rate: f32) -> Self { + Self { + txid, + fee_rate, + allow_shrinking: None, + rbf: None, + } + } + + fn allow_shrinking(&self, address: String) -> Arc { + Arc::new(Self { + txid: self.txid.clone(), + fee_rate: self.fee_rate, + allow_shrinking: Some(address), + rbf: self.rbf.clone(), + }) + } + + fn enable_rbf(&self) -> Arc { + Arc::new(Self { + txid: self.txid.clone(), + fee_rate: self.fee_rate, + rbf: Some(RbfValue::Default), + allow_shrinking: self.allow_shrinking.clone(), + }) + } + + fn enable_rbf_with_sequence(&self, nsequence: u32) -> Arc { + Arc::new(Self { + txid: self.txid.clone(), + fee_rate: self.fee_rate, + rbf: Some(RbfValue::Value(nsequence)), + allow_shrinking: self.allow_shrinking.clone(), + }) + } + + fn build(&self, wallet: &Wallet) -> Result, Error> { + let wallet = wallet.get_wallet(); + let txid = Txid::from_str(self.txid.as_str())?; + let mut tx_builder = wallet.build_fee_bump(txid)?; + tx_builder.fee_rate(FeeRate::from_sat_per_vb(self.fee_rate)); + if let Some(rbf) = &self.rbf { + match *rbf { + RbfValue::Default => { + tx_builder.enable_rbf(); + } + RbfValue::Value(nsequence) => { + tx_builder.enable_rbf_with_sequence(nsequence); + } + } + } + if let Some(allow_shrinking) = &self.allow_shrinking { + let address = + Address::from_str(allow_shrinking).map_err(|e| Error::Generic(e.to_string()))?; + let script = address.script_pubkey(); + tx_builder.allow_shrinking(script)?; + } + tx_builder + .finish() + .map(|(psbt, _)| PartiallySignedBitcoinTransaction { + internal: Mutex::new(psbt), + }) + .map(Arc::new) + } +} + uniffi::deps::static_assertions::assert_impl_all!(Wallet: Sync, Send); From 390d12703eb12fc3b58a14f62a64f8582ebbeaf2 Mon Sep 17 00:00:00 2001 From: Steve Myers Date: Fri, 6 May 2022 09:52:20 -0700 Subject: [PATCH 2/3] Change TxBuilder and BumpFeeTxBuilder build() to finish() --- CHANGELOG.md | 1 + src/bdk.udl | 4 ++-- src/lib.rs | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 713c56e..c8cb22e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Update BDK to version 0.18.0 - Add BumpFeeTxBuilder to bump the fee on an unconfirmed tx created by the Wallet +- Change TxBuilder.build() to TxBuilder.finish() to align with bdk function name ## [v0.5.0] diff --git a/src/bdk.udl b/src/bdk.udl index b722f09..46a1ead 100644 --- a/src/bdk.udl +++ b/src/bdk.udl @@ -155,7 +155,7 @@ interface TxBuilder { TxBuilder enable_rbf(); TxBuilder enable_rbf_with_sequence(u32 nsequence); [Throws=BdkError] - PartiallySignedBitcoinTransaction build([ByRef] Wallet wallet); + PartiallySignedBitcoinTransaction finish([ByRef] Wallet wallet); }; interface BumpFeeTxBuilder { @@ -164,7 +164,7 @@ interface BumpFeeTxBuilder { BumpFeeTxBuilder enable_rbf(); BumpFeeTxBuilder enable_rbf_with_sequence(u32 nsequence); [Throws=BdkError] - PartiallySignedBitcoinTransaction build([ByRef] Wallet wallet); + PartiallySignedBitcoinTransaction finish([ByRef] Wallet wallet); }; dictionary ExtendedKeyInfo { diff --git a/src/lib.rs b/src/lib.rs index 22d99bd..d4f5eee 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -406,7 +406,7 @@ impl TxBuilder { }) } - fn build(&self, wallet: &Wallet) -> Result, Error> { + fn finish(&self, wallet: &Wallet) -> Result, Error> { let wallet = wallet.get_wallet(); let mut tx_builder = wallet.build_tx(); for (address, amount) in &self.recipients { @@ -484,7 +484,7 @@ impl BumpFeeTxBuilder { }) } - fn build(&self, wallet: &Wallet) -> Result, Error> { + fn finish(&self, wallet: &Wallet) -> Result, Error> { let wallet = wallet.get_wallet(); let txid = Txid::from_str(self.txid.as_str())?; let mut tx_builder = wallet.build_fee_bump(txid)?; From 0787d9c446a3390f0e020dcabd5f30a9d760391d Mon Sep 17 00:00:00 2001 From: Steve Myers Date: Fri, 6 May 2022 09:59:07 -0700 Subject: [PATCH 3/3] Fix order of BumpFeeTxBuilder parameters --- src/lib.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d4f5eee..9a5868f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -443,8 +443,8 @@ impl TxBuilder { struct BumpFeeTxBuilder { txid: String, fee_rate: f32, - rbf: Option, allow_shrinking: Option, + rbf: Option, } impl BumpFeeTxBuilder { @@ -470,8 +470,8 @@ impl BumpFeeTxBuilder { Arc::new(Self { txid: self.txid.clone(), fee_rate: self.fee_rate, - rbf: Some(RbfValue::Default), allow_shrinking: self.allow_shrinking.clone(), + rbf: Some(RbfValue::Default), }) } @@ -479,8 +479,8 @@ impl BumpFeeTxBuilder { Arc::new(Self { txid: self.txid.clone(), fee_rate: self.fee_rate, - rbf: Some(RbfValue::Value(nsequence)), allow_shrinking: self.allow_shrinking.clone(), + rbf: Some(RbfValue::Value(nsequence)), }) } @@ -489,6 +489,12 @@ impl BumpFeeTxBuilder { let txid = Txid::from_str(self.txid.as_str())?; let mut tx_builder = wallet.build_fee_bump(txid)?; tx_builder.fee_rate(FeeRate::from_sat_per_vb(self.fee_rate)); + if let Some(allow_shrinking) = &self.allow_shrinking { + let address = + Address::from_str(allow_shrinking).map_err(|e| Error::Generic(e.to_string()))?; + let script = address.script_pubkey(); + tx_builder.allow_shrinking(script)?; + } if let Some(rbf) = &self.rbf { match *rbf { RbfValue::Default => { @@ -499,12 +505,6 @@ impl BumpFeeTxBuilder { } } } - if let Some(allow_shrinking) = &self.allow_shrinking { - let address = - Address::from_str(allow_shrinking).map_err(|e| Error::Generic(e.to_string()))?; - let script = address.script_pubkey(); - tx_builder.allow_shrinking(script)?; - } tx_builder .finish() .map(|(psbt, _)| PartiallySignedBitcoinTransaction {