use crate::error::{anyhow, bail, AnyError, AnyResult};
use cosmwasm_std::{
from_json, Binary, CosmosMsg, CustomMsg, CustomQuery, Deps, DepsMut, Empty, Env, MessageInfo,
QuerierWrapper, Reply, Response, SubMsg,
};
use cosmwasm_std::{
IbcBasicResponse, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg,
IbcChannelOpenResponse, IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg,
IbcReceiveResponse,
};
use serde::de::DeserializeOwned;
use std::fmt::{Debug, Display};
use std::ops::Deref;
#[rustfmt::skip]
pub trait Contract<C, Q = Empty>
where
C: CustomMsg,
Q: CustomQuery,
{
fn execute(&self, deps: DepsMut<Q>, env: Env, info: MessageInfo, msg: Vec<u8>) -> AnyResult<Response<C>>;
fn instantiate(&self, deps: DepsMut<Q>, env: Env, info: MessageInfo, msg: Vec<u8>) -> AnyResult<Response<C>>;
fn query(&self, deps: Deps<Q>, env: Env, msg: Vec<u8>) -> AnyResult<Binary>;
fn sudo(&self, deps: DepsMut<Q>, env: Env, msg: Vec<u8>) -> AnyResult<Response<C>>;
fn reply(&self, deps: DepsMut<Q>, env: Env, msg: Reply) -> AnyResult<Response<C>>;
fn migrate(&self, deps: DepsMut<Q>, env: Env, msg: Vec<u8>) -> AnyResult<Response<C>>;
#[allow(unused)]
fn ibc_channel_open(
&self,
deps: DepsMut<Q>,
env: Env,
msg: IbcChannelOpenMsg,
) -> AnyResult<IbcChannelOpenResponse> {
bail!("No Ibc capabilities on this contract")
}
#[allow(unused)]
fn ibc_channel_connect(
&self,
deps: DepsMut<Q>,
env: Env,
msg: IbcChannelConnectMsg,
) -> AnyResult<IbcBasicResponse<C>> {
bail!("No Ibc capabilities on this contract")
}
#[allow(unused)]
fn ibc_channel_close(
&self,
deps: DepsMut<Q>,
env: Env,
msg: IbcChannelCloseMsg,
) -> AnyResult<IbcBasicResponse<C>> {
bail!("No Ibc capabilities on this contract")
}
#[allow(unused)]
fn ibc_packet_receive(
&self,
deps: DepsMut<Q>,
env: Env,
msg: IbcPacketReceiveMsg,
) -> AnyResult<IbcReceiveResponse<C>> {
bail!("No Ibc capabilities on this contract")
}
#[allow(unused)]
fn ibc_packet_acknowledge(
&self,
deps: DepsMut<Q>,
env: Env,
msg: IbcPacketAckMsg,
) -> AnyResult<IbcBasicResponse<C>> {
bail!("No Ibc capabilities on this contract")
}
#[allow(unused)]
fn ibc_packet_timeout(
&self,
deps: DepsMut<Q>,
env: Env,
msg: IbcPacketTimeoutMsg,
) -> AnyResult<IbcBasicResponse<C>> {
bail!("No Ibc capabilities on this contract")
}
}
#[rustfmt::skip]
mod closures {
use super::*;
pub type IbcFn<T, R, E, Q> = fn(deps: DepsMut<Q>, env: Env, msg: T) -> Result<R, E>;
pub type ContractFn<T, C, E, Q> = fn(deps: DepsMut<Q>, env: Env, info: MessageInfo, msg: T) -> Result<Response<C>, E>;
pub type PermissionedFn<T, C, E, Q> = fn(deps: DepsMut<Q>, env: Env, msg: T) -> Result<Response<C>, E>;
pub type ReplyFn<C, E, Q> = fn(deps: DepsMut<Q>, env: Env, msg: Reply) -> Result<Response<C>, E>;
pub type QueryFn<T, E, Q> = fn(deps: Deps<Q>, env: Env, msg: T) -> Result<Binary, E>;
pub type IbcClosure<T, R, E, Q> = Box<dyn Fn(DepsMut<Q>,Env, T) -> Result<R, E>>;
pub type ContractClosure<T, C, E, Q> = Box<dyn Fn(DepsMut<Q>, Env, MessageInfo, T) -> Result<Response<C>, E>>;
pub type PermissionedClosure<T, C, E, Q> = Box<dyn Fn(DepsMut<Q>, Env, T) -> Result<Response<C>, E>>;
pub type ReplyClosure<C, E, Q> = Box<dyn Fn(DepsMut<Q>, Env, Reply) -> Result<Response<C>, E>>;
pub type QueryClosure<T, E, Q> = Box<dyn Fn(Deps<Q>, Env, T) -> Result<Binary, E>>;
}
use closures::*;
pub struct ContractWrapper<
T1,
T2,
T3,
E1,
E2,
E3,
C = Empty,
Q = Empty,
T4 = Empty,
E4 = AnyError,
E5 = AnyError,
T6 = Empty,
E6 = AnyError,
E7 = AnyError,
E8 = AnyError,
E9 = AnyError,
E10 = AnyError,
E11 = AnyError,
E12 = AnyError,
> where
T1: DeserializeOwned, T2: DeserializeOwned, T3: DeserializeOwned, T4: DeserializeOwned, T6: DeserializeOwned, E1: Display + Debug + Send + Sync, E2: Display + Debug + Send + Sync, E3: Display + Debug + Send + Sync, E4: Display + Debug + Send + Sync, E5: Display + Debug + Send + Sync, E6: Display + Debug + Send + Sync, E7: Display + Debug + Send + Sync, E8: Display + Debug + Send + Sync, E9: Display + Debug + Send + Sync, E10: Display + Debug + Send + Sync, E11: Display + Debug + Send + Sync, E12: Display + Debug + Send + Sync, C: CustomMsg, Q: CustomQuery + DeserializeOwned, {
execute_fn: ContractClosure<T1, C, E1, Q>,
instantiate_fn: ContractClosure<T2, C, E2, Q>,
query_fn: QueryClosure<T3, E3, Q>,
sudo_fn: Option<PermissionedClosure<T4, C, E4, Q>>,
reply_fn: Option<ReplyClosure<C, E5, Q>>,
migrate_fn: Option<PermissionedClosure<T6, C, E6, Q>>,
channel_open_fn: Option<IbcClosure<IbcChannelOpenMsg, IbcChannelOpenResponse, E7, Q>>,
channel_connect_fn: Option<IbcClosure<IbcChannelConnectMsg, IbcBasicResponse<C>, E8, Q>>,
channel_close_fn: Option<IbcClosure<IbcChannelCloseMsg, IbcBasicResponse<C>, E9, Q>>,
ibc_packet_receive_fn: Option<IbcClosure<IbcPacketReceiveMsg, IbcReceiveResponse<C>, E10, Q>>,
ibc_packet_ack_fn: Option<IbcClosure<IbcPacketAckMsg, IbcBasicResponse<C>, E11, Q>>,
ibc_packet_timeout_fn: Option<IbcClosure<IbcPacketTimeoutMsg, IbcBasicResponse<C>, E12, Q>>,
}
impl<T1, T2, T3, E1, E2, E3, C, Q> ContractWrapper<T1, T2, T3, E1, E2, E3, C, Q>
where
T1: DeserializeOwned + 'static, T2: DeserializeOwned + 'static, T3: DeserializeOwned + 'static, E1: Display + Debug + Send + Sync + 'static, E2: Display + Debug + Send + Sync + 'static, E3: Display + Debug + Send + Sync + 'static, C: CustomMsg + 'static, Q: CustomQuery + DeserializeOwned + 'static, {
pub fn new(
execute_fn: ContractFn<T1, C, E1, Q>,
instantiate_fn: ContractFn<T2, C, E2, Q>,
query_fn: QueryFn<T3, E3, Q>,
) -> Self {
Self {
execute_fn: Box::new(execute_fn),
instantiate_fn: Box::new(instantiate_fn),
query_fn: Box::new(query_fn),
sudo_fn: None,
reply_fn: None,
migrate_fn: None,
channel_open_fn: None,
channel_connect_fn: None,
channel_close_fn: None,
ibc_packet_receive_fn: None,
ibc_packet_ack_fn: None,
ibc_packet_timeout_fn: None,
}
}
pub fn new_with_empty(
execute_fn: ContractFn<T1, Empty, E1, Empty>,
instantiate_fn: ContractFn<T2, Empty, E2, Empty>,
query_fn: QueryFn<T3, E3, Empty>,
) -> Self {
Self {
execute_fn: customize_contract_fn(execute_fn),
instantiate_fn: customize_contract_fn(instantiate_fn),
query_fn: customize_query_fn(query_fn),
sudo_fn: None,
reply_fn: None,
migrate_fn: None,
channel_open_fn: None,
channel_connect_fn: None,
channel_close_fn: None,
ibc_packet_receive_fn: None,
ibc_packet_ack_fn: None,
ibc_packet_timeout_fn: None,
}
}
}
#[allow(clippy::type_complexity)]
impl<T1, T2, T3, E1, E2, E3, C, Q, T4, E4, E5, T6, E6>
ContractWrapper<T1, T2, T3, E1, E2, E3, C, Q, T4, E4, E5, T6, E6>
where
T1: DeserializeOwned, T2: DeserializeOwned, T3: DeserializeOwned, T4: DeserializeOwned, T6: DeserializeOwned, E1: Display + Debug + Send + Sync, E2: Display + Debug + Send + Sync, E3: Display + Debug + Send + Sync, E4: Display + Debug + Send + Sync, E5: Display + Debug + Send + Sync, E6: Display + Debug + Send + Sync, C: CustomMsg + 'static, Q: CustomQuery + DeserializeOwned + 'static, {
pub fn with_sudo<T4A, E4A>(
self,
sudo_fn: PermissionedFn<T4A, C, E4A, Q>,
) -> ContractWrapper<T1, T2, T3, E1, E2, E3, C, Q, T4A, E4A, E5, T6, E6>
where
T4A: DeserializeOwned + 'static,
E4A: Display + Debug + Send + Sync + 'static,
{
ContractWrapper {
execute_fn: self.execute_fn,
instantiate_fn: self.instantiate_fn,
query_fn: self.query_fn,
sudo_fn: Some(Box::new(sudo_fn)),
reply_fn: self.reply_fn,
migrate_fn: self.migrate_fn,
channel_open_fn: self.channel_open_fn,
channel_connect_fn: self.channel_connect_fn,
channel_close_fn: self.channel_close_fn,
ibc_packet_receive_fn: self.ibc_packet_receive_fn,
ibc_packet_ack_fn: self.ibc_packet_ack_fn,
ibc_packet_timeout_fn: self.ibc_packet_timeout_fn,
}
}
pub fn with_sudo_empty<T4A, E4A>(
self,
sudo_fn: PermissionedFn<T4A, Empty, E4A, Empty>,
) -> ContractWrapper<T1, T2, T3, E1, E2, E3, C, Q, T4A, E4A, E5, T6, E6>
where
T4A: DeserializeOwned + 'static,
E4A: Display + Debug + Send + Sync + 'static,
{
ContractWrapper {
execute_fn: self.execute_fn,
instantiate_fn: self.instantiate_fn,
query_fn: self.query_fn,
sudo_fn: Some(customize_permissioned_fn(sudo_fn)),
reply_fn: self.reply_fn,
migrate_fn: self.migrate_fn,
channel_open_fn: self.channel_open_fn,
channel_connect_fn: self.channel_connect_fn,
channel_close_fn: self.channel_close_fn,
ibc_packet_receive_fn: self.ibc_packet_receive_fn,
ibc_packet_ack_fn: self.ibc_packet_ack_fn,
ibc_packet_timeout_fn: self.ibc_packet_timeout_fn,
}
}
pub fn with_reply<E5A>(
self,
reply_fn: ReplyFn<C, E5A, Q>,
) -> ContractWrapper<T1, T2, T3, E1, E2, E3, C, Q, T4, E4, E5A, T6, E6>
where
E5A: Display + Debug + Send + Sync + 'static,
{
ContractWrapper {
execute_fn: self.execute_fn,
instantiate_fn: self.instantiate_fn,
query_fn: self.query_fn,
sudo_fn: self.sudo_fn,
reply_fn: Some(Box::new(reply_fn)),
migrate_fn: self.migrate_fn,
channel_open_fn: self.channel_open_fn,
channel_connect_fn: self.channel_connect_fn,
channel_close_fn: self.channel_close_fn,
ibc_packet_receive_fn: self.ibc_packet_receive_fn,
ibc_packet_ack_fn: self.ibc_packet_ack_fn,
ibc_packet_timeout_fn: self.ibc_packet_timeout_fn,
}
}
pub fn with_reply_empty<E5A>(
self,
reply_fn: ReplyFn<Empty, E5A, Empty>,
) -> ContractWrapper<T1, T2, T3, E1, E2, E3, C, Q, T4, E4, E5A, T6, E6>
where
E5A: Display + Debug + Send + Sync + 'static,
{
ContractWrapper {
execute_fn: self.execute_fn,
instantiate_fn: self.instantiate_fn,
query_fn: self.query_fn,
sudo_fn: self.sudo_fn,
reply_fn: Some(customize_permissioned_fn(reply_fn)),
migrate_fn: self.migrate_fn,
channel_open_fn: self.channel_open_fn,
channel_connect_fn: self.channel_connect_fn,
channel_close_fn: self.channel_close_fn,
ibc_packet_receive_fn: self.ibc_packet_receive_fn,
ibc_packet_ack_fn: self.ibc_packet_ack_fn,
ibc_packet_timeout_fn: self.ibc_packet_timeout_fn,
}
}
pub fn with_migrate<T6A, E6A>(
self,
migrate_fn: PermissionedFn<T6A, C, E6A, Q>,
) -> ContractWrapper<T1, T2, T3, E1, E2, E3, C, Q, T4, E4, E5, T6A, E6A>
where
T6A: DeserializeOwned + 'static,
E6A: Display + Debug + Send + Sync + 'static,
{
ContractWrapper {
execute_fn: self.execute_fn,
instantiate_fn: self.instantiate_fn,
query_fn: self.query_fn,
sudo_fn: self.sudo_fn,
reply_fn: self.reply_fn,
migrate_fn: Some(Box::new(migrate_fn)),
channel_open_fn: self.channel_open_fn,
channel_connect_fn: self.channel_connect_fn,
channel_close_fn: self.channel_close_fn,
ibc_packet_receive_fn: self.ibc_packet_receive_fn,
ibc_packet_ack_fn: self.ibc_packet_ack_fn,
ibc_packet_timeout_fn: self.ibc_packet_timeout_fn,
}
}
pub fn with_migrate_empty<T6A, E6A>(
self,
migrate_fn: PermissionedFn<T6A, Empty, E6A, Empty>,
) -> ContractWrapper<T1, T2, T3, E1, E2, E3, C, Q, T4, E4, E5, T6A, E6A>
where
T6A: DeserializeOwned + 'static,
E6A: Display + Debug + Send + Sync + 'static,
{
ContractWrapper {
execute_fn: self.execute_fn,
instantiate_fn: self.instantiate_fn,
query_fn: self.query_fn,
sudo_fn: self.sudo_fn,
reply_fn: self.reply_fn,
migrate_fn: Some(customize_permissioned_fn(migrate_fn)),
channel_open_fn: self.channel_open_fn,
channel_connect_fn: self.channel_connect_fn,
channel_close_fn: self.channel_close_fn,
ibc_packet_receive_fn: self.ibc_packet_receive_fn,
ibc_packet_ack_fn: self.ibc_packet_ack_fn,
ibc_packet_timeout_fn: self.ibc_packet_timeout_fn,
}
}
pub fn with_ibc<E7A, E8A, E9A, E10A, E11A, E12A>(
self,
channel_open_fn: IbcFn<IbcChannelOpenMsg, IbcChannelOpenResponse, E7A, Q>,
channel_connect_fn: IbcFn<IbcChannelConnectMsg, IbcBasicResponse<C>, E8A, Q>,
channel_close_fn: IbcFn<IbcChannelCloseMsg, IbcBasicResponse<C>, E9A, Q>,
ibc_packet_receive_fn: IbcFn<IbcPacketReceiveMsg, IbcReceiveResponse<C>, E10A, Q>,
ibc_packet_ack_fn: IbcFn<IbcPacketAckMsg, IbcBasicResponse<C>, E11A, Q>,
ibc_packet_timeout_fn: IbcFn<IbcPacketTimeoutMsg, IbcBasicResponse<C>, E12A, Q>,
) -> ContractWrapper<
T1,
T2,
T3,
E1,
E2,
E3,
C,
Q,
T4,
E4,
E5,
T6,
E6,
E7A,
E8A,
E9A,
E10A,
E11A,
E12A,
>
where
E7A: Display + Debug + Send + Sync + 'static,
E8A: Display + Debug + Send + Sync + 'static,
E9A: Display + Debug + Send + Sync + 'static,
E10A: Display + Debug + Send + Sync + 'static,
E11A: Display + Debug + Send + Sync + 'static,
E12A: Display + Debug + Send + Sync + 'static,
{
ContractWrapper {
execute_fn: self.execute_fn,
instantiate_fn: self.instantiate_fn,
query_fn: self.query_fn,
sudo_fn: self.sudo_fn,
reply_fn: self.reply_fn,
migrate_fn: self.migrate_fn,
channel_open_fn: Some(Box::new(channel_open_fn)),
channel_connect_fn: Some(Box::new(channel_connect_fn)),
channel_close_fn: Some(Box::new(channel_close_fn)),
ibc_packet_receive_fn: Some(Box::new(ibc_packet_receive_fn)),
ibc_packet_ack_fn: Some(Box::new(ibc_packet_ack_fn)),
ibc_packet_timeout_fn: Some(Box::new(ibc_packet_timeout_fn)),
}
}
}
fn customize_contract_fn<T, C, E, Q>(
raw_fn: ContractFn<T, Empty, E, Empty>,
) -> ContractClosure<T, C, E, Q>
where
T: DeserializeOwned + 'static,
E: Display + Debug + Send + Sync + 'static,
C: CustomMsg,
Q: CustomQuery + DeserializeOwned,
{
Box::new(
move |mut deps: DepsMut<Q>,
env: Env,
info: MessageInfo,
msg: T|
-> Result<Response<C>, E> {
let deps = decustomize_deps_mut(&mut deps);
raw_fn(deps, env, info, msg).map(customize_response::<C>)
},
)
}
fn customize_query_fn<T, E, Q>(raw_fn: QueryFn<T, E, Empty>) -> QueryClosure<T, E, Q>
where
T: DeserializeOwned + 'static,
E: Display + Debug + Send + Sync + 'static,
Q: CustomQuery + DeserializeOwned,
{
Box::new(
move |deps: Deps<Q>, env: Env, msg: T| -> Result<Binary, E> {
let deps = decustomize_deps(&deps);
raw_fn(deps, env, msg)
},
)
}
fn customize_permissioned_fn<T, C, E, Q>(
raw_fn: PermissionedFn<T, Empty, E, Empty>,
) -> PermissionedClosure<T, C, E, Q>
where
T: DeserializeOwned + 'static,
E: Display + Debug + Send + Sync + 'static,
C: CustomMsg,
Q: CustomQuery + DeserializeOwned,
{
Box::new(
move |mut deps: DepsMut<Q>, env: Env, msg: T| -> Result<Response<C>, E> {
let deps = decustomize_deps_mut(&mut deps);
raw_fn(deps, env, msg).map(customize_response::<C>)
},
)
}
fn decustomize_deps_mut<'a, Q>(deps: &'a mut DepsMut<Q>) -> DepsMut<'a, Empty>
where
Q: CustomQuery + DeserializeOwned,
{
DepsMut {
storage: deps.storage,
api: deps.api,
querier: QuerierWrapper::new(deps.querier.deref()),
}
}
fn decustomize_deps<'a, Q>(deps: &'a Deps<'a, Q>) -> Deps<'a, Empty>
where
Q: CustomQuery + DeserializeOwned,
{
Deps {
storage: deps.storage,
api: deps.api,
querier: QuerierWrapper::new(deps.querier.deref()),
}
}
fn customize_response<C>(resp: Response<Empty>) -> Response<C>
where
C: CustomMsg,
{
let mut customized_resp = Response::<C>::new()
.add_submessages(resp.messages.into_iter().map(customize_msg::<C>))
.add_events(resp.events)
.add_attributes(resp.attributes);
customized_resp.data = resp.data;
customized_resp
}
fn customize_msg<C>(msg: SubMsg<Empty>) -> SubMsg<C>
where
C: CustomMsg,
{
SubMsg {
msg: match msg.msg {
CosmosMsg::Wasm(wasm) => CosmosMsg::Wasm(wasm),
CosmosMsg::Bank(bank) => CosmosMsg::Bank(bank),
CosmosMsg::Staking(staking) => CosmosMsg::Staking(staking),
CosmosMsg::Distribution(distribution) => CosmosMsg::Distribution(distribution),
CosmosMsg::Custom(_) => unreachable!(),
CosmosMsg::Ibc(ibc) => CosmosMsg::Ibc(ibc),
CosmosMsg::Stargate { type_url, value } => CosmosMsg::Stargate { type_url, value },
_ => panic!("unknown message variant {:?}", msg),
},
id: msg.id,
gas_limit: msg.gas_limit,
reply_on: msg.reply_on,
}
}
impl<T1, T2, T3, E1, E2, E3, C, T4, E4, E5, T6, E6, E7, E8, E9, E10, E11, E12, Q> Contract<C, Q>
for ContractWrapper<T1, T2, T3, E1, E2, E3, C, Q, T4, E4, E5, T6, E6, E7, E8, E9, E10, E11, E12>
where
T1: DeserializeOwned, T2: DeserializeOwned, T3: DeserializeOwned, T4: DeserializeOwned, T6: DeserializeOwned, E1: Display + Debug + Send + Sync + 'static, E2: Display + Debug + Send + Sync + 'static, E3: Display + Debug + Send + Sync + 'static, E4: Display + Debug + Send + Sync + 'static, E5: Display + Debug + Send + Sync + 'static, E6: Display + Debug + Send + Sync + 'static, E7: Display + Debug + Send + Sync + 'static, E8: Display + Debug + Send + Sync + 'static, E9: Display + Debug + Send + Sync + 'static, E10: Display + Debug + Send + Sync + 'static, E11: Display + Debug + Send + Sync + 'static, E12: Display + Debug + Send + Sync + 'static, C: CustomMsg, Q: CustomQuery + DeserializeOwned, {
fn execute(
&self,
deps: DepsMut<Q>,
env: Env,
info: MessageInfo,
msg: Vec<u8>,
) -> AnyResult<Response<C>> {
let msg: T1 = from_json(msg)?;
(self.execute_fn)(deps, env, info, msg).map_err(|err: E1| anyhow!(err))
}
fn instantiate(
&self,
deps: DepsMut<Q>,
env: Env,
info: MessageInfo,
msg: Vec<u8>,
) -> AnyResult<Response<C>> {
let msg: T2 = from_json(msg)?;
(self.instantiate_fn)(deps, env, info, msg).map_err(|err: E2| anyhow!(err))
}
fn query(&self, deps: Deps<Q>, env: Env, msg: Vec<u8>) -> AnyResult<Binary> {
let msg: T3 = from_json(msg)?;
(self.query_fn)(deps, env, msg).map_err(|err: E3| anyhow!(err))
}
fn sudo(&self, deps: DepsMut<Q>, env: Env, msg: Vec<u8>) -> AnyResult<Response<C>> {
let msg: T4 = from_json(msg)?;
match &self.sudo_fn {
Some(sudo) => sudo(deps, env, msg).map_err(|err: E4| anyhow!(err)),
None => bail!("sudo is not implemented for contract"),
}
}
fn reply(&self, deps: DepsMut<Q>, env: Env, reply_data: Reply) -> AnyResult<Response<C>> {
let msg: Reply = reply_data;
match &self.reply_fn {
Some(reply) => reply(deps, env, msg).map_err(|err: E5| anyhow!(err)),
None => bail!("reply is not implemented for contract"),
}
}
fn migrate(&self, deps: DepsMut<Q>, env: Env, msg: Vec<u8>) -> AnyResult<Response<C>> {
let msg: T6 = from_json(msg)?;
match &self.migrate_fn {
Some(migrate) => migrate(deps, env, msg).map_err(|err: E6| anyhow!(err)),
None => bail!("migrate is not implemented for contract"),
}
}
fn ibc_channel_open(
&self,
deps: DepsMut<Q>,
env: Env,
msg: IbcChannelOpenMsg,
) -> AnyResult<IbcChannelOpenResponse> {
match &self.channel_open_fn {
Some(channel_open) => channel_open(deps, env, msg).map_err(|err| anyhow!(err)),
None => bail!("channel open not implemented for contract"),
}
}
fn ibc_channel_connect(
&self,
deps: DepsMut<Q>,
env: Env,
msg: IbcChannelConnectMsg,
) -> AnyResult<IbcBasicResponse<C>> {
match &self.channel_connect_fn {
Some(channel_connect) => channel_connect(deps, env, msg).map_err(|err| anyhow!(err)),
None => bail!("channel connect not implemented for contract"),
}
}
fn ibc_channel_close(
&self,
deps: DepsMut<Q>,
env: Env,
msg: IbcChannelCloseMsg,
) -> AnyResult<IbcBasicResponse<C>> {
match &self.channel_close_fn {
Some(channel_close) => channel_close(deps, env, msg).map_err(|err| anyhow!(err)),
None => bail!("channel close not implemented for contract"),
}
}
fn ibc_packet_receive(
&self,
deps: DepsMut<Q>,
env: Env,
msg: IbcPacketReceiveMsg,
) -> AnyResult<IbcReceiveResponse<C>> {
match &self.ibc_packet_receive_fn {
Some(packet_receive) => packet_receive(deps, env, msg).map_err(|err| anyhow!(err)),
None => bail!("packet receive not implemented for contract"),
}
}
fn ibc_packet_acknowledge(
&self,
deps: DepsMut<Q>,
env: Env,
msg: IbcPacketAckMsg,
) -> AnyResult<IbcBasicResponse<C>> {
match &self.ibc_packet_ack_fn {
Some(packet_ack) => packet_ack(deps, env, msg).map_err(|err| anyhow!(err)),
None => bail!("packet ack not implemented for contract"),
}
}
fn ibc_packet_timeout(
&self,
deps: DepsMut<Q>,
env: Env,
msg: IbcPacketTimeoutMsg,
) -> AnyResult<IbcBasicResponse<C>> {
match &self.ibc_packet_timeout_fn {
Some(packet_timeout) => packet_timeout(deps, env, msg).map_err(|err| anyhow!(err)),
None => bail!("packet timeout not implemented for contract"),
}
}
}