@@ -19,6 +19,7 @@ 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 ;
2324use bdk_wallet:: bitcoin:: Amount as BdkAmount ;
2425use bdk_wallet:: bitcoin:: BlockHash as BitcoinBlockHash ;
@@ -767,6 +768,183 @@ impl From<&BdkInput> for Input {
767768 }
768769}
769770
771+ #[ derive( Clone , Debug , uniffi:: Enum ) ]
772+ pub enum TapLeaf {
773+ /// A known script
774+ Script ,
775+ /// Hidden node
776+ Hidden ,
777+ }
778+
779+ #[ derive( Clone , Debug , uniffi:: Record ) ]
780+ pub struct TapLeafInfo {
781+ /// Type of leaf
782+ pub leaf_type : TapLeaf ,
783+ /// The script if this is a Script leaf
784+ pub script : Option < Arc < Script > > ,
785+ /// The version if this is a Script leaf
786+ pub version : Option < u8 > ,
787+ /// The hash if this is a Hidden leaf
788+ pub hash : Option < String > ,
789+ }
790+
791+ #[ derive( Clone , Debug , uniffi:: Record ) ]
792+ pub struct LeafNode {
793+ /// The tap leaf info (script or hidden)
794+ pub leaf : TapLeafInfo ,
795+ /// The merkle proof (hashing partners) to get this node as hex strings
796+ pub merkle_branch : Vec < String > ,
797+ }
798+
799+ #[ derive( Clone , Debug , uniffi:: Record ) ]
800+ pub struct TapTree {
801+ /// TapTree merkle root (TapNodeHash) as hex string
802+ pub hash : String ,
803+ /// Whether the tree contains hidden nodes
804+ pub has_hidden_nodes : bool ,
805+ /// Leaf nodes in this tree
806+ pub leaves : Vec < LeafNode > ,
807+ }
808+
809+ #[ derive( Clone , Debug , uniffi:: Record ) ]
810+ pub struct Output {
811+ /// The redeem script for this output.
812+ pub redeem_script : Option < Arc < Script > > ,
813+ /// The witness script for this output.
814+ pub witness_script : Option < Arc < Script > > ,
815+ /// Map of public keys needed to spend this output to their corresponding
816+ /// master key fingerprints and derivation paths.
817+ pub bip32_derivation : HashMap < String , KeySource > ,
818+ /// Taproot Internal key.
819+ pub tap_internal_key : Option < String > ,
820+ /// Taproot Output tree (structured record).
821+ pub tap_tree : Option < TapTree > ,
822+ /// Map of tap root x only keys to origin info and leaf hashes contained in it.
823+ pub tap_key_origins : HashMap < String , TapKeyOrigin > ,
824+ /// Proprietary key-value pairs for this output.
825+ pub proprietary : HashMap < ProprietaryKey , Vec < u8 > > ,
826+ /// Unknown key-value pairs for this output.
827+ pub unknown : HashMap < Key , Vec < u8 > > ,
828+ }
829+
830+ impl From < & BdkOutput > for Output {
831+ fn from ( output : & BdkOutput ) -> Self {
832+ Output {
833+ redeem_script : output
834+ . redeem_script
835+ . as_ref ( )
836+ . map ( |s| Arc :: new ( Script ( s. clone ( ) ) ) ) ,
837+ witness_script : output
838+ . witness_script
839+ . as_ref ( )
840+ . map ( |s| Arc :: new ( Script ( s. clone ( ) ) ) ) ,
841+ bip32_derivation : output
842+ . bip32_derivation
843+ . iter ( )
844+ . map ( |( pk, ( fingerprint, deriv_path) ) | {
845+ (
846+ pk. to_string ( ) ,
847+ KeySource {
848+ fingerprint : fingerprint. to_string ( ) ,
849+ path : Arc :: new ( deriv_path. clone ( ) . into ( ) ) ,
850+ } ,
851+ )
852+ } )
853+ . collect ( ) ,
854+ tap_internal_key : output. tap_internal_key . as_ref ( ) . map ( |k| k. to_string ( ) ) ,
855+ tap_tree : output. tap_tree . as_ref ( ) . map ( |t| {
856+ let node_info = t. node_info ( ) ;
857+ let leaves = node_info
858+ . leaf_nodes ( )
859+ . map ( |leaf_node| {
860+ let ( leaf_type, script, version, hash) = match leaf_node. leaf ( ) {
861+ bdk_wallet:: bitcoin:: taproot:: TapLeaf :: Script ( script, ver) => {
862+ ( TapLeaf :: Script ,
863+ Some ( Arc :: new ( Script ( script. clone ( ) ) ) ) ,
864+ Some ( ver. to_consensus ( ) ) ,
865+ None )
866+ }
867+ bdk_wallet:: bitcoin:: taproot:: TapLeaf :: Hidden ( hash) => {
868+ ( TapLeaf :: Hidden ,
869+ None ,
870+ None ,
871+ Some ( hash. to_string ( ) ) )
872+ }
873+ } ;
874+
875+ let leaf = TapLeafInfo {
876+ leaf_type,
877+ script,
878+ version,
879+ hash,
880+ } ;
881+
882+ LeafNode {
883+ leaf,
884+ merkle_branch : leaf_node
885+ . merkle_branch ( )
886+ . iter ( )
887+ . map ( |h| h. to_string ( ) )
888+ . collect ( ) ,
889+ }
890+ } )
891+ . collect ( ) ;
892+
893+ TapTree {
894+ hash : node_info. node_hash ( ) . to_string ( ) ,
895+ has_hidden_nodes : false ,
896+ leaves,
897+ }
898+ } ) ,
899+ tap_key_origins : output
900+ . tap_key_origins
901+ . iter ( )
902+ . map ( |( k, v) | {
903+ let key = k. to_string ( ) ;
904+ let value = TapKeyOrigin {
905+ tap_leaf_hashes : v. 0 . iter ( ) . map ( |h| h. to_string ( ) ) . collect ( ) ,
906+ key_source : KeySource {
907+ // Unnecessary spaces being added by fmt. We use #[rustfmt::skip] to avoid them for now.
908+ #[ rustfmt:: skip]
909+ fingerprint : v. 1 . 0 . to_string ( ) ,
910+ #[ rustfmt:: skip]
911+ path : Arc :: new ( v. 1 . 1 . clone ( ) . into ( ) ) ,
912+ } ,
913+ } ;
914+ ( key, value)
915+ } )
916+ . collect ( ) ,
917+ proprietary : output
918+ . proprietary
919+ . iter ( )
920+ . map ( |( k, v) | {
921+ (
922+ ProprietaryKey {
923+ prefix : k. prefix . clone ( ) ,
924+ subtype : k. subtype ,
925+ key : k. key . clone ( ) ,
926+ } ,
927+ v. to_vec ( ) ,
928+ )
929+ } )
930+ . collect ( ) ,
931+ unknown : output
932+ . unknown
933+ . iter ( )
934+ . map ( |( k, v) | {
935+ (
936+ Key {
937+ key : k. key . clone ( ) ,
938+ type_value : k. type_value ,
939+ } ,
940+ v. to_vec ( ) ,
941+ )
942+ } )
943+ . collect ( ) ,
944+ }
945+ }
946+ }
947+
770948/// A Partially Signed Transaction.
771949#[ derive( uniffi:: Object ) ]
772950pub struct Psbt ( pub ( crate ) Mutex < BdkPsbt > ) ;
@@ -898,6 +1076,12 @@ impl Psbt {
8981076 let psbt = self . 0 . lock ( ) . unwrap ( ) ;
8991077 psbt. inputs . iter ( ) . map ( |input| input. into ( ) ) . collect ( )
9001078 }
1079+
1080+ /// The corresponding key-value map for each output in the unsigned transaction.
1081+ pub fn output ( & self ) -> Vec < Output > {
1082+ let psbt = self . 0 . lock ( ) . unwrap ( ) ;
1083+ psbt. outputs . iter ( ) . map ( |o| o. into ( ) ) . collect ( )
1084+ }
9011085}
9021086
9031087impl From < BdkPsbt > for Psbt {
0 commit comments