@@ -20,8 +20,6 @@ use bdk_wallet::bitcoin::io::Cursor;
2020use bdk_wallet:: bitcoin:: psbt:: Input as BdkInput ;
2121use bdk_wallet:: bitcoin:: psbt:: Output as BdkOutput ;
2222use bdk_wallet:: bitcoin:: secp256k1:: Secp256k1 ;
23- use std:: collections:: HashMap ;
24- use std:: convert:: TryFrom ;
2523
2624use bdk_wallet:: bitcoin:: bip32:: ChildNumber as BdkChildNumber ;
2725use bdk_wallet:: bitcoin:: taproot:: LeafNode as BdkLeafNode ;
@@ -42,6 +40,8 @@ use bdk_wallet::bitcoin::Wtxid as BitcoinWtxid;
4240use bdk_wallet:: miniscript:: psbt:: PsbtExt ;
4341use bdk_wallet:: serde_json;
4442
43+ use std:: collections:: HashMap ;
44+ use std:: convert:: TryFrom ;
4545use std:: fmt:: Display ;
4646use std:: fs:: File ;
4747use std:: io:: { BufReader , BufWriter } ;
@@ -692,6 +692,8 @@ pub struct Input {
692692 pub unknown : HashMap < Key , Vec < u8 > > ,
693693}
694694
695+ use crate :: error:: AddForeignUtxoError ;
696+
695697impl From < & BdkInput > for Input {
696698 fn from ( input : & BdkInput ) -> Self {
697699 Input {
@@ -832,6 +834,338 @@ impl From<&BdkInput> for Input {
832834 }
833835}
834836
837+ impl TryFrom < Input > for BdkInput {
838+ type Error = AddForeignUtxoError ;
839+
840+ fn try_from ( input : Input ) -> Result < Self , Self :: Error > {
841+ use bdk_wallet:: bitcoin:: ecdsa;
842+ use bdk_wallet:: bitcoin:: hashes:: Hash as HashTrait ;
843+ use bdk_wallet:: bitcoin:: key:: PublicKey as Secp256k1PublicKey ;
844+ use bdk_wallet:: bitcoin:: psbt:: PsbtSighashType ;
845+ use bdk_wallet:: bitcoin:: secp256k1:: XOnlyPublicKey ;
846+ use bdk_wallet:: bitcoin:: taproot:: {
847+ ControlBlock as BdkControlBlock , LeafVersion , TapLeafHash , TapNodeHash ,
848+ } ;
849+ use std:: str:: FromStr ;
850+
851+ let non_witness_utxo = input. non_witness_utxo . map ( |tx| tx. 0 . clone ( ) ) ;
852+
853+ let witness_utxo = input. witness_utxo . map ( |txout| txout. into ( ) ) ;
854+
855+ let partial_sigs = input
856+ . partial_sigs
857+ . into_iter ( )
858+ . map ( |( k, v) | {
859+ let pubkey = Secp256k1PublicKey :: from_str ( & k) . map_err ( |e| {
860+ AddForeignUtxoError :: InputConversionError {
861+ error_message : format ! ( "invalid public key in partial_sigs: {}" , e) ,
862+ }
863+ } ) ?;
864+ let sig = ecdsa:: Signature :: from_slice ( & v) . map_err ( |e| {
865+ AddForeignUtxoError :: InputConversionError {
866+ error_message : format ! ( "invalid signature in partial_sigs: {}" , e) ,
867+ }
868+ } ) ?;
869+ Ok ( ( pubkey, sig) )
870+ } )
871+ . collect :: < Result < std:: collections:: BTreeMap < _ , _ > , AddForeignUtxoError > > ( ) ?;
872+
873+ let sighash_type = input
874+ . sighash_type
875+ . map ( |s| {
876+ PsbtSighashType :: from_str ( & s) . map_err ( |e| {
877+ AddForeignUtxoError :: InputConversionError {
878+ error_message : format ! ( "invalid sighash type: {}" , e) ,
879+ }
880+ } )
881+ } )
882+ . transpose ( ) ?;
883+
884+ let redeem_script = input. redeem_script . map ( |s| s. 0 . clone ( ) ) ;
885+ let witness_script = input. witness_script . map ( |s| s. 0 . clone ( ) ) ;
886+
887+ let bip32_derivation = input
888+ . bip32_derivation
889+ . into_iter ( )
890+ . map ( |( k, v) | {
891+ use bdk_wallet:: bitcoin:: bip32:: { DerivationPath , Fingerprint } ;
892+ use bdk_wallet:: bitcoin:: secp256k1:: PublicKey as Secp256k1RawPublicKey ;
893+ let pubkey = Secp256k1RawPublicKey :: from_str ( & k) . map_err ( |e| {
894+ AddForeignUtxoError :: InputConversionError {
895+ error_message : format ! ( "invalid public key in bip32_derivation: {}" , e) ,
896+ }
897+ } ) ?;
898+ let fingerprint = Fingerprint :: from_str ( & v. fingerprint ) . map_err ( |e| {
899+ AddForeignUtxoError :: InputConversionError {
900+ error_message : format ! ( "invalid fingerprint: {}" , e) ,
901+ }
902+ } ) ?;
903+ let path: DerivationPath = v. path . 0 . clone ( ) ;
904+ Ok ( ( pubkey, ( fingerprint, path) ) )
905+ } )
906+ . collect :: < Result < std:: collections:: BTreeMap < _ , _ > , AddForeignUtxoError > > ( ) ?;
907+
908+ let final_script_sig = input. final_script_sig . map ( |s| s. 0 . clone ( ) ) ;
909+
910+ let final_script_witness = input. final_script_witness . map ( |w| {
911+ use bdk_wallet:: bitcoin:: Witness ;
912+ Witness :: from_slice ( & w)
913+ } ) ;
914+
915+ let ripemd160_preimages = input
916+ . ripemd160_preimages
917+ . into_iter ( )
918+ . map ( |( k, v) | {
919+ use bdk_wallet:: bitcoin:: hashes:: ripemd160;
920+ let hash = ripemd160:: Hash :: from_str ( & k) . map_err ( |e| {
921+ AddForeignUtxoError :: InputConversionError {
922+ error_message : format ! ( "invalid ripemd160 hash: {}" , e) ,
923+ }
924+ } ) ?;
925+ Ok ( ( hash, v) )
926+ } )
927+ . collect :: < Result < _ , AddForeignUtxoError > > ( ) ?;
928+
929+ let sha256_preimages = input
930+ . sha256_preimages
931+ . into_iter ( )
932+ . map ( |( k, v) | {
933+ use bdk_wallet:: bitcoin:: hashes:: sha256;
934+ let hash = sha256:: Hash :: from_str ( & k) . map_err ( |e| {
935+ AddForeignUtxoError :: InputConversionError {
936+ error_message : format ! ( "invalid sha256 hash: {}" , e) ,
937+ }
938+ } ) ?;
939+ Ok ( ( hash, v) )
940+ } )
941+ . collect :: < Result < _ , AddForeignUtxoError > > ( ) ?;
942+
943+ let hash160_preimages = input
944+ . hash160_preimages
945+ . into_iter ( )
946+ . map ( |( k, v) | {
947+ use bdk_wallet:: bitcoin:: hashes:: hash160;
948+ let hash = hash160:: Hash :: from_str ( & k) . map_err ( |e| {
949+ AddForeignUtxoError :: InputConversionError {
950+ error_message : format ! ( "invalid hash160: {}" , e) ,
951+ }
952+ } ) ?;
953+ Ok ( ( hash, v) )
954+ } )
955+ . collect :: < Result < _ , AddForeignUtxoError > > ( ) ?;
956+
957+ let hash256_preimages = input
958+ . hash256_preimages
959+ . into_iter ( )
960+ . map ( |( k, v) | {
961+ use bdk_wallet:: bitcoin:: hashes:: sha256d;
962+ let hash = sha256d:: Hash :: from_str ( & k) . map_err ( |e| {
963+ AddForeignUtxoError :: InputConversionError {
964+ error_message : format ! ( "invalid hash256: {}" , e) ,
965+ }
966+ } ) ?;
967+ Ok ( ( hash, v) )
968+ } )
969+ . collect :: < Result < _ , AddForeignUtxoError > > ( ) ?;
970+
971+ let tap_key_sig = input
972+ . tap_key_sig
973+ . map ( |s| {
974+ use bdk_wallet:: bitcoin:: taproot:: Signature ;
975+ Signature :: from_slice ( & s) . map_err ( |e| AddForeignUtxoError :: InputConversionError {
976+ error_message : format ! ( "invalid taproot signature: {}" , e) ,
977+ } )
978+ } )
979+ . transpose ( ) ?;
980+
981+ let tap_script_sigs = input
982+ . tap_script_sigs
983+ . into_iter ( )
984+ . map ( |( k, v) | {
985+ use bdk_wallet:: bitcoin:: taproot:: Signature ;
986+ let xonly = XOnlyPublicKey :: from_str ( & k. xonly_pubkey ) . map_err ( |e| {
987+ AddForeignUtxoError :: InputConversionError {
988+ error_message : format ! ( "invalid xonly pubkey: {}" , e) ,
989+ }
990+ } ) ?;
991+ let leaf_hash = TapLeafHash :: from_str ( & k. tap_leaf_hash ) . map_err ( |e| {
992+ AddForeignUtxoError :: InputConversionError {
993+ error_message : format ! ( "invalid tap leaf hash: {}" , e) ,
994+ }
995+ } ) ?;
996+ let sig = Signature :: from_slice ( & v) . map_err ( |e| {
997+ AddForeignUtxoError :: InputConversionError {
998+ error_message : format ! ( "invalid taproot script signature: {}" , e) ,
999+ }
1000+ } ) ?;
1001+ Ok ( ( ( xonly, leaf_hash) , sig) )
1002+ } )
1003+ . collect :: < Result < _ , AddForeignUtxoError > > ( ) ?;
1004+
1005+ let tap_scripts = input
1006+ . tap_scripts
1007+ . into_iter ( )
1008+ . map ( |( k, v) | {
1009+ use bdk_wallet:: bitcoin:: key:: XOnlyPublicKey as BdkXOnlyPublicKey ;
1010+ use bdk_wallet:: bitcoin:: taproot:: TapNodeHash ;
1011+
1012+ let internal_key = BdkXOnlyPublicKey :: from_slice ( & k. internal_key ) . map_err ( |e| {
1013+ AddForeignUtxoError :: InputConversionError {
1014+ error_message : format ! ( "invalid internal key: {}" , e) ,
1015+ }
1016+ } ) ?;
1017+
1018+ let output_key_parity = k. output_key_parity ;
1019+ let leaf_version_u8 = k. leaf_version ;
1020+
1021+ let merkle_branch: Vec < TapNodeHash > = k
1022+ . merkle_branch
1023+ . into_iter ( )
1024+ . map ( |h| {
1025+ TapNodeHash :: from_str ( & h) . map_err ( |e| {
1026+ AddForeignUtxoError :: InputConversionError {
1027+ error_message : format ! ( "invalid merkle branch hash: {}" , e) ,
1028+ }
1029+ } )
1030+ } )
1031+ . collect :: < Result < _ , AddForeignUtxoError > > ( ) ?;
1032+
1033+ let mut control_block_bytes = vec ! [ output_key_parity | leaf_version_u8] ;
1034+ control_block_bytes. extend_from_slice ( & internal_key. serialize ( ) ) ;
1035+ for hash in & merkle_branch {
1036+ control_block_bytes. extend_from_slice ( & hash. to_byte_array ( ) ) ;
1037+ }
1038+
1039+ let control_block = BdkControlBlock :: decode ( & control_block_bytes) . map_err ( |e| {
1040+ AddForeignUtxoError :: InputConversionError {
1041+ error_message : format ! ( "invalid control block: {}" , e) ,
1042+ }
1043+ } ) ?;
1044+
1045+ let leaf_version = LeafVersion :: from_consensus ( leaf_version_u8) . map_err ( |_| {
1046+ AddForeignUtxoError :: InputConversionError {
1047+ error_message : format ! ( "invalid leaf version: {}" , leaf_version_u8) ,
1048+ }
1049+ } ) ?;
1050+
1051+ Ok ( ( control_block, ( v. script . 0 . clone ( ) , leaf_version) ) )
1052+ } )
1053+ . collect :: < Result < _ , AddForeignUtxoError > > ( ) ?;
1054+
1055+ let tap_key_origins = input
1056+ . tap_key_origins
1057+ . into_iter ( )
1058+ . map ( |( k, v) | {
1059+ use bdk_wallet:: bitcoin:: bip32:: { DerivationPath , Fingerprint } ;
1060+
1061+ let xonly = XOnlyPublicKey :: from_str ( & k) . map_err ( |e| {
1062+ AddForeignUtxoError :: InputConversionError {
1063+ error_message : format ! ( "invalid xonly pubkey in tap_key_origins: {}" , e) ,
1064+ }
1065+ } ) ?;
1066+
1067+ let leaf_hashes: Vec < TapLeafHash > = v
1068+ . tap_leaf_hashes
1069+ . into_iter ( )
1070+ . map ( |h| {
1071+ TapLeafHash :: from_str ( & h) . map_err ( |e| {
1072+ AddForeignUtxoError :: InputConversionError {
1073+ error_message : format ! ( "invalid tap leaf hash: {}" , e) ,
1074+ }
1075+ } )
1076+ } )
1077+ . collect :: < Result < _ , AddForeignUtxoError > > ( ) ?;
1078+
1079+ let fingerprint =
1080+ Fingerprint :: from_str ( & v. key_source . fingerprint ) . map_err ( |e| {
1081+ AddForeignUtxoError :: InputConversionError {
1082+ error_message : format ! ( "invalid fingerprint in tap_key_origins: {}" , e) ,
1083+ }
1084+ } ) ?;
1085+
1086+ let path: DerivationPath = v. key_source . path . 0 . clone ( ) ;
1087+
1088+ Ok ( ( xonly, ( leaf_hashes, ( fingerprint, path) ) ) )
1089+ } )
1090+ . collect :: < Result < _ , AddForeignUtxoError > > ( ) ?;
1091+
1092+ let tap_internal_key = input
1093+ . tap_internal_key
1094+ . map ( |k| {
1095+ XOnlyPublicKey :: from_str ( & k) . map_err ( |e| {
1096+ AddForeignUtxoError :: InputConversionError {
1097+ error_message : format ! ( "invalid tap internal key: {}" , e) ,
1098+ }
1099+ } )
1100+ } )
1101+ . transpose ( ) ?;
1102+
1103+ let tap_merkle_root = input
1104+ . tap_merkle_root
1105+ . map ( |k| {
1106+ TapNodeHash :: from_str ( & k) . map_err ( |e| AddForeignUtxoError :: InputConversionError {
1107+ error_message : format ! ( "invalid tap merkle root: {}" , e) ,
1108+ } )
1109+ } )
1110+ . transpose ( ) ?;
1111+
1112+ let proprietary = input
1113+ . proprietary
1114+ . into_iter ( )
1115+ . map ( |( k, v) | {
1116+ use bdk_wallet:: bitcoin:: psbt:: raw:: ProprietaryKey as BdkProprietaryKey ;
1117+ (
1118+ BdkProprietaryKey {
1119+ prefix : k. prefix ,
1120+ subtype : k. subtype ,
1121+ key : k. key ,
1122+ } ,
1123+ v,
1124+ )
1125+ } )
1126+ . collect ( ) ;
1127+
1128+ let unknown = input
1129+ . unknown
1130+ . into_iter ( )
1131+ . map ( |( k, v) | {
1132+ use bdk_wallet:: bitcoin:: psbt:: raw:: Key as BdkKey ;
1133+ (
1134+ BdkKey {
1135+ type_value : k. type_value ,
1136+ key : k. key ,
1137+ } ,
1138+ v,
1139+ )
1140+ } )
1141+ . collect ( ) ;
1142+
1143+ Ok ( BdkInput {
1144+ non_witness_utxo,
1145+ witness_utxo,
1146+ partial_sigs,
1147+ sighash_type,
1148+ redeem_script,
1149+ witness_script,
1150+ bip32_derivation,
1151+ final_script_sig,
1152+ final_script_witness,
1153+ ripemd160_preimages,
1154+ sha256_preimages,
1155+ hash160_preimages,
1156+ hash256_preimages,
1157+ tap_key_sig,
1158+ tap_script_sigs,
1159+ tap_scripts,
1160+ tap_key_origins,
1161+ tap_internal_key,
1162+ tap_merkle_root,
1163+ proprietary,
1164+ unknown,
1165+ } )
1166+ }
1167+ }
1168+
8351169/// Store information about taproot leaf node.
8361170#[ derive( Debug , uniffi:: Object ) ]
8371171#[ uniffi:: export( Display ) ]
0 commit comments