1mod execute;
2mod ibc_callback;
3pub mod instantiate;
4mod migrate;
5mod module_ibc;
6mod query;
7mod reply;
8mod sudo;
9
10#[macro_export]
11macro_rules! export_endpoints {
28 ($app_const:expr, $app_type:ty) => {
29 $crate::__endpoints_without_custom__!($app_const, $app_type);
30
31 #[::cosmwasm_std::entry_point]
33 pub fn execute(
34 deps: ::cosmwasm_std::DepsMut,
35 env: ::cosmwasm_std::Env,
36 info: ::cosmwasm_std::MessageInfo,
37 msg: <$app_type as $crate::sdk::base::ExecuteEndpoint>::ExecuteMsg,
38 ) -> Result<::cosmwasm_std::Response, <$app_type as $crate::sdk::base::Handler>::Error> {
39 use $crate::sdk::base::ExecuteEndpoint;
40 $app_const.execute(deps, env, info, msg)
41 }
42 };
43 ($app_const:expr, $app_type:ty, $custom_exec:ty) => {
44 $crate::__endpoints_without_custom__!($app_const, $app_type);
45
46 #[::cosmwasm_std::entry_point]
48 pub fn execute(
49 deps: ::cosmwasm_std::DepsMut,
50 env: ::cosmwasm_std::Env,
51 info: ::cosmwasm_std::MessageInfo,
52 msg: $custom_exec,
53 ) -> Result<::cosmwasm_std::Response, <$app_type as $crate::sdk::base::Handler>::Error> {
54 use $crate::sdk::base::{CustomExecuteHandler, ExecuteEndpoint};
55 match CustomExecuteHandler::try_into_base(msg) {
56 Ok(default) => $app_const.execute(deps, env, info, default),
57 Err(custom) => custom.custom_execute(deps, env, info, $app_const),
58 }
59 }
60 };
61}
62
63#[macro_export]
64#[doc(hidden)]
65macro_rules! __endpoints_without_custom__ {
66 ($app_const:expr, $app_type:ty) => {
67 #[::cosmwasm_std::entry_point]
69 pub fn instantiate(
70 deps: ::cosmwasm_std::DepsMut,
71 env: ::cosmwasm_std::Env,
72 info: ::cosmwasm_std::MessageInfo,
73 msg: <$app_type as $crate::sdk::base::InstantiateEndpoint>::InstantiateMsg,
74 ) -> Result<::cosmwasm_std::Response, <$app_type as $crate::sdk::base::Handler>::Error> {
75 use $crate::sdk::base::InstantiateEndpoint;
76 $app_const.instantiate(deps, env, info, msg)
77 }
78
79 #[::cosmwasm_std::entry_point]
81 pub fn query(
82 deps: ::cosmwasm_std::Deps,
83 env: ::cosmwasm_std::Env,
84 msg: <$app_type as $crate::sdk::base::QueryEndpoint>::QueryMsg,
85 ) -> Result<::cosmwasm_std::Binary, <$app_type as $crate::sdk::base::Handler>::Error> {
86 use $crate::sdk::base::QueryEndpoint;
87 $app_const.query(deps, env, msg)
88 }
89
90 #[::cosmwasm_std::entry_point]
92 pub fn migrate(
93 deps: ::cosmwasm_std::DepsMut,
94 env: ::cosmwasm_std::Env,
95 msg: <$app_type as $crate::sdk::base::MigrateEndpoint>::MigrateMsg,
96 ) -> Result<::cosmwasm_std::Response, <$app_type as $crate::sdk::base::Handler>::Error> {
97 use $crate::sdk::base::MigrateEndpoint;
98 $app_const.migrate(deps, env, msg)
99 }
100
101 #[::cosmwasm_std::entry_point]
103 pub fn reply(
104 deps: ::cosmwasm_std::DepsMut,
105 env: ::cosmwasm_std::Env,
106 msg: ::cosmwasm_std::Reply,
107 ) -> Result<::cosmwasm_std::Response, <$app_type as $crate::sdk::base::Handler>::Error> {
108 use $crate::sdk::base::ReplyEndpoint;
109 $app_const.reply(deps, env, msg)
110 }
111
112 #[::cosmwasm_std::entry_point]
114 pub fn sudo(
115 deps: ::cosmwasm_std::DepsMut,
116 env: ::cosmwasm_std::Env,
117 msg: <$app_type as $crate::sdk::base::Handler>::SudoMsg,
118 ) -> Result<::cosmwasm_std::Response, <$app_type as $crate::sdk::base::Handler>::Error> {
119 use $crate::sdk::base::SudoEndpoint;
120 $app_const.sudo(deps, env, msg)
121 }
122 };
123}
124
125#[cfg(test)]
126mod test {
127 #![allow(clippy::needless_borrows_for_generic_args)]
128 use crate::mock::*;
129 use crate::sdk::base::{
130 ExecuteEndpoint, InstantiateEndpoint, MigrateEndpoint, QueryEndpoint, ReplyEndpoint,
131 SudoEndpoint,
132 };
133 use abstract_sdk::base::CustomExecuteHandler;
134 use abstract_testing::prelude::*;
135 use cosmwasm_std::{Binary, SubMsgResult};
136
137 #[coverage_helper::test]
138 fn exports_endpoints() {
139 export_endpoints!(MOCK_APP_WITH_DEP, MockAppContract);
140
141 let mut deps = mock_dependencies();
142 let env = mock_env_validated(deps.api);
143 let abstr = AbstractMockAddrs::new(deps.api);
144
145 let init_msg = app::InstantiateMsg {
147 base: app::BaseInstantiateMsg {
148 account: abstr.account,
149 },
150 module: MockInitMsg {},
151 };
152 let actual_init = instantiate(
153 deps.as_mut(),
154 env.clone(),
155 message_info(&abstr.owner, &[]),
156 init_msg.clone(),
157 );
158 let expected_init = MOCK_APP_WITH_DEP.instantiate(
159 deps.as_mut(),
160 env.clone(),
161 message_info(&abstr.owner, &[]),
162 init_msg,
163 );
164 assert_eq!(actual_init, expected_init);
165
166 let exec_msg = app::ExecuteMsg::Module(MockExecMsg::DoSomething {});
168 let actual_exec = execute(
169 deps.as_mut(),
170 env.clone(),
171 message_info(&abstr.owner, &[]),
172 exec_msg.clone(),
173 );
174 let expected_exec = MOCK_APP_WITH_DEP.execute(
175 deps.as_mut(),
176 env.clone(),
177 message_info(&abstr.owner, &[]),
178 exec_msg,
179 );
180 assert_eq!(actual_exec, expected_exec);
181
182 let query_msg = app::QueryMsg::Module(MockQueryMsg::GetSomething {});
184 let actual_query = query(deps.as_ref(), env.clone(), query_msg.clone());
185 let expected_query = MOCK_APP_WITH_DEP.query(deps.as_ref(), env.clone(), query_msg);
186 assert_eq!(actual_query, expected_query);
187
188 let migrate_msg = app::MigrateMsg {
190 base: app::BaseMigrateMsg {},
191 module: MockMigrateMsg,
192 };
193 let actual_migrate = migrate(deps.as_mut(), env.clone(), migrate_msg.clone());
194 let expected_migrate = MOCK_APP_WITH_DEP.migrate(deps.as_mut(), env.clone(), migrate_msg);
195 assert_eq!(actual_migrate, expected_migrate);
196
197 let sudo_msg = MockSudoMsg {};
199 let actual_sudo = sudo(deps.as_mut(), env.clone(), sudo_msg.clone());
200 let expected_sudo = MOCK_APP_WITH_DEP.sudo(deps.as_mut(), env.clone(), sudo_msg);
201 assert_eq!(actual_sudo, expected_sudo);
202
203 let reply_msg = ::cosmwasm_std::Reply {
205 id: 0,
206 result: SubMsgResult::Err("test".into()),
207 payload: Binary::default(),
208 gas_used: 0,
209 };
210 let actual_reply = reply(deps.as_mut(), env.clone(), reply_msg.clone());
211 let expected_reply = MOCK_APP_WITH_DEP.reply(deps.as_mut(), env, reply_msg);
212 assert_eq!(actual_reply, expected_reply);
213 }
214
215 #[coverage_helper::test]
216 fn exports_endpoints_custom() {
217 #[cosmwasm_schema::cw_serde]
218 #[derive(cw_orch::ExecuteFns)]
219 pub enum CustomExecMsg {
220 Base(abstract_std::app::BaseExecuteMsg),
221 Module(crate::mock::MockExecMsg),
222 IbcCallback(abstract_std::ibc::IbcResponseMsg),
223 ModuleIbc(abstract_std::ibc::ModuleIbcMsg),
224 Foo {},
225 }
226
227 impl From<crate::mock::MockExecMsg> for CustomExecMsg {
228 fn from(request: crate::mock::MockExecMsg) -> Self {
229 Self::Module(request)
230 }
231 }
232
233 impl CustomExecuteHandler<MockAppContract> for CustomExecMsg {
234 type ExecuteMsg = crate::mock::ExecuteMsg;
235
236 fn try_into_base(self) -> Result<Self::ExecuteMsg, Self> {
237 match self {
238 CustomExecMsg::Base(msg) => Ok(Self::ExecuteMsg::Base(msg)),
239 CustomExecMsg::Module(msg) => Ok(Self::ExecuteMsg::Module(msg)),
240 CustomExecMsg::IbcCallback(msg) => Ok(Self::ExecuteMsg::IbcCallback(msg)),
241 CustomExecMsg::ModuleIbc(msg) => Ok(Self::ExecuteMsg::ModuleIbc(msg)),
242 _ => Err(self),
243 }
244 }
245
246 fn custom_execute(
247 self,
248 _deps: cosmwasm_std::DepsMut,
249 _env: cosmwasm_std::Env,
250 _info: cosmwasm_std::MessageInfo,
251 _module: MockAppContract,
252 ) -> Result<cosmwasm_std::Response, crate::mock::MockError> {
253 Ok(cosmwasm_std::Response::new().set_data(b"foo"))
254 }
255 }
256
257 export_endpoints!(MOCK_APP_WITH_DEP, MockAppContract, CustomExecMsg);
258
259 let mut deps = mock_dependencies();
260 let env = mock_env_validated(deps.api);
261 let abstr = AbstractMockAddrs::new(deps.api);
262
263 let actual_custom_exec = execute(
265 deps.as_mut(),
266 env.clone(),
267 message_info(&abstr.owner, &[]),
268 CustomExecMsg::Foo {},
269 )
270 .unwrap();
271 let expected_custom_exec =
272 cosmwasm_std::Response::<cosmwasm_std::Empty>::new().set_data(b"foo");
273 assert_eq!(actual_custom_exec, expected_custom_exec);
274
275 let init_msg = app::InstantiateMsg {
279 base: app::BaseInstantiateMsg {
280 account: test_account(deps.api),
281 },
282 module: MockInitMsg {},
283 };
284 let actual_init = instantiate(
285 deps.as_mut(),
286 env.clone(),
287 message_info(&abstr.owner, &[]),
288 init_msg.clone(),
289 );
290 let expected_init = MOCK_APP_WITH_DEP.instantiate(
291 deps.as_mut(),
292 env.clone(),
293 message_info(&abstr.owner, &[]),
294 init_msg,
295 );
296 assert_eq!(actual_init, expected_init);
297
298 let exec_msg = app::ExecuteMsg::Module(MockExecMsg::DoSomething {});
300 let actual_exec = execute(
301 deps.as_mut(),
302 env.clone(),
303 message_info(&abstr.owner, &[]),
304 CustomExecMsg::Module(MockExecMsg::DoSomething {}),
305 );
306 let expected_exec = MOCK_APP_WITH_DEP.execute(
307 deps.as_mut(),
308 env.clone(),
309 message_info(&abstr.owner, &[]),
310 exec_msg,
311 );
312 assert_eq!(actual_exec, expected_exec);
313
314 let query_msg = app::QueryMsg::Module(MockQueryMsg::GetSomething {});
316 let actual_query = query(deps.as_ref(), env.clone(), query_msg.clone());
317 let expected_query = MOCK_APP_WITH_DEP.query(deps.as_ref(), env.clone(), query_msg);
318 assert_eq!(actual_query, expected_query);
319
320 let migrate_msg = app::MigrateMsg {
322 base: app::BaseMigrateMsg {},
323 module: MockMigrateMsg,
324 };
325 let actual_migrate = migrate(deps.as_mut(), env.clone(), migrate_msg.clone());
326 let expected_migrate = MOCK_APP_WITH_DEP.migrate(deps.as_mut(), env.clone(), migrate_msg);
327 assert_eq!(actual_migrate, expected_migrate);
328
329 let sudo_msg = MockSudoMsg {};
331 let actual_sudo = sudo(deps.as_mut(), env.clone(), sudo_msg.clone());
332 let expected_sudo = MOCK_APP_WITH_DEP.sudo(deps.as_mut(), env.clone(), sudo_msg);
333 assert_eq!(actual_sudo, expected_sudo);
334
335 let reply_msg = ::cosmwasm_std::Reply {
337 id: 0,
338 result: SubMsgResult::Err("test".into()),
339 payload: Binary::default(),
340 gas_used: 0,
341 };
342 let actual_reply = reply(deps.as_mut(), env.clone(), reply_msg.clone());
343 let expected_reply = MOCK_APP_WITH_DEP.reply(deps.as_mut(), env, reply_msg);
344 assert_eq!(actual_reply, expected_reply);
345 }
346}