Skip to content

Commit

Permalink
feat: expose TxBuilder::nlocktime
Browse files Browse the repository at this point in the history
  • Loading branch information
thunderbiscuit committed Nov 21, 2024
1 parent 1d8b95d commit 0741588
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 4 deletions.
5 changes: 5 additions & 0 deletions bdk-ffi/src/bdk.udl
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ interface CreateTxError {
MissingNonWitnessUtxo(string outpoint);
MiniscriptPsbt(string error_message);
PushBytesError();
LockTimeConversionError();
};

[Error]
Expand Down Expand Up @@ -707,6 +708,8 @@ interface TxBuilder {

TxBuilder current_height(u32 height);

TxBuilder nlocktime(LockTime locktime);

[Throws=CreateTxError]
Psbt finish([ByRef] Wallet wallet);
};
Expand All @@ -718,6 +721,8 @@ interface BumpFeeTxBuilder {

BumpFeeTxBuilder current_height(u32 height);

BumpFeeTxBuilder nlocktime(LockTime locktime);

[Throws=CreateTxError]
Psbt finish([ByRef] Wallet wallet);
};
Expand Down
3 changes: 3 additions & 0 deletions bdk-ffi/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,9 @@ pub enum CreateTxError {

#[error("attempt to prepare too many bytes to be pushed into script")]
PushBytesError,

#[error("invalid lock time value")]
LockTimeConversionError,
}

#[derive(Debug, thiserror::Error)]
Expand Down
34 changes: 31 additions & 3 deletions bdk-ffi/src/tx_builder.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use crate::bitcoin::Psbt;
use crate::error::CreateTxError;
use crate::types::ScriptAmount;
use crate::types::{LockTime, ScriptAmount};
use crate::wallet::Wallet;

use bitcoin_ffi::{Amount, FeeRate, Script};

use bdk_wallet::bitcoin::absolute::LockTime as BdkLockTime;
use bdk_wallet::bitcoin::amount::Amount as BdkAmount;
use bdk_wallet::bitcoin::script::PushBytesBuf;
use bdk_wallet::bitcoin::Psbt as BdkPsbt;
Expand All @@ -16,7 +17,7 @@ use bdk_wallet::KeychainKind;
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::collections::HashSet;
use std::convert::TryFrom;
use std::convert::{TryFrom, TryInto};
use std::str::FromStr;
use std::sync::Arc;

Expand All @@ -37,6 +38,7 @@ pub struct TxBuilder {
pub(crate) sequence: Option<u32>,
pub(crate) data: Vec<u8>,
pub(crate) current_height: Option<u32>,
pub(crate) locktime: Option<LockTime>,
}

impl TxBuilder {
Expand All @@ -57,6 +59,7 @@ impl TxBuilder {
sequence: None,
data: Vec::new(),
current_height: None,
locktime: None,
}
}

Expand Down Expand Up @@ -213,6 +216,13 @@ impl TxBuilder {
})
}

pub(crate) fn nlocktime(&self, locktime: LockTime) -> Arc<Self> {
Arc::new(TxBuilder {
locktime: Some(locktime),
..self.clone()
})
}

pub(crate) fn finish(&self, wallet: &Arc<Wallet>) -> Result<Arc<Psbt>, CreateTxError> {
// 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();
Expand Down Expand Up @@ -264,6 +274,11 @@ impl TxBuilder {
if let Some(height) = self.current_height {
tx_builder.current_height(height);
}
// let bdk_locktime = locktime.try_into().map_err(CreateTxError::LockTimeConversionError)?;
if let Some(locktime) = &self.locktime {
let bdk_locktime: BdkLockTime = locktime.try_into()?;
tx_builder.nlocktime(bdk_locktime);
}

let psbt = tx_builder.finish().map_err(CreateTxError::from)?;

Expand All @@ -277,15 +292,17 @@ pub(crate) struct BumpFeeTxBuilder {
pub(crate) fee_rate: Arc<FeeRate>,
pub(crate) sequence: Option<u32>,
pub(crate) current_height: Option<u32>,
pub(crate) locktime: Option<LockTime>,
}

impl BumpFeeTxBuilder {
pub(crate) fn new(txid: String, fee_rate: Arc<FeeRate>) -> Self {
Self {
BumpFeeTxBuilder {
txid,
fee_rate,
sequence: None,
current_height: None,
locktime: None,
}
}

Expand All @@ -303,6 +320,13 @@ impl BumpFeeTxBuilder {
})
}

pub(crate) fn nlocktime(&self, locktime: LockTime) -> Arc<Self> {
Arc::new(BumpFeeTxBuilder {
locktime: Some(locktime),
..self.clone()
})
}

pub(crate) fn finish(&self, wallet: &Arc<Wallet>) -> Result<Arc<Psbt>, CreateTxError> {
let txid = Txid::from_str(self.txid.as_str()).map_err(|_| CreateTxError::UnknownUtxo {
outpoint: self.txid.clone(),
Expand All @@ -316,6 +340,10 @@ impl BumpFeeTxBuilder {
if let Some(height) = self.current_height {
tx_builder.current_height(height);
}
if let Some(locktime) = &self.locktime {
let bdk_locktime: BdkLockTime = locktime.try_into()?;
tx_builder.nlocktime(bdk_locktime);
}

let psbt: BdkPsbt = tx_builder.finish()?;

Expand Down
16 changes: 15 additions & 1 deletion bdk-ffi/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::bitcoin::{Address, Transaction, TxOut};
use crate::error::RequestBuilderError;
use crate::error::{CreateTxError, RequestBuilderError};

use bitcoin_ffi::Amount;
use bitcoin_ffi::OutPoint;
Expand Down Expand Up @@ -29,6 +29,7 @@ use bdk_wallet::LocalOutput as BdkLocalOutput;
use bdk_wallet::Update as BdkUpdate;

use std::collections::HashMap;
use std::convert::TryFrom;
use std::sync::{Arc, Mutex};

#[derive(Debug)]
Expand Down Expand Up @@ -405,6 +406,19 @@ impl From<BdkLockTime> for LockTime {
}
}

impl TryFrom<&LockTime> for BdkLockTime {
type Error = CreateTxError;

fn try_from(value: &LockTime) -> Result<Self, CreateTxError> {
match value {
LockTime::Blocks { height } => BdkLockTime::from_height(*height)
.map_err(|_| CreateTxError::LockTimeConversionError),
LockTime::Seconds { consensus_time } => BdkLockTime::from_time(*consensus_time)
.map_err(|_| CreateTxError::LockTimeConversionError),
}
}
}

#[derive(Debug, Clone)]
pub enum Satisfaction {
Partial {
Expand Down

0 comments on commit 0741588

Please sign in to comment.