abstract_app/
features.rs

1use abstract_sdk::{
2    feature_objects::{AnsHost, RegistryContract},
3    features::{AbstractNameService, AbstractRegistryAccess, AccountIdentification},
4    AbstractSdkResult,
5};
6use abstract_std::{native_addrs, registry::Account};
7use cosmwasm_std::Deps;
8
9use crate::{state::ContractError, AppContract};
10
11// ANCHOR: ans
12impl<
13        Error: ContractError,
14        CustomInitMsg,
15        CustomExecMsg,
16        CustomQueryMsg,
17        CustomMigrateMsg,
18        SudoMsg,
19    > AbstractNameService
20    for AppContract<Error, CustomInitMsg, CustomExecMsg, CustomQueryMsg, CustomMigrateMsg, SudoMsg>
21{
22    fn ans_host(&self, deps: Deps) -> AbstractSdkResult<AnsHost> {
23        let state = self.base_state.load(deps.storage)?;
24        let abstract_code_id =
25            native_addrs::abstract_code_id(&deps.querier, state.account.into_addr())?;
26        AnsHost::new(deps, abstract_code_id).map_err(Into::into)
27    }
28}
29// ANCHOR_END: ans
30
31impl<
32        Error: ContractError,
33        CustomInitMsg,
34        CustomExecMsg,
35        CustomQueryMsg,
36        CustomMigrateMsg,
37        SudoMsg,
38    > AccountIdentification
39    for AppContract<Error, CustomInitMsg, CustomExecMsg, CustomQueryMsg, CustomMigrateMsg, SudoMsg>
40{
41    fn account(&self, deps: Deps) -> AbstractSdkResult<Account> {
42        Ok(self.base_state.load(deps.storage)?.account)
43    }
44}
45
46impl<
47        Error: ContractError,
48        CustomInitMsg,
49        CustomExecMsg,
50        CustomQueryMsg,
51        CustomMigrateMsg,
52        SudoMsg,
53    > AbstractRegistryAccess
54    for AppContract<Error, CustomInitMsg, CustomExecMsg, CustomQueryMsg, CustomMigrateMsg, SudoMsg>
55{
56    fn abstract_registry(&self, deps: Deps) -> AbstractSdkResult<RegistryContract> {
57        let state = self.base_state.load(deps.storage)?;
58        let abstract_code_id =
59            native_addrs::abstract_code_id(&deps.querier, state.account.into_addr())?;
60        RegistryContract::new(deps, abstract_code_id).map_err(Into::into)
61    }
62}
63
64#[cfg(test)]
65mod test {
66    #![allow(clippy::needless_borrows_for_generic_args)]
67    use abstract_sdk::{AccountVerification, ModuleRegistryInterface};
68    use abstract_std::objects::{
69        namespace::{Namespace, ABSTRACT_NAMESPACE},
70        ABSTRACT_ACCOUNT_ID,
71    };
72    use abstract_testing::prelude::*;
73
74    use super::*;
75    use crate::mock::*;
76
77    #[coverage_helper::test]
78    fn test_ans_host() -> AppTestResult {
79        let deps = mock_init();
80        let abstr = AbstractMockAddrs::new(deps.api);
81
82        let ans_host = MOCK_APP_WITH_DEP.ans_host(deps.as_ref())?;
83
84        assert_eq!(ans_host.address, abstr.ans_host);
85        Ok(())
86    }
87
88    #[coverage_helper::test]
89    fn test_abstract_registry() -> AppTestResult {
90        let deps = mock_init();
91        let abstr = AbstractMockAddrs::new(deps.api);
92
93        let abstract_registry = MOCK_APP_WITH_DEP.abstract_registry(deps.as_ref())?;
94
95        assert_eq!(abstract_registry.address, abstr.registry);
96        Ok(())
97    }
98
99    #[coverage_helper::test]
100    fn test_traits_generated() -> AppTestResult {
101        let mut deps = mock_init();
102        let test_account = test_account(deps.api);
103        let abstr = AbstractMockAddrs::new(deps.api);
104        deps.querier = abstract_mock_querier_builder(deps.api)
105            .account(&test_account, TEST_ACCOUNT_ID)
106            .with_contract_map_entry(
107                &abstr.registry,
108                abstract_std::registry::state::NAMESPACES,
109                (
110                    &Namespace::unchecked(ABSTRACT_NAMESPACE),
111                    ABSTRACT_ACCOUNT_ID,
112                ),
113            )
114            .build();
115        // Account identification
116        let base = MOCK_APP_WITH_DEP.account(deps.as_ref())?;
117        assert_eq!(base, test_account.clone());
118
119        // AbstractNameService
120        let host = MOCK_APP_WITH_DEP.name_service(deps.as_ref()).host().clone();
121        assert_eq!(host, AnsHost::new(deps.as_ref(), 1)?);
122
123        // AccountRegistry
124        let binding = MOCK_APP_WITH_DEP;
125        let account_registry = binding.account_registry(deps.as_ref())?;
126        let base = account_registry.account(&TEST_ACCOUNT_ID)?;
127        assert_eq!(base, test_account);
128
129        let module_registry = binding.module_registry(deps.as_ref())?;
130        let abstract_namespace =
131            module_registry.query_namespace_raw(Namespace::unchecked(ABSTRACT_NAMESPACE))?;
132        assert_eq!(abstract_namespace, Some(ABSTRACT_ACCOUNT_ID));
133
134        Ok(())
135    }
136
137    #[coverage_helper::test]
138    fn test_account_address() -> AppTestResult {
139        let deps = mock_init();
140        let expected_account = test_account(deps.api);
141
142        let account = MOCK_APP_WITH_DEP.account(deps.as_ref())?;
143
144        assert_eq!(account, expected_account);
145
146        Ok(())
147    }
148
149    #[coverage_helper::test]
150    fn test_module_id() -> AppTestResult {
151        let module_id = MOCK_APP_WITH_DEP.module_id();
152
153        assert_eq!(module_id, TEST_WITH_DEP_MODULE_ID);
154        Ok(())
155    }
156}