use abstract_core::{
account_factory,
ibc_host::state::CONFIG,
manager::{self, ModuleInstallConfig},
objects::{chain_name::ChainName, AccountId, AssetEntry},
proxy,
version_control::AccountBase,
PROXY,
};
use abstract_sdk::{
core::{objects::ChannelEntry, ICS20},
Resolve,
};
use cosmwasm_std::{
to_json_binary, wasm_execute, CosmosMsg, Deps, DepsMut, Env, IbcMsg, Response, SubMsg,
};
use crate::{
contract::{HostResponse, HostResult},
endpoints::reply::{INIT_BEFORE_ACTION_REPLY_ID, RESPONSE_REPLY_ID},
HostError,
};
const PACKET_LIFETIME: u64 = 60 * 60;
#[allow(clippy::too_many_arguments)]
pub fn receive_register(
deps: DepsMut,
env: Env,
account_id: AccountId,
name: String,
description: Option<String>,
link: Option<String>,
base_asset: Option<AssetEntry>,
namespace: Option<String>,
install_modules: Vec<ModuleInstallConfig>,
with_reply: bool,
) -> HostResult {
let cfg = CONFIG.load(deps.storage)?;
account_id.trace().verify_remote()?;
let factory_msg = wasm_execute(
cfg.account_factory,
&account_factory::ExecuteMsg::CreateAccount {
governance: abstract_core::objects::gov_type::GovernanceDetails::External {
governance_address: env.contract.address.into_string(),
governance_type: "abstract-ibc".into(), },
name,
description,
link,
account_id: Some(account_id.clone()),
base_asset,
install_modules,
namespace,
},
vec![],
)?;
let sub_msg = if with_reply {
SubMsg::reply_on_success(factory_msg, INIT_BEFORE_ACTION_REPLY_ID)
} else {
SubMsg::new(factory_msg)
};
Ok(Response::new()
.add_submessage(sub_msg)
.add_attribute("action", "register"))
}
pub fn receive_dispatch(
_deps: DepsMut,
account: AccountBase,
manager_msg: manager::ExecuteMsg,
) -> HostResult {
let manager_call_msg = wasm_execute(account.manager, &manager_msg, vec![])?;
let submsg = SubMsg::reply_on_success(manager_call_msg, RESPONSE_REPLY_ID);
Ok(Response::new()
.add_submessage(submsg)
.add_attribute("action", "receive_dispatch"))
}
pub fn receive_send_all_back(
deps: DepsMut,
env: Env,
account: AccountBase,
client_proxy_address: String,
client_chain: ChainName,
) -> HostResult {
let wasm_msg = send_all_back(
deps.as_ref(),
env,
account,
client_proxy_address,
client_chain,
)?;
Ok(HostResponse::action("receive_dispatch").add_message(wasm_msg))
}
pub fn send_all_back(
deps: Deps,
env: Env,
account: AccountBase,
client_proxy_address: String,
client_chain: ChainName,
) -> Result<CosmosMsg, HostError> {
let ans = CONFIG.load(deps.storage)?.ans_host;
let ics20_channel_entry = ChannelEntry {
connected_chain: client_chain,
protocol: ICS20.to_string(),
};
let ics20_channel_id = ics20_channel_entry.resolve(&deps.querier, &ans)?;
let coins = deps.querier.query_all_balances(account.proxy)?;
let mut msgs: Vec<CosmosMsg> = vec![];
for coin in coins {
msgs.push(
IbcMsg::Transfer {
channel_id: ics20_channel_id.clone(),
to_address: client_proxy_address.to_string(),
amount: coin,
timeout: env.block.time.plus_seconds(PACKET_LIFETIME).into(),
}
.into(),
)
}
let manager_msg = wasm_execute(
account.manager,
&manager::ExecuteMsg::ExecOnModule {
module_id: PROXY.into(),
exec_msg: to_json_binary(&proxy::ExecuteMsg::ModuleAction { msgs })?,
},
vec![],
)?;
Ok(manager_msg.into())
}
pub fn get_account(deps: Deps, account_id: &AccountId) -> Result<AccountBase, HostError> {
let version_control = CONFIG.load(deps.storage)?.version_control;
let account_base = version_control.account_base(account_id, &deps.querier)?;
Ok(account_base)
}