abstract_adapter/
features.rs1use abstract_sdk::{
2 feature_objects::{AnsHost, RegistryContract},
3 features::{AbstractNameService, AbstractRegistryAccess, AccountIdentification},
4 AbstractSdkResult,
5};
6use cosmwasm_std::{Deps, StdError};
7
8use crate::{state::ContractError, AdapterContract};
9
10impl<Error: ContractError, CustomInitMsg, CustomExecMsg, CustomQueryMsg, SudoMsg>
11 AbstractNameService
12 for AdapterContract<Error, CustomInitMsg, CustomExecMsg, CustomQueryMsg, SudoMsg>
13{
14 fn ans_host(&self, deps: Deps) -> AbstractSdkResult<AnsHost> {
15 let state = self.state(deps.storage)?;
16 AnsHost::new(deps, state.code_id).map_err(Into::into)
17 }
18}
19
20impl<Error: ContractError, CustomInitMsg, CustomExecMsg, CustomQueryMsg, SudoMsg>
22 AccountIdentification
23 for AdapterContract<Error, CustomInitMsg, CustomExecMsg, CustomQueryMsg, SudoMsg>
24{
25 fn account(&self, _deps: Deps) -> AbstractSdkResult<abstract_std::registry::Account> {
26 if let Some(target) = &self.target_account {
27 Ok(target.clone())
28 } else {
29 Err(StdError::generic_err("No target Account specified to execute on.").into())
30 }
31 }
32}
33
34impl<Error: ContractError, CustomInitMsg, CustomExecMsg, CustomQueryMsg, SudoMsg>
36 AbstractRegistryAccess
37 for AdapterContract<Error, CustomInitMsg, CustomExecMsg, CustomQueryMsg, SudoMsg>
38{
39 fn abstract_registry(&self, deps: Deps) -> AbstractSdkResult<RegistryContract> {
40 let state = self.state(deps.storage)?;
41 RegistryContract::new(deps, state.code_id).map_err(Into::into)
42 }
43}
44#[cfg(test)]
45mod tests {
46 use abstract_sdk::base::ExecuteEndpoint;
47 use abstract_std::adapter::{AdapterRequestMsg, ExecuteMsg};
48 use abstract_testing::prelude::*;
49 use cosmwasm_std::{testing::*, DepsMut, Env, MessageInfo, Response};
50
51 use super::*;
52 use crate::mock::{
53 mock_init, mock_init_custom, MockAdapterContract, MockError, MockExecMsg, MOCK_ADAPTER,
54 TEST_METADATA,
55 };
56
57 pub fn feature_exec_fn(
58 deps: DepsMut,
59 _env: Env,
60 _info: MessageInfo,
61 module: MockAdapterContract,
62 _msg: MockExecMsg,
63 ) -> Result<Response, MockError> {
64 let mock_api = MockApi::default();
65 let expected_account = test_account(mock_api);
66 let state = module.state(deps.storage)?;
68 let account = module.account(deps.as_ref())?;
69 assert_eq!(account, expected_account);
70 let ans = module.ans_host(deps.as_ref())?;
71 assert_eq!(ans, AnsHost::new(deps.as_ref(), state.code_id)?);
72 let registry = module.abstract_registry(deps.as_ref())?;
73 assert_eq!(
74 registry,
75 RegistryContract::new(deps.as_ref(), state.code_id)?
76 );
77
78 module.target()?;
79
80 Ok(Response::default())
81 }
82
83 pub fn featured_adapter() -> MockAdapterContract {
84 MockAdapterContract::new(TEST_MODULE_ID, TEST_VERSION, Some(TEST_METADATA))
85 .with_execute(feature_exec_fn)
86 }
87
88 #[coverage_helper::test]
89 fn custom_exec() {
90 let mut deps = mock_dependencies();
91 let account = test_account(deps.api);
92 let env = mock_env_validated(deps.api);
93
94 deps.querier = MockQuerierBuilder::new(deps.api)
95 .account(&account, TEST_ACCOUNT_ID)
96 .build();
97
98 mock_init_custom(&mut deps, featured_adapter()).unwrap();
99
100 let msg = ExecuteMsg::Module(AdapterRequestMsg {
101 account_address: None,
102 request: MockExecMsg {},
103 });
104
105 let res =
106 featured_adapter().execute(deps.as_mut(), env, message_info(account.addr(), &[]), msg);
107
108 assert!(res.is_ok());
109 }
110
111 #[coverage_helper::test]
112 fn targets_not_set() {
113 let mut deps = mock_dependencies();
114 deps.querier = MockQuerierBuilder::new(deps.api)
115 .account(&test_account(deps.api), TEST_ACCOUNT_ID)
116 .build();
117
118 mock_init(&mut deps).unwrap();
119
120 let res = MOCK_ADAPTER.account(deps.as_ref());
121 assert!(res.is_err());
122 }
123}