use crate::error::CronCatContractError;
use crate::types::{CronCatTaskSubmessageParams, SubMessageReplyType};
use crate::{REPLY_CRONCAT_TASK_CREATION, TASKS_NAME};
use cosmwasm_std::CosmosMsg::Wasm;
use cosmwasm_std::WasmMsg::Execute;
use cosmwasm_std::{to_binary, Addr, CosmosMsg, MessageInfo, QuerierWrapper, SubMsg};
use croncat_sdk_factory::msg::ContractMetadataResponse;
use croncat_sdk_factory::msg::FactoryQueryMsg::LatestContract;
use croncat_sdk_tasks::msg::TasksExecuteMsg::CreateTask;
use croncat_sdk_tasks::types::TaskRequest;
pub fn get_latest_croncat_contract(
querier: &QuerierWrapper,
croncat_factory_address: Addr,
croncat_contract_name: String,
) -> Result<Addr, CronCatContractError> {
let query_factory_msg = LatestContract {
contract_name: croncat_contract_name.clone(),
};
let latest_contract_res: ContractMetadataResponse =
querier.query_wasm_smart(&croncat_factory_address, &query_factory_msg)?;
let contract_metadata =
latest_contract_res
.metadata
.ok_or(CronCatContractError::NoSuchContractOnFactory {
contract_name: croncat_contract_name,
factory_addr: croncat_factory_address,
version: "latest".to_owned(),
})?;
Ok(contract_metadata.contract_addr)
}
pub fn get_croncat_contract(
querier: &QuerierWrapper,
croncat_factory_address: Addr,
croncat_contract_name: String,
croncat_version: String,
) -> Result<Addr, CronCatContractError> {
let croncat_version_parsed = croncat_version
.split('.')
.map(|ver| {
ver.parse()
.map_err(|_| CronCatContractError::InvalidVersionString {})
})
.collect::<Result<Vec<u8>, _>>()?;
let contract_addr = croncat_factory::state::CONTRACT_ADDRS
.query(
querier,
croncat_factory_address.clone(),
(&croncat_contract_name, &croncat_version_parsed),
)?
.ok_or(CronCatContractError::NoSuchContractOnFactory {
contract_name: croncat_contract_name,
factory_addr: croncat_factory_address,
version: croncat_version,
})?;
Ok(contract_addr)
}
pub fn create_croncat_task_submessage(
querier: &QuerierWrapper,
info: MessageInfo,
croncat_factory_address: Addr,
task: TaskRequest,
reply_type: Option<CronCatTaskSubmessageParams>,
) -> Result<SubMsg, CronCatContractError> {
croncat_basic_validation(&info)?;
let wasm_exec_msg =
create_croncat_task_cosmos_msg(querier, info, croncat_factory_address, task)?;
let (reply_id, sub_reply_type) = match reply_type {
None => (REPLY_CRONCAT_TASK_CREATION, SubMessageReplyType::Always),
Some(params) => (
params.reply_id.unwrap_or(REPLY_CRONCAT_TASK_CREATION),
params.reply_type.unwrap_or(SubMessageReplyType::Always),
),
};
let sub_message = match sub_reply_type {
SubMessageReplyType::Always => SubMsg::reply_always(wasm_exec_msg, reply_id),
SubMessageReplyType::OnError => SubMsg::reply_on_error(wasm_exec_msg, reply_id),
SubMessageReplyType::OnSuccess => SubMsg::reply_on_success(wasm_exec_msg, reply_id),
};
Ok(sub_message)
}
pub fn create_croncat_task_message(
querier: &QuerierWrapper,
info: MessageInfo,
croncat_factory_address: Addr,
task: TaskRequest,
) -> Result<CosmosMsg, CronCatContractError> {
croncat_basic_validation(&info)?;
let wasm_exec_msg =
create_croncat_task_cosmos_msg(querier, info, croncat_factory_address, task)?;
Ok(wasm_exec_msg)
}
pub fn create_croncat_task_cosmos_msg(
querier: &QuerierWrapper,
info: MessageInfo,
croncat_factory_address: Addr,
task: TaskRequest,
) -> Result<CosmosMsg, CronCatContractError> {
let tasks_addr =
get_latest_croncat_contract(querier, croncat_factory_address, TASKS_NAME.to_string())?;
Ok(Wasm(Execute {
contract_addr: String::from(tasks_addr),
msg: to_binary(&CreateTask {
task: Box::new(task),
})?,
funds: info.funds,
}))
}
pub fn croncat_basic_validation(info: &MessageInfo) -> Result<(), CronCatContractError> {
if info.funds.is_empty() {
return Err(CronCatContractError::TaskCreationNoFunds {});
}
Ok(())
}