bdkffi/
bitcoin.rs

1use crate::error::{
2    AddressParseError, Bip32Error, ExtractTxError, FeeRateError, FromScriptError, HashParseError,
3    PsbtError, PsbtParseError, TransactionError,
4};
5use crate::error::{ParseAmountError, PsbtFinalizeError};
6use crate::keys::DerivationPath;
7
8use crate::{impl_from_core_type, impl_hash_like, impl_into_core_type};
9use bdk_wallet::bitcoin::address::NetworkChecked;
10use bdk_wallet::bitcoin::address::NetworkUnchecked;
11use bdk_wallet::bitcoin::address::{Address as BdkAddress, AddressData as BdkAddressData};
12use bdk_wallet::bitcoin::bip32::ChildNumber as BdkChildNumber;
13use bdk_wallet::bitcoin::blockdata::block::Block as BdkBlock;
14use bdk_wallet::bitcoin::blockdata::block::Header as BdkHeader;
15use bdk_wallet::bitcoin::consensus::encode::deserialize;
16use bdk_wallet::bitcoin::consensus::encode::serialize;
17use bdk_wallet::bitcoin::hashes::sha256::Hash as BitcoinSha256Hash;
18use bdk_wallet::bitcoin::hashes::sha256d::Hash as BitcoinDoubleSha256Hash;
19use bdk_wallet::bitcoin::psbt::Input as BdkInput;
20use bdk_wallet::bitcoin::psbt::Output as BdkOutput;
21use bdk_wallet::bitcoin::secp256k1::Secp256k1;
22use bdk_wallet::bitcoin::taproot::LeafNode as BdkLeafNode;
23use bdk_wallet::bitcoin::taproot::NodeInfo as BdkNodeInfo;
24use bdk_wallet::bitcoin::taproot::TapTree as BdkTapTree;
25use bdk_wallet::bitcoin::Amount as BdkAmount;
26use bdk_wallet::bitcoin::BlockHash as BitcoinBlockHash;
27use bdk_wallet::bitcoin::FeeRate as BdkFeeRate;
28use bdk_wallet::bitcoin::OutPoint as BdkOutPoint;
29use bdk_wallet::bitcoin::Psbt as BdkPsbt;
30use bdk_wallet::bitcoin::ScriptBuf as BdkScriptBuf;
31use bdk_wallet::bitcoin::Transaction as BdkTransaction;
32use bdk_wallet::bitcoin::TxIn as BdkTxIn;
33use bdk_wallet::bitcoin::TxOut as BdkTxOut;
34use bdk_wallet::bitcoin::Txid as BitcoinTxid;
35use bdk_wallet::bitcoin::Weight;
36use bdk_wallet::bitcoin::Wtxid as BitcoinWtxid;
37use bdk_wallet::miniscript::psbt::PsbtExt;
38use bdk_wallet::serde_json;
39
40use std::collections::HashMap;
41use std::convert::TryFrom;
42use std::fmt::Display;
43use std::fs::File;
44use std::io::{BufReader, BufWriter};
45use std::ops::Deref;
46use std::str::FromStr;
47use std::sync::{Arc, Mutex};
48
49pub type DescriptorType = bdk_wallet::miniscript::descriptor::DescriptorType;
50pub type Network = bdk_wallet::bitcoin::Network;
51pub(crate) type NetworkKind = bdk_wallet::bitcoin::NetworkKind;
52
53/// What kind of network we are on.
54#[uniffi::remote(Enum)]
55pub enum NetworkKind {
56    /// The Bitcoin mainnet network.
57    Main,
58    /// Some kind of testnet network.
59    Test,
60}
61
62/// A reference to an unspent output by TXID and output index.
63#[derive(Debug, Clone, Eq, PartialEq, std::hash::Hash, uniffi:: Record)]
64pub struct OutPoint {
65    /// The transaction.
66    pub txid: Arc<Txid>,
67    /// The index of the output in the transaction.
68    pub vout: u32,
69}
70
71impl From<&BdkOutPoint> for OutPoint {
72    fn from(outpoint: &BdkOutPoint) -> Self {
73        OutPoint {
74            txid: Arc::new(Txid(outpoint.txid)),
75            vout: outpoint.vout,
76        }
77    }
78}
79
80impl From<BdkOutPoint> for OutPoint {
81    fn from(value: BdkOutPoint) -> Self {
82        Self {
83            txid: Arc::new(Txid(value.txid)),
84            vout: value.vout,
85        }
86    }
87}
88
89impl From<OutPoint> for BdkOutPoint {
90    fn from(outpoint: OutPoint) -> Self {
91        BdkOutPoint {
92            txid: BitcoinTxid::from_raw_hash(outpoint.txid.0.to_raw_hash()),
93            vout: outpoint.vout,
94        }
95    }
96}
97
98/// The cryptocurrency network to act on.
99///
100/// This is an exhaustive enum, meaning that we cannot add any future networks without defining a
101/// new, incompatible version of this type. If you are using this type directly and wish to support
102/// the new network, this will be a breaking change to your APIs and likely require changes in your
103/// code.
104///
105/// If you are concerned about forward compatibility, consider using T: Into<Params> instead of this
106/// type as a parameter to functions in your public API, or directly using the Params type.
107#[uniffi::remote(Enum)]
108pub enum Network {
109    Bitcoin,
110    Testnet,
111    Testnet4,
112    Signet,
113    Regtest,
114}
115
116/// An [`OutPoint`] used as a key in a hash map.
117///
118/// Due to limitations in generating the foreign language bindings, we cannot use [`OutPoint`] as a
119/// key for hash maps.
120#[derive(Debug, PartialEq, Eq, std::hash::Hash, uniffi::Object)]
121#[uniffi::export(Debug, Eq, Hash)]
122pub struct HashableOutPoint(pub(crate) OutPoint);
123
124#[uniffi::export]
125impl HashableOutPoint {
126    /// Create a key for a key-value store from an [`OutPoint`]
127    #[uniffi::constructor]
128    pub fn new(outpoint: OutPoint) -> Self {
129        Self(outpoint)
130    }
131
132    /// Get the internal [`OutPoint`]
133    pub fn outpoint(&self) -> OutPoint {
134        self.0.clone()
135    }
136}
137
138/// Represents fee rate.
139///
140/// This is an integer type representing fee rate in sat/kwu. It provides protection against mixing
141/// up the types as well as basic formatting features.
142#[derive(Clone, Debug, uniffi::Object)]
143#[uniffi::export(Display)]
144pub struct FeeRate(pub(crate) BdkFeeRate);
145
146#[uniffi::export]
147impl FeeRate {
148    /// Constructs `FeeRate` from satoshis per virtual bytes.
149    #[uniffi::constructor]
150    pub fn from_sat_per_vb(sat_vb: u64) -> Result<Self, FeeRateError> {
151        let fee_rate: Option<BdkFeeRate> = BdkFeeRate::from_sat_per_vb(sat_vb);
152        match fee_rate {
153            Some(fee_rate) => Ok(FeeRate(fee_rate)),
154            None => Err(FeeRateError::ArithmeticOverflow),
155        }
156    }
157
158    /// Constructs `FeeRate` from satoshis per 1000 weight units.
159    #[uniffi::constructor]
160    pub fn from_sat_per_kwu(sat_kwu: u64) -> Self {
161        FeeRate(BdkFeeRate::from_sat_per_kwu(sat_kwu))
162    }
163
164    /// Converts to sat/vB rounding up.
165    pub fn to_sat_per_vb_ceil(&self) -> u64 {
166        self.0.to_sat_per_vb_ceil()
167    }
168
169    /// Converts to sat/vB rounding down.
170    pub fn to_sat_per_vb_floor(&self) -> u64 {
171        self.0.to_sat_per_vb_floor()
172    }
173
174    /// Returns raw fee rate.
175    pub fn to_sat_per_kwu(&self) -> u64 {
176        self.0.to_sat_per_kwu()
177    }
178
179    /// Calculates fee in satoshis by multiplying this fee rate by weight, in virtual bytes, returning `None` if overflow occurred.
180    ///
181    /// This is equivalent to converting vb to weight using Weight::from_vb and then calling Self::fee_wu(weight).
182    pub fn fee_vb(&self, vb: u64) -> Option<Arc<Amount>> {
183        let rust_amount: BdkAmount = self.0.fee_vb(vb)?;
184        let amount: Amount = rust_amount.into();
185        Some(Arc::new(amount))
186
187        // The whole code above should be replaceable by the following line:
188        // self.0.fee_vb(vb).map(Arc::new(Amount::from))
189        // But in practice you get uniffi compilation errors on it. Not sure what is going on with it,
190        // but the code we use works just as well.
191    }
192
193    /// Calculates fee by multiplying this fee rate by weight, in weight units, returning `None` if overflow occurred.
194    ///
195    /// This is equivalent to Self::checked_mul_by_weight().
196    pub fn fee_wu(&self, wu: u64) -> Option<Arc<Amount>> {
197        let weight: Weight = Weight::from_wu(wu);
198        let rust_amount: BdkAmount = self.0.fee_wu(weight)?;
199        let amount: Amount = rust_amount.into();
200        Some(Arc::new(amount))
201    }
202}
203
204impl Display for FeeRate {
205    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
206        write!(f, "{:#}", self.0)
207    }
208}
209
210impl_from_core_type!(BdkFeeRate, FeeRate);
211impl_into_core_type!(FeeRate, BdkFeeRate);
212
213/// The Amount type can be used to express Bitcoin amounts that support arithmetic and conversion
214/// to various denominations. The operations that Amount implements will panic when overflow or
215/// underflow occurs. Also note that since the internal representation of amounts is unsigned,
216/// subtracting below zero is considered an underflow and will cause a panic.
217#[derive(Debug, Clone, PartialEq, Eq, uniffi::Object)]
218#[uniffi::export(Display)]
219pub struct Amount(pub(crate) BdkAmount);
220
221#[uniffi::export]
222impl Amount {
223    /// Create an Amount with satoshi precision and the given number of satoshis.
224    #[uniffi::constructor]
225    pub fn from_sat(satoshi: u64) -> Self {
226        Amount(BdkAmount::from_sat(satoshi))
227    }
228
229    /// Convert from a value expressing bitcoins to an Amount.
230    #[uniffi::constructor]
231    pub fn from_btc(btc: f64) -> Result<Self, ParseAmountError> {
232        let bitcoin_amount = BdkAmount::from_btc(btc).map_err(ParseAmountError::from)?;
233        Ok(Amount(bitcoin_amount))
234    }
235
236    /// Get the number of satoshis in this Amount.
237    pub fn to_sat(&self) -> u64 {
238        self.0.to_sat()
239    }
240
241    /// Express this Amount as a floating-point value in Bitcoin. Please be aware of the risk of
242    /// using floating-point numbers.
243    pub fn to_btc(&self) -> f64 {
244        self.0.to_btc()
245    }
246}
247
248impl_from_core_type!(BdkAmount, Amount);
249impl_into_core_type!(Amount, BdkAmount);
250
251impl Display for Amount {
252    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
253        write!(f, "{}", self.0)
254    }
255}
256
257/// A bitcoin script: https://en.bitcoin.it/wiki/Script
258#[derive(Clone, Debug, uniffi::Object)]
259#[uniffi::export(Display)]
260pub struct Script(pub(crate) BdkScriptBuf);
261
262#[uniffi::export]
263impl Script {
264    /// Interpret an array of bytes as a bitcoin script.
265    #[uniffi::constructor]
266    pub fn new(raw_output_script: Vec<u8>) -> Self {
267        let script: BdkScriptBuf = raw_output_script.into();
268        Script(script)
269    }
270
271    /// Convert a script into an array of bytes.
272    pub fn to_bytes(&self) -> Vec<u8> {
273        self.0.to_bytes()
274    }
275}
276
277impl_from_core_type!(BdkScriptBuf, Script);
278impl_into_core_type!(Script, BdkScriptBuf);
279
280impl Display for Script {
281    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
282        self.0.fmt_asm(f)
283    }
284}
285
286/// Bitcoin block header.
287/// Contains all the block’s information except the actual transactions, but including a root of a merkle tree
288/// committing to all transactions in the block.
289#[derive(uniffi::Record)]
290pub struct Header {
291    /// Block version, now repurposed for soft fork signalling.
292    pub version: i32,
293    /// Reference to the previous block in the chain.
294    pub prev_blockhash: Arc<BlockHash>,
295    /// The root hash of the merkle tree of transactions in the block.
296    pub merkle_root: Arc<TxMerkleNode>,
297    /// The timestamp of the block, as claimed by the miner.
298    pub time: u32,
299    /// The target value below which the blockhash must lie.
300    pub bits: u32,
301    /// The nonce, selected to obtain a low enough blockhash.
302    pub nonce: u32,
303}
304
305impl From<BdkHeader> for Header {
306    fn from(bdk_header: BdkHeader) -> Self {
307        Header {
308            version: bdk_header.version.to_consensus(),
309            prev_blockhash: Arc::new(BlockHash(bdk_header.prev_blockhash)),
310            merkle_root: Arc::new(TxMerkleNode(bdk_header.merkle_root.to_raw_hash())),
311            time: bdk_header.time,
312            bits: bdk_header.bits.to_consensus(),
313            nonce: bdk_header.nonce,
314        }
315    }
316}
317
318/// Bitcoin block.
319/// A collection of transactions with an attached proof of work.
320#[derive(uniffi::Record)]
321pub struct Block {
322    pub header: Header,
323    pub txdata: Vec<Arc<Transaction>>,
324}
325
326impl From<BdkBlock> for Block {
327    fn from(bdk_block: BdkBlock) -> Self {
328        Block {
329            header: bdk_block.header.into(),
330            txdata: bdk_block
331                .txdata
332                .into_iter()
333                .map(|tx| Arc::new(tx.into()))
334                .collect(),
335        }
336    }
337}
338
339/// The type of address.
340#[derive(Debug, uniffi::Enum)]
341pub enum AddressData {
342    /// Legacy.
343    P2pkh { pubkey_hash: String },
344    /// Wrapped Segwit
345    P2sh { script_hash: String },
346    /// Segwit
347    Segwit { witness_program: WitnessProgram },
348}
349
350/// The version and program of a Segwit address.
351#[derive(Debug, uniffi::Record)]
352pub struct WitnessProgram {
353    /// Version. For example 1 for Taproot.
354    pub version: u8,
355    /// The witness program.
356    pub program: Vec<u8>,
357}
358
359/// A bitcoin address
360#[derive(Debug, PartialEq, Eq, uniffi::Object)]
361#[uniffi::export(Eq, Display)]
362pub struct Address(pub(crate) BdkAddress<NetworkChecked>);
363
364#[uniffi::export]
365impl Address {
366    /// Parse a string as an address for the given network.
367    #[uniffi::constructor]
368    pub fn new(address: String, network: Network) -> Result<Self, AddressParseError> {
369        let parsed_address = address.parse::<bdk_wallet::bitcoin::Address<NetworkUnchecked>>()?;
370        let network_checked_address = parsed_address.require_network(network)?;
371
372        Ok(Address(network_checked_address))
373    }
374
375    /// Parse a script as an address for the given network
376    #[uniffi::constructor]
377    pub fn from_script(script: Arc<Script>, network: Network) -> Result<Self, FromScriptError> {
378        let address = BdkAddress::from_script(&script.0.clone(), network)?;
379
380        Ok(Address(address))
381    }
382
383    /// Return the `scriptPubKey` underlying an address.
384    pub fn script_pubkey(&self) -> Arc<Script> {
385        Arc::new(Script(self.0.script_pubkey()))
386    }
387
388    /// Return a BIP-21 URI string for this address.
389    pub fn to_qr_uri(&self) -> String {
390        self.0.to_qr_uri()
391    }
392
393    /// Is the address valid for the provided network
394    pub fn is_valid_for_network(&self, network: Network) -> bool {
395        let address_str = self.0.to_string();
396        if let Ok(unchecked_address) = address_str.parse::<BdkAddress<NetworkUnchecked>>() {
397            unchecked_address.is_valid_for_network(network)
398        } else {
399            false
400        }
401    }
402
403    /// Return the data for the address.
404    pub fn to_address_data(&self) -> AddressData {
405        match self.0.to_address_data() {
406            BdkAddressData::P2pkh { pubkey_hash } => AddressData::P2pkh {
407                pubkey_hash: pubkey_hash.to_string(),
408            },
409            BdkAddressData::P2sh { script_hash } => AddressData::P2sh {
410                script_hash: script_hash.to_string(),
411            },
412            BdkAddressData::Segwit { witness_program } => AddressData::Segwit {
413                witness_program: WitnessProgram {
414                    version: witness_program.version().to_num(),
415                    program: witness_program.program().as_bytes().to_vec(),
416                },
417            },
418            // AddressData is marked #[non_exhaustive] in bitcoin crate
419            _ => unimplemented!("Unsupported address type"),
420        }
421    }
422}
423
424impl Display for Address {
425    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
426        write!(f, "{}", self.0)
427    }
428}
429
430impl_from_core_type!(BdkAddress, Address);
431impl_into_core_type!(Address, BdkAddress);
432
433/// Bitcoin transaction.
434/// An authenticated movement of coins.
435#[derive(Debug, Clone, PartialEq, Eq, uniffi::Object)]
436#[uniffi::export(Eq, Display)]
437pub struct Transaction(BdkTransaction);
438
439#[uniffi::export]
440impl Transaction {
441    /// Creates a new `Transaction` instance from serialized transaction bytes.
442    #[uniffi::constructor]
443    pub fn new(transaction_bytes: Vec<u8>) -> Result<Self, TransactionError> {
444        let tx: BdkTransaction = deserialize(&transaction_bytes)?;
445        Ok(Transaction(tx))
446    }
447
448    /// Computes the Txid.
449    /// Hashes the transaction excluding the segwit data (i.e. the marker, flag bytes, and the witness fields themselves).
450    pub fn compute_txid(&self) -> Arc<Txid> {
451        Arc::new(Txid(self.0.compute_txid()))
452    }
453
454    /// Compute the Wtxid, which includes the witness in the transaction hash.
455    pub fn compute_wtxid(&self) -> Arc<Wtxid> {
456        Arc::new(Wtxid(self.0.compute_wtxid()))
457    }
458
459    /// Returns the weight of this transaction, as defined by BIP-141.
460    ///
461    /// > Transaction weight is defined as Base transaction size * 3 + Total transaction size (ie.
462    /// > the same method as calculating Block weight from Base size and Total size).
463    ///
464    /// For transactions with an empty witness, this is simply the consensus-serialized size times
465    /// four. For transactions with a witness, this is the non-witness consensus-serialized size
466    /// multiplied by three plus the with-witness consensus-serialized size.
467    ///
468    /// For transactions with no inputs, this function will return a value 2 less than the actual
469    /// weight of the serialized transaction. The reason is that zero-input transactions, post-segwit,
470    /// cannot be unambiguously serialized; we make a choice that adds two extra bytes. For more
471    /// details see [BIP 141](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki)
472    /// which uses a "input count" of `0x00` as a `marker` for a Segwit-encoded transaction.
473    ///
474    /// If you need to use 0-input transactions, we strongly recommend you do so using the PSBT
475    /// API. The unsigned transaction encoded within PSBT is always a non-segwit transaction
476    /// and can therefore avoid this ambiguity.
477    #[inline]
478    pub fn weight(&self) -> u64 {
479        self.0.weight().to_wu()
480    }
481
482    /// Returns the total transaction size
483    ///
484    /// Total transaction size is the transaction size in bytes serialized as described in BIP144,
485    /// including base data and witness data.
486    pub fn total_size(&self) -> u64 {
487        self.0.total_size() as u64
488    }
489
490    /// Returns the "virtual size" (vsize) of this transaction.
491    ///
492    /// Will be `ceil(weight / 4.0)`. Note this implements the virtual size as per [`BIP141`], which
493    /// is different to what is implemented in Bitcoin Core.
494    /// > Virtual transaction size is defined as Transaction weight / 4 (rounded up to the next integer).
495    ///
496    /// [`BIP141`]: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki
497    #[inline]
498    pub fn vsize(&self) -> u64 {
499        self.0.vsize() as u64
500    }
501
502    /// Checks if this is a coinbase transaction.
503    /// The first transaction in the block distributes the mining reward and is called the coinbase transaction.
504    /// It is impossible to check if the transaction is first in the block, so this function checks the structure
505    /// of the transaction instead - the previous output must be all-zeros (creates satoshis “out of thin air”).
506    pub fn is_coinbase(&self) -> bool {
507        self.0.is_coinbase()
508    }
509
510    /// Returns `true` if the transaction itself opted in to be BIP-125-replaceable (RBF).
511    ///
512    /// # Warning
513    ///
514    /// **Incorrectly relying on RBF may lead to monetary loss!**
515    ///
516    /// This **does not** cover the case where a transaction becomes replaceable due to ancestors
517    /// being RBF. Please note that transactions **may be replaced** even if they **do not** include
518    /// the RBF signal: <https://bitcoinops.org/en/newsletters/2022/10/19/#transaction-replacement-option>.
519    pub fn is_explicitly_rbf(&self) -> bool {
520        self.0.is_explicitly_rbf()
521    }
522
523    /// Returns `true` if this transactions nLockTime is enabled ([BIP-65]).
524    ///
525    /// [BIP-65]: https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki
526    pub fn is_lock_time_enabled(&self) -> bool {
527        self.0.is_lock_time_enabled()
528    }
529
530    /// The protocol version, is currently expected to be 1 or 2 (BIP 68).
531    pub fn version(&self) -> i32 {
532        self.0.version.0
533    }
534
535    /// Serialize transaction into consensus-valid format. See https://docs.rs/bitcoin/latest/bitcoin/struct.Transaction.html#serialization-notes for more notes on transaction serialization.
536    pub fn serialize(&self) -> Vec<u8> {
537        serialize(&self.0)
538    }
539
540    /// List of transaction inputs.
541    pub fn input(&self) -> Vec<TxIn> {
542        self.0.input.iter().map(|tx_in| tx_in.into()).collect()
543    }
544
545    /// List of transaction outputs.
546    pub fn output(&self) -> Vec<TxOut> {
547        self.0.output.iter().map(|tx_out| tx_out.into()).collect()
548    }
549
550    /// Block height or timestamp. Transaction cannot be included in a block until this height/time.
551    ///
552    /// /// ### Relevant BIPs
553    ///
554    /// * [BIP-65 OP_CHECKLOCKTIMEVERIFY](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki)
555    /// * [BIP-113 Median time-past as endpoint for lock-time calculations](https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki)
556    pub fn lock_time(&self) -> u32 {
557        self.0.lock_time.to_consensus_u32()
558    }
559}
560
561impl From<BdkTransaction> for Transaction {
562    fn from(tx: BdkTransaction) -> Self {
563        Transaction(tx)
564    }
565}
566
567impl From<&BdkTransaction> for Transaction {
568    fn from(tx: &BdkTransaction) -> Self {
569        Transaction(tx.clone())
570    }
571}
572
573impl From<&Transaction> for BdkTransaction {
574    fn from(tx: &Transaction) -> Self {
575        tx.0.clone()
576    }
577}
578
579impl Display for Transaction {
580    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
581        write!(f, "{:?}", self.0)
582    }
583}
584
585#[derive(Clone, Debug, uniffi::Record)]
586pub struct TapScriptEntry {
587    /// script (reuse existing `Script` FFI type)
588    pub script: Arc<Script>,
589    /// leaf version
590    pub leaf_version: u8,
591}
592
593#[derive(Clone, Debug, uniffi::Record)]
594pub struct TapKeyOrigin {
595    /// leaf hashes as hex strings
596    pub tap_leaf_hashes: Vec<String>,
597    /// key source
598    pub key_source: KeySource,
599}
600
601#[derive(Clone, Debug, uniffi::Record)]
602pub struct KeySource {
603    /// A fingerprint
604    pub fingerprint: String,
605    /// A BIP-32 derivation path.
606    pub path: Arc<DerivationPath>,
607}
608
609#[derive(Clone, Debug, Hash, Eq, PartialEq, uniffi::Record)]
610pub struct Key {
611    /// The type of this PSBT key.
612    pub type_value: u8,
613    /// The key itself in raw byte form.
614    /// `<key> := <keylen> <keytype> <keydata>`
615    pub key: Vec<u8>,
616}
617
618#[derive(Clone, Debug, Hash, Eq, PartialEq, uniffi::Record)]
619pub struct ProprietaryKey {
620    /// Proprietary type prefix used for grouping together keys under some
621    /// application and avoid namespace collision
622    pub prefix: Vec<u8>,
623    /// Custom proprietary subtype
624    pub subtype: u8,
625    /// Additional key bytes (like serialized public key data etc)
626    pub key: Vec<u8>,
627}
628
629#[derive(Clone, Debug, Hash, Eq, PartialEq, uniffi::Record)]
630pub struct ControlBlock {
631    /// The internal key.
632    pub internal_key: Vec<u8>,
633    /// The merkle proof of a script associated with this leaf.
634    pub merkle_branch: Vec<String>,
635    /// The parity of the output key (NOT THE INTERNAL KEY WHICH IS ALWAYS XONLY).
636    pub output_key_parity: u8,
637    /// The tapleaf version.
638    pub leaf_version: u8,
639}
640
641#[derive(Clone, Debug, Hash, Eq, PartialEq, uniffi::Record)]
642pub struct TapScriptSigKey {
643    /// An x-only public key, used for verification of Taproot signatures and serialized according to BIP-340.
644    pub xonly_pubkey: String,
645    /// Taproot-tagged hash with tag "TapLeaf".
646    /// This is used for computing tapscript script spend hash.
647    pub tap_leaf_hash: String,
648}
649
650/// A key-value map for an input of the corresponding index in the unsigned transaction.
651#[derive(Clone, Debug, uniffi::Record)]
652pub struct Input {
653    /// The non-witness transaction this input spends from. Should only be
654    /// `Option::Some` for inputs which spend non-segwit outputs or
655    /// if it is unknown whether an input spends a segwit output.
656    pub non_witness_utxo: Option<Arc<Transaction>>,
657    /// The transaction output this input spends from. Should only be
658    /// `Option::Some` for inputs which spend segwit outputs,
659    /// including P2SH embedded ones.
660    pub witness_utxo: Option<TxOut>,
661    /// A map from public keys to their corresponding signature as would be
662    /// pushed to the stack from a scriptSig or witness for a non-taproot inputs.
663    pub partial_sigs: HashMap<String, Vec<u8>>,
664    /// The sighash type to be used for this input. Signatures for this input
665    /// must use the sighash type.
666    pub sighash_type: Option<String>,
667    /// The redeem script for this input.
668    pub redeem_script: Option<Arc<Script>>,
669    /// The witness script for this input.
670    pub witness_script: Option<Arc<Script>>,
671    /// A map from public keys needed to sign this input to their corresponding
672    /// master key fingerprints and derivation paths.
673    pub bip32_derivation: HashMap<String, KeySource>,
674
675    /// The finalized, fully-constructed scriptSig with signatures and any other
676    /// scripts necessary for this input to pass validation.
677    pub final_script_sig: Option<Arc<Script>>,
678
679    /// The finalized, fully-constructed scriptWitness with signatures and any
680    /// other scripts necessary for this input to pass validation.
681    pub final_script_witness: Option<Vec<Vec<u8>>>,
682    /// RIPEMD160 hash to preimage map.
683    pub ripemd160_preimages: HashMap<String, Vec<u8>>,
684    /// SHA256 hash to preimage map.
685    pub sha256_preimages: HashMap<String, Vec<u8>>,
686    /// HASH160 hash to preimage map.
687    pub hash160_preimages: HashMap<String, Vec<u8>>,
688    /// HASH256 hash to preimage map.
689    pub hash256_preimages: HashMap<String, Vec<u8>>,
690    /// Serialized taproot signature with sighash type for key spend.
691    pub tap_key_sig: Option<Vec<u8>>,
692    /// Map of `<xonlypubkey>|<leafhash>` with signature.
693    pub tap_script_sigs: HashMap<TapScriptSigKey, Vec<u8>>,
694    /// Map of Control blocks to Script version pair.
695    pub tap_scripts: HashMap<ControlBlock, TapScriptEntry>,
696    /// Map of tap root x only keys to origin info and leaf hashes contained in it.
697    pub tap_key_origins: HashMap<String, TapKeyOrigin>,
698    /// Taproot Internal key.
699    pub tap_internal_key: Option<String>,
700    /// Taproot Merkle root.
701    pub tap_merkle_root: Option<String>,
702    /// Proprietary key-value pairs for this input.
703    pub proprietary: HashMap<ProprietaryKey, Vec<u8>>,
704    /// Unknown key-value pairs for this input.
705    pub unknown: HashMap<Key, Vec<u8>>,
706}
707
708use crate::error::AddForeignUtxoError;
709
710impl From<&BdkInput> for Input {
711    fn from(input: &BdkInput) -> Self {
712        Input {
713            non_witness_utxo: input
714                .non_witness_utxo
715                .as_ref()
716                .map(|tx| Arc::new(Transaction(tx.clone()))),
717            witness_utxo: input.witness_utxo.as_ref().map(TxOut::from),
718            partial_sigs: input
719                .partial_sigs
720                .iter()
721                .map(|(k, v)| (k.to_string(), v.to_vec()))
722                .collect(),
723            sighash_type: input.sighash_type.as_ref().map(|s| s.to_string()),
724            redeem_script: input
725                .redeem_script
726                .as_ref()
727                .map(|s| Arc::new(Script(s.clone()))),
728            witness_script: input
729                .witness_script
730                .as_ref()
731                .map(|s| Arc::new(Script(s.clone()))),
732            bip32_derivation: input
733                .bip32_derivation
734                .iter()
735                .map(|(pk, (fingerprint, deriv_path))| {
736                    (
737                        pk.to_string(),
738                        KeySource {
739                            fingerprint: fingerprint.to_string(),
740                            path: Arc::new(deriv_path.clone().into()),
741                        },
742                    )
743                })
744                .collect(),
745            final_script_sig: input
746                .final_script_sig
747                .as_ref()
748                .map(|s| Arc::new(Script(s.clone()))),
749            final_script_witness: input.final_script_witness.as_ref().map(|w| w.to_vec()),
750            ripemd160_preimages: input
751                .ripemd160_preimages
752                .iter()
753                .map(|(k, v)| (k.to_string(), v.clone()))
754                .collect(),
755            sha256_preimages: input
756                .sha256_preimages
757                .iter()
758                .map(|(k, v)| (k.to_string(), v.clone()))
759                .collect(),
760            hash160_preimages: input
761                .hash160_preimages
762                .iter()
763                .map(|(k, v)| (k.to_string(), v.clone()))
764                .collect(),
765            hash256_preimages: input
766                .hash256_preimages
767                .iter()
768                .map(|(k, v)| (k.to_string(), v.clone()))
769                .collect(),
770            tap_key_sig: input.tap_key_sig.as_ref().map(|s| s.serialize().to_vec()),
771            tap_script_sigs: input
772                .tap_script_sigs
773                .iter()
774                .map(|(k, v)| {
775                    let key = TapScriptSigKey {
776                        xonly_pubkey: k.0.to_string(),
777                        tap_leaf_hash: k.1.to_string(),
778                    };
779                    (key, v.to_vec())
780                })
781                .collect(),
782            tap_scripts: input
783                .tap_scripts
784                .iter()
785                .map(|(k, v)| {
786                    let key = ControlBlock {
787                        internal_key: k.internal_key.serialize().to_vec(),
788                        merkle_branch: k.merkle_branch.iter().map(|h| h.to_string()).collect(),
789                        output_key_parity: k.output_key_parity.to_u8(),
790                        leaf_version: k.leaf_version.to_consensus(),
791                    };
792                    let entry = TapScriptEntry {
793                        script: Arc::new(v.0.clone().into()),
794                        leaf_version: v.1.to_consensus(),
795                    };
796                    (key, entry)
797                })
798                .collect(),
799            tap_key_origins: input
800                .tap_key_origins
801                .iter()
802                .map(|(k, v)| {
803                    let key = k.to_string();
804                    let value = TapKeyOrigin {
805                        tap_leaf_hashes: v.0.iter().map(|h| h.to_string()).collect(),
806                        key_source: KeySource {
807                            // Unnecessary spaces being added by fmt. We use #[rustfmt::skip] to avoid them for now.
808                            #[rustfmt::skip]
809                            fingerprint: v.1.0.to_string(),
810                            #[rustfmt::skip]
811                            path: Arc::new(v.1.1.clone().into()),
812                        },
813                    };
814                    (key, value)
815                })
816                .collect(),
817            tap_internal_key: input.tap_internal_key.as_ref().map(|k| k.to_string()),
818            tap_merkle_root: input.tap_merkle_root.as_ref().map(|k| k.to_string()),
819            proprietary: input
820                .proprietary
821                .iter()
822                .map(|(k, v)| {
823                    (
824                        ProprietaryKey {
825                            prefix: k.prefix.clone(),
826                            subtype: k.subtype,
827                            key: k.key.clone(),
828                        },
829                        v.to_vec(),
830                    )
831                })
832                .collect(),
833            unknown: input
834                .unknown
835                .iter()
836                .map(|(k, v)| {
837                    (
838                        Key {
839                            key: k.key.clone(),
840                            type_value: k.type_value,
841                        },
842                        v.to_vec(),
843                    )
844                })
845                .collect(),
846        }
847    }
848}
849
850impl TryFrom<Input> for BdkInput {
851    type Error = AddForeignUtxoError;
852
853    fn try_from(input: Input) -> Result<Self, Self::Error> {
854        use bdk_wallet::bitcoin::ecdsa;
855        use bdk_wallet::bitcoin::hashes::Hash as HashTrait;
856        use bdk_wallet::bitcoin::key::PublicKey as Secp256k1PublicKey;
857        use bdk_wallet::bitcoin::psbt::PsbtSighashType;
858        use bdk_wallet::bitcoin::secp256k1::XOnlyPublicKey;
859        use bdk_wallet::bitcoin::taproot::{
860            ControlBlock as BdkControlBlock, LeafVersion, TapLeafHash, TapNodeHash,
861        };
862        use std::str::FromStr;
863
864        let non_witness_utxo = input.non_witness_utxo.map(|tx| tx.0.clone());
865
866        let witness_utxo = input.witness_utxo.map(|txout| txout.into());
867
868        let partial_sigs = input
869            .partial_sigs
870            .into_iter()
871            .map(|(k, v)| {
872                let pubkey = Secp256k1PublicKey::from_str(&k).map_err(|e| {
873                    AddForeignUtxoError::InputConversionError {
874                        error_message: format!("invalid public key in partial_sigs: {}", e),
875                    }
876                })?;
877                let sig = ecdsa::Signature::from_slice(&v).map_err(|e| {
878                    AddForeignUtxoError::InputConversionError {
879                        error_message: format!("invalid signature in partial_sigs: {}", e),
880                    }
881                })?;
882                Ok((pubkey, sig))
883            })
884            .collect::<Result<std::collections::BTreeMap<_, _>, AddForeignUtxoError>>()?;
885
886        let sighash_type = input
887            .sighash_type
888            .map(|s| {
889                PsbtSighashType::from_str(&s).map_err(|e| {
890                    AddForeignUtxoError::InputConversionError {
891                        error_message: format!("invalid sighash type: {}", e),
892                    }
893                })
894            })
895            .transpose()?;
896
897        let redeem_script = input.redeem_script.map(|s| s.0.clone());
898        let witness_script = input.witness_script.map(|s| s.0.clone());
899
900        let bip32_derivation = input
901            .bip32_derivation
902            .into_iter()
903            .map(|(k, v)| {
904                use bdk_wallet::bitcoin::bip32::{DerivationPath, Fingerprint};
905                use bdk_wallet::bitcoin::secp256k1::PublicKey as Secp256k1RawPublicKey;
906                let pubkey = Secp256k1RawPublicKey::from_str(&k).map_err(|e| {
907                    AddForeignUtxoError::InputConversionError {
908                        error_message: format!("invalid public key in bip32_derivation: {}", e),
909                    }
910                })?;
911                let fingerprint = Fingerprint::from_str(&v.fingerprint).map_err(|e| {
912                    AddForeignUtxoError::InputConversionError {
913                        error_message: format!("invalid fingerprint: {}", e),
914                    }
915                })?;
916                let path: DerivationPath = v.path.0.clone();
917                Ok((pubkey, (fingerprint, path)))
918            })
919            .collect::<Result<std::collections::BTreeMap<_, _>, AddForeignUtxoError>>()?;
920
921        let final_script_sig = input.final_script_sig.map(|s| s.0.clone());
922
923        let final_script_witness = input.final_script_witness.map(|w| {
924            use bdk_wallet::bitcoin::Witness;
925            Witness::from_slice(&w)
926        });
927
928        let ripemd160_preimages = input
929            .ripemd160_preimages
930            .into_iter()
931            .map(|(k, v)| {
932                use bdk_wallet::bitcoin::hashes::ripemd160;
933                let hash = ripemd160::Hash::from_str(&k).map_err(|e| {
934                    AddForeignUtxoError::InputConversionError {
935                        error_message: format!("invalid ripemd160 hash: {}", e),
936                    }
937                })?;
938                Ok((hash, v))
939            })
940            .collect::<Result<_, AddForeignUtxoError>>()?;
941
942        let sha256_preimages = input
943            .sha256_preimages
944            .into_iter()
945            .map(|(k, v)| {
946                use bdk_wallet::bitcoin::hashes::sha256;
947                let hash = sha256::Hash::from_str(&k).map_err(|e| {
948                    AddForeignUtxoError::InputConversionError {
949                        error_message: format!("invalid sha256 hash: {}", e),
950                    }
951                })?;
952                Ok((hash, v))
953            })
954            .collect::<Result<_, AddForeignUtxoError>>()?;
955
956        let hash160_preimages = input
957            .hash160_preimages
958            .into_iter()
959            .map(|(k, v)| {
960                use bdk_wallet::bitcoin::hashes::hash160;
961                let hash = hash160::Hash::from_str(&k).map_err(|e| {
962                    AddForeignUtxoError::InputConversionError {
963                        error_message: format!("invalid hash160: {}", e),
964                    }
965                })?;
966                Ok((hash, v))
967            })
968            .collect::<Result<_, AddForeignUtxoError>>()?;
969
970        let hash256_preimages = input
971            .hash256_preimages
972            .into_iter()
973            .map(|(k, v)| {
974                use bdk_wallet::bitcoin::hashes::sha256d;
975                let hash = sha256d::Hash::from_str(&k).map_err(|e| {
976                    AddForeignUtxoError::InputConversionError {
977                        error_message: format!("invalid hash256: {}", e),
978                    }
979                })?;
980                Ok((hash, v))
981            })
982            .collect::<Result<_, AddForeignUtxoError>>()?;
983
984        let tap_key_sig = input
985            .tap_key_sig
986            .map(|s| {
987                use bdk_wallet::bitcoin::taproot::Signature;
988                Signature::from_slice(&s).map_err(|e| AddForeignUtxoError::InputConversionError {
989                    error_message: format!("invalid taproot signature: {}", e),
990                })
991            })
992            .transpose()?;
993
994        let tap_script_sigs = input
995            .tap_script_sigs
996            .into_iter()
997            .map(|(k, v)| {
998                use bdk_wallet::bitcoin::taproot::Signature;
999                let xonly = XOnlyPublicKey::from_str(&k.xonly_pubkey).map_err(|e| {
1000                    AddForeignUtxoError::InputConversionError {
1001                        error_message: format!("invalid xonly pubkey: {}", e),
1002                    }
1003                })?;
1004                let leaf_hash = TapLeafHash::from_str(&k.tap_leaf_hash).map_err(|e| {
1005                    AddForeignUtxoError::InputConversionError {
1006                        error_message: format!("invalid tap leaf hash: {}", e),
1007                    }
1008                })?;
1009                let sig = Signature::from_slice(&v).map_err(|e| {
1010                    AddForeignUtxoError::InputConversionError {
1011                        error_message: format!("invalid taproot script signature: {}", e),
1012                    }
1013                })?;
1014                Ok(((xonly, leaf_hash), sig))
1015            })
1016            .collect::<Result<_, AddForeignUtxoError>>()?;
1017
1018        let tap_scripts = input
1019            .tap_scripts
1020            .into_iter()
1021            .map(|(k, v)| {
1022                use bdk_wallet::bitcoin::key::XOnlyPublicKey as BdkXOnlyPublicKey;
1023                use bdk_wallet::bitcoin::taproot::TapNodeHash;
1024
1025                let internal_key = BdkXOnlyPublicKey::from_slice(&k.internal_key).map_err(|e| {
1026                    AddForeignUtxoError::InputConversionError {
1027                        error_message: format!("invalid internal key: {}", e),
1028                    }
1029                })?;
1030
1031                let output_key_parity = k.output_key_parity;
1032                let leaf_version_u8 = k.leaf_version;
1033
1034                let merkle_branch: Vec<TapNodeHash> = k
1035                    .merkle_branch
1036                    .into_iter()
1037                    .map(|h| {
1038                        TapNodeHash::from_str(&h).map_err(|e| {
1039                            AddForeignUtxoError::InputConversionError {
1040                                error_message: format!("invalid merkle branch hash: {}", e),
1041                            }
1042                        })
1043                    })
1044                    .collect::<Result<_, AddForeignUtxoError>>()?;
1045
1046                let mut control_block_bytes = vec![output_key_parity | leaf_version_u8];
1047                control_block_bytes.extend_from_slice(&internal_key.serialize());
1048                for hash in &merkle_branch {
1049                    control_block_bytes.extend_from_slice(&hash.to_byte_array());
1050                }
1051
1052                let control_block = BdkControlBlock::decode(&control_block_bytes).map_err(|e| {
1053                    AddForeignUtxoError::InputConversionError {
1054                        error_message: format!("invalid control block: {}", e),
1055                    }
1056                })?;
1057
1058                let leaf_version = LeafVersion::from_consensus(leaf_version_u8).map_err(|_| {
1059                    AddForeignUtxoError::InputConversionError {
1060                        error_message: format!("invalid leaf version: {}", leaf_version_u8),
1061                    }
1062                })?;
1063
1064                Ok((control_block, (v.script.0.clone(), leaf_version)))
1065            })
1066            .collect::<Result<_, AddForeignUtxoError>>()?;
1067
1068        let tap_key_origins = input
1069            .tap_key_origins
1070            .into_iter()
1071            .map(|(k, v)| {
1072                use bdk_wallet::bitcoin::bip32::{DerivationPath, Fingerprint};
1073
1074                let xonly = XOnlyPublicKey::from_str(&k).map_err(|e| {
1075                    AddForeignUtxoError::InputConversionError {
1076                        error_message: format!("invalid xonly pubkey in tap_key_origins: {}", e),
1077                    }
1078                })?;
1079
1080                let leaf_hashes: Vec<TapLeafHash> = v
1081                    .tap_leaf_hashes
1082                    .into_iter()
1083                    .map(|h| {
1084                        TapLeafHash::from_str(&h).map_err(|e| {
1085                            AddForeignUtxoError::InputConversionError {
1086                                error_message: format!("invalid tap leaf hash: {}", e),
1087                            }
1088                        })
1089                    })
1090                    .collect::<Result<_, AddForeignUtxoError>>()?;
1091
1092                let fingerprint =
1093                    Fingerprint::from_str(&v.key_source.fingerprint).map_err(|e| {
1094                        AddForeignUtxoError::InputConversionError {
1095                            error_message: format!("invalid fingerprint in tap_key_origins: {}", e),
1096                        }
1097                    })?;
1098
1099                let path: DerivationPath = v.key_source.path.0.clone();
1100
1101                Ok((xonly, (leaf_hashes, (fingerprint, path))))
1102            })
1103            .collect::<Result<_, AddForeignUtxoError>>()?;
1104
1105        let tap_internal_key = input
1106            .tap_internal_key
1107            .map(|k| {
1108                XOnlyPublicKey::from_str(&k).map_err(|e| {
1109                    AddForeignUtxoError::InputConversionError {
1110                        error_message: format!("invalid tap internal key: {}", e),
1111                    }
1112                })
1113            })
1114            .transpose()?;
1115
1116        let tap_merkle_root = input
1117            .tap_merkle_root
1118            .map(|k| {
1119                TapNodeHash::from_str(&k).map_err(|e| AddForeignUtxoError::InputConversionError {
1120                    error_message: format!("invalid tap merkle root: {}", e),
1121                })
1122            })
1123            .transpose()?;
1124
1125        let proprietary = input
1126            .proprietary
1127            .into_iter()
1128            .map(|(k, v)| {
1129                use bdk_wallet::bitcoin::psbt::raw::ProprietaryKey as BdkProprietaryKey;
1130                (
1131                    BdkProprietaryKey {
1132                        prefix: k.prefix,
1133                        subtype: k.subtype,
1134                        key: k.key,
1135                    },
1136                    v,
1137                )
1138            })
1139            .collect();
1140
1141        let unknown = input
1142            .unknown
1143            .into_iter()
1144            .map(|(k, v)| {
1145                use bdk_wallet::bitcoin::psbt::raw::Key as BdkKey;
1146                (
1147                    BdkKey {
1148                        type_value: k.type_value,
1149                        key: k.key,
1150                    },
1151                    v,
1152                )
1153            })
1154            .collect();
1155
1156        Ok(BdkInput {
1157            non_witness_utxo,
1158            witness_utxo,
1159            partial_sigs,
1160            sighash_type,
1161            redeem_script,
1162            witness_script,
1163            bip32_derivation,
1164            final_script_sig,
1165            final_script_witness,
1166            ripemd160_preimages,
1167            sha256_preimages,
1168            hash160_preimages,
1169            hash256_preimages,
1170            tap_key_sig,
1171            tap_script_sigs,
1172            tap_scripts,
1173            tap_key_origins,
1174            tap_internal_key,
1175            tap_merkle_root,
1176            proprietary,
1177            unknown,
1178        })
1179    }
1180}
1181
1182/// Store information about taproot leaf node.
1183#[derive(Debug, uniffi::Object)]
1184#[uniffi::export(Display)]
1185pub struct LeafNode(BdkLeafNode);
1186
1187#[uniffi::export]
1188impl LeafNode {
1189    /// Returns the depth of this script leaf in the tap tree.
1190    pub fn depth(&self) -> u8 {
1191        self.0.depth()
1192    }
1193
1194    /// Computes a leaf hash for this ScriptLeaf if the leaf is known.
1195    /// This TapLeafHash is useful while signing taproot script spends.
1196    /// See LeafNode::node_hash for computing the TapNodeHash which returns the hidden node hash if the node is hidden.
1197    pub fn leaf_hash(&self) -> Option<String> {
1198        self.0.leaf_hash().map(|h| h.to_string())
1199    }
1200
1201    /// Computes the [`TapNodeHash`] for this [`ScriptLeaf`]. This returns the
1202    /// leaf hash if the leaf is known and the hidden node hash if the leaf is
1203    /// hidden.
1204    /// See also, [`bdk_electrum::bdk_core::bitcoin::taproot::LeafNode::leaf_hash`].
1205    pub fn node_hash(&self) -> String {
1206        self.0.node_hash().to_string()
1207    }
1208
1209    /// Returns reference to the leaf script if the leaf is known.
1210    pub fn script(&self) -> Option<Arc<Script>> {
1211        self.0.script().map(|s| Arc::new(Script(s.to_owned())))
1212    }
1213
1214    /// Returns leaf version of the script if the leaf is known.
1215    pub fn leaf_version(&self) -> Option<u8> {
1216        self.0.leaf_version().map(|n| n.to_consensus())
1217    }
1218
1219    /// Returns reference to the merkle proof (hashing partners) to get this
1220    /// node in form of [`TaprootMerkleBranch`].
1221    pub fn merkle_branch(&self) -> Vec<String> {
1222        self.0
1223            .merkle_branch()
1224            .to_vec()
1225            .iter()
1226            .map(|h| h.to_string())
1227            .collect()
1228    }
1229}
1230
1231impl Display for LeafNode {
1232    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1233        write!(f, "{:?}", self)
1234    }
1235}
1236
1237/// Taproot Tree representing a complete binary tree without any hidden nodes.
1238///
1239/// This is in contrast to NodeInfo, which allows hidden nodes. The implementations for Eq, PartialEq and Hash compare the merkle root of the tree
1240#[derive(Debug, uniffi::Object)]
1241#[uniffi::export(Display)]
1242pub struct TapTree(BdkTapTree);
1243
1244#[uniffi::export]
1245impl TapTree {
1246    /// Returns the root TapNodeHash of this tree.
1247    pub fn root_hash(&self) -> String {
1248        self.0.root_hash().to_string()
1249    }
1250
1251    /// Gets the reference to inner NodeInfo of this tree root.
1252    pub fn node_info(&self) -> Arc<NodeInfo> {
1253        Arc::new(NodeInfo(self.0.node_info().clone()))
1254    }
1255}
1256
1257impl Display for TapTree {
1258    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1259        write!(f, "{:?}", self)
1260    }
1261}
1262
1263/// Represents the node information in taproot tree. In contrast to TapTree, this is allowed to have hidden leaves as children.
1264///
1265/// Helper type used in merkle tree construction allowing one to build sparse merkle trees. The node represents part of the tree that has information about all of its descendants. See how TaprootBuilder works for more details.
1266/// You can use TaprootSpendInfo::from_node_info to a get a TaprootSpendInfo from the merkle root NodeInfo.
1267#[derive(Debug, uniffi::Object)]
1268#[uniffi::export(Display)]
1269pub struct NodeInfo(BdkNodeInfo);
1270
1271#[uniffi::export]
1272impl NodeInfo {
1273    /// Creates an iterator over all leaves (including hidden leaves) in the tree.
1274    pub fn leaf_nodes(&self) -> Vec<Arc<LeafNode>> {
1275        self.0
1276            .leaf_nodes()
1277            .map(|ln| Arc::new(LeafNode(ln.clone())))
1278            .collect()
1279    }
1280
1281    /// Returns the root TapNodeHash of this node info.
1282    pub fn node_hash(&self) -> String {
1283        self.0.node_hash().to_string()
1284    }
1285}
1286
1287impl Display for NodeInfo {
1288    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1289        write!(f, "{:?}", self)
1290    }
1291}
1292
1293/// A key-value map for an output of the corresponding index in the unsigned
1294/// transaction.
1295#[derive(Debug, uniffi::Record)]
1296pub struct Output {
1297    /// The redeem script for this output.
1298    pub redeem_script: Option<Arc<Script>>,
1299    /// The witness script for this output.
1300    pub witness_script: Option<Arc<Script>>,
1301    /// Map of public keys needed to spend this output to their corresponding
1302    /// master key fingerprints and derivation paths.
1303    pub bip32_derivation: HashMap<String, KeySource>,
1304    /// Taproot Internal key.
1305    pub tap_internal_key: Option<String>,
1306    /// Taproot Output tree (structured record).
1307    pub tap_tree: Option<Arc<TapTree>>,
1308    /// Map of tap root x only keys to origin info and leaf hashes contained in it.
1309    pub tap_key_origins: HashMap<String, TapKeyOrigin>,
1310    /// Proprietary key-value pairs for this output.
1311    pub proprietary: HashMap<ProprietaryKey, Vec<u8>>,
1312    /// Unknown key-value pairs for this output.
1313    pub unknown: HashMap<Key, Vec<u8>>,
1314}
1315
1316impl From<&BdkOutput> for Output {
1317    fn from(output: &BdkOutput) -> Self {
1318        Output {
1319            redeem_script: output
1320                .redeem_script
1321                .as_ref()
1322                .map(|s| Arc::new(Script(s.clone()))),
1323            witness_script: output
1324                .witness_script
1325                .as_ref()
1326                .map(|s| Arc::new(Script(s.clone()))),
1327            bip32_derivation: output
1328                .bip32_derivation
1329                .iter()
1330                .map(|(pk, (fingerprint, deriv_path))| {
1331                    (
1332                        pk.to_string(),
1333                        KeySource {
1334                            fingerprint: fingerprint.to_string(),
1335                            path: Arc::new(deriv_path.clone().into()),
1336                        },
1337                    )
1338                })
1339                .collect(),
1340            tap_internal_key: output.tap_internal_key.as_ref().map(|k| k.to_string()),
1341            tap_tree: output
1342                .tap_tree
1343                .as_ref()
1344                .map(|t| Arc::new(TapTree(t.clone()))),
1345            tap_key_origins: output
1346                .tap_key_origins
1347                .iter()
1348                .map(|(k, v)| {
1349                    let key = k.to_string();
1350                    let value = TapKeyOrigin {
1351                        tap_leaf_hashes: v.0.iter().map(|h| h.to_string()).collect(),
1352                        key_source: KeySource {
1353                            // Unnecessary spaces being added by fmt. We use #[rustfmt::skip] to avoid them for now.
1354                            #[rustfmt::skip]
1355                            fingerprint: v.1.0.to_string(),
1356                            #[rustfmt::skip]
1357                            path: Arc::new(v.1.1.clone().into()),
1358                        },
1359                    };
1360                    (key, value)
1361                })
1362                .collect(),
1363            proprietary: output
1364                .proprietary
1365                .iter()
1366                .map(|(k, v)| {
1367                    (
1368                        ProprietaryKey {
1369                            prefix: k.prefix.clone(),
1370                            subtype: k.subtype,
1371                            key: k.key.clone(),
1372                        },
1373                        v.to_vec(),
1374                    )
1375                })
1376                .collect(),
1377            unknown: output
1378                .unknown
1379                .iter()
1380                .map(|(k, v)| {
1381                    (
1382                        Key {
1383                            key: k.key.clone(),
1384                            type_value: k.type_value,
1385                        },
1386                        v.to_vec(),
1387                    )
1388                })
1389                .collect(),
1390        }
1391    }
1392}
1393
1394/// A Partially Signed Transaction.
1395#[derive(uniffi::Object)]
1396#[uniffi::export(Display)]
1397pub struct Psbt(pub(crate) Mutex<BdkPsbt>);
1398
1399#[uniffi::export]
1400impl Psbt {
1401    /// Creates a new `Psbt` instance from a base64-encoded string.
1402    #[uniffi::constructor]
1403    pub fn new(psbt_base64: String) -> Result<Self, PsbtParseError> {
1404        let psbt: BdkPsbt = BdkPsbt::from_str(&psbt_base64)?;
1405        Ok(Psbt(Mutex::new(psbt)))
1406    }
1407
1408    /// Creates a PSBT from an unsigned transaction.
1409    ///
1410    /// # Errors
1411    ///
1412    /// If transactions is not unsigned.
1413    #[uniffi::constructor]
1414    pub fn from_unsigned_tx(tx: Arc<Transaction>) -> Result<Arc<Psbt>, PsbtError> {
1415        let psbt: BdkPsbt = BdkPsbt::from_unsigned_tx(tx.0.clone())?;
1416        Ok(Arc::new(Psbt(Mutex::new(psbt))))
1417    }
1418
1419    /// Create a new `Psbt` from a `.psbt` file.
1420    #[uniffi::constructor]
1421    pub fn from_file(path: String) -> Result<Self, PsbtError> {
1422        let file = File::open(path)?;
1423        let mut buf_read = BufReader::new(file);
1424        let psbt: BdkPsbt = BdkPsbt::deserialize_from_reader(&mut buf_read)?;
1425        Ok(Psbt(Mutex::new(psbt)))
1426    }
1427
1428    /// Serialize the PSBT into a base64-encoded string.
1429    pub fn serialize(&self) -> String {
1430        let psbt = self.0.lock().unwrap().clone();
1431        psbt.to_string()
1432    }
1433
1434    /// Extracts the `Transaction` from a `Psbt` by filling in the available signature information.
1435    ///
1436    /// #### Errors
1437    ///
1438    /// `ExtractTxError` variants will contain either the `Psbt` itself or the `Transaction`
1439    /// that was extracted. These can be extracted from the Errors in order to recover.
1440    /// See the error documentation for info on the variants. In general, it covers large fees.
1441    pub fn extract_tx(&self) -> Result<Arc<Transaction>, ExtractTxError> {
1442        let tx: BdkTransaction = self.0.lock().unwrap().clone().extract_tx()?;
1443        let transaction: Transaction = tx.into();
1444        Ok(Arc::new(transaction))
1445    }
1446
1447    /// Extracts the `Transaction` from a `Psbt` by filling in the available signature information.
1448    ///
1449    /// #### Errors
1450    ///
1451    /// See `extract_tx`.
1452    pub fn extract_tx_with_fee_rate_limit(
1453        &self,
1454        max_fee_rate: Arc<FeeRate>,
1455    ) -> Result<Arc<Transaction>, ExtractTxError> {
1456        let tx: BdkTransaction = self
1457            .0
1458            .lock()
1459            .unwrap()
1460            .clone()
1461            .extract_tx_with_fee_rate_limit(max_fee_rate.0)?;
1462        let transaction: Transaction = tx.into();
1463        Ok(Arc::new(transaction))
1464    }
1465
1466    /// Perform `extract_tx` without the fee rate check.
1467    ///
1468    /// This can result in a transaction with absurdly high fees. Use with caution.
1469    pub fn extract_tx_unchecked_fee_rate(&self) -> Arc<Transaction> {
1470        let tx: BdkTransaction = self
1471            .0
1472            .lock()
1473            .unwrap()
1474            .clone()
1475            .extract_tx_unchecked_fee_rate();
1476        Arc::new(tx.into())
1477    }
1478
1479    /// Calculates transaction fee.
1480    ///
1481    /// 'Fee' being the amount that will be paid for mining a transaction with the current inputs
1482    /// and outputs i.e., the difference in value of the total inputs and the total outputs.
1483    ///
1484    /// #### Errors
1485    ///
1486    /// - `MissingUtxo` when UTXO information for any input is not present or is invalid.
1487    /// - `NegativeFee` if calculated value is negative.
1488    /// - `FeeOverflow` if an integer overflow occurs.
1489    pub fn fee(&self) -> Result<u64, PsbtError> {
1490        self.0
1491            .lock()
1492            .unwrap()
1493            .fee()
1494            .map(|fee| fee.to_sat())
1495            .map_err(PsbtError::from)
1496    }
1497
1498    /// Combines this `Psbt` with `other` PSBT as described by BIP 174.
1499    ///
1500    /// In accordance with BIP 174 this function is commutative i.e., `A.combine(B) == B.combine(A)`
1501    pub fn combine(&self, other: Arc<Psbt>) -> Result<Arc<Psbt>, PsbtError> {
1502        let mut original_psbt = self.0.lock().unwrap().clone();
1503        let other_psbt = other.0.lock().unwrap().clone();
1504        original_psbt.combine(other_psbt)?;
1505        Ok(Arc::new(Psbt(Mutex::new(original_psbt))))
1506    }
1507
1508    /// Finalizes the current PSBT and produces a result indicating
1509    ///
1510    /// whether the finalization was successful or not.
1511    pub fn finalize(&self) -> FinalizedPsbtResult {
1512        let curve = Secp256k1::verification_only();
1513        let finalized = self.0.lock().unwrap().clone().finalize(&curve);
1514        match finalized {
1515            Ok(psbt) => FinalizedPsbtResult {
1516                psbt: Arc::new(psbt.into()),
1517                could_finalize: true,
1518                errors: None,
1519            },
1520            Err((psbt, errors)) => {
1521                let errors = errors.into_iter().map(|e| e.into()).collect();
1522                FinalizedPsbtResult {
1523                    psbt: Arc::new(psbt.into()),
1524                    could_finalize: false,
1525                    errors: Some(errors),
1526                }
1527            }
1528        }
1529    }
1530
1531    /// Write the `Psbt` to a file. Note that the file must not yet exist.
1532    pub fn write_to_file(&self, path: String) -> Result<(), PsbtError> {
1533        let file = File::create_new(path)?;
1534        let mut writer = BufWriter::new(file);
1535        let psbt = self.0.lock().unwrap();
1536        psbt.serialize_to_writer(&mut writer)?;
1537        Ok(())
1538    }
1539
1540    /// Serializes the PSBT into a JSON string representation.
1541    pub fn json_serialize(&self) -> String {
1542        let psbt = self.0.lock().unwrap();
1543        serde_json::to_string(psbt.deref()).unwrap()
1544    }
1545
1546    /// Returns the spending utxo for this PSBT's input at `input_index`.
1547    pub fn spend_utxo(&self, input_index: u64) -> String {
1548        let psbt = self.0.lock().unwrap();
1549        let utxo = psbt.spend_utxo(input_index as usize).unwrap();
1550        serde_json::to_string(&utxo).unwrap()
1551    }
1552
1553    /// The corresponding key-value map for each input in the unsigned transaction.
1554    pub fn input(&self) -> Vec<Input> {
1555        let psbt = self.0.lock().unwrap();
1556        psbt.inputs.iter().map(|input| input.into()).collect()
1557    }
1558
1559    /// The corresponding key-value map for each output in the unsigned transaction.
1560    pub fn output(&self) -> Vec<Output> {
1561        let psbt = self.0.lock().unwrap();
1562        psbt.outputs.iter().map(|o| o.into()).collect()
1563    }
1564}
1565
1566impl From<BdkPsbt> for Psbt {
1567    fn from(psbt: BdkPsbt) -> Self {
1568        Psbt(Mutex::new(psbt))
1569    }
1570}
1571
1572impl Display for Psbt {
1573    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1574        write!(f, "{}", self.0.lock().unwrap())
1575    }
1576}
1577
1578#[derive(uniffi::Record)]
1579pub struct FinalizedPsbtResult {
1580    pub psbt: Arc<Psbt>,
1581    pub could_finalize: bool,
1582    pub errors: Option<Vec<PsbtFinalizeError>>,
1583}
1584
1585/// A transcation input.
1586#[derive(Debug, Clone, uniffi::Record)]
1587pub struct TxIn {
1588    /// A pointer to the previous output this input spends from.
1589    pub previous_output: OutPoint,
1590    /// The script corresponding to the `scriptPubKey`, empty in SegWit transactions.
1591    pub script_sig: Arc<Script>,
1592    /// https://bitcoin.stackexchange.com/questions/87372/what-does-the-sequence-in-a-transaction-input-mean
1593    pub sequence: u32,
1594    /// A proof for the script that authorizes the spend of the output.
1595    pub witness: Vec<Vec<u8>>,
1596}
1597
1598impl From<&BdkTxIn> for TxIn {
1599    fn from(tx_in: &BdkTxIn) -> Self {
1600        TxIn {
1601            previous_output: OutPoint {
1602                txid: Arc::new(Txid(tx_in.previous_output.txid)),
1603                vout: tx_in.previous_output.vout,
1604            },
1605            script_sig: Arc::new(Script(tx_in.script_sig.clone())),
1606            sequence: tx_in.sequence.0,
1607            witness: tx_in.witness.to_vec(),
1608        }
1609    }
1610}
1611
1612/// Bitcoin transaction output.
1613///
1614/// Defines new coins to be created as a result of the transaction,
1615/// along with spending conditions ("script", aka "output script"),
1616/// which an input spending it must satisfy.
1617///
1618/// An output that is not yet spent by an input is called Unspent Transaction Output ("UTXO").
1619#[derive(Debug, Clone, uniffi::Record)]
1620pub struct TxOut {
1621    /// The value of the output, in satoshis.
1622    pub value: Arc<Amount>,
1623    /// The script which must be satisfied for the output to be spent.
1624    pub script_pubkey: Arc<Script>,
1625}
1626
1627impl From<&BdkTxOut> for TxOut {
1628    fn from(tx_out: &BdkTxOut) -> Self {
1629        TxOut {
1630            value: Arc::new(Amount(tx_out.value)),
1631            script_pubkey: Arc::new(Script(tx_out.script_pubkey.clone())),
1632        }
1633    }
1634}
1635
1636impl From<BdkTxOut> for TxOut {
1637    fn from(tx_out: BdkTxOut) -> Self {
1638        Self {
1639            value: Arc::new(Amount(tx_out.value)),
1640            script_pubkey: Arc::new(Script(tx_out.script_pubkey)),
1641        }
1642    }
1643}
1644
1645impl From<TxOut> for BdkTxOut {
1646    fn from(tx_out: TxOut) -> Self {
1647        Self {
1648            value: tx_out.value.0,
1649            script_pubkey: tx_out.script_pubkey.0.clone(),
1650        }
1651    }
1652}
1653
1654/// A child number in a derivation path
1655#[derive(Copy, Clone, uniffi::Enum)]
1656pub enum ChildNumber {
1657    /// Non-hardened key
1658    Normal {
1659        /// Key index, within [0, 2^31 - 1]
1660        index: u32,
1661    },
1662    /// Hardened key
1663    Hardened {
1664        /// Key index, within [0, 2^31 - 1]
1665        index: u32,
1666    },
1667}
1668
1669impl From<BdkChildNumber> for ChildNumber {
1670    fn from(value: BdkChildNumber) -> Self {
1671        match value {
1672            BdkChildNumber::Normal { index } => ChildNumber::Normal { index },
1673            BdkChildNumber::Hardened { index } => ChildNumber::Hardened { index },
1674        }
1675    }
1676}
1677
1678impl TryFrom<ChildNumber> for BdkChildNumber {
1679    type Error = Bip32Error;
1680
1681    fn try_from(value: ChildNumber) -> Result<Self, Self::Error> {
1682        match value {
1683            ChildNumber::Normal { index } => {
1684                BdkChildNumber::from_normal_idx(index).map_err(Bip32Error::from)
1685            }
1686            ChildNumber::Hardened { index } => {
1687                BdkChildNumber::from_hardened_idx(index).map_err(Bip32Error::from)
1688            }
1689        }
1690    }
1691}
1692
1693/// A bitcoin Block hash
1694#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, std::hash::Hash, uniffi::Object)]
1695#[uniffi::export(Display, Eq, Hash, Ord)]
1696pub struct BlockHash(pub(crate) BitcoinBlockHash);
1697
1698impl_hash_like!(BlockHash, BitcoinBlockHash);
1699
1700/// A bitcoin transaction identifier
1701#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, std::hash::Hash, uniffi::Object)]
1702#[uniffi::export(Display, Eq, Hash, Ord)]
1703pub struct Txid(pub(crate) BitcoinTxid);
1704
1705impl_hash_like!(Txid, BitcoinTxid);
1706
1707/// A bitcoin transaction identifier, including witness data.
1708/// For transactions with no SegWit inputs, the `txid` will be equivalent to `wtxid`.
1709#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, std::hash::Hash, uniffi::Object)]
1710#[uniffi::export(Display, Eq, Hash, Ord)]
1711pub struct Wtxid(pub(crate) BitcoinWtxid);
1712
1713impl_hash_like!(Wtxid, BitcoinWtxid);
1714
1715/// A collision-proof unique identifier for a descriptor.
1716#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, std::hash::Hash, uniffi::Object)]
1717#[uniffi::export(Display, Eq, Hash, Ord)]
1718pub struct DescriptorId(pub(crate) BitcoinSha256Hash);
1719
1720impl_hash_like!(DescriptorId, BitcoinSha256Hash);
1721
1722/// The merkle root of the merkle tree corresponding to a block's transactions.
1723#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, std::hash::Hash, uniffi::Object)]
1724#[uniffi::export(Display, Eq, Hash, Ord)]
1725pub struct TxMerkleNode(pub(crate) BitcoinDoubleSha256Hash);
1726
1727impl_hash_like!(TxMerkleNode, BitcoinDoubleSha256Hash);
1728
1729/// Descriptor Type of the descriptor
1730#[uniffi::remote(Enum)]
1731pub enum DescriptorType {
1732    /// Bare descriptor(Contains the native P2pk)
1733    Bare,
1734    /// Pure Sh Descriptor. Does not contain nested Wsh/Wpkh
1735    Sh,
1736    /// Pkh Descriptor
1737    Pkh,
1738    /// Wpkh Descriptor
1739    Wpkh,
1740    /// Wsh
1741    Wsh,
1742    /// Sh Wrapped Wsh
1743    ShWsh,
1744    /// Sh wrapped Wpkh
1745    ShWpkh,
1746    /// Sh Sorted Multi
1747    ShSortedMulti,
1748    /// Wsh Sorted Multi
1749    WshSortedMulti,
1750    /// Sh Wsh Sorted Multi
1751    ShWshSortedMulti,
1752    /// Tr Descriptor
1753    Tr,
1754}