abstract_std/native/
ibc.rspub mod ibc_client;
pub mod ibc_host;
pub mod ica_client;
pub mod polytone_callbacks;
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{
to_json_binary, wasm_execute, Binary, CosmosMsg, Empty, Event, QueryRequest, StdError,
StdResult,
};
use schemars::JsonSchema;
use serde::Serialize;
use crate::{
base::ExecuteMsg,
objects::{module::ModuleInfo, TruncatedChainId},
};
use polytone_callbacks::{Callback as PolytoneCallback, ErrorResponse, ExecutionResponse};
#[cosmwasm_schema::cw_serde]
pub struct Callback {
pub msg: Binary,
}
impl Callback {
pub fn new<T: Serialize>(msg: &T) -> StdResult<Self> {
Ok(Self {
msg: to_json_binary(msg)?,
})
}
}
#[cosmwasm_schema::cw_serde]
pub struct IbcResponseMsg {
pub callback: Callback,
pub result: IbcResult,
}
impl IbcResponseMsg {
pub fn into_json_binary(self) -> StdResult<Binary> {
let msg = ExecuteMsg::IbcCallback::<Empty, Empty>(self);
to_json_binary(&msg)
}
pub fn into_cosmos_msg<T: Into<String>, C>(self, contract_addr: T) -> StdResult<CosmosMsg<C>>
where
C: Clone + std::fmt::Debug + PartialEq + JsonSchema,
{
Ok(wasm_execute(
contract_addr.into(),
&ExecuteMsg::IbcCallback::<Empty, Empty>(self),
vec![],
)?
.into())
}
}
#[cosmwasm_schema::cw_serde]
pub enum IbcResult {
Query {
queries: Vec<QueryRequest<ModuleQuery>>,
results: Result<Vec<Binary>, ErrorResponse>,
},
Execute {
initiator_msg: Binary,
result: Result<ExecutionResponse, String>,
},
FatalError(String),
}
impl IbcResult {
pub fn from_query(
callback: PolytoneCallback,
queries: Vec<QueryRequest<ModuleQuery>>,
) -> Result<Self, StdError> {
match callback {
PolytoneCallback::Query(q) => Ok(Self::Query {
queries,
results: q,
}),
PolytoneCallback::Execute(_) => Err(StdError::generic_err(
"Expected a query result, got an execute result",
)),
PolytoneCallback::FatalError(e) => Ok(Self::FatalError(e)),
}
}
pub fn from_execute(
callback: PolytoneCallback,
initiator_msg: Binary,
) -> Result<Self, StdError> {
match callback {
PolytoneCallback::Query(_) => Err(StdError::generic_err(
"Expected an execution result, got a query result",
)),
PolytoneCallback::Execute(e) => Ok(Self::Execute {
initiator_msg,
result: e,
}),
PolytoneCallback::FatalError(e) => Ok(Self::FatalError(e)),
}
}
pub fn get_query_result(&self, index: usize) -> StdResult<(QueryRequest<ModuleQuery>, Binary)> {
match &self {
IbcResult::Query { queries, results } => {
let results = results
.as_ref()
.map_err(|err| StdError::generic_err(err.error.clone()))?;
Ok((queries[index].clone(), results[index].clone()))
}
IbcResult::Execute { .. } => Err(StdError::generic_err(
"expected query, got execute ibc result",
)),
IbcResult::FatalError(err) => Err(StdError::generic_err(err.to_owned())),
}
}
pub fn get_execute_events(&self) -> StdResult<Vec<Event>> {
match &self {
IbcResult::Execute { result, .. } => {
let result = result
.as_ref()
.map_err(|err| StdError::generic_err(err.clone()))?;
let res = result
.result
.first()
.expect("execution response without submsg");
Ok(res.events.clone())
}
IbcResult::Query { .. } => Err(StdError::generic_err(
"expected execute, got query ibc result",
)),
IbcResult::FatalError(err) => Err(StdError::generic_err(err.to_owned())),
}
}
}
#[cw_serde]
pub struct ModuleIbcMsg {
pub src_module_info: ModuleIbcInfo,
pub msg: Binary,
}
#[cw_serde]
pub struct ModuleIbcInfo {
pub chain: TruncatedChainId,
pub module: ModuleInfo,
}
#[cw_serde]
pub struct ModuleQuery {
pub target_module: ibc_client::InstalledModuleIdentification,
pub msg: Binary,
}