1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
use crate::{
account_commands::{self, receive_dispatch, receive_register, receive_send_all_back},
contract::HostResult,
};
use abstract_core::{
ibc_host::{
state::{ActionAfterCreationCache, TEMP_ACTION_AFTER_CREATION},
HelperAction,
},
objects::{chain_name::ChainName, AccountId},
};
use abstract_sdk::core::ibc_host::{HostAction, InternalAction};
use cosmwasm_std::{DepsMut, Env};
/// Handle actions that are passed to the IBC host contract
/// This function is not permissioned and access control needs to be handled outside of it
/// Usually the `client_chain` argument needs to be derived from the message sender
pub fn handle_host_action(
deps: DepsMut,
env: Env,
client_chain: ChainName,
proxy_address: String,
received_account_id: AccountId,
host_action: HostAction,
) -> HostResult {
// Push the client chain to the account trace
let mut account_id = received_account_id.clone();
account_id.trace_mut().push_chain(client_chain.clone());
// get the local account information
match host_action {
HostAction::Internal(InternalAction::Register {
description,
link,
name,
base_asset,
namespace,
install_modules,
}) => receive_register(
deps,
env,
account_id,
name,
description,
link,
base_asset,
namespace,
install_modules,
false,
),
action => {
// If this account already exists, we can propagate the action
if let Ok(account) = account_commands::get_account(deps.as_ref(), &account_id) {
match action {
HostAction::Dispatch { manager_msg } => {
receive_dispatch(deps, account, manager_msg)
}
HostAction::Helpers(helper_action) => match helper_action {
HelperAction::SendAllBack => {
receive_send_all_back(deps, env, account, proxy_address, client_chain)
}
_ => unimplemented!(""),
},
HostAction::Internal(InternalAction::Register { .. }) => {
unreachable!("This action is handled above")
}
_ => unimplemented!(""),
}
} else {
// If no account is created already, we create one and execute the action on reply
// The account metadata are not set with this call
// One will have to change them at a later point if they decide to
let name = format!(
"Remote Abstract Account for {}/{}",
client_chain.as_str(),
account_id
);
// We save the action they wanted to dispatch for the reply triggered by the receive_register function
TEMP_ACTION_AFTER_CREATION.save(
deps.storage,
&ActionAfterCreationCache {
action,
client_proxy_address: proxy_address,
account_id: received_account_id,
chain_name: client_chain,
},
)?;
receive_register(
deps,
env,
account_id,
name,
None,
None,
None,
None,
vec![],
true,
)
}
}
}
.map_err(Into::into)
}