use crate::{Abstract, AbstractInterfaceError, IbcClient, IbcHost, VersionControl};
use abstract_std::{IBC_CLIENT, IBC_HOST};
use cw_orch::prelude::*;
pub struct AbstractIbc<Chain: CwEnv> {
pub client: IbcClient<Chain>,
pub host: IbcHost<Chain>,
}
impl<Chain: CwEnv> AbstractIbc<Chain> {
pub fn new(chain: &Chain) -> Self {
let ibc_client = IbcClient::new(IBC_CLIENT, chain.clone());
let ibc_host = IbcHost::new(IBC_HOST, chain.clone());
Self {
client: ibc_client,
host: ibc_host,
}
}
pub fn upload(&self) -> Result<(), crate::AbstractInterfaceError> {
self.client.upload()?;
self.host.upload()?;
Ok(())
}
pub fn instantiate(&self, abstr: &Abstract<Chain>, admin: &Addr) -> Result<(), CwOrchError> {
self.client.instantiate(
&abstract_std::ibc_client::InstantiateMsg {
ans_host_address: abstr.ans_host.addr_str()?,
version_control_address: abstr.version_control.addr_str()?,
},
Some(admin),
None,
)?;
self.host.instantiate(
&abstract_std::ibc_host::InstantiateMsg {
ans_host_address: abstr.ans_host.addr_str()?,
account_factory_address: abstr.account_factory.addr_str()?,
version_control_address: abstr.version_control.addr_str()?,
},
Some(admin),
None,
)?;
Ok(())
}
pub fn register(
&self,
version_control: &VersionControl<Chain>,
) -> Result<(), AbstractInterfaceError> {
version_control.register_natives(vec![
(
self.client.as_instance(),
ibc_client::contract::CONTRACT_VERSION.to_string(),
),
(
self.host.as_instance(),
ibc_host::contract::CONTRACT_VERSION.to_string(),
),
])
}
}
#[cfg(feature="interchain")]
pub mod connection {
use super::*;
use cw_orch_interchain::prelude::*;
use cw_orch_interchain::InterchainError;
use abstract_std::account_factory::ExecuteMsgFns;
use abstract_std::ibc_client::ExecuteMsgFns as _;
use abstract_std::ibc_client::QueryMsgFns;
use abstract_std::ibc_host::ExecuteMsgFns as _;
use abstract_std::objects::chain_name::ChainName;
use cw_orch_polytone::Polytone;
pub fn abstract_ibc_connection_with<Chain: IbcQueryHandler, IBC: InterchainEnv<Chain>>(
abstr: &Abstract<Chain>,
interchain: &IBC,
dest: &Abstract<Chain>,
polytone_src: &Polytone<Chain>,
) -> Result<(), InterchainError> {
let chain1_id = abstr.ibc.client.get_chain().chain_id();
let chain1_name = ChainName::from_chain_id(&chain1_id);
let chain2_id = dest.ibc.client.get_chain().chain_id();
let chain2_name = ChainName::from_chain_id(&chain2_id);
let proxy_tx_result = abstr.ibc.client.register_infrastructure(
chain2_name.to_string(),
dest.ibc.host.address()?.to_string(),
polytone_src.note.address()?.to_string(),
)?;
interchain.check_ibc(&chain1_id, proxy_tx_result)?;
let proxy_address = abstr.ibc.client.host(chain2_name.to_string())?;
dest.ibc.host.register_chain_proxy(
chain1_name.to_string(),
proxy_address.remote_polytone_proxy.unwrap(),
)?;
dest.account_factory.update_config(
None,
Some(dest.ibc.host.address()?.to_string()),
None,
None,
)?;
Ok(())
}
}