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 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
//! # Account Manager
//!
//! `abstract_core::manager` implements the contract interface and state lay-out.
//!
//! ## Description
//!
//! The Account manager is part of the Core Abstract Account contracts along with the `abstract_core::proxy` contract.
//! This contract is responsible for:
//! - Managing modules instantiation and migrations.
//! - Managing permissions.
//! - Upgrading the Account and its modules.
//! - Providing module name to address resolution.
//!
//! **The manager should be set as the contract/CosmWasm admin by default on your modules.**
//! ## Migration
//! Migrating this contract is done by calling `ExecuteMsg::Upgrade` with `abstract::manager` as module.
pub mod state {
use crate::module_factory::ModuleInstallConfig;
pub use crate::objects::account::ACCOUNT_ID;
use crate::objects::common_namespace::OWNERSHIP_STORAGE_KEY;
use crate::objects::{gov_type::GovernanceDetails, module::ModuleId};
use cosmwasm_std::{Addr, Deps};
use cw_address_like::AddressLike;
use cw_controllers::Admin;
use cw_ownable::Ownership;
use cw_storage_plus::{Item, Map};
use std::collections::HashSet;
pub type SuspensionStatus = bool;
/// Manager configuration
#[cosmwasm_schema::cw_serde]
pub struct Config {
pub version_control_address: Addr,
pub module_factory_address: Addr,
}
/// Abstract Account details.
#[cosmwasm_schema::cw_serde]
pub struct AccountInfo<T: AddressLike = Addr> {
pub name: String,
pub governance_details: GovernanceDetails<T>,
pub chain_id: String,
pub description: Option<String>,
pub link: Option<String>,
}
impl AccountInfo<String> {
/// Check an account's info, verifying the gov details.
pub fn verify(
self,
deps: Deps,
version_control_addr: Addr,
) -> Result<AccountInfo<Addr>, crate::AbstractError> {
let governance_details = self.governance_details.verify(deps, version_control_addr)?;
Ok(AccountInfo {
name: self.name,
governance_details,
chain_id: self.chain_id,
description: self.description,
link: self.link,
})
}
}
impl From<AccountInfo<Addr>> for AccountInfo<String> {
fn from(value: AccountInfo<Addr>) -> Self {
AccountInfo {
name: value.name,
governance_details: value.governance_details.into(),
chain_id: value.chain_id,
description: value.description,
link: value.link,
}
}
}
/// Suspension status
pub const SUSPENSION_STATUS: Item<SuspensionStatus> = Item::new("\u{0}{12}is_suspended");
/// Configuration
pub const CONFIG: Item<Config> = Item::new("\u{0}{6}config");
/// Info about the Account
pub const INFO: Item<AccountInfo<Addr>> = Item::new("\u{0}{4}info");
/// Contract Admin
pub const ACCOUNT_FACTORY: Admin = Admin::new("\u{0}{7}factory");
/// Account owner - managed by cw-ownable
pub const OWNER: Item<Ownership<Addr>> = Item::new(OWNERSHIP_STORAGE_KEY);
/// Enabled Abstract modules
pub const ACCOUNT_MODULES: Map<ModuleId, Addr> = Map::new("modules");
/// Stores the dependency relationship between modules
/// map module -> modules that depend on module.
pub const DEPENDENTS: Map<ModuleId, HashSet<String>> = Map::new("dependents");
/// Stores a queue of modules to install on the account after creation.
pub const MODULE_QUEUE: Item<Vec<ModuleInstallConfig>> = Item::new("mqueue");
/// List of sub-accounts
pub const SUB_ACCOUNTS: Map<u32, cosmwasm_std::Empty> = Map::new("sub_accs");
/// Pending new governance
pub const PENDING_GOVERNANCE: Item<GovernanceDetails<Addr>> = Item::new("pgov");
}
use self::state::AccountInfo;
use crate::manager::state::SuspensionStatus;
use crate::module_factory::ModuleInstallConfig;
use crate::objects::AssetEntry;
use crate::objects::{
account::AccountId,
gov_type::GovernanceDetails,
module::{Module, ModuleInfo},
};
use cosmwasm_schema::QueryResponses;
use cosmwasm_std::{Addr, Binary};
use cw2::ContractVersion;
/// Manager Migrate Msg
#[cosmwasm_schema::cw_serde]
pub struct MigrateMsg {}
/// Manager Instantiate Msg
#[cosmwasm_schema::cw_serde]
pub struct InstantiateMsg {
pub account_id: AccountId,
pub owner: GovernanceDetails<String>,
pub version_control_address: String,
pub module_factory_address: String,
pub name: String,
pub description: Option<String>,
pub link: Option<String>,
// Optionally modules can be provided. They will be installed after account registration.
pub install_modules: Vec<ModuleInstallConfig>,
}
/// Callback message to set the dependencies after module upgrades.
#[cosmwasm_schema::cw_serde]
pub struct CallbackMsg {}
/// Internal configuration actions accessible from the [`ExecuteMsg::UpdateInternalConfig`] message.
#[cosmwasm_schema::cw_serde]
#[non_exhaustive]
pub enum InternalConfigAction {
/// Updates the [`state::ACCOUNT_MODULES`] map
/// Only callable by account factory or owner.
UpdateModuleAddresses {
to_add: Option<Vec<(String, String)>>,
to_remove: Option<Vec<String>>,
},
}
#[cosmwasm_schema::cw_serde]
#[non_exhaustive]
pub enum UpdateSubAccountAction {
/// Unregister sub-account
/// It will unregister sub-account from the state
/// Could be called only by the sub-account itself
UnregisterSubAccount { id: u32 },
/// Register sub-account
/// It will register new sub-account into the state
/// Could be called by the sub-account manager
/// Note: since it happens after the claim by this manager state won't have spam accounts
RegisterSubAccount { id: u32 },
}
#[cosmwasm_schema::cw_serde]
pub struct RegisterModuleData {
pub module_address: String,
pub module: Module,
}
/// Manager execute messages
#[cw_ownable::cw_ownable_execute]
#[cosmwasm_schema::cw_serde]
#[cfg_attr(feature = "interface", derive(cw_orch::ExecuteFns))]
pub enum ExecuteMsg {
/// Forward execution message to module
#[cfg_attr(feature = "interface", payable)]
ExecOnModule { module_id: String, exec_msg: Binary },
/// Update Abstract-specific configuration of the module.
/// Only callable by the account factory or owner.
UpdateInternalConfig(Binary),
/// Install module using module factory, callable by Owner
#[cfg_attr(feature = "interface", payable)]
InstallModules {
// Module information and Instantiate message to instantiate the contract
modules: Vec<ModuleInstallConfig>,
},
/// Registers a module after creation.
/// Used as a callback *only* by the Module Factory to register the module on the Account.
RegisterModules { modules: Vec<RegisterModuleData> },
/// Uninstall a module given its ID.
UninstallModule { module_id: String },
/// Upgrade the module to a new version
/// If module is `abstract::manager` then the contract will do a self-migration.
Upgrade {
modules: Vec<(ModuleInfo, Option<Binary>)>,
},
/// Creates a sub-account on the account
CreateSubAccount {
// Name of the sub-account
name: String,
// Description of the account
description: Option<String>,
// URL linked to the account
link: Option<String>,
// Optionally specify a base asset for the sub-account
base_asset: Option<AssetEntry>,
// optionally specify a namespace for the sub-account
namespace: Option<String>,
// Provide list of module to install after sub-account creation
install_modules: Vec<ModuleInstallConfig>,
},
/// Update info
UpdateInfo {
name: Option<String>,
description: Option<String>,
link: Option<String>,
},
/// Sets a new Owner
/// New owner will have to claim ownership
SetOwner { owner: GovernanceDetails<String> },
/// Update account statuses
UpdateStatus { is_suspended: Option<bool> },
/// Update settings for the Account, including IBC enabled, etc.
UpdateSettings { ibc_enabled: Option<bool> },
/// Actions called by internal or external sub-accounts
UpdateSubAccount(UpdateSubAccountAction),
/// Callback endpoint
Callback(CallbackMsg),
}
/// Manager query messages
#[cw_ownable::cw_ownable_query]
#[cosmwasm_schema::cw_serde]
#[derive(QueryResponses)]
#[cfg_attr(feature = "interface", derive(cw_orch::QueryFns))]
pub enum QueryMsg {
/// Query the versions of modules installed on the account given their `ids`.
/// Returns [`ModuleVersionsResponse`]
#[returns(ModuleVersionsResponse)]
ModuleVersions { ids: Vec<String> },
/// Query the addresses of modules installed on the account given their `ids`.
/// Returns [`ModuleAddressesResponse`]
#[returns(ModuleAddressesResponse)]
ModuleAddresses { ids: Vec<String> },
/// Query information of all modules installed on the account.
/// Returns [`ModuleInfosResponse`]
#[returns(ModuleInfosResponse)]
ModuleInfos {
start_after: Option<String>,
limit: Option<u8>,
},
/// Query the manager's config.
/// Returns [`ConfigResponse`]
#[returns(ConfigResponse)]
Config {},
/// Query the Account info.
/// Returns [`InfoResponse`]
#[returns(InfoResponse)]
Info {},
#[returns(SubAccountIdsResponse)]
SubAccountIds {
start_after: Option<u32>,
limit: Option<u8>,
},
}
#[cosmwasm_schema::cw_serde]
pub struct ModuleVersionsResponse {
pub versions: Vec<ContractVersion>,
}
#[cosmwasm_schema::cw_serde]
pub struct ModuleAddressesResponse {
pub modules: Vec<(String, Addr)>,
}
#[cosmwasm_schema::cw_serde]
pub struct ConfigResponse {
pub account_id: AccountId,
pub is_suspended: SuspensionStatus,
pub version_control_address: Addr,
pub module_factory_address: Addr,
}
#[cosmwasm_schema::cw_serde]
pub struct InfoResponse {
pub info: AccountInfo<Addr>,
}
#[cosmwasm_schema::cw_serde]
pub struct ManagerModuleInfo {
pub id: String,
pub version: ContractVersion,
pub address: Addr,
}
#[cosmwasm_schema::cw_serde]
pub struct ModuleInfosResponse {
pub module_infos: Vec<ManagerModuleInfo>,
}
#[cosmwasm_schema::cw_serde]
pub struct SubAccountIdsResponse {
pub sub_accounts: Vec<u32>,
}