@@ -30,7 +30,7 @@ use namada_sdk::ibc::core::host::types::identifiers::{ChannelId, PortId};
3030use namada_sdk:: io:: { Client , NamadaIo } ;
3131use namada_sdk:: key:: { common, ed25519, RefTo , SigScheme } ;
3232use namada_sdk:: masp:: shielded_wallet:: ShieldedApi ;
33- use namada_sdk:: masp:: ShieldedContext ;
33+ use namada_sdk:: masp:: { Conversions , ShieldedContext , SpentNotesTracker } ;
3434use namada_sdk:: masp_primitives:: sapling:: ViewingKey ;
3535use namada_sdk:: masp_primitives:: transaction:: components:: amount:: I128Sum ;
3636use namada_sdk:: masp_primitives:: transaction:: TxId ;
@@ -691,9 +691,21 @@ impl Sdk {
691691 }
692692 } ;
693693
694+ let masp_section = tx
695+ . sections
696+ . iter ( )
697+ . find_map ( |section| section. masp_tx ( ) )
698+ . ok_or_err_msg ( "Could not find masp_tx section" ) ?;
699+
700+ self . namada
701+ . shielded_mut ( )
702+ . await
703+ . pre_cache_transaction ( & masp_section)
704+ . await
705+ . map_err ( |e| JsError :: new ( & e. to_string ( ) ) ) ?;
706+
694707 self . serialize_tx_result ( tx, wrapper_tx_msg, signing_data, Some ( masp_signing_data) )
695708 }
696-
697709 pub async fn build_unshielding_transfer (
698710 & self ,
699711 unshielding_transfer_msg : & [ u8 ] ,
@@ -1165,6 +1177,95 @@ impl Sdk {
11651177 to_js_result ( reward)
11661178 }
11671179
1180+ pub async fn query_notes_to_spend (
1181+ & self ,
1182+ owner : String ,
1183+ chain_id : String ,
1184+ ) -> Result < JsValue , JsError > {
1185+ let xvk = ExtendedViewingKey :: from_str ( & owner) ?;
1186+ let viewing_key = ExtendedFullViewingKey :: from ( xvk) . fvk . vk ;
1187+
1188+ let mut shielded: ShieldedContext < masp:: JSShieldedUtils > = ShieldedContext :: default ( ) ;
1189+ shielded. utils . chain_id = chain_id. clone ( ) ;
1190+ // TODO: pass handler
1191+ shielded. try_load ( async |_| { } ) . await ;
1192+
1193+ let res = shielded
1194+ . exchange_notes (
1195+ & self . namada ,
1196+ & mut SpentNotesTracker :: new ( ) ,
1197+ & viewing_key,
1198+ & mut Conversions :: new ( ) ,
1199+ )
1200+ . await
1201+ . map_err ( |e| JsError :: new ( & e. to_string ( ) ) ) ?;
1202+
1203+ let values = res. values ( ) . collect :: < Vec < _ > > ( ) ;
1204+
1205+ let mut final_res: HashMap < Address , Vec < ( Amount , Option < Amount > ) > > = HashMap :: new ( ) ;
1206+
1207+ for ( _, _, _, value) in values. iter ( ) {
1208+ let mut res: HashMap < Address , Amount > = HashMap :: new ( ) ;
1209+
1210+ for ( ( digit, address) , val) in value. components ( ) {
1211+ if res. contains_key ( address) {
1212+ let existing = res
1213+ . get ( address)
1214+ . ok_or ( JsError :: new ( "Expected to find map entry" ) ) ?;
1215+ let new_amount =
1216+ existing
1217+ . checked_add ( Amount :: from_masp_denominated_i128 ( * val, * digit) . ok_or (
1218+ JsError :: new ( "Cannot create amount from masp denominated" ) ,
1219+ ) ?)
1220+ . ok_or ( JsError :: new ( "Overflow when summing amounts" ) ) ?;
1221+
1222+ res. insert ( address. clone ( ) , new_amount) ;
1223+ } else {
1224+ res. insert (
1225+ address. clone ( ) ,
1226+ Amount :: from_masp_denominated_i128 ( * val, * digit) . unwrap ( ) ,
1227+ ) ;
1228+ }
1229+ }
1230+
1231+ let note = res
1232+ . get_index ( 0 )
1233+ . ok_or ( JsError :: new ( "Expected to find at least one component" ) ) ?;
1234+ let conv = res. get_index ( 1 ) ;
1235+
1236+ let note_addr = note. 0 . clone ( ) ;
1237+ if final_res. contains_key ( & note_addr) {
1238+ let mut existing = final_res
1239+ . get ( & note_addr)
1240+ . ok_or ( JsError :: new ( "Expected to find an entry" ) ) ?
1241+ . clone ( ) ;
1242+ existing. push ( ( * note. 1 , None ) ) ;
1243+
1244+ final_res. insert ( note_addr, existing) ;
1245+ } else {
1246+ final_res. insert ( note_addr, vec ! [ ( * note. 1 , None ) ] ) ;
1247+ }
1248+
1249+ if let Some ( conv) = conv {
1250+ let conv_addr = conv. 0 . clone ( ) ;
1251+ if final_res. contains_key ( & conv_addr) {
1252+ let mut existing = final_res
1253+ . get ( & conv_addr)
1254+ . ok_or ( JsError :: new ( "Expected to find an entry" ) ) ?
1255+ . clone ( ) ;
1256+ existing. push ( ( * note. 1 , Some ( * conv. 1 ) ) ) ;
1257+
1258+ final_res. insert ( conv_addr, existing) ;
1259+ } else {
1260+ final_res. insert ( conv_addr, vec ! [ ( * note. 1 , Some ( * conv. 1 ) ) ] ) ;
1261+ }
1262+ }
1263+ }
1264+
1265+ to_js_result ( final_res)
1266+ }
1267+
1268+
11681269 pub fn masp_address ( & self ) -> String {
11691270 MASP . to_string ( )
11701271 }
0 commit comments