polytone_proxy/
contract.rs1#[cfg(not(feature = "library"))]
2use cosmwasm_std::entry_point;
3use cosmwasm_std::{
4 to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdResult, SubMsg,
5 SubMsgResponse, SubMsgResult,
6};
7use cw2::set_contract_version;
8use polytone::ack::ack_execute_success;
9
10use crate::error::ContractError;
11use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg};
12use crate::state::{COLLECTOR, INSTANTIATOR};
13
14const CONTRACT_NAME: &str = "crates.io:polytone-proxy";
15const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
16
17#[cfg_attr(not(feature = "library"), entry_point)]
18pub fn instantiate(
19 deps: DepsMut,
20 _env: Env,
21 info: MessageInfo,
22 _msg: InstantiateMsg,
23) -> Result<Response, ContractError> {
24 set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
25 INSTANTIATOR.save(deps.storage, &info.sender)?;
26
27 Ok(Response::default()
28 .add_attribute("method", "instantiate")
29 .add_attribute("owner", info.sender))
30}
31
32#[cfg_attr(not(feature = "library"), entry_point)]
33pub fn execute(
34 deps: DepsMut,
35 env: Env,
36 info: MessageInfo,
37 msg: ExecuteMsg,
38) -> Result<Response, ContractError> {
39 match msg {
40 ExecuteMsg::Proxy { msgs } => {
41 if info.sender == INSTANTIATOR.load(deps.storage)? {
42 let response = Response::default()
43 .add_attribute("method", "execute_proxy")
44 .add_attribute("sender", info.sender);
45 if msgs.is_empty() {
46 Ok(response.set_data(ack_execute_success(
47 vec![],
48 env.contract.address.into_string(),
49 )))
50 } else {
51 COLLECTOR.save(deps.storage, &vec![None; msgs.len()])?;
52 Ok(response.add_submessages(
53 msgs.into_iter()
54 .enumerate()
55 .map(|(id, msg)| SubMsg::reply_always(msg, id as u64)),
56 ))
57 }
58 } else {
59 Err(ContractError::NotInstantiator)
60 }
61 }
62 }
63}
64
65#[cfg_attr(not(feature = "library"), entry_point)]
66pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
67 match msg {
68 QueryMsg::Instantiator {} => to_binary(&INSTANTIATOR.load(deps.storage)?),
69 }
70}
71
72#[cfg_attr(not(feature = "library"), entry_point)]
73pub fn reply(deps: DepsMut, env: Env, msg: Reply) -> Result<Response, ContractError> {
74 let mut collector = COLLECTOR.load(deps.storage)?;
75
76 match msg.result {
77 SubMsgResult::Err(error) => Err(ContractError::MsgError {
78 index: msg.id,
79 error,
80 }),
81 SubMsgResult::Ok(res) => {
82 collector[msg.id as usize] = Some(res);
83
84 if msg.id + 1 == collector.len() as u64 {
85 COLLECTOR.remove(deps.storage);
86 let collector = collector
87 .into_iter()
88 .map(|res| res.unwrap())
89 .collect::<Vec<SubMsgResponse>>();
90 Ok(Response::default()
91 .add_attribute("callbacks_processed", (msg.id + 1).to_string())
92 .set_data(ack_execute_success(
93 collector,
94 env.contract.address.into_string(),
95 )))
96 } else {
97 COLLECTOR.save(deps.storage, &collector)?;
98 Ok(Response::default())
99 }
100 }
101 }
102}