@@ -19,7 +19,9 @@ use bdk_wallet::bitcoin::hashes::sha256::Hash as BitcoinSha256Hash;
1919use bdk_wallet:: bitcoin:: hashes:: sha256d:: Hash as BitcoinDoubleSha256Hash ;
2020use bdk_wallet:: bitcoin:: io:: Cursor ;
2121use bdk_wallet:: bitcoin:: psbt:: Input as BdkInput ;
22+ use bdk_wallet:: bitcoin:: psbt:: Output as BdkOutput ;
2223use bdk_wallet:: bitcoin:: secp256k1:: Secp256k1 ;
24+ use bdk_wallet:: bitcoin:: taproot:: TapLeaf as BdkTapLeaf ;
2325use bdk_wallet:: bitcoin:: Amount as BdkAmount ;
2426use bdk_wallet:: bitcoin:: BlockHash as BitcoinBlockHash ;
2527use bdk_wallet:: bitcoin:: FeeRate as BdkFeeRate ;
@@ -767,6 +769,172 @@ impl From<&BdkInput> for Input {
767769 }
768770}
769771
772+ #[ derive( Clone , Debug , uniffi:: Enum ) ]
773+ pub enum TapLeaf {
774+ /// A known script
775+ Script ,
776+ /// Hidden node
777+ Hidden ,
778+ }
779+
780+ #[ derive( Clone , Debug , uniffi:: Record ) ]
781+ pub struct LeafNode {
782+ /// The leaf type (script or hidden)
783+ pub leaf_type : TapLeaf ,
784+ /// The script if this is a Script leaf (None if Hidden)
785+ pub script : Option < Arc < Script > > ,
786+ /// The version if this is a Script leaf (None if Hidden)
787+ pub version : Option < u8 > ,
788+ /// The hash if this is a Hidden leaf (None if Script)
789+ pub hash : Option < String > ,
790+ /// The merkle proof (hashing partners) to get this node.
791+ pub merkle_branch : Vec < String > ,
792+ }
793+
794+ #[ derive( Clone , Debug , uniffi:: Record ) ]
795+ pub struct TapTree {
796+ /// Merkle hash for this node.
797+ pub hash : String ,
798+ /// Tracks information on hidden nodes below this node.
799+ pub has_hidden_nodes : bool ,
800+ /// Information about leaves inside this node.
801+ pub leaves : Vec < LeafNode > ,
802+ }
803+
804+ #[ derive( Clone , Debug , uniffi:: Record ) ]
805+ pub struct Output {
806+ /// The redeem script for this output.
807+ pub redeem_script : Option < Arc < Script > > ,
808+ /// The witness script for this output.
809+ pub witness_script : Option < Arc < Script > > ,
810+ /// Map of public keys needed to spend this output to their corresponding
811+ /// master key fingerprints and derivation paths.
812+ pub bip32_derivation : HashMap < String , KeySource > ,
813+ /// Taproot Internal key.
814+ pub tap_internal_key : Option < String > ,
815+ /// Taproot Output tree (structured record).
816+ pub tap_tree : Option < TapTree > ,
817+ /// Map of tap root x only keys to origin info and leaf hashes contained in it.
818+ pub tap_key_origins : HashMap < String , TapKeyOrigin > ,
819+ /// Proprietary key-value pairs for this output.
820+ pub proprietary : HashMap < ProprietaryKey , Vec < u8 > > ,
821+ /// Unknown key-value pairs for this output.
822+ pub unknown : HashMap < Key , Vec < u8 > > ,
823+ }
824+
825+ impl From < & BdkOutput > for Output {
826+ fn from ( output : & BdkOutput ) -> Self {
827+ Output {
828+ redeem_script : output
829+ . redeem_script
830+ . as_ref ( )
831+ . map ( |s| Arc :: new ( Script ( s. clone ( ) ) ) ) ,
832+ witness_script : output
833+ . witness_script
834+ . as_ref ( )
835+ . map ( |s| Arc :: new ( Script ( s. clone ( ) ) ) ) ,
836+ bip32_derivation : output
837+ . bip32_derivation
838+ . iter ( )
839+ . map ( |( pk, ( fingerprint, deriv_path) ) | {
840+ (
841+ pk. to_string ( ) ,
842+ KeySource {
843+ fingerprint : fingerprint. to_string ( ) ,
844+ path : Arc :: new ( deriv_path. clone ( ) . into ( ) ) ,
845+ } ,
846+ )
847+ } )
848+ . collect ( ) ,
849+ tap_internal_key : output. tap_internal_key . as_ref ( ) . map ( |k| k. to_string ( ) ) ,
850+ tap_tree : output. tap_tree . as_ref ( ) . map ( |t| {
851+ let node_info = t. node_info ( ) ;
852+ let mut has_hidden_nodes = false ;
853+ let leaves: Vec < LeafNode > = node_info
854+ . leaf_nodes ( )
855+ . map ( |leaf_node| {
856+ let ( leaf_type, script, version, hash) = match leaf_node. leaf ( ) {
857+ BdkTapLeaf :: Script ( script, ver) => (
858+ TapLeaf :: Script ,
859+ Some ( Arc :: new ( Script ( script. clone ( ) ) ) ) ,
860+ Some ( ver. to_consensus ( ) ) ,
861+ None ,
862+ ) ,
863+ BdkTapLeaf :: Hidden ( hash) => {
864+ has_hidden_nodes = true ;
865+ ( TapLeaf :: Hidden , None , None , Some ( hash. to_string ( ) ) )
866+ }
867+ } ;
868+
869+ LeafNode {
870+ leaf_type,
871+ script,
872+ version,
873+ hash,
874+ merkle_branch : leaf_node
875+ . merkle_branch ( )
876+ . iter ( )
877+ . map ( |h| h. to_string ( ) )
878+ . collect ( ) ,
879+ }
880+ } )
881+ . collect ( ) ;
882+
883+ TapTree {
884+ hash : node_info. node_hash ( ) . to_string ( ) ,
885+ has_hidden_nodes,
886+ leaves,
887+ }
888+ } ) ,
889+ tap_key_origins : output
890+ . tap_key_origins
891+ . iter ( )
892+ . map ( |( k, v) | {
893+ let key = k. to_string ( ) ;
894+ let value = TapKeyOrigin {
895+ tap_leaf_hashes : v. 0 . iter ( ) . map ( |h| h. to_string ( ) ) . collect ( ) ,
896+ key_source : KeySource {
897+ // Unnecessary spaces being added by fmt. We use #[rustfmt::skip] to avoid them for now.
898+ #[ rustfmt:: skip]
899+ fingerprint : v. 1 . 0 . to_string ( ) ,
900+ #[ rustfmt:: skip]
901+ path : Arc :: new ( v. 1 . 1 . clone ( ) . into ( ) ) ,
902+ } ,
903+ } ;
904+ ( key, value)
905+ } )
906+ . collect ( ) ,
907+ proprietary : output
908+ . proprietary
909+ . iter ( )
910+ . map ( |( k, v) | {
911+ (
912+ ProprietaryKey {
913+ prefix : k. prefix . clone ( ) ,
914+ subtype : k. subtype ,
915+ key : k. key . clone ( ) ,
916+ } ,
917+ v. to_vec ( ) ,
918+ )
919+ } )
920+ . collect ( ) ,
921+ unknown : output
922+ . unknown
923+ . iter ( )
924+ . map ( |( k, v) | {
925+ (
926+ Key {
927+ key : k. key . clone ( ) ,
928+ type_value : k. type_value ,
929+ } ,
930+ v. to_vec ( ) ,
931+ )
932+ } )
933+ . collect ( ) ,
934+ }
935+ }
936+ }
937+
770938/// A Partially Signed Transaction.
771939#[ derive( uniffi:: Object ) ]
772940pub struct Psbt ( pub ( crate ) Mutex < BdkPsbt > ) ;
@@ -898,6 +1066,12 @@ impl Psbt {
8981066 let psbt = self . 0 . lock ( ) . unwrap ( ) ;
8991067 psbt. inputs . iter ( ) . map ( |input| input. into ( ) ) . collect ( )
9001068 }
1069+
1070+ /// The corresponding key-value map for each output in the unsigned transaction.
1071+ pub fn output ( & self ) -> Vec < Output > {
1072+ let psbt = self . 0 . lock ( ) . unwrap ( ) ;
1073+ psbt. outputs . iter ( ) . map ( |o| o. into ( ) ) . collect ( )
1074+ }
9011075}
9021076
9031077impl From < BdkPsbt > for Psbt {
0 commit comments