abstract_adapter/endpoints/
instantiate.rs

1use abstract_sdk::base::{Handler, InstantiateEndpoint};
2use abstract_std::{
3    adapter::{AdapterState, InstantiateMsg},
4    objects::module_version::set_module_data,
5};
6use cosmwasm_std::{DepsMut, Env, MessageInfo, Response};
7use cw2::set_contract_version;
8use schemars::JsonSchema;
9use serde::Serialize;
10
11use crate::state::{AdapterContract, ContractError};
12
13impl<
14        Error: ContractError,
15        CustomInitMsg: Serialize + JsonSchema,
16        CustomExecMsg,
17        CustomQueryMsg,
18        SudoMsg,
19    > InstantiateEndpoint
20    for AdapterContract<Error, CustomInitMsg, CustomExecMsg, CustomQueryMsg, SudoMsg>
21{
22    type InstantiateMsg = InstantiateMsg<CustomInitMsg>;
23    /// Instantiate the api
24    fn instantiate(
25        self,
26        deps: DepsMut,
27        env: Env,
28        info: MessageInfo,
29        msg: Self::InstantiateMsg,
30    ) -> Result<Response, Error> {
31        // Base state
32        let contract_info = deps
33            .querier
34            .query_wasm_contract_info(msg.base.registry_address)?;
35        let state = AdapterState {
36            code_id: contract_info.code_id,
37        };
38        let (name, version, metadata) = self.info();
39        set_module_data(deps.storage, name, version, self.dependencies(), metadata)?;
40        set_contract_version(deps.storage, name, version)?;
41        self.base_state.save(deps.storage, &state)?;
42
43        let Some(handler) = self.maybe_instantiate_handler() else {
44            return Ok(Response::new());
45        };
46        handler(deps, env, info, self, msg.module)
47    }
48}
49
50#[cfg(test)]
51mod test {
52    #![allow(clippy::needless_borrows_for_generic_args)]
53    use abstract_sdk::base::InstantiateEndpoint;
54    use abstract_std::{
55        adapter::{AdapterState, BaseInstantiateMsg, InstantiateMsg},
56        objects::module_version::{ModuleData, MODULE},
57    };
58    use abstract_testing::prelude::*;
59    use cosmwasm_std::testing::*;
60    use cw2::{ContractVersion, CONTRACT};
61
62    use crate::mock::{AdapterMockResult, MockInitMsg, MOCK_ADAPTER, MOCK_DEP, TEST_METADATA};
63
64    #[coverage_helper::test]
65    fn successful() -> AdapterMockResult {
66        let api = MOCK_ADAPTER.with_dependencies(&[MOCK_DEP]);
67        let mut deps = mock_dependencies();
68        let env = mock_env_validated(deps.api);
69        let abstr = AbstractMockAddrs::new(deps.api);
70
71        let info = message_info(abstr.account.addr(), &[]);
72        deps.querier = abstract_testing::abstract_mock_querier(deps.api);
73        let init_msg = InstantiateMsg {
74            base: BaseInstantiateMsg {
75                registry_address: abstr.registry.to_string(),
76            },
77            module: MockInitMsg {},
78        };
79        let res = api.instantiate(deps.as_mut(), env, info, init_msg)?;
80        assert_eq!(res.messages.len(), 0);
81        // confirm mock init handler executed
82        assert_eq!(res.data, Some("mock_init".as_bytes().into()));
83
84        let module_data = MODULE.load(&deps.storage)?;
85        assert_eq!(
86            module_data,
87            ModuleData {
88                module: TEST_MODULE_ID.into(),
89                version: TEST_VERSION.into(),
90                dependencies: vec![(&crate::mock::MOCK_DEP).into()],
91                metadata: Some(TEST_METADATA.into()),
92            }
93        );
94
95        let contract_version = CONTRACT.load(&deps.storage)?;
96        assert_eq!(
97            contract_version,
98            ContractVersion {
99                contract: TEST_MODULE_ID.into(),
100                version: TEST_VERSION.into(),
101            }
102        );
103
104        let api = MOCK_ADAPTER;
105        let none_authorized = api.authorized_addresses.is_empty(&deps.storage);
106        assert!(none_authorized);
107
108        let state = api.base_state.load(&deps.storage)?;
109        assert_eq!(state, AdapterState { code_id: 1 });
110        Ok(())
111    }
112}