@@ -2,9 +2,13 @@ use std::str::FromStr;
2
2
3
3
use axelar_core_std:: nexus;
4
4
use axelar_wasm_std:: msg_id:: HexTxHashAndEventIndex ;
5
+ use axelar_wasm_std:: token:: GetToken ;
5
6
use axelar_wasm_std:: { address, FnExt , IntoContractError } ;
6
7
use cosmwasm_schema:: cw_serde;
7
- use cosmwasm_std:: { Addr , DepsMut , HexBinary , QuerierWrapper , Response , Storage } ;
8
+ use cosmwasm_std:: {
9
+ to_json_binary, Addr , DepsMut , HexBinary , MessageInfo , QuerierWrapper , Response , Storage ,
10
+ WasmMsg ,
11
+ } ;
8
12
use error_stack:: { bail, ensure, report, Result , ResultExt } ;
9
13
use itertools:: Itertools ;
10
14
use router_api:: client:: Router ;
@@ -47,6 +51,8 @@ pub enum Error {
47
51
Nexus ,
48
52
#[ error( "nonce from the nexus module overflowed u32" ) ]
49
53
NonceOverflow ,
54
+ #[ error( "invalid token received" ) ]
55
+ InvalidToken ,
50
56
}
51
57
52
58
#[ cw_serde]
@@ -71,10 +77,14 @@ impl CallContractData {
71
77
pub fn call_contract (
72
78
storage : & mut dyn Storage ,
73
79
querier : QuerierWrapper ,
74
- sender : Addr ,
80
+ info : MessageInfo ,
75
81
call_contract : CallContractData ,
76
82
) -> Result < Response , Error > {
77
- let Config { router, chain_name } = state:: load_config ( storage) ;
83
+ let Config {
84
+ router,
85
+ chain_name,
86
+ nexus_gateway,
87
+ } = state:: load_config ( storage) ;
78
88
79
89
let client: nexus:: Client = client:: CosmosClient :: new ( querier) . into ( ) ;
80
90
let nexus:: query:: TxHashAndNonceResponse { tx_hash, nonce } =
@@ -88,31 +98,42 @@ pub fn call_contract(
88
98
) ,
89
99
)
90
100
. change_context ( Error :: InvalidCrossChainId ) ?;
91
- let source_address = Address :: from_str ( sender. as_str ( ) )
92
- . change_context ( Error :: InvalidSourceAddress ( sender. clone ( ) ) ) ?;
101
+ let source_address = Address :: from_str ( info . sender . as_str ( ) )
102
+ . change_context ( Error :: InvalidSourceAddress ( info . sender . clone ( ) ) ) ?;
93
103
let msg = call_contract. to_message ( id, source_address) ;
94
104
95
105
state:: save_unique_routable_msg ( storage, & msg. cc_id , & msg)
96
106
. inspect_err ( |err| panic_if_already_exists ( err, & msg. cc_id ) )
97
107
. change_context ( Error :: SaveRoutableMessage ) ?;
98
108
99
- Ok (
100
- route_to_router ( storage, & Router :: new ( router) , vec ! [ msg. clone( ) ] ) ?. add_event (
101
- AxelarnetGatewayEvent :: ContractCalled {
102
- msg,
103
- payload : call_contract. payload ,
104
- }
105
- . into ( ) ,
106
- ) ,
107
- )
109
+ let token = info. single_token ( ) . change_context ( Error :: InvalidToken ) ?;
110
+ let event = AxelarnetGatewayEvent :: ContractCalled {
111
+ msg : msg. clone ( ) ,
112
+ payload : call_contract. payload ,
113
+ token : token. clone ( ) ,
114
+ } ;
115
+ let res = match token {
116
+ None => route_to_router ( storage, & Router :: new ( router) , vec ! [ msg] ) ?,
117
+ Some ( token) => Response :: new ( ) . add_message ( WasmMsg :: Execute {
118
+ contract_addr : nexus_gateway. to_string ( ) ,
119
+ msg : to_json_binary ( & nexus_gateway:: msg:: ExecuteMsg :: RouteMessageWithToken ( msg) )
120
+ . expect ( "failed to serialize route message with token" ) ,
121
+ funds : vec ! [ token] ,
122
+ } ) ,
123
+ }
124
+ . add_event ( event. into ( ) ) ;
125
+
126
+ Ok ( res)
108
127
}
109
128
110
129
pub fn route_messages (
111
130
storage : & mut dyn Storage ,
112
131
sender : Addr ,
113
132
msgs : Vec < Message > ,
114
133
) -> Result < Response , Error > {
115
- let Config { chain_name, router } = state:: load_config ( storage) ;
134
+ let Config {
135
+ chain_name, router, ..
136
+ } = state:: load_config ( storage) ;
116
137
let router = Router :: new ( router) ;
117
138
118
139
if sender == router. address {
0 commit comments