1mod execute;
2mod ibc_callback;
3mod instantiate;
4mod module_ibc;
5mod query;
6mod reply;
7mod sudo;
8
9#[macro_export]
10macro_rules! export_endpoints {
11 ($api_const:expr, $api_type:ty) => {
12 $crate::__endpoints_without_custom__!($api_const, $api_type);
13 #[::cosmwasm_std::entry_point]
15 pub fn execute(
16 deps: ::cosmwasm_std::DepsMut,
17 env: ::cosmwasm_std::Env,
18 info: ::cosmwasm_std::MessageInfo,
19 msg: <$api_type as $crate::sdk::base::ExecuteEndpoint>::ExecuteMsg,
20 ) -> Result<::cosmwasm_std::Response, <$api_type as $crate::sdk::base::Handler>::Error> {
21 use $crate::sdk::base::ExecuteEndpoint;
22 $api_const.execute(deps, env, info, msg)
23 }
24 };
25 ($api_const:expr, $api_type:ty, $custom_exec:ty) => {
26 $crate::__endpoints_without_custom__!($api_const, $api_type);
27 #[::cosmwasm_std::entry_point]
29 pub fn execute(
30 deps: ::cosmwasm_std::DepsMut,
31 env: ::cosmwasm_std::Env,
32 info: ::cosmwasm_std::MessageInfo,
33 msg: $custom_exec,
34 ) -> Result<::cosmwasm_std::Response, <$api_type as $crate::sdk::base::Handler>::Error> {
35 use $crate::sdk::base::{CustomExecuteHandler, ExecuteEndpoint};
36 match CustomExecuteHandler::try_into_base(msg) {
37 Ok(default) => $api_const.execute(deps, env, info, default),
38 Err(custom) => custom.custom_execute(deps, env, info, $api_const),
39 }
40 }
41 };
42}
43
44#[macro_export]
45#[doc(hidden)]
46macro_rules! __endpoints_without_custom__ {
47 ($api_const:expr, $api_type:ty) => {
48 #[::cosmwasm_std::entry_point]
50 pub fn instantiate(
51 deps: ::cosmwasm_std::DepsMut,
52 env: ::cosmwasm_std::Env,
53 info: ::cosmwasm_std::MessageInfo,
54 msg: <$api_type as $crate::sdk::base::InstantiateEndpoint>::InstantiateMsg,
55 ) -> Result<::cosmwasm_std::Response, <$api_type as $crate::sdk::base::Handler>::Error> {
56 use $crate::sdk::base::InstantiateEndpoint;
57 $api_const.instantiate(deps, env, info, msg)
58 }
59
60 #[::cosmwasm_std::entry_point]
62 pub fn query(
63 deps: ::cosmwasm_std::Deps,
64 env: ::cosmwasm_std::Env,
65 msg: <$api_type as $crate::sdk::base::QueryEndpoint>::QueryMsg,
66 ) -> Result<::cosmwasm_std::Binary, <$api_type as $crate::sdk::base::Handler>::Error> {
67 use $crate::sdk::base::QueryEndpoint;
68 $api_const.query(deps, env, msg)
69 }
70
71 #[::cosmwasm_std::entry_point]
73 pub fn reply(
74 deps: ::cosmwasm_std::DepsMut,
75 env: ::cosmwasm_std::Env,
76 msg: ::cosmwasm_std::Reply,
77 ) -> Result<::cosmwasm_std::Response, <$api_type as $crate::sdk::base::Handler>::Error> {
78 use $crate::sdk::base::ReplyEndpoint;
79 $api_const.reply(deps, env, msg)
80 }
81
82 #[::cosmwasm_std::entry_point]
84 pub fn sudo(
85 deps: ::cosmwasm_std::DepsMut,
86 env: ::cosmwasm_std::Env,
87 msg: <$api_type as $crate::sdk::base::Handler>::SudoMsg,
88 ) -> Result<::cosmwasm_std::Response, <$api_type as $crate::sdk::base::Handler>::Error> {
89 use $crate::sdk::base::SudoEndpoint;
90 $api_const.sudo(deps, env, msg)
91 }
92 };
93}
94
95#[cfg(test)]
96mod test {
97 #![allow(clippy::needless_borrows_for_generic_args)]
98 use abstract_sdk::base::{
99 CustomExecuteHandler, ExecuteEndpoint, InstantiateEndpoint, QueryEndpoint, ReplyEndpoint,
100 SudoEndpoint,
101 };
102 use abstract_std::adapter::{self, AdapterRequestMsg};
103 use abstract_testing::prelude::*;
104 use cosmwasm_std::{
105 testing::{message_info, mock_dependencies},
106 Binary, SubMsgResult,
107 };
108
109 use crate::mock::*;
110
111 #[coverage_helper::test]
112 fn exports_endpoints() {
113 export_endpoints!(MOCK_ADAPTER, MockAdapterContract);
114
115 let mut deps = mock_dependencies();
116 let env = mock_env_validated(deps.api);
117 let abstr = AbstractMockAddrs::new(deps.api);
118 let owner = abstr.owner;
119
120 let init_msg = adapter::InstantiateMsg {
122 base: adapter::BaseInstantiateMsg {
123 registry_address: abstr.registry.to_string(),
124 },
125 module: MockInitMsg {},
126 };
127 let actual_init = instantiate(
128 deps.as_mut(),
129 env.clone(),
130 message_info(&owner, &[]),
131 init_msg.clone(),
132 );
133 let expected_init = MOCK_ADAPTER.instantiate(
134 deps.as_mut(),
135 env.clone(),
136 message_info(&owner, &[]),
137 init_msg,
138 );
139 assert_eq!(actual_init, expected_init);
140
141 let exec_msg = adapter::ExecuteMsg::Module(AdapterRequestMsg::new(None, MockExecMsg {}));
143 let actual_exec = execute(
144 deps.as_mut(),
145 env.clone(),
146 message_info(&owner, &[]),
147 exec_msg.clone(),
148 );
149 let expected_exec = MOCK_ADAPTER.execute(
150 deps.as_mut(),
151 env.clone(),
152 message_info(&owner, &[]),
153 exec_msg,
154 );
155 assert_eq!(actual_exec, expected_exec);
156
157 let query_msg = adapter::QueryMsg::Module(MockQueryMsg::GetSomething {});
159 let actual_query = query(deps.as_ref(), env.clone(), query_msg.clone());
160 let expected_query = MOCK_ADAPTER.query(deps.as_ref(), env.clone(), query_msg);
161 assert_eq!(actual_query, expected_query);
162
163 let sudo_msg = MockSudoMsg {};
165 let actual_sudo = sudo(deps.as_mut(), env.clone(), sudo_msg.clone());
166 let expected_sudo = MOCK_ADAPTER.sudo(deps.as_mut(), env.clone(), sudo_msg);
167 assert_eq!(actual_sudo, expected_sudo);
168
169 let reply_msg = ::cosmwasm_std::Reply {
171 id: 0,
172 result: SubMsgResult::Err("test".into()),
173 payload: Binary::default(),
174 gas_used: 0,
175 };
176 let actual_reply = reply(deps.as_mut(), env.clone(), reply_msg.clone());
177 let expected_reply = MOCK_ADAPTER.reply(deps.as_mut(), env, reply_msg);
178 assert_eq!(actual_reply, expected_reply);
179 }
180
181 #[coverage_helper::test]
182 fn export_endpoints_custom() {
183 #[cosmwasm_schema::cw_serde]
184 #[derive(cw_orch::ExecuteFns)]
185 pub enum CustomExecMsg {
186 Base(abstract_std::adapter::BaseExecuteMsg),
187 Module(AdapterRequestMsg<crate::mock::MockExecMsg>),
188 IbcCallback(abstract_std::ibc::IbcResponseMsg),
189 ModuleIbc(abstract_std::ibc::ModuleIbcMsg),
190 Foo {},
191 }
192
193 impl From<crate::mock::MockExecMsg> for CustomExecMsg {
194 fn from(request: crate::mock::MockExecMsg) -> Self {
195 Self::Module(AdapterRequestMsg {
196 account_address: None,
197 request,
198 })
199 }
200 }
201
202 impl CustomExecuteHandler<MockAdapterContract> for CustomExecMsg {
203 type ExecuteMsg = crate::mock::ExecuteMsg;
204
205 fn try_into_base(self) -> Result<Self::ExecuteMsg, Self> {
206 match self {
207 CustomExecMsg::Base(msg) => Ok(Self::ExecuteMsg::Base(msg)),
208 CustomExecMsg::Module(msg) => Ok(Self::ExecuteMsg::Module(msg)),
209 CustomExecMsg::IbcCallback(msg) => Ok(Self::ExecuteMsg::IbcCallback(msg)),
210 CustomExecMsg::ModuleIbc(msg) => Ok(Self::ExecuteMsg::ModuleIbc(msg)),
211 _ => Err(self),
212 }
213 }
214
215 fn custom_execute(
216 self,
217 _deps: cosmwasm_std::DepsMut,
218 _env: cosmwasm_std::Env,
219 _info: cosmwasm_std::MessageInfo,
220 _module: MockAdapterContract,
221 ) -> Result<cosmwasm_std::Response, crate::mock::MockError> {
222 Ok(cosmwasm_std::Response::new().set_data(b"foo"))
223 }
224 }
225 export_endpoints!(MOCK_ADAPTER, MockAdapterContract, CustomExecMsg);
226
227 let mut deps = mock_dependencies();
228 let env = mock_env_validated(deps.api);
229
230 let abstr = AbstractMockAddrs::new(deps.api);
231 let actual_custom_exec = execute(
233 deps.as_mut(),
234 env.clone(),
235 message_info(&abstr.owner, &[]),
236 CustomExecMsg::Foo {},
237 )
238 .unwrap();
239 let expected_custom_exec =
240 cosmwasm_std::Response::<cosmwasm_std::Empty>::new().set_data(b"foo");
241 assert_eq!(actual_custom_exec, expected_custom_exec);
242
243 let init_msg = adapter::InstantiateMsg {
247 base: adapter::BaseInstantiateMsg {
248 registry_address: abstr.registry.to_string(),
249 },
250 module: MockInitMsg {},
251 };
252 let actual_init = instantiate(
253 deps.as_mut(),
254 env.clone(),
255 message_info(&abstr.owner, &[]),
256 init_msg.clone(),
257 );
258 let expected_init = MOCK_ADAPTER.instantiate(
259 deps.as_mut(),
260 env.clone(),
261 message_info(&abstr.owner, &[]),
262 init_msg,
263 );
264 assert_eq!(actual_init, expected_init);
265
266 let exec_msg = MockExecMsg {};
268 let actual_exec = execute(
269 deps.as_mut(),
270 env.clone(),
271 message_info(&abstr.owner, &[]),
272 exec_msg.clone().into(),
273 );
274 let expected_exec = MOCK_ADAPTER.execute(
275 deps.as_mut(),
276 env.clone(),
277 message_info(&abstr.owner, &[]),
278 exec_msg.into(),
279 );
280 assert_eq!(actual_exec, expected_exec);
281
282 let query_msg = adapter::QueryMsg::Module(MockQueryMsg::GetSomething {});
284 let actual_query = query(deps.as_ref(), env.clone(), query_msg.clone());
285 let expected_query = MOCK_ADAPTER.query(deps.as_ref(), env.clone(), query_msg);
286 assert_eq!(actual_query, expected_query);
287
288 let sudo_msg = MockSudoMsg {};
290 let actual_sudo = sudo(deps.as_mut(), env.clone(), sudo_msg.clone());
291 let expected_sudo = MOCK_ADAPTER.sudo(deps.as_mut(), env.clone(), sudo_msg);
292 assert_eq!(actual_sudo, expected_sudo);
293
294 let reply_msg = ::cosmwasm_std::Reply {
296 id: 0,
297 result: SubMsgResult::Err("test".into()),
298 payload: Binary::default(),
299 gas_used: 0,
300 };
301 let actual_reply = reply(deps.as_mut(), env.clone(), reply_msg.clone());
302 let expected_reply = MOCK_ADAPTER.reply(deps.as_mut(), env, reply_msg);
303 assert_eq!(actual_reply, expected_reply);
304 }
305}