warp_resolver/
contract.rs

1use crate::util::condition::{resolve_cond, resolve_query_expr};
2use crate::util::variable::{
3    apply_var_fn, has_duplicates, hydrate_msgs, hydrate_vars, msgs_valid, string_vars_in_vector,
4    vars_valid,
5};
6use crate::ContractError;
7use cosmwasm_std::{
8    entry_point, to_binary, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Response, StdError,
9    StdResult,
10};
11
12use warp_resolver_pkg::condition::Condition;
13use warp_resolver_pkg::variable::{QueryExpr, Variable};
14use warp_resolver_pkg::{
15    ExecuteApplyVarFnMsg, ExecuteHydrateMsgsMsg, ExecuteHydrateVarsMsg, ExecuteMsg,
16    ExecuteResolveConditionMsg, ExecuteSimulateQueryMsg, ExecuteValidateJobCreationMsg,
17    InstantiateMsg, MigrateMsg, QueryApplyVarFnMsg, QueryHydrateMsgsMsg, QueryHydrateVarsMsg,
18    QueryMsg, QueryResolveConditionMsg, QueryValidateJobCreationMsg, SimulateQueryMsg,
19    SimulateResponse,
20};
21
22#[cfg_attr(not(feature = "library"), entry_point)]
23pub fn instantiate(
24    _deps: DepsMut,
25    _env: Env,
26    _info: MessageInfo,
27    _msg: InstantiateMsg,
28) -> Result<Response, ContractError> {
29    Ok(Response::new().add_attribute("action", "instantiate"))
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::ExecuteSimulateQuery(msg) => execute_simulate_query(deps, env, info, msg),
41        ExecuteMsg::ExecuteValidateJobCreation(data) => {
42            execute_validate_job_creation(deps, env, info, data)
43        }
44        ExecuteMsg::ExecuteHydrateVars(data) => execute_hydrate_vars(deps, env, info, data),
45        ExecuteMsg::ExecuteResolveCondition(data) => {
46            execute_resolve_condition(deps, env, info, data)
47        }
48        ExecuteMsg::ExecuteApplyVarFn(data) => execute_apply_var_fn(deps, env, info, data),
49        ExecuteMsg::ExecuteHydrateMsgs(data) => execute_hydrate_msgs(deps, env, info, data),
50    }
51}
52
53pub fn execute_simulate_query(
54    deps: DepsMut,
55    env: Env,
56    _info: MessageInfo,
57    msg: ExecuteSimulateQueryMsg,
58) -> Result<Response, ContractError> {
59    let result = query_simulate_query(deps.as_ref(), env, SimulateQueryMsg { query: msg.query })?;
60
61    Ok(Response::new()
62        .add_attribute("action", "execute_simulate_query")
63        .add_attribute("response", result.response))
64}
65
66pub fn execute_validate_job_creation(
67    deps: DepsMut,
68    env: Env,
69    _info: MessageInfo,
70    data: ExecuteValidateJobCreationMsg,
71) -> Result<Response, ContractError> {
72    let result = query_validate_job_creation(
73        deps.as_ref(),
74        env,
75        QueryValidateJobCreationMsg {
76            condition: data.condition,
77            terminate_condition: data.terminate_condition,
78            vars: data.vars,
79            msgs: data.msgs,
80        },
81    )?;
82
83    Ok(Response::new()
84        .add_attribute("action", "execute_validate_job_creation")
85        .add_attribute(
86            "response",
87            if result.is_empty() {
88                "valid"
89            } else {
90                "invalid"
91            },
92        ))
93}
94
95pub fn execute_hydrate_vars(
96    deps: DepsMut,
97    env: Env,
98    _info: MessageInfo,
99    data: ExecuteHydrateVarsMsg,
100) -> Result<Response, ContractError> {
101    let result = query_hydrate_vars(
102        deps.as_ref(),
103        env,
104        QueryHydrateVarsMsg {
105            vars: data.vars,
106            external_inputs: data.external_inputs,
107        },
108    )?;
109
110    Ok(Response::new()
111        .add_attribute("action", "execute_hydrate_vars")
112        .add_attribute("response", result))
113}
114
115pub fn execute_resolve_condition(
116    deps: DepsMut,
117    env: Env,
118    _info: MessageInfo,
119    data: ExecuteResolveConditionMsg,
120) -> Result<Response, ContractError> {
121    let result = query_resolve_condition(
122        deps.as_ref(),
123        env,
124        QueryResolveConditionMsg {
125            condition: data.condition,
126            vars: data.vars,
127        },
128    )?;
129
130    Ok(Response::new()
131        .add_attribute("action", "execute_resolve_condition")
132        .add_attribute("response", result.to_string()))
133}
134
135pub fn execute_apply_var_fn(
136    deps: DepsMut,
137    env: Env,
138    _info: MessageInfo,
139    data: ExecuteApplyVarFnMsg,
140) -> Result<Response, ContractError> {
141    let result = query_apply_var_fn(
142        deps.as_ref(),
143        env,
144        QueryApplyVarFnMsg {
145            vars: data.vars,
146            status: data.status,
147        },
148    )?;
149    Ok(Response::new()
150        .add_attribute("action", "execute_apply_var_fn")
151        .add_attribute("response", result))
152}
153
154pub fn execute_hydrate_msgs(
155    deps: DepsMut,
156    env: Env,
157    _info: MessageInfo,
158    data: ExecuteHydrateMsgsMsg,
159) -> Result<Response, ContractError> {
160    let result = query_hydrate_msgs(
161        deps.as_ref(),
162        env,
163        QueryHydrateMsgsMsg {
164            msgs: data.msgs,
165            vars: data.vars,
166        },
167    )?;
168
169    Ok(Response::new()
170        .add_attribute("action", "execute_hydrate_msgs")
171        .add_attribute("response", serde_json_wasm::to_string(&result)?))
172}
173
174#[cfg_attr(not(feature = "library"), entry_point)]
175pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {
176    match msg {
177        QueryMsg::SimulateQuery(data) => to_binary(&query_simulate_query(deps, env, data)?),
178        QueryMsg::QueryValidateJobCreation(data) => {
179            to_binary(&query_validate_job_creation(deps, env, data)?)
180        }
181        QueryMsg::QueryHydrateVars(data) => to_binary(&query_hydrate_vars(deps, env, data)?),
182        QueryMsg::QueryResolveCondition(data) => {
183            to_binary(&query_resolve_condition(deps, env, data)?)
184        }
185        QueryMsg::QueryApplyVarFn(data) => to_binary(&query_apply_var_fn(deps, env, data)?),
186        QueryMsg::QueryHydrateMsgs(data) => to_binary(&query_hydrate_msgs(deps, env, data)?),
187    }
188}
189
190fn query_validate_job_creation(
191    _deps: Deps,
192    _env: Env,
193    data: QueryValidateJobCreationMsg,
194) -> StdResult<String> {
195    let _condition: Condition = serde_json_wasm::from_str(&data.condition)
196        .map_err(|e| StdError::generic_err(format!("Condition input invalid: {}", e)))?;
197    let terminate_condition_str = data.terminate_condition.clone().unwrap_or("".to_string());
198    if !terminate_condition_str.is_empty() {
199        let _terminate_condition: Condition = serde_json_wasm::from_str(&terminate_condition_str)
200            .map_err(|e| {
201            StdError::generic_err(format!("Terminate condition input invalid: {}", e))
202        })?;
203    }
204    let vars: Vec<Variable> = serde_json_wasm::from_str(&data.vars)
205        .map_err(|e| StdError::generic_err(format!("Vars input invalid: {}", e)))?;
206
207    if !vars_valid(&vars) {
208        return Err(StdError::generic_err(
209            ContractError::InvalidVariables {}.to_string(),
210        ));
211    }
212
213    if has_duplicates(&vars) {
214        return Err(StdError::generic_err(
215            ContractError::VariablesContainDuplicates {}.to_string(),
216        ));
217    }
218
219    if !(string_vars_in_vector(&vars, &data.condition)
220        && string_vars_in_vector(&vars, &terminate_condition_str)
221        && string_vars_in_vector(&vars, &data.msgs))
222    {
223        return Err(StdError::generic_err(
224            ContractError::VariablesMissingFromVector {}.to_string(),
225        ));
226    }
227
228    if !msgs_valid(&data.msgs, &vars).map_err(|e| StdError::generic_err(e.to_string()))? {
229        return Err(StdError::generic_err(
230            ContractError::MsgError {
231                msg: "msgs are invalid".to_string(),
232            }
233            .to_string(),
234        ));
235    }
236
237    Ok("".to_string())
238}
239
240fn query_hydrate_vars(deps: Deps, env: Env, data: QueryHydrateVarsMsg) -> StdResult<String> {
241    let vars: Vec<Variable> =
242        serde_json_wasm::from_str(&data.vars).map_err(|e| StdError::generic_err(e.to_string()))?;
243    serde_json_wasm::to_string(
244        &hydrate_vars(deps, env, vars, data.external_inputs)
245            .map_err(|e| StdError::generic_err(e.to_string()))?,
246    )
247    .map_err(|e| StdError::generic_err(e.to_string()))
248}
249
250fn query_resolve_condition(
251    deps: Deps,
252    env: Env,
253    data: QueryResolveConditionMsg,
254) -> StdResult<bool> {
255    let condition: Condition = serde_json_wasm::from_str(&data.condition)
256        .map_err(|e| StdError::generic_err(e.to_string()))?;
257    let vars: Vec<Variable> =
258        serde_json_wasm::from_str(&data.vars).map_err(|e| StdError::generic_err(e.to_string()))?;
259
260    resolve_cond(deps, env, condition, &vars).map_err(|e| StdError::generic_err(e.to_string()))
261}
262
263fn query_apply_var_fn(deps: Deps, env: Env, data: QueryApplyVarFnMsg) -> StdResult<String> {
264    let vars: Vec<Variable> =
265        serde_json_wasm::from_str(&data.vars).map_err(|e| StdError::generic_err(e.to_string()))?;
266
267    apply_var_fn(deps, env, vars, data.status).map_err(|e| StdError::generic_err(e.to_string()))
268}
269
270fn query_hydrate_msgs(
271    _deps: Deps,
272    _env: Env,
273    data: QueryHydrateMsgsMsg,
274) -> StdResult<Vec<CosmosMsg>> {
275    let vars: Vec<Variable> =
276        serde_json_wasm::from_str(&data.vars).map_err(|e| StdError::generic_err(e.to_string()))?;
277
278    hydrate_msgs(data.msgs, vars).map_err(|e| StdError::generic_err(e.to_string()))
279}
280
281pub fn query_simulate_query(
282    deps: Deps,
283    env: Env,
284    data: SimulateQueryMsg,
285) -> StdResult<SimulateResponse> {
286    Ok(SimulateResponse {
287        response: resolve_query_expr(
288            deps,
289            env,
290            QueryExpr {
291                selector: "".to_string(),
292                query: data.query,
293            },
294        )
295        .map_err(|e| StdError::generic_err(e.to_string()))?,
296    })
297}
298
299#[cfg_attr(not(feature = "library"), entry_point)]
300pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result<Response, ContractError> {
301    Ok(Response::new())
302}