1
1
use anyhow:: Context ;
2
+ use namada_ibc:: OsmosisSwapMemoDataInner ;
2
3
use namada_ibc:: apps:: nft_transfer:: types:: PORT_ID_STR as NFT_PORT_ID_STR ;
3
4
use namada_ibc:: apps:: transfer:: types:: packet:: PacketData as FtPacketData ;
4
5
use namada_ibc:: apps:: transfer:: types:: {
@@ -10,6 +11,7 @@ use namada_ibc::core::channel::types::msgs::PacketMsg;
10
11
use namada_ibc:: core:: channel:: types:: packet:: Packet ;
11
12
use namada_ibc:: core:: handler:: types:: msgs:: MsgEnvelope ;
12
13
use namada_ibc:: core:: host:: types:: identifiers:: { ChannelId , PortId } ;
14
+ use namada_ibc:: trace:: convert_to_address;
13
15
use namada_sdk:: address:: Address ;
14
16
use namada_sdk:: token:: Transfer ;
15
17
@@ -100,7 +102,49 @@ fn packet_msg_to_balance_info(
100
102
native_token : Id ,
101
103
packet_msg : PacketMsg ,
102
104
) -> 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
+
103
146
let extract = |packet : Packet | -> anyhow:: Result < BalanceChange > {
147
+ let native_token = native_token. clone ( ) ;
104
148
let packet_data = serde_json:: from_slice :: < FtPacketData > ( & packet. data )
105
149
. context ( "Could not deserialize IBC fungible token packet" ) ?;
106
150
@@ -128,7 +172,10 @@ fn packet_msg_to_balance_info(
128
172
. context ( "Could not deserialize IBC acknowledgement" ) ?;
129
173
130
174
match ack {
131
- AcknowledgementStatus :: Success ( _) => Ok ( None ) ,
175
+ AcknowledgementStatus :: Success ( _) => {
176
+ // Needed to update the balance of overflow receiver when doing shielded swaps
177
+ try_extract_swap_overflow ( msg. packet )
178
+ }
132
179
AcknowledgementStatus :: Error ( _) => {
133
180
extract ( msg. packet ) . map ( Some )
134
181
}
0 commit comments