diff --git a/bdk-ffi/src/bdk.udl b/bdk-ffi/src/bdk.udl index 2418d8a5..121c766f 100644 --- a/bdk-ffi/src/bdk.udl +++ b/bdk-ffi/src/bdk.udl @@ -75,6 +75,7 @@ interface CreateTxError { UnknownUtxo(string outpoint); MissingNonWitnessUtxo(string outpoint); MiniscriptPsbt(string error_message); + PushBytesError(); }; [Error] @@ -702,6 +703,8 @@ interface TxBuilder { TxBuilder set_exact_sequence(u32 nsequence); + TxBuilder add_data(sequence data); + [Throws=CreateTxError] Psbt finish([ByRef] Wallet wallet); }; diff --git a/bdk-ffi/src/error.rs b/bdk-ffi/src/error.rs index 7aab6eaa..54fe1d03 100644 --- a/bdk-ffi/src/error.rs +++ b/bdk-ffi/src/error.rs @@ -1,5 +1,6 @@ use bitcoin_ffi::OutPoint; +use bdk_core::bitcoin::script::PushBytesError; use bdk_electrum::electrum_client::Error as BdkElectrumError; use bdk_esplora::esplora_client::{Error as BdkEsploraError, Error}; use bdk_wallet::bitcoin::address::ParseError as BdkParseError; @@ -194,6 +195,9 @@ pub enum CreateTxError { #[error("miniscript psbt error: {error_message}")] MiniscriptPsbt { error_message: String }, + + #[error("attempt to prepare too many bytes to be pushed into script")] + PushBytesError, } #[derive(Debug, thiserror::Error)] @@ -940,6 +944,12 @@ impl From for CreateTxError { } } +impl From for CreateTxError { + fn from(_: PushBytesError) -> Self { + CreateTxError::PushBytesError + } +} + impl From> for CreateWithPersistError { fn from(error: BdkCreateWithPersistError) -> Self { match error { diff --git a/bdk-ffi/src/tx_builder.rs b/bdk-ffi/src/tx_builder.rs index c11e6b0b..dde2a6fe 100644 --- a/bdk-ffi/src/tx_builder.rs +++ b/bdk-ffi/src/tx_builder.rs @@ -14,7 +14,9 @@ use bdk_wallet::ChangeSpendPolicy; use std::collections::BTreeMap; use std::collections::HashMap; +use bdk_wallet::bitcoin::script::PushBytesBuf; use std::collections::HashSet; +use std::convert::TryFrom; use std::str::FromStr; use std::sync::Arc; @@ -33,6 +35,7 @@ pub struct TxBuilder { pub(crate) drain_wallet: bool, pub(crate) drain_to: Option, pub(crate) sequence: Option, + pub(crate) data: Vec, } impl TxBuilder { @@ -51,6 +54,7 @@ impl TxBuilder { drain_wallet: false, drain_to: None, sequence: None, + data: Vec::new(), } } @@ -193,6 +197,13 @@ impl TxBuilder { }) } + pub(crate) fn add_data(&self, data: Vec) -> Arc { + Arc::new(TxBuilder { + data, + ..self.clone() + }) + } + pub(crate) fn finish(&self, wallet: &Arc) -> Result, 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(); @@ -237,6 +248,10 @@ impl TxBuilder { if let Some(sequence) = self.sequence { tx_builder.set_exact_sequence(Sequence(sequence)); } + if !&self.data.is_empty() { + let push_bytes = PushBytesBuf::try_from(self.data.clone())?; + tx_builder.add_data(&push_bytes); + } let psbt = tx_builder.finish().map_err(CreateTxError::from)?;