1pub type ModuleMapEntry = (ModuleInfo, ModuleReference);
12
13#[cosmwasm_schema::cw_serde]
15pub struct Config {
16 pub account_factory_address: Option<Addr>,
17 pub allow_direct_module_registration_and_updates: bool,
18 pub namespace_registration_fee: Option<Coin>,
19}
20
21pub mod state {
22 use cw_storage_plus::{Index, IndexList, IndexedMap, Item, Map, MultiIndex};
23
24 use super::{AccountBase, Config, ModuleConfiguration, ModuleDefaultConfiguration};
25 use crate::objects::{
26 account::AccountId, module::ModuleInfo, module_reference::ModuleReference,
27 namespace::Namespace,
28 };
29
30 pub const CONFIG: Item<Config> = Item::new("cfg");
31
32 pub const PENDING_MODULES: Map<&ModuleInfo, ModuleReference> = Map::new("pendm");
34 pub const REGISTERED_MODULES: Map<&ModuleInfo, ModuleReference> = Map::new("lib");
36 pub const STANDALONE_INFOS: Map<u64, ModuleInfo> = Map::new("stli");
38 pub const YANKED_MODULES: Map<&ModuleInfo, ModuleReference> = Map::new("yknd");
40 pub const MODULE_CONFIG: Map<&ModuleInfo, ModuleConfiguration> = Map::new("cfg");
42 pub const MODULE_DEFAULT_CONFIG: Map<(&Namespace, &str), ModuleDefaultConfiguration> =
44 Map::new("dcfg");
45 pub const ACCOUNT_ADDRESSES: Map<&AccountId, AccountBase> = Map::new("accs");
47
48 pub struct NamespaceIndexes<'a> {
51 pub account_id: MultiIndex<'a, AccountId, AccountId, &'a Namespace>,
52 }
53
54 impl<'a> IndexList<AccountId> for NamespaceIndexes<'a> {
55 fn get_indexes(&'_ self) -> Box<dyn Iterator<Item = &'_ dyn Index<AccountId>> + '_> {
56 let v: Vec<&dyn Index<AccountId>> = vec![&self.account_id];
57 Box::new(v.into_iter())
58 }
59 }
60
61 pub const NAMESPACES_INFO: IndexedMap<&Namespace, AccountId, NamespaceIndexes> =
63 IndexedMap::new(
64 "nmspc",
65 NamespaceIndexes {
66 account_id: MultiIndex::new(|_pk, d| d.clone(), "nmspc", "nmspc_a"),
67 },
68 );
69}
70
71use cosmwasm_schema::QueryResponses;
72use cosmwasm_std::{Addr, Coin, Storage};
73use cw_clearable::Clearable;
74
75use self::state::{MODULE_CONFIG, MODULE_DEFAULT_CONFIG};
76use crate::objects::{
77 account::AccountId,
78 module::{Module, ModuleInfo, ModuleMetadata, ModuleStatus, Monetization},
79 module_reference::ModuleReference,
80 namespace::Namespace,
81};
82
83#[cosmwasm_schema::cw_serde]
85pub struct AccountBase {
86 pub manager: Addr,
87 pub proxy: Addr,
88}
89
90#[cosmwasm_schema::cw_serde]
92pub struct InstantiateMsg {
93 pub admin: String,
94 pub allow_direct_module_registration_and_updates: Option<bool>,
98 pub namespace_registration_fee: Option<Coin>,
99}
100
101#[cw_ownable::cw_ownable_execute]
103#[cosmwasm_schema::cw_serde]
104#[cfg_attr(feature = "interface", derive(cw_orch::ExecuteFns))]
105pub enum ExecuteMsg {
106 RemoveModule { module: ModuleInfo },
108 YankModule { module: ModuleInfo },
111 ProposeModules { modules: Vec<ModuleMapEntry> },
115 UpdateModuleConfiguration {
118 module_name: String,
119 namespace: Namespace,
120 update_module: UpdateModule,
121 },
122 ApproveOrRejectModules {
126 approves: Vec<ModuleInfo>,
127 rejects: Vec<ModuleInfo>,
128 },
129 ClaimNamespace {
131 account_id: AccountId,
132 namespace: String,
133 },
134 RemoveNamespaces { namespaces: Vec<String> },
137 AddAccount {
141 account_id: AccountId,
142 account_base: AccountBase,
143 namespace: Option<String>,
144 },
145 UpdateConfig {
147 account_factory_address: Option<String>,
149 allow_direct_module_registration_and_updates: Option<bool>,
151 namespace_registration_fee: Option<Clearable<Coin>>,
153 },
154}
155
156#[non_exhaustive]
157#[cosmwasm_schema::cw_serde]
158pub enum UpdateModule {
159 Default { metadata: ModuleMetadata },
161 Versioned {
163 version: String,
165 metadata: Option<ModuleMetadata>,
167 monetization: Option<Monetization>,
169 instantiation_funds: Option<Vec<Coin>>,
171 },
172}
173
174#[derive(Default)]
176#[cosmwasm_schema::cw_serde]
177pub struct ModuleFilter {
178 pub namespace: Option<String>,
179 pub name: Option<String>,
180 pub version: Option<String>,
181 pub status: Option<ModuleStatus>,
182}
183
184#[cw_ownable::cw_ownable_query]
186#[cosmwasm_schema::cw_serde]
187#[derive(QueryResponses)]
188#[cfg_attr(feature = "interface", derive(cw_orch::QueryFns))]
189pub enum QueryMsg {
190 #[returns(AccountBaseResponse)]
193 AccountBase { account_id: AccountId },
194 #[returns(ModulesResponse)]
198 Modules { infos: Vec<ModuleInfo> },
199 #[returns(NamespacesResponse)]
202 Namespaces { accounts: Vec<AccountId> },
203 #[returns(NamespaceResponse)]
206 Namespace { namespace: Namespace },
207 #[returns(ConfigResponse)]
209 Config {},
210 #[returns(ModulesListResponse)]
212 ModuleList {
213 filter: Option<ModuleFilter>,
214 start_after: Option<ModuleInfo>,
215 limit: Option<u8>,
216 },
217 #[returns(NamespaceListResponse)]
219 NamespaceList {
220 start_after: Option<String>,
221 limit: Option<u8>,
222 },
223}
224
225#[cosmwasm_schema::cw_serde]
226pub struct AccountBaseResponse {
227 pub account_base: AccountBase,
228}
229
230#[cosmwasm_schema::cw_serde]
231pub struct ModulesResponse {
232 pub modules: Vec<ModuleResponse>,
233}
234
235#[cosmwasm_schema::cw_serde]
236pub struct ModuleResponse {
237 pub module: Module,
238 pub config: ModuleConfiguration,
239}
240
241#[non_exhaustive]
242#[cosmwasm_schema::cw_serde]
243#[derive(Default)]
244pub struct ModuleConfiguration {
245 pub monetization: Monetization,
246 pub metadata: Option<ModuleMetadata>,
247 pub instantiation_funds: Vec<Coin>,
248}
249
250#[non_exhaustive]
251#[cosmwasm_schema::cw_serde]
252pub struct ModuleDefaultConfiguration {
253 pub metadata: ModuleMetadata,
254}
255
256impl ModuleDefaultConfiguration {
257 pub fn new(metadata: ModuleMetadata) -> Self {
258 Self { metadata }
259 }
260}
261
262impl ModuleConfiguration {
263 pub fn new(
264 monetization: Monetization,
265 metadata: Option<ModuleMetadata>,
266 instantiation_funds: Vec<Coin>,
267 ) -> Self {
268 Self {
269 monetization,
270 metadata,
271 instantiation_funds,
272 }
273 }
274
275 pub fn from_storage(
276 storage: &dyn Storage,
277 module: &ModuleInfo,
278 ) -> cosmwasm_std::StdResult<Self> {
279 let mut mod_cfg = MODULE_CONFIG.may_load(storage, module)?.unwrap_or_default();
280
281 if mod_cfg.metadata.is_none() {
282 if let Some(ModuleDefaultConfiguration { metadata }) =
284 MODULE_DEFAULT_CONFIG.may_load(storage, (&module.namespace, &module.name))?
285 {
286 mod_cfg.metadata = Some(metadata);
287 }
288 }
289
290 Ok(mod_cfg)
291 }
292}
293
294#[cosmwasm_schema::cw_serde]
295pub struct ModulesListResponse {
296 pub modules: Vec<ModuleResponse>,
297}
298
299#[cosmwasm_schema::cw_serde]
300pub enum NamespaceResponse {
301 Claimed(NamespaceInfo),
302 Unclaimed {},
303}
304
305impl NamespaceResponse {
306 pub fn unwrap(self) -> NamespaceInfo {
307 match self {
308 NamespaceResponse::Claimed(info) => info,
309 NamespaceResponse::Unclaimed {} => {
310 panic!("called `NamespaceResponse::unwrap()` on a `Unclaimed` value")
311 }
312 }
313 }
314}
315
316#[cosmwasm_schema::cw_serde]
317pub struct NamespaceInfo {
318 pub account_id: AccountId,
319 pub account_base: AccountBase,
320}
321
322#[cosmwasm_schema::cw_serde]
323pub struct NamespacesResponse {
324 pub namespaces: Vec<(Namespace, AccountId)>,
325}
326
327#[cosmwasm_schema::cw_serde]
328pub struct NamespaceListResponse {
329 pub namespaces: Vec<(Namespace, AccountId)>,
330}
331
332#[cosmwasm_schema::cw_serde]
333pub struct ConfigResponse {
334 pub account_factory_address: Option<Addr>,
335 pub allow_direct_module_registration_and_updates: bool,
336 pub namespace_registration_fee: Option<Coin>,
337}
338
339#[cosmwasm_schema::cw_serde]
340pub struct MigrateMsg {}