Skip to content

Commit

Permalink
temp
Browse files Browse the repository at this point in the history
  • Loading branch information
thunderbiscuit committed Nov 17, 2023
1 parent ede1592 commit 3e5b0c5
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 67 deletions.
14 changes: 14 additions & 0 deletions bdk-ffi/src/bdk.udl
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ enum BdkError {
"Psbt",
};

enum ChangeSpendPolicy {
"ChangeAllowed",
"OnlyChange",
"ChangeForbidden"
};

interface Balance {
u64 immature();

Expand Down Expand Up @@ -101,6 +107,14 @@ interface TxBuilder {

TxBuilder add_utxo(OutPoint outpoint);

TxBuilder change_policy(ChangeSpendPolicy change_policy);

TxBuilder do_not_spend_change();

TxBuilder only_spend_change();

TxBuilder manually_selected_only();

TxBuilder fee_rate(float sat_per_vbyte);

[Throws=BdkError]
Expand Down
1 change: 1 addition & 0 deletions bdk-ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use crate::wallet::Update;
use crate::wallet::Wallet;

use bdk::keys::bip39::WordCount;
use bdk::wallet::tx_builder::ChangeSpendPolicy;
use bdk::wallet::AddressIndex as BdkAddressIndex;
use bdk::wallet::AddressInfo as BdkAddressInfo;
use bdk::wallet::Balance as BdkBalance;
Expand Down
140 changes: 73 additions & 67 deletions bdk-ffi/src/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ use crate::{Balance, Script};
use std::collections::HashSet;

use bdk::bitcoin::blockdata::script::ScriptBuf as BdkScriptBuf;
use bdk::bitcoin::OutPoint as BdkOutPoint;
use bdk::wallet::Update as BdkUpdate;
use bdk::Wallet as BdkWallet;
use bdk::{Error as BdkError, FeeRate};

use bdk::wallet::tx_builder::ChangeSpendPolicy;
use std::sync::{Arc, Mutex, MutexGuard};

#[derive(Debug)]
Expand Down Expand Up @@ -265,7 +267,7 @@ pub struct TxBuilder {
pub(crate) utxos: Vec<OutPoint>,
pub(crate) unspendable: HashSet<OutPoint>,
pub(crate) change_policy: ChangeSpendPolicy,
// pub(crate) manually_selected_only: bool,
pub(crate) manually_selected_only: bool,
pub(crate) fee_rate: Option<f32>,
// pub(crate) fee_absolute: Option<u64>,
// pub(crate) drain_wallet: bool,
Expand All @@ -281,7 +283,7 @@ impl TxBuilder {
utxos: Vec::new(),
unspendable: HashSet::new(),
change_policy: ChangeSpendPolicy::ChangeAllowed,
// manually_selected_only: false,
manually_selected_only: false,
fee_rate: None,
// fee_absolute: None,
// drain_wallet: false,
Expand Down Expand Up @@ -324,49 +326,56 @@ impl TxBuilder {
})
}

/// Add an outpoint to the internal list of UTXOs that must be spent. These have priority over the "unspendable"
/// utxos, meaning that if a utxo is present both in the "utxos" and the "unspendable" list, it will be spent.
pub(crate) fn add_utxo(&self, outpoint: OutPoint) -> Arc<Self> {
self.add_utxos(vec![outpoint])
}
/// Add an outpoint to the internal list of UTXOs that must be spent. These have priority over the "unspendable"
/// utxos, meaning that if a utxo is present both in the "utxos" and the "unspendable" list, it will be spent.
pub(crate) fn add_utxo(&self, outpoint: OutPoint) -> Arc<Self> {
self.add_utxos(vec![outpoint])
}

/// Add the list of outpoints to the internal list of UTXOs that must be spent. If an error occurs while adding
/// any of the UTXOs then none of them are added and the error is returned. These have priority over the "unspendable"
/// utxos, meaning that if a utxo is present both in the "utxos" and the "unspendable" list, it will be spent.
pub(crate) fn add_utxos(&self, mut outpoints: Vec<OutPoint>) -> Arc<Self> {
let mut utxos = self.utxos.to_vec();
utxos.append(&mut outpoints);
Arc::new(TxBuilder {
utxos,
..self.clone()
})
}
/// Add the list of outpoints to the internal list of UTXOs that must be spent. If an error occurs while adding
/// any of the UTXOs then none of them are added and the error is returned. These have priority over the "unspendable"
/// utxos, meaning that if a utxo is present both in the "utxos" and the "unspendable" list, it will be spent.
pub(crate) fn add_utxos(&self, mut outpoints: Vec<OutPoint>) -> Arc<Self> {
let mut utxos = self.utxos.to_vec();
utxos.append(&mut outpoints);
Arc::new(TxBuilder {
utxos,
..self.clone()
})
}

pub(crate) fn change_policy(&self, change_policy: ChangeSpendPolicy) -> Arc<Self> {
Arc::new(TxBuilder {
change_policy,
..self.clone()
})
}

/// Do not spend change outputs. This effectively adds all the change outputs to the "unspendable" list. See TxBuilder.unspendable.
pub(crate) fn do_not_spend_change(&self) -> Arc<Self> {
Arc::new(TxBuilder {
change_policy: ChangeSpendPolicy::ChangeForbidden,
..self.clone()
})
}

/// Only spend change outputs. This effectively adds all the non-change outputs to the "unspendable" list. See TxBuilder.unspendable.
pub(crate) fn only_spend_change(&self) -> Arc<Self> {
Arc::new(TxBuilder {
change_policy: ChangeSpendPolicy::OnlyChange,
..self.clone()
})
}

/// Only spend utxos added by [add_utxo]. The wallet will not add additional utxos to the transaction even if they are
/// needed to make the transaction valid.
pub(crate) fn manually_selected_only(&self) -> Arc<Self> {
Arc::new(TxBuilder {
manually_selected_only: true,
..self.clone()
})
}

/// Do not spend change outputs. This effectively adds all the change outputs to the "unspendable" list. See TxBuilder.unspendable.
// pub(crate) fn do_not_spend_change(&self) -> Arc<Self> {
// Arc::new(TxBuilder {
// change_policy: ChangeSpendPolicy::ChangeForbidden,
// ..self.clone()
// })
// }
//
// /// Only spend utxos added by [add_utxo]. The wallet will not add additional utxos to the transaction even if they are
// /// needed to make the transaction valid.
pub(crate) fn manually_selected_only(&self) -> Arc<Self> {
Arc::new(TxBuilder {
manually_selected_only: true,
..self.clone()
})
}
//
// /// Only spend change outputs. This effectively adds all the non-change outputs to the "unspendable" list. See TxBuilder.unspendable.
// pub(crate) fn only_spend_change(&self) -> Arc<Self> {
// Arc::new(TxBuilder {
// change_policy: ChangeSpendPolicy::OnlyChange,
// ..self.clone()
// })
// }
//
// /// Replace the internal list of unspendable utxos with a new list. It’s important to note that the "must-be-spent" utxos added with
// /// TxBuilder.addUtxo have priority over these. See the Rust docs of the two linked methods for more details.
// pub(crate) fn unspendable(&self, unspendable: Vec<OutPoint>) -> Arc<Self> {
Expand All @@ -375,15 +384,15 @@ impl TxBuilder {
// ..self.clone()
// })
// }
//

/// Set a custom fee rate.
pub(crate) fn fee_rate(&self, sat_per_vb: f32) -> Arc<Self> {
Arc::new(TxBuilder {
fee_rate: Some(sat_per_vb),
..self.clone()
})
}
//

// /// Set an absolute fee.
// pub(crate) fn fee_absolute(&self, fee_amount: u64) -> Arc<Self> {
// Arc::new(TxBuilder {
Expand Down Expand Up @@ -432,43 +441,40 @@ impl TxBuilder {
// ..self.clone()
// })
// }
//
// /// Add data as an output using OP_RETURN.
// pub(crate) fn add_data(&self, data: Vec<u8>) -> Arc<Self> {
// Arc::new(TxBuilder {
// data,
// ..self.clone()
// })
// }
//

/// Add data as an output using OP_RETURN.
// pub(crate) fn add_data(&self, data: Vec<u8>) -> Arc<Self> {
// Arc::new(TxBuilder {
// data,
// ..self.clone()
// })
// }

/// Finish building the transaction. Returns the BIP174 PSBT.
/// TODO: The TxBuilder in bdk returns a Psbt type
pub(crate) fn finish(
&self,
wallet: &Wallet,
) -> Result<Arc<PartiallySignedTransaction>, BdkError> {
// TODO: I had to change the wallet here to be mutable. Why is that now required with the 1.0 API?
let mut wallet = wallet.get_wallet();
let mut tx_builder = wallet.build_tx();
// TODO: I'm not yet clear on the Script/ScriptBuf differences and whether this is the best
// way to do this.
for (script, amount) in &self.recipients {
tx_builder.add_recipient(script.clone(), *amount);
}
// tx_builder.change_policy(self.change_policy);
// if !self.utxos.is_empty() {
// let bdk_utxos: Vec<BdkOutPoint> = self.utxos.iter().map(BdkOutPoint::from).collect();
// let utxos: &[BdkOutPoint] = &bdk_utxos;
// tx_builder.add_utxos(utxos)?;
// }
tx_builder.change_policy(self.change_policy);
if !self.utxos.is_empty() {
let bdk_utxos: Vec<BdkOutPoint> = self.utxos.iter().map(BdkOutPoint::from).collect();
let utxos: &[BdkOutPoint] = &bdk_utxos;
tx_builder.add_utxos(utxos)?;
}
// if !self.unspendable.is_empty() {
// let bdk_unspendable: Vec<BdkOutPoint> =
// self.unspendable.iter().map(BdkOutPoint::from).collect();
// tx_builder.unspendable(bdk_unspendable);
// }
// if self.manually_selected_only {
// tx_builder.manually_selected_only();
// }
if self.manually_selected_only {
tx_builder.manually_selected_only();
}
if let Some(sat_per_vb) = self.fee_rate {
tx_builder.fee_rate(FeeRate::from_sat_per_vb(sat_per_vb));
}
Expand Down Expand Up @@ -502,7 +508,7 @@ impl TxBuilder {
Ok(Arc::new(psbt.into()))
}
}
//

// /// The BumpFeeTxBuilder is used to bump the fee on a transaction that has been broadcast and has its RBF flag set to true.
// #[derive(Clone)]
// pub(crate) struct BumpFeeTxBuilder {
Expand Down

0 comments on commit 3e5b0c5

Please sign in to comment.