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
//! # Account Manager
//!
//! `abstract_std::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_std::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 std::collections::HashSet;
use cosmwasm_std::Addr;
use cw_storage_plus::{Item, Map};
pub use crate::objects::account::ACCOUNT_ID;
use crate::objects::module::ModuleId;
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 {
pub name: String,
pub chain_id: String,
pub description: Option<String>,
pub link: Option<String>,
}
/// 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> = Item::new("info");
/// 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");
/// List of sub-accounts
pub const SUB_ACCOUNTS: Map<u32, cosmwasm_std::Empty> = Map::new("sub_accs");
/// Context for old adapters that are currently removing authorized addresses
pub const REMOVE_ADAPTER_AUTHORIZED_CONTEXT: Item<u64> = Item::new("rm_a_auth");
// Additional states, not listed here: cw_gov_ownable::GovOwnership
}
use cosmwasm_schema::QueryResponses;
use cosmwasm_std::{Addr, Binary};
use cw2::ContractVersion;
use self::state::AccountInfo;
use crate::{
manager::state::SuspensionStatus,
objects::{
account::AccountId,
gov_type::{GovAction, GovernanceDetails, TopLevelOwnerResponse},
module::ModuleInfo,
ownership::Ownership,
AssetEntry,
},
};
/// 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 proxy_addr: 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 },
}
/// Module info and init message
#[non_exhaustive]
#[cosmwasm_schema::cw_serde]
pub struct ModuleInstallConfig {
pub module: ModuleInfo,
pub init_msg: Option<Binary>,
}
impl ModuleInstallConfig {
pub fn new(module: ModuleInfo, init_msg: Option<Binary>) -> Self {
Self { module, init_msg }
}
}
/// Manager execute messages
#[cosmwasm_schema::cw_serde]
#[derive(cw_orch::ExecuteFns)]
pub enum ExecuteMsg {
/// Forward execution message to module
#[cw_orch(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
#[cw_orch(payable)]
InstallModules {
// Module information and Instantiate message to instantiate the contract
modules: Vec<ModuleInstallConfig>,
},
/// 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
#[cw_orch(payable)]
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>,
/// If `None`, will create a new local account without asserting account-id.
///
/// When provided sequence in 0..2147483648 range: The tx will error
/// When provided sequence in 2147483648..u32::MAX range: Signals use of unclaimed Account Id in this range. The tx will error if this account-id already claimed. Useful for instantiate2 address prediction.
account_id: Option<u32>,
},
/// Update info
UpdateInfo {
name: Option<String>,
description: Option<String>,
link: Option<String>,
},
/// Update account statuses
UpdateStatus { is_suspended: Option<bool> },
/// Actions called by internal or external sub-accounts
UpdateSubAccount(UpdateSubAccountAction),
/// Callback endpoint
Callback(CallbackMsg),
/// Update the contract's ownership. The `action`
/// can propose transferring ownership to an account,
/// accept a pending ownership transfer, or renounce the ownership
/// of the account permanently.
UpdateOwnership(GovAction),
}
/// Manager query messages
#[cosmwasm_schema::cw_serde]
#[derive(QueryResponses, 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`]
#[returns(SubAccountIdsResponse)]
SubAccountIds {
start_after: Option<u32>,
limit: Option<u8>,
},
/// Returns [`TopLevelOwnerResponse`]
#[returns(TopLevelOwnerResponse)]
TopLevelOwner {},
/// Query the contract's ownership information
#[returns(Ownership<String>)]
Ownership {},
}
#[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,
}
#[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>,
}