@@ -42,6 +42,59 @@ use crate::init_logger;
4242use ffi_helpers:: task:: TaskHandle ;
4343use serde_json:: json as serde_json_json;
4444
45+ /// Wrapper struct for wallet data to ensure consistent serialization.
46+ /// This replaces the tuple `(i64, Option<SecretKey>)` which can have
47+ /// inconsistent JSON serialization behavior across epic versions.
48+ /// SecretKey is serialized as a hex string to avoid version-specific serialization issues.
49+ #[ derive( serde:: Serialize , serde:: Deserialize ) ]
50+ struct WalletData {
51+ wallet_ptr : i64 ,
52+ #[ serde(
53+ serialize_with = "serialize_secret_key" ,
54+ deserialize_with = "deserialize_secret_key"
55+ ) ]
56+ keychain_mask : Option < SecretKey > ,
57+ }
58+
59+ fn serialize_secret_key < S > (
60+ key : & Option < SecretKey > ,
61+ serializer : S ,
62+ ) -> Result < S :: Ok , S :: Error >
63+ where
64+ S : serde:: Serializer ,
65+ {
66+ use epic_util:: secp:: constants:: SECRET_KEY_SIZE ;
67+ match key {
68+ Some ( k) => {
69+ let bytes = & k. 0 [ ..SECRET_KEY_SIZE ] ;
70+ let hex_string = hex:: encode ( bytes) ;
71+ serializer. serialize_some ( & hex_string)
72+ }
73+ None => serializer. serialize_none ( ) ,
74+ }
75+ }
76+
77+ fn deserialize_secret_key < ' de , D > (
78+ deserializer : D ,
79+ ) -> Result < Option < SecretKey > , D :: Error >
80+ where
81+ D : serde:: Deserializer < ' de > ,
82+ {
83+ use serde:: Deserialize ;
84+ use serde:: de:: Error ;
85+ use epic_util:: secp:: Secp256k1 ;
86+
87+ let opt: Option < String > = Option :: deserialize ( deserializer) ?;
88+ match opt {
89+ Some ( hex_string) => {
90+ let bytes = hex:: decode ( & hex_string) . map_err ( D :: Error :: custom) ?;
91+ let secp = Secp256k1 :: new ( ) ;
92+ SecretKey :: from_slice ( & secp, & bytes) . map_err ( D :: Error :: custom) . map ( Some )
93+ }
94+ None => Ok ( None ) ,
95+ }
96+ }
97+
4598fn is_error_str ( s : & str ) -> bool {
4699 s. starts_with ( "Error " ) || s. to_uppercase ( ) . contains ( "ERROR" )
47100}
@@ -352,8 +405,12 @@ fn _open_wallet(
352405 let wlt = res. 0 ;
353406 let sek_key = res. 1 ;
354407 let wallet_int = Box :: into_raw ( Box :: new ( wlt) ) as i64 ;
355- let wallet_data = ( wallet_int, sek_key) ;
408+ let wallet_data = WalletData {
409+ wallet_ptr : wallet_int,
410+ keychain_mask : sek_key,
411+ } ;
356412 let wallet_ptr = serde_json:: to_string ( & wallet_data) . unwrap ( ) ;
413+ println ! ( "DEBUG: Serialized wallet data: {}" , wallet_ptr) ;
357414 result. push_str ( & wallet_ptr) ;
358415 }
359416 Err ( err) => {
@@ -386,9 +443,9 @@ pub unsafe extern "C" fn rust_wallet_balances(
386443 } ;
387444
388445 let wallet_data = wallet_ptr. to_str ( ) . unwrap ( ) ;
389- let tuple_wallet_data : ( i64 , Option < SecretKey > ) = serde_json:: from_str ( wallet_data) . unwrap ( ) ;
390- let wlt = tuple_wallet_data . 0 ;
391- let sek_key = tuple_wallet_data . 1 ;
446+ let deserialized_wallet_data : WalletData = serde_json:: from_str ( wallet_data) . unwrap ( ) ;
447+ let wlt = deserialized_wallet_data . wallet_ptr ;
448+ let sek_key = deserialized_wallet_data . keychain_mask ;
392449
393450 ensure_wallet ! ( wlt, wallet) ;
394451
@@ -532,9 +589,9 @@ pub unsafe extern "C" fn rust_wallet_scan_outputs(
532589 let number_of_blocks: u64 = c_number_of_blocks. to_str ( ) . unwrap ( ) . to_string ( ) . parse ( ) . unwrap ( ) ;
533590
534591 let wallet_data = wallet_ptr. to_str ( ) . unwrap ( ) ;
535- let tuple_wallet_data : ( i64 , Option < SecretKey > ) = serde_json:: from_str ( wallet_data) . unwrap ( ) ;
536- let wlt = tuple_wallet_data . 0 ;
537- let sek_key = tuple_wallet_data . 1 ;
592+ let deserialized_wallet_data : WalletData = serde_json:: from_str ( wallet_data) . unwrap ( ) ;
593+ let wlt = deserialized_wallet_data . wallet_ptr ;
594+ let sek_key = deserialized_wallet_data . keychain_mask ;
538595
539596 ensure_wallet ! ( wlt, wallet) ;
540597
@@ -616,7 +673,7 @@ pub unsafe extern "C" fn rust_create_tx(
616673 let key_index: u32 = CStr :: from_ptr ( secret_key_index) . to_str ( ) . unwrap ( ) . parse ( ) . unwrap ( ) ;
617674 let epicbox_config = CStr :: from_ptr ( epicbox_config) . to_str ( ) . unwrap ( ) ;
618675
619- let tuple_wallet_data : ( i64 , Option < SecretKey > ) = serde_json:: from_str ( wallet_data) . unwrap ( ) ;
676+ let deserialized_wallet_data : WalletData = serde_json:: from_str ( wallet_data) . unwrap ( ) ;
620677
621678 let listen = Listener {
622679 wallet_ptr_str : wallet_data. to_string ( ) ,
@@ -627,8 +684,8 @@ pub unsafe extern "C" fn rust_create_tx(
627684 listener_cancel ( handle) ;
628685 debug ! ( "LISTENER CANCELLED IS {}" , listener_cancelled( handle) ) ;
629686
630- let wlt = tuple_wallet_data . 0 ;
631- let sek_key = tuple_wallet_data . 1 ;
687+ let wlt = deserialized_wallet_data . wallet_ptr ;
688+ let sek_key = deserialized_wallet_data . keychain_mask ;
632689
633690 ensure_wallet ! ( wlt, wallet) ;
634691
@@ -714,9 +771,9 @@ pub unsafe extern "C" fn rust_txs_get(
714771 } ;
715772
716773 let wallet_data = c_wallet. to_str ( ) . unwrap ( ) ;
717- let tuple_wallet_data : ( i64 , Option < SecretKey > ) = serde_json:: from_str ( wallet_data) . unwrap ( ) ;
718- let wlt = tuple_wallet_data . 0 ;
719- let sek_key = tuple_wallet_data . 1 ;
774+ let deserialized_wallet_data : WalletData = serde_json:: from_str ( wallet_data) . unwrap ( ) ;
775+ let wlt = deserialized_wallet_data . wallet_ptr ;
776+ let sek_key = deserialized_wallet_data . keychain_mask ;
720777
721778 ensure_wallet ! ( wlt, wallet) ;
722779
@@ -776,9 +833,9 @@ pub unsafe extern "C" fn rust_tx_cancel(
776833 let uuid = Uuid :: parse_str ( tx_id) . map_err ( |e| EpicWalletControllerError :: GenericError ( e. to_string ( ) ) ) . unwrap ( ) ;
777834
778835 let wallet_data = wallet_ptr. to_str ( ) . unwrap ( ) ;
779- let tuple_wallet_data : ( i64 , Option < SecretKey > ) = serde_json:: from_str ( wallet_data) . unwrap ( ) ;
780- let wlt = tuple_wallet_data . 0 ;
781- let sek_key = tuple_wallet_data . 1 ;
836+ let deserialized_wallet_data : WalletData = serde_json:: from_str ( wallet_data) . unwrap ( ) ;
837+ let wlt = deserialized_wallet_data . wallet_ptr ;
838+ let sek_key = deserialized_wallet_data . keychain_mask ;
782839
783840 ensure_wallet ! ( wlt, wallet) ;
784841
@@ -933,9 +990,9 @@ pub unsafe extern "C" fn rust_tx_send_http(
933990 let str_address = c_address. to_str ( ) . unwrap ( ) ;
934991
935992 let wallet_data = c_wallet. to_str ( ) . unwrap ( ) ;
936- let tuple_wallet_data : ( i64 , Option < SecretKey > ) = serde_json:: from_str ( wallet_data) . unwrap ( ) ;
937- let wlt = tuple_wallet_data . 0 ;
938- let sek_key = tuple_wallet_data . 1 ;
993+ let deserialized_wallet_data : WalletData = serde_json:: from_str ( wallet_data) . unwrap ( ) ;
994+ let wlt = deserialized_wallet_data . wallet_ptr ;
995+ let sek_key = deserialized_wallet_data . keychain_mask ;
939996 ensure_wallet ! ( wlt, wallet) ;
940997
941998 let result = match _tx_send_http (
@@ -1010,9 +1067,9 @@ pub unsafe extern "C" fn rust_get_wallet_address(
10101067 let index: u32 = index. to_str ( ) . unwrap ( ) . to_string ( ) . parse ( ) . unwrap ( ) ;
10111068
10121069 let wallet_data = wallet_ptr. to_str ( ) . unwrap ( ) ;
1013- let tuple_wallet_data : ( i64 , Option < SecretKey > ) = serde_json:: from_str ( wallet_data) . unwrap ( ) ;
1014- let wlt = tuple_wallet_data . 0 ;
1015- let sek_key = tuple_wallet_data . 1 ;
1070+ let deserialized_wallet_data : WalletData = serde_json:: from_str ( wallet_data) . unwrap ( ) ;
1071+ let wlt = deserialized_wallet_data . wallet_ptr ;
1072+ let sek_key = deserialized_wallet_data . keychain_mask ;
10161073
10171074 ensure_wallet ! ( wlt, wallet) ;
10181075 let result = match _get_wallet_address (
@@ -1098,9 +1155,9 @@ pub unsafe extern "C" fn rust_get_tx_fees(
10981155 let amount: u64 = amount. to_str ( ) . unwrap ( ) . to_string ( ) . parse ( ) . unwrap ( ) ;
10991156
11001157 let wallet_data = wallet_ptr. to_str ( ) . unwrap ( ) ;
1101- let tuple_wallet_data : ( i64 , Option < SecretKey > ) = serde_json:: from_str ( wallet_data) . unwrap ( ) ;
1102- let wlt = tuple_wallet_data . 0 ;
1103- let sek_key = tuple_wallet_data . 1 ;
1158+ let deserialized_wallet_data : WalletData = serde_json:: from_str ( wallet_data) . unwrap ( ) ;
1159+ let wlt = deserialized_wallet_data . wallet_ptr ;
1160+ let sek_key = deserialized_wallet_data . keychain_mask ;
11041161
11051162 ensure_wallet ! ( wlt, wallet) ;
11061163
0 commit comments