Skip to content

Commit 1b0741c

Browse files
authored
Support multiple polytone evm connections on ica client (#567)
1 parent f2d49ab commit 1b0741c

File tree

7 files changed

+111
-39
lines changed

7 files changed

+111
-39
lines changed

framework/contracts/native/ica-client/src/chain_types/evm.rs

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,19 @@
1-
use abstract_ica::EVM_NOTE_ID;
2-
use abstract_sdk::{
3-
feature_objects::{AnsHost, RegistryContract},
4-
Resolve,
5-
};
1+
use abstract_sdk::{feature_objects::AnsHost, Resolve};
62
use abstract_std::{
73
ibc::PACKET_LIFETIME,
84
native_addrs,
9-
objects::{module::ModuleInfo, ChannelEntry, ContractEntry, TruncatedChainId},
10-
};
11-
use cosmwasm_std::{
12-
wasm_execute, Addr, Binary, Coin, CosmosMsg, Deps, Env, HexBinary, QuerierWrapper, WasmMsg,
5+
objects::{ChannelEntry, ContractEntry, TruncatedChainId},
136
};
7+
use cosmwasm_std::{wasm_execute, Addr, Binary, Coin, CosmosMsg, Deps, Env, HexBinary, WasmMsg};
148
use evm_note::msg::{CallbackRequest, EvmMsg};
159

1610
use crate::{contract::IcaClientResult, error::IcaClientError};
1711

1812
pub fn execute(
19-
querier: &QuerierWrapper,
20-
vc: &RegistryContract,
13+
note_addr: Addr,
2114
msgs: Vec<EvmMsg<String>>,
2215
callback: Option<CallbackRequest>,
2316
) -> IcaClientResult<WasmMsg> {
24-
let note_addr = evm_note_addr(vc, querier)?;
25-
2617
wasm_execute(
2718
note_addr,
2819
&evm_note::msg::ExecuteMsg::Execute {
@@ -38,6 +29,7 @@ pub fn execute(
3829
pub fn send_funds(
3930
deps: Deps,
4031
env: &Env,
32+
note_addr: &Addr,
4133
evm_chain: &TruncatedChainId,
4234
funds: Vec<Coin>,
4335
receiver: Option<Binary>,
@@ -50,12 +42,9 @@ pub fn send_funds(
5042
let receiver: HexBinary = match receiver {
5143
Some(r) => r.into(),
5244
None => {
53-
let registry = RegistryContract::new(deps, abstract_code_id)?;
54-
let note_addr = evm_note_addr(&registry, &deps.querier)?;
55-
5645
// If state objects will be public on evm_note
5746
let remote_acc: Option<String> = deps.querier.query_wasm_smart(
58-
&note_addr,
47+
note_addr,
5948
&evm_note::msg::QueryMsg::RemoteAddress {
6049
local_address: env.contract.address.to_string(),
6150
},
@@ -100,16 +89,6 @@ pub fn send_funds(
10089
Ok(forwarder_msg)
10190
}
10291

103-
fn evm_note_addr(vc: &RegistryContract, querier: &QuerierWrapper) -> IcaClientResult<Addr> {
104-
let evm_note_entry =
105-
ModuleInfo::from_id(EVM_NOTE_ID, abstract_ica::POLYTONE_EVM_VERSION.parse()?)?;
106-
107-
vc.query_module(evm_note_entry, querier)?
108-
.reference
109-
.unwrap_native()
110-
.map_err(Into::into)
111-
}
112-
11392
pub(crate) mod types {
11493
use super::*;
11594

framework/contracts/native/ica-client/src/contract.rs

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
use crate::msg::*;
22
use abstract_macros::abstract_response;
33
use abstract_std::{
4-
objects::module_version::{assert_cw_contract_upgrade, migrate_module_data},
4+
ica_client::state::{IcaInfrastructure, ICA_INFRA},
5+
objects::{
6+
module_version::{assert_cw_contract_upgrade, migrate_module_data},
7+
TruncatedChainId,
8+
},
59
ICA_CLIENT,
610
};
711
use cosmwasm_std::{to_json_binary, Deps, DepsMut, Env, MessageInfo, QueryResponse, Response};
@@ -36,7 +40,57 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> I
3640
cw_ownable::update_ownership(deps, &env.block, &info.sender, action)?;
3741
Ok(IcaClientResponse::action("update_ownership"))
3842
}
43+
ExecuteMsg::RegisterInfrastructure { chain, note} => {
44+
execute_register_infrastructure(deps, info, chain, note)
45+
}
46+
ExecuteMsg::RemoveHost { host_chain } => execute_remove_host(deps, info, host_chain),
47+
}
48+
}
49+
50+
/// Registers a chain to the client.
51+
/// This registration includes the counterparty information (note and proxy address)
52+
pub fn execute_register_infrastructure(
53+
deps: DepsMut,
54+
info: MessageInfo,
55+
host_chain: TruncatedChainId,
56+
note: String,
57+
) -> IcaClientResult {
58+
host_chain.verify()?;
59+
60+
// auth check
61+
cw_ownable::assert_owner(deps.storage, &info.sender)?;
62+
63+
let note = deps.api.addr_validate(&note)?;
64+
// Can't allow if it already exists
65+
if ICA_INFRA.has(deps.storage, &host_chain) {
66+
return Err(IcaClientError::ChainExists {});
3967
}
68+
69+
ICA_INFRA.save(
70+
deps.storage,
71+
&host_chain,
72+
&IcaInfrastructure {
73+
polytone_note: note.clone(),
74+
},
75+
)?;
76+
77+
Ok(IcaClientResponse::action("register_infrastructure"))
78+
}
79+
80+
// allows admins to clear host if needed
81+
pub fn execute_remove_host(
82+
deps: DepsMut,
83+
info: MessageInfo,
84+
host_chain: TruncatedChainId,
85+
) -> IcaClientResult {
86+
host_chain.verify()?;
87+
88+
// auth check
89+
cw_ownable::assert_owner(deps.storage, &info.sender)?;
90+
91+
ICA_INFRA.remove(deps.storage, &host_chain);
92+
93+
Ok(IcaClientResponse::action("remove_host"))
4094
}
4195

4296
#[cfg_attr(feature = "export", cosmwasm_std::entry_point)]

framework/contracts/native/ica-client/src/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,7 @@ pub enum IcaClientError {
3030

3131
#[error("messages for chain {chain} are not of type {ty}")]
3232
WrongChainType { chain: String, ty: String },
33+
34+
#[error("Chain already registered.")]
35+
ChainExists {},
3336
}

framework/contracts/native/ica-client/src/queries.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use abstract_ica::{msg::ConfigResponse, ChainType, IcaAction, IcaActionResponse};
22
use abstract_sdk::feature_objects::{AnsHost, RegistryContract};
3-
use abstract_std::{native_addrs, objects::TruncatedChainId};
3+
use abstract_std::{ica_client::state::ICA_INFRA, native_addrs, objects::TruncatedChainId};
44
use cosmwasm_std::{ensure_eq, CosmosMsg, Deps, Env};
55

66
use crate::{chain_types::evm, contract::IcaClientResult, error::IcaClientError};
@@ -28,6 +28,13 @@ pub(crate) fn ica_action(
2828
chain: chain.to_string(),
2929
})?;
3030

31+
let ica_infra =
32+
ICA_INFRA
33+
.may_load(deps.storage, &chain)?
34+
.ok_or(IcaClientError::NoChainType {
35+
chain: chain.to_string(),
36+
})?;
37+
3138
let process_action = |action: IcaAction| -> IcaClientResult<Vec<CosmosMsg>> {
3239
match action {
3340
IcaAction::Execute(ica_exec) => match ica_exec {
@@ -40,13 +47,8 @@ pub(crate) fn ica_action(
4047
ty: chain_type.to_string()
4148
}
4249
);
43-
let abstract_code_id = native_addrs::abstract_code_id(
44-
&deps.querier,
45-
env.contract.address.clone(),
46-
)?;
47-
let registry = RegistryContract::new(deps, abstract_code_id)?;
4850

49-
let msg = evm::execute(&deps.querier, &registry, msgs, callback)?;
51+
let msg = evm::execute(ica_infra.polytone_note.clone(), msgs, callback)?;
5052

5153
Ok(vec![msg.into()])
5254
}
@@ -58,7 +60,13 @@ pub(crate) fn ica_action(
5860
memo,
5961
} => match chain_type {
6062
ChainType::Evm => Ok(vec![evm::send_funds(
61-
deps, &env, &chain, funds, receiver, memo,
63+
deps,
64+
&env,
65+
&ica_infra.polytone_note,
66+
&chain,
67+
funds,
68+
receiver,
69+
memo,
6270
)?]),
6371
_ => unimplemented!(),
6472
},

framework/packages/abstract-ica/src/msg.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,21 @@ pub enum MigrateMsg {
1717
Migrate {},
1818
}
1919

20+
pub type EvmChainId = u64;
21+
2022
#[cw_ownable_execute]
2123
#[cosmwasm_schema::cw_serde]
2224
#[derive(cw_orch::ExecuteFns)]
23-
pub enum ExecuteMsg {}
25+
pub enum ExecuteMsg {
26+
RegisterInfrastructure {
27+
/// Chain to register the infrastructure for ("sepolia", "osmosis", "holesky", etc.)
28+
chain: TruncatedChainId,
29+
/// Polytone note (locally deployed)
30+
note: String,
31+
},
32+
/// Owner method: Remove connection for remote chain
33+
RemoveHost { host_chain: TruncatedChainId },
34+
}
2435

2536
#[cw_ownable_query]
2637
#[cosmwasm_schema::cw_serde]
Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,16 @@
1-
pub mod state {}
1+
pub mod state {
2+
use cosmwasm_std::Addr;
3+
use cw_storage_plus::Map;
4+
5+
use crate::objects::{storage_namespaces, TruncatedChainId};
6+
7+
/// Information about the deployed infrastructure we're connected to.
8+
#[cosmwasm_schema::cw_serde]
9+
pub struct IcaInfrastructure {
10+
/// Address of the polytone note deployed on the local chain. This contract will forward the messages for us.
11+
pub polytone_note: Addr,
12+
}
13+
14+
pub const ICA_INFRA: Map<&TruncatedChainId, IcaInfrastructure> =
15+
Map::new(storage_namespaces::ica_client::ICA_INFRA);
16+
}

framework/packages/abstract-std/src/objects/storage_namespaces.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,6 @@ pub mod ibc_host {
6868
pub const TEMP_ACTION_AFTER_CREATION: &str = "fc";
6969
}
7070

71-
pub mod ica_client {}
71+
pub mod ica_client {
72+
pub const ICA_INFRA: &str = "ga";
73+
}

0 commit comments

Comments
 (0)