pub type ModuleMapEntry = (ModuleInfo, ModuleReference);
#[cosmwasm_schema::cw_serde]
pub struct Config {
pub security_enabled: bool,
pub namespace_registration_fee: Option<Coin>,
}
pub mod state {
use cw_storage_plus::{Item, Map};
use super::{Account, Config, ModuleConfiguration, ModuleDefaultConfiguration};
use crate::objects::{
account::{AccountId, AccountSequence},
module::ModuleInfo,
module_reference::ModuleReference,
namespace::Namespace,
storage_namespaces::{self},
};
pub const CONFIG: Item<Config> = Item::new(storage_namespaces::CONFIG_STORAGE_KEY);
pub const PENDING_MODULES: Map<&ModuleInfo, ModuleReference> =
Map::new(storage_namespaces::registry::PENDING_MODULES);
pub const REGISTERED_MODULES: Map<&ModuleInfo, ModuleReference> =
Map::new(storage_namespaces::registry::REGISTERED_MODULES);
pub const STANDALONE_INFOS: Map<u64, ModuleInfo> =
Map::new(storage_namespaces::registry::STANDALONE_INFOS);
pub const SERVICE_INFOS: Map<&cosmwasm_std::Addr, ModuleInfo> =
Map::new(storage_namespaces::registry::SERVICE_INFOS);
pub const YANKED_MODULES: Map<&ModuleInfo, ModuleReference> =
Map::new(storage_namespaces::registry::YANKED_MODULES);
pub const MODULE_CONFIG: Map<&ModuleInfo, ModuleConfiguration> =
Map::new(storage_namespaces::registry::MODULE_CONFIG);
pub const MODULE_DEFAULT_CONFIG: Map<(&Namespace, &str), ModuleDefaultConfiguration> =
Map::new(storage_namespaces::registry::MODULE_DEFAULT_CONFIG);
pub const ACCOUNT_ADDRESSES: Map<&AccountId, Account> =
Map::new(storage_namespaces::registry::ACCOUNT_ADDRESSES);
pub const LOCAL_ACCOUNT_SEQUENCE: Item<AccountSequence> =
Item::new(storage_namespaces::registry::LOCAL_ACCOUNT_SEQUENCE);
pub const NAMESPACES: Map<&Namespace, AccountId> =
Map::new(storage_namespaces::registry::NAMESPACES);
pub const REV_NAMESPACES: Map<&AccountId, Namespace> =
Map::new(storage_namespaces::registry::REV_NAMESPACES);
}
use cosmwasm_schema::QueryResponses;
use cosmwasm_std::{Addr, Api, Coin, Storage};
use cw_clearable::Clearable;
use self::state::{MODULE_CONFIG, MODULE_DEFAULT_CONFIG};
use crate::objects::{
account::AccountId,
module::{Module, ModuleInfo, ModuleMetadata, ModuleStatus, Monetization},
module_reference::ModuleReference,
namespace::Namespace,
};
#[cosmwasm_schema::cw_serde]
pub struct Account<T = Addr>(T);
impl<T> Account<T> {
pub fn new(addr: T) -> Self {
Self(addr)
}
}
impl Account<String> {
pub fn verify(self, api: &dyn Api) -> cosmwasm_std::StdResult<Account<Addr>> {
let addr = api.addr_validate(&self.0)?;
Ok(Account(addr))
}
}
impl Account {
pub fn addr(&self) -> &Addr {
&self.0
}
pub fn into_addr(self) -> Addr {
self.0
}
}
impl From<Account<Addr>> for Account<String> {
fn from(addr: Account<Addr>) -> Self {
Account(addr.0.to_string())
}
}
#[cosmwasm_schema::cw_serde]
pub struct InstantiateMsg {
pub admin: String,
pub security_enabled: Option<bool>,
pub namespace_registration_fee: Option<Coin>,
}
#[cw_ownable::cw_ownable_execute]
#[cosmwasm_schema::cw_serde]
#[derive(cw_orch::ExecuteFns)]
pub enum ExecuteMsg {
RemoveModule { module: ModuleInfo },
YankModule { module: ModuleInfo },
ProposeModules { modules: Vec<ModuleMapEntry> },
UpdateModuleConfiguration {
module_name: String,
namespace: Namespace,
update_module: UpdateModule,
},
ApproveOrRejectModules {
approves: Vec<ModuleInfo>,
rejects: Vec<ModuleInfo>,
},
ClaimNamespace {
account_id: AccountId,
namespace: String,
},
ForgoNamespace { namespaces: Vec<String> },
AddAccount {
namespace: Option<String>,
creator: String,
},
UpdateConfig {
security_enabled: Option<bool>,
namespace_registration_fee: Option<Clearable<Coin>>,
},
}
#[non_exhaustive]
#[cosmwasm_schema::cw_serde]
pub enum UpdateModule {
Default { metadata: ModuleMetadata },
Versioned {
version: String,
metadata: Option<ModuleMetadata>,
monetization: Option<Monetization>,
instantiation_funds: Option<Vec<Coin>>,
},
}
#[derive(Default)]
#[cosmwasm_schema::cw_serde]
pub struct ModuleFilter {
pub namespace: Option<String>,
pub name: Option<String>,
pub version: Option<String>,
pub status: Option<ModuleStatus>,
}
#[cw_ownable::cw_ownable_query]
#[cosmwasm_schema::cw_serde]
#[derive(QueryResponses, cw_orch::QueryFns)]
pub enum QueryMsg {
#[returns(AccountsResponse)]
Accounts { account_ids: Vec<AccountId> },
#[returns(ModulesResponse)]
Modules { infos: Vec<ModuleInfo> },
#[returns(NamespacesResponse)]
Namespaces { accounts: Vec<AccountId> },
#[returns(NamespaceResponse)]
Namespace { namespace: Namespace },
#[returns(ConfigResponse)]
Config {},
#[returns(AccountListResponse)]
AccountList {
start_after: Option<AccountId>,
limit: Option<u8>,
},
#[returns(ModulesListResponse)]
ModuleList {
filter: Option<ModuleFilter>,
start_after: Option<ModuleInfo>,
limit: Option<u8>,
},
#[returns(NamespaceListResponse)]
NamespaceList {
start_after: Option<String>,
limit: Option<u8>,
},
}
#[cosmwasm_schema::cw_serde]
pub struct AccountsResponse {
pub accounts: Vec<Account>,
}
#[cosmwasm_schema::cw_serde]
pub struct AccountListResponse {
pub accounts: Vec<(AccountId, Account)>,
}
#[cosmwasm_schema::cw_serde]
pub struct ModulesResponse {
pub modules: Vec<ModuleResponse>,
}
#[cosmwasm_schema::cw_serde]
pub struct ModuleResponse {
pub module: Module,
pub config: ModuleConfiguration,
}
#[non_exhaustive]
#[cosmwasm_schema::cw_serde]
#[derive(Default)]
pub struct ModuleConfiguration {
pub monetization: Monetization,
pub metadata: Option<ModuleMetadata>,
pub instantiation_funds: Vec<Coin>,
}
#[non_exhaustive]
#[cosmwasm_schema::cw_serde]
pub struct ModuleDefaultConfiguration {
pub metadata: ModuleMetadata,
}
impl ModuleDefaultConfiguration {
pub fn new(metadata: ModuleMetadata) -> Self {
Self { metadata }
}
}
impl ModuleConfiguration {
pub fn new(
monetization: Monetization,
metadata: Option<ModuleMetadata>,
instantiation_funds: Vec<Coin>,
) -> Self {
Self {
monetization,
metadata,
instantiation_funds,
}
}
pub fn from_storage(
storage: &dyn Storage,
module: &ModuleInfo,
) -> cosmwasm_std::StdResult<Self> {
let mut mod_cfg = MODULE_CONFIG.may_load(storage, module)?.unwrap_or_default();
if mod_cfg.metadata.is_none() {
if let Some(ModuleDefaultConfiguration { metadata }) =
MODULE_DEFAULT_CONFIG.may_load(storage, (&module.namespace, &module.name))?
{
mod_cfg.metadata = Some(metadata);
}
}
Ok(mod_cfg)
}
}
#[cosmwasm_schema::cw_serde]
pub struct ModulesListResponse {
pub modules: Vec<ModuleResponse>,
}
#[cosmwasm_schema::cw_serde]
pub enum NamespaceResponse {
Claimed(NamespaceInfo),
Unclaimed {},
}
impl NamespaceResponse {
pub fn unwrap(self) -> NamespaceInfo {
match self {
NamespaceResponse::Claimed(info) => info,
NamespaceResponse::Unclaimed {} => {
panic!("called `NamespaceResponse::unwrap()` on a `Unclaimed` value")
}
}
}
}
#[cosmwasm_schema::cw_serde]
pub struct NamespaceInfo {
pub account_id: AccountId,
pub account: Account,
}
#[cosmwasm_schema::cw_serde]
pub struct NamespacesResponse {
pub namespaces: Vec<(Namespace, AccountId)>,
}
#[cosmwasm_schema::cw_serde]
pub struct NamespaceListResponse {
pub namespaces: Vec<(Namespace, AccountId)>,
}
#[cosmwasm_schema::cw_serde]
pub struct ConfigResponse {
pub security_enabled: bool,
pub namespace_registration_fee: Option<Coin>,
pub local_account_sequence: u32,
}
#[cosmwasm_schema::cw_serde]
pub enum MigrateMsg {
Instantiate(InstantiateMsg),
Migrate {},
}