11use anyhow:: Context ;
2+ use namada_ibc:: OsmosisSwapMemoDataInner ;
23use namada_ibc:: apps:: nft_transfer:: types:: PORT_ID_STR as NFT_PORT_ID_STR ;
34use namada_ibc:: apps:: transfer:: types:: packet:: PacketData as FtPacketData ;
45use namada_ibc:: apps:: transfer:: types:: {
@@ -10,6 +11,7 @@ use namada_ibc::core::channel::types::msgs::PacketMsg;
1011use namada_ibc:: core:: channel:: types:: packet:: Packet ;
1112use namada_ibc:: core:: handler:: types:: msgs:: MsgEnvelope ;
1213use namada_ibc:: core:: host:: types:: identifiers:: { ChannelId , PortId } ;
14+ use namada_ibc:: trace:: convert_to_address;
1315use namada_sdk:: address:: Address ;
1416use namada_sdk:: token:: Transfer ;
1517
@@ -100,7 +102,49 @@ fn packet_msg_to_balance_info(
100102 native_token : Id ,
101103 packet_msg : PacketMsg ,
102104) -> anyhow:: Result < Option < BalanceChange > > {
105+ let try_extract_swap_overflow = |packet : Packet | -> anyhow:: Result <
106+ Option < BalanceChange > ,
107+ > {
108+ let native_token = native_token. clone ( ) ;
109+ let packet_data = serde_json:: from_slice :: < FtPacketData > ( & packet. data )
110+ . context ( "Could not deserialize IBC fungible token packet" ) ?;
111+
112+ let memo_data =
113+ serde_json:: from_str :: < serde_json:: Value > ( packet_data. memo . as_ref ( ) )
114+ . context ( "Invalid JSON" ) ?
115+ . pointer ( "/forward/next/wasm/msg/osmosis_swap/final_memo/namada/osmosis_swap" )
116+ . map ( |swap| {
117+ serde_json:: from_value :: < OsmosisSwapMemoDataInner > ( swap. clone ( ) )
118+ . context ( "Failed to deserialize Osmosis swap memo" )
119+ } )
120+ . transpose ( ) ?;
121+
122+ if let Some ( memo_data) = memo_data {
123+ let trace = memo_data. overflow_trace ;
124+
125+ let token =
126+ // For nam overflow_trace should be nam's tnam address
127+ if Id :: Account ( trace. clone ( ) ) == native_token {
128+ Token :: Native ( native_token)
129+ // For ibc overflow_trace should be /transfer/channel-x/denom
130+ } else {
131+ Token :: Ibc ( crate :: token:: IbcToken {
132+ address : convert_to_address ( & trace)
133+ . context ( "Failed to convert IBC trace to address" ) ?
134+ . into ( ) ,
135+ trace : Id :: IbcTrace ( trace) ,
136+ } )
137+ } ;
138+ let source = Id :: from ( memo_data. overflow_receiver ) ;
139+
140+ return Ok ( Some ( BalanceChange :: new ( source, token) ) ) ;
141+ } ;
142+
143+ Ok ( None )
144+ } ;
145+
103146 let extract = |packet : Packet | -> anyhow:: Result < BalanceChange > {
147+ let native_token = native_token. clone ( ) ;
104148 let packet_data = serde_json:: from_slice :: < FtPacketData > ( & packet. data )
105149 . context ( "Could not deserialize IBC fungible token packet" ) ?;
106150
@@ -128,7 +172,9 @@ fn packet_msg_to_balance_info(
128172 . context ( "Could not deserialize IBC acknowledgement" ) ?;
129173
130174 match ack {
131- AcknowledgementStatus :: Success ( _) => Ok ( None ) ,
175+ AcknowledgementStatus :: Success ( _) => {
176+ try_extract_swap_overflow ( msg. packet )
177+ }
132178 AcknowledgementStatus :: Error ( _) => {
133179 extract ( msg. packet ) . map ( Some )
134180 }
0 commit comments