marbu_customization_module/
contract.rs

1#[cfg(not(feature = "library"))]
2use cosmwasm_std::entry_point;
3use cosmwasm_std::{
4    from_binary, to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Order, Response, StdResult,
5};
6use cw2::set_contract_version;
7use komple_framework_types::shared::query::ResponseWrapper;
8use komple_framework_types::shared::RegisterMsg;
9use komple_framework_utils::check_admin_privileges;
10use komple_framework_utils::shared::execute_lock_execute;
11
12use crate::error::ContractError;
13use crate::msg::{ExecuteMsg, QueryMsg};
14use crate::state::{Config, Data, CONFIG, DATA_MAP, EXECUTE_LOCK, HUB_ADDR};
15
16// version info for migration info
17const CONTRACT_NAME: &str = "crates.io:marbu-customization-module";
18const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
19
20#[cfg_attr(not(feature = "library"), entry_point)]
21pub fn instantiate(
22    deps: DepsMut,
23    _env: Env,
24    info: MessageInfo,
25    msg: RegisterMsg,
26) -> Result<Response, ContractError> {
27    set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
28
29    let admin = deps.api.addr_validate(&msg.admin)?;
30
31    let config = Config { admin };
32    CONFIG.save(deps.storage, &config)?;
33
34    HUB_ADDR.save(deps.storage, &info.sender)?;
35
36    EXECUTE_LOCK.save(deps.storage, &false)?;
37    
38    if let Some(data) = msg.data {
39        let data: Vec<Data> = from_binary(&data)?;
40    
41        // Save the customization data
42        for d in data {
43            DATA_MAP.save(deps.storage, d.key, &d.value)?;
44        }
45    };
46
47    /* TODO: Add events in here for indexing */
48    Ok(Response::default())
49}
50
51#[cfg_attr(not(feature = "library"), entry_point)]
52pub fn execute(
53    deps: DepsMut,
54    env: Env,
55    info: MessageInfo,
56    msg: ExecuteMsg,
57) -> Result<Response, ContractError> {
58    let execute_lock = EXECUTE_LOCK.load(deps.storage)?;
59    if execute_lock {
60        return Err(ContractError::ExecuteLocked {});
61    };
62
63    match msg {
64        ExecuteMsg::SetData { key, value } => execute_set_data(deps, env, info, key, value),
65        ExecuteMsg::SetDataBatch { data } => execute_set_data_batch(deps, env, info, data),
66        ExecuteMsg::LockExecute {} => {
67            let res = execute_lock_execute(
68                deps,
69                info,
70                "marbu_customization",
71                &env.contract.address,
72                EXECUTE_LOCK,
73            );
74            match res {
75                Ok(res) => Ok(res),
76                Err(err) => Err(err.into()),
77            }
78        }
79    }
80}
81
82fn execute_set_data(
83    deps: DepsMut,
84    env: Env,
85    info: MessageInfo,
86    key: String,
87    value: Binary,
88) -> Result<Response, ContractError> {
89    let config = CONFIG.load(deps.storage)?;
90    let hub_addr = HUB_ADDR.may_load(deps.storage)?;
91
92    check_admin_privileges(
93        &info.sender,
94        &env.contract.address,
95        &config.admin,
96        hub_addr,
97        None,
98    )?;
99
100    DATA_MAP.save(deps.storage, key, &value)?;
101
102    /* TODO: Add events in here for indexing */
103    Ok(Response::new().add_attribute("action", "set_data"))
104}
105
106fn execute_set_data_batch(
107    deps: DepsMut,
108    env: Env,
109    info: MessageInfo,
110    data: Vec<Data>,
111) -> Result<Response, ContractError> {
112    let config = CONFIG.load(deps.storage)?;
113    let hub_addr = HUB_ADDR.may_load(deps.storage)?;
114
115    check_admin_privileges(
116        &info.sender,
117        &env.contract.address,
118        &config.admin,
119        hub_addr,
120        None,
121    )?;
122
123    for d in data {
124        DATA_MAP.save(deps.storage, d.key, &d.value)?;
125    }
126
127    /* TODO: Add events in here for indexing */
128    Ok(Response::new().add_attribute("action", "set_data_batch"))
129}
130
131#[cfg_attr(not(feature = "library"), entry_point)]
132pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
133    match msg {
134        QueryMsg::Config {} => to_binary(&query_config(deps)?),
135        QueryMsg::GetData { key } => to_binary(&query_get_data(deps, key)?),
136        QueryMsg::GetDataBatch { keys } => to_binary(&query_get_data_batch(deps, keys)?),
137        QueryMsg::ListKeys {} => to_binary(&query_list_keys(deps)?),
138    }
139}
140
141fn query_config(deps: Deps) -> StdResult<ResponseWrapper<Config>> {
142    let config = CONFIG.load(deps.storage)?;
143    Ok(ResponseWrapper::new("config", config))
144}
145
146fn query_get_data(deps: Deps, key: String) -> StdResult<ResponseWrapper<Option<Binary>>> {
147    let data = DATA_MAP.may_load(deps.storage, key)?;
148    Ok(ResponseWrapper::new("get_data", data))
149}
150
151fn query_get_data_batch(
152    deps: Deps,
153    keys: Vec<String>,
154) -> StdResult<ResponseWrapper<Vec<Option<Binary>>>> {
155    let mut all_data: Vec<Option<Binary>> = vec![];
156
157    for key in keys {
158        let data = DATA_MAP.may_load(deps.storage, key)?;
159        all_data.push(data);
160    }
161
162    Ok(ResponseWrapper::new("get_data", all_data))
163}
164
165fn query_list_keys(deps: Deps) -> StdResult<ResponseWrapper<Vec<String>>> {
166    let keys = DATA_MAP
167        .keys(deps.storage, None, None, Order::Ascending)
168        .map(|item| {
169            let key = item.unwrap();
170            key
171        })
172        .collect::<Vec<String>>();
173
174    Ok(ResponseWrapper::new("list_keys", keys))
175}