use cosmwasm_schema::QueryResponses;
use cosmwasm_std::{Binary, Coin, CosmosMsg, Empty};
use crate::objects::{
gov_type::{GovAction, GovernanceDetails, TopLevelOwnerResponse},
module::ModuleInfo,
ownership::Ownership,
AccountId,
};
use cosmwasm_std::Addr;
use cw2::ContractVersion;
use state::{AccountInfo, SuspensionStatus};
pub mod state {
use std::collections::HashSet;
use cosmwasm_std::Addr;
use cw_storage_plus::{Item, Map};
use crate::objects::{module::ModuleId, storage_namespaces, AccountId};
pub type SuspensionStatus = bool;
#[cosmwasm_schema::cw_serde]
#[derive(Default)]
pub struct AccountInfo {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub link: Option<String>,
}
impl AccountInfo {
pub fn has_info(&self) -> bool {
self.name.is_some() || self.description.is_some() || self.link.is_some()
}
}
#[cosmwasm_schema::cw_serde]
pub struct WhitelistedModules(pub Vec<Addr>);
pub const WHITELISTED_MODULES: Item<WhitelistedModules> =
Item::new(storage_namespaces::account::WHITELISTED_MODULES);
pub const SUSPENSION_STATUS: Item<SuspensionStatus> =
Item::new(storage_namespaces::account::SUSPENSION_STATUS);
pub const INFO: Item<AccountInfo> = Item::new(storage_namespaces::account::INFO);
pub const ACCOUNT_MODULES: Map<ModuleId, Addr> =
Map::new(storage_namespaces::account::ACCOUNT_MODULES);
pub const DEPENDENTS: Map<ModuleId, HashSet<String>> =
Map::new(storage_namespaces::account::DEPENDENTS);
pub const SUB_ACCOUNTS: Map<u32, cosmwasm_std::Empty> =
Map::new(storage_namespaces::account::SUB_ACCOUNTS);
pub const ACCOUNT_ID: Item<AccountId> = Item::new(storage_namespaces::account::ACCOUNT_ID);
pub const CALLING_TO_AS_ADMIN: Item<Addr> =
Item::new(storage_namespaces::account::CALLING_TO_AS_ADMIN);
pub const CALLING_TO_AS_ADMIN_WILD_CARD: &str = "calling-to-wild-card";
#[cfg(feature = "xion")]
pub const AUTH_ADMIN: Item<bool> = Item::new(storage_namespaces::account::AUTH_ADMIN);
}
#[cosmwasm_schema::cw_serde]
pub struct MigrateMsg {
pub code_id: Option<u64>,
}
#[cosmwasm_schema::cw_serde]
pub struct InstantiateMsg<Authenticator = Empty> {
pub code_id: u64,
pub owner: Option<GovernanceDetails<String>>,
pub account_id: Option<AccountId>,
pub authenticator: Option<Authenticator>,
pub namespace: Option<String>,
#[serde(default)]
pub install_modules: Vec<ModuleInstallConfig>,
pub name: Option<String>,
pub description: Option<String>,
pub link: Option<String>,
}
#[cosmwasm_schema::cw_serde]
pub struct CallbackMsg {}
#[cosmwasm_schema::cw_serde]
#[derive(cw_orch::ExecuteFns)]
pub enum ExecuteMsg<Authenticator = Empty> {
#[cw_orch(fn_name("execute_msgs"), payable)]
Execute {
msgs: Vec<CosmosMsg<Empty>>,
},
#[cw_orch(payable)]
ExecuteWithData {
msg: CosmosMsg<Empty>,
},
#[cw_orch(payable)]
ExecuteOnModule {
module_id: String,
exec_msg: Binary,
funds: Vec<Coin>,
},
#[cw_orch(payable)]
AdminExecute {
addr: String,
msg: Binary,
},
#[cw_orch(payable)]
AdminExecuteOnModule {
module_id: String,
msg: Binary,
},
IcaAction {
action_query_msg: Binary,
},
UpdateInternalConfig(InternalConfigAction),
#[cw_orch(payable)]
InstallModules {
modules: Vec<ModuleInstallConfig>,
},
UninstallModule {
module_id: String,
},
Upgrade {
modules: Vec<(ModuleInfo, Option<Binary>)>,
},
#[cw_orch(payable)]
CreateSubAccount {
name: Option<String>,
description: Option<String>,
link: Option<String>,
namespace: Option<String>,
install_modules: Vec<ModuleInstallConfig>,
account_id: Option<u32>,
},
UpdateInfo {
name: Option<String>,
description: Option<String>,
link: Option<String>,
},
UpdateStatus {
is_suspended: Option<bool>,
},
UpdateSubAccount(UpdateSubAccountAction),
UpdateOwnership(GovAction),
AddAuthMethod {
add_authenticator: Authenticator,
},
RemoveAuthMethod {
id: u8,
},
}
#[cosmwasm_schema::cw_serde]
#[derive(QueryResponses, cw_orch::QueryFns)]
pub enum QueryMsg {
#[returns(ConfigResponse)]
Config {},
#[returns(ModuleVersionsResponse)]
ModuleVersions { ids: Vec<String> },
#[returns(ModuleAddressesResponse)]
ModuleAddresses { ids: Vec<String> },
#[returns(ModuleInfosResponse)]
ModuleInfos {
start_after: Option<String>,
limit: Option<u8>,
},
#[returns(InfoResponse)]
Info {},
#[returns(SubAccountIdsResponse)]
SubAccountIds {
start_after: Option<u32>,
limit: Option<u8>,
},
#[returns(TopLevelOwnerResponse)]
TopLevelOwner {},
#[returns(Ownership<String>)]
Ownership {},
#[returns(Binary)]
AuthenticatorByID { id: u8 },
#[returns(Binary)]
AuthenticatorIDs {},
}
#[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 }
}
}
#[cosmwasm_schema::cw_serde]
#[non_exhaustive]
pub enum InternalConfigAction {
UpdateModuleAddresses {
to_add: Vec<(String, String)>,
to_remove: Vec<String>,
},
UpdateWhitelist {
to_add: Vec<String>,
to_remove: Vec<String>,
},
}
#[cosmwasm_schema::cw_serde]
#[non_exhaustive]
pub enum UpdateSubAccountAction {
UnregisterSubAccount { id: u32 },
RegisterSubAccount { id: u32 },
}
#[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 InfoResponse {
pub info: AccountInfo,
}
#[cosmwasm_schema::cw_serde]
pub struct AccountModuleInfo {
pub id: String,
pub version: ContractVersion,
pub address: Addr,
}
#[cosmwasm_schema::cw_serde]
pub struct ModuleInfosResponse {
pub module_infos: Vec<AccountModuleInfo>,
}
#[cosmwasm_schema::cw_serde]
pub struct SubAccountIdsResponse {
pub sub_accounts: Vec<u32>,
}
#[cosmwasm_schema::cw_serde]
pub struct ConfigResponse {
pub whitelisted_addresses: Vec<Addr>,
pub account_id: AccountId,
pub is_suspended: SuspensionStatus,
pub registry_address: Addr,
pub module_factory_address: Addr,
}
#[cfg(test)]
mod test {
use cw_orch::core::serde_json::json;
use super::*;
#[coverage_helper::test]
fn minimal_deser_instantiate_test() {
let init_msg_binary: InstantiateMsg =
cosmwasm_std::from_json(br#"{"code_id": 1, "owner": {"renounced": {}}}"#).unwrap();
assert_eq!(
init_msg_binary,
InstantiateMsg {
code_id: 1,
owner: Some(GovernanceDetails::Renounced {}),
authenticator: Default::default(),
account_id: Default::default(),
namespace: Default::default(),
install_modules: Default::default(),
name: Default::default(),
description: Default::default(),
link: Default::default()
}
);
let init_msg_string: InstantiateMsg = cosmwasm_std::from_json(
json!({
"code_id": 1,
"owner": GovernanceDetails::Monarchy {
monarch: "bob".to_owned()
}
})
.to_string(),
)
.unwrap();
assert_eq!(
init_msg_string,
InstantiateMsg {
code_id: 1,
owner: Some(GovernanceDetails::Monarchy {
monarch: "bob".to_owned()
}),
authenticator: Default::default(),
account_id: Default::default(),
namespace: Default::default(),
install_modules: Default::default(),
name: Default::default(),
description: Default::default(),
link: Default::default()
}
)
}
}