pallet_nfts/features/settings.rs
1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! This module provides helper methods to configure collection settings for the NFTs pallet.
19
20use crate::*;
21use frame_support::pallet_prelude::*;
22
23impl<T: Config<I>, I: 'static> Pallet<T, I> {
24 /// Forcefully change the configuration of a collection.
25 ///
26 /// - `collection`: The ID of the collection for which to update the configuration.
27 /// - `config`: The new collection configuration to set.
28 ///
29 /// This function allows for changing the configuration of a collection without any checks.
30 /// It updates the collection configuration and emits a `CollectionConfigChanged` event.
31 pub(crate) fn do_force_collection_config(
32 collection: T::CollectionId,
33 config: CollectionConfigFor<T, I>,
34 ) -> DispatchResult {
35 ensure!(Collection::<T, I>::contains_key(&collection), Error::<T, I>::UnknownCollection);
36 CollectionConfigOf::<T, I>::insert(&collection, config);
37 Self::deposit_event(Event::CollectionConfigChanged { collection });
38 Ok(())
39 }
40
41 /// Set the maximum supply for a collection.
42 ///
43 /// - `maybe_check_owner`: An optional account ID used to check permissions.
44 /// - `collection`: The ID of the collection for which to set the maximum supply.
45 /// - `max_supply`: The new maximum supply to set for the collection.
46 ///
47 /// This function checks if the setting `UnlockedMaxSupply` is enabled in the collection
48 /// configuration. If it is not enabled, it returns an `Error::MaxSupplyLocked`. If
49 /// `maybe_check_owner` is `Some(owner)`, it checks if the caller of the function is the
50 /// owner of the collection. If the caller is not the owner and the `maybe_check_owner`
51 /// parameter is provided, it returns an `Error::NoPermission`.
52 ///
53 /// It also checks if the new maximum supply is greater than the current number of items in
54 /// the collection, and if not, it returns an `Error::MaxSupplyTooSmall`. If all checks pass,
55 /// it updates the collection configuration with the new maximum supply and emits a
56 /// `CollectionMaxSupplySet` event.
57 pub(crate) fn do_set_collection_max_supply(
58 maybe_check_owner: Option<T::AccountId>,
59 collection: T::CollectionId,
60 max_supply: u32,
61 ) -> DispatchResult {
62 let collection_config = Self::get_collection_config(&collection)?;
63 ensure!(
64 collection_config.is_setting_enabled(CollectionSetting::UnlockedMaxSupply),
65 Error::<T, I>::MaxSupplyLocked
66 );
67
68 let details =
69 Collection::<T, I>::get(&collection).ok_or(Error::<T, I>::UnknownCollection)?;
70 if let Some(check_owner) = &maybe_check_owner {
71 ensure!(check_owner == &details.owner, Error::<T, I>::NoPermission);
72 }
73
74 ensure!(details.items <= max_supply, Error::<T, I>::MaxSupplyTooSmall);
75
76 CollectionConfigOf::<T, I>::try_mutate(collection, |maybe_config| {
77 let config = maybe_config.as_mut().ok_or(Error::<T, I>::NoConfig)?;
78 config.max_supply = Some(max_supply);
79 Self::deposit_event(Event::CollectionMaxSupplySet { collection, max_supply });
80 Ok(())
81 })
82 }
83
84 /// Update the mint settings for a collection.
85 ///
86 /// - `maybe_check_origin`: An optional account ID used to check issuer permissions.
87 /// - `collection`: The ID of the collection for which to update the mint settings.
88 /// - `mint_settings`: The new mint settings to set for the collection.
89 ///
90 /// This function updates the mint settings for a collection. If `maybe_check_origin` is
91 /// `Some(origin)`, it checks if the caller of the function has the `CollectionRole::Issuer`
92 /// for the given collection. If the caller doesn't have the required permission and
93 /// `maybe_check_origin` is provided, it returns an `Error::NoPermission`. If all checks
94 /// pass, it updates the collection configuration with the new mint settings and emits a
95 /// `CollectionMintSettingsUpdated` event.
96 pub(crate) fn do_update_mint_settings(
97 maybe_check_origin: Option<T::AccountId>,
98 collection: T::CollectionId,
99 mint_settings: MintSettings<BalanceOf<T, I>, BlockNumberFor<T, I>, T::CollectionId>,
100 ) -> DispatchResult {
101 if let Some(check_origin) = &maybe_check_origin {
102 ensure!(
103 Self::has_role(&collection, &check_origin, CollectionRole::Issuer),
104 Error::<T, I>::NoPermission
105 );
106 }
107
108 CollectionConfigOf::<T, I>::try_mutate(collection, |maybe_config| {
109 let config = maybe_config.as_mut().ok_or(Error::<T, I>::NoConfig)?;
110 config.mint_settings = mint_settings;
111 Self::deposit_event(Event::CollectionMintSettingsUpdated { collection });
112 Ok(())
113 })
114 }
115
116 /// Get the configuration for a specific collection.
117 ///
118 /// - `collection_id`: The ID of the collection for which to retrieve the configuration.
119 ///
120 /// This function attempts to fetch the configuration (`CollectionConfigFor`) associated
121 /// with the given `collection_id`. If the configuration exists, it returns `Ok(config)`,
122 /// otherwise, it returns a `DispatchError` with `Error::NoConfig`.
123 pub(crate) fn get_collection_config(
124 collection_id: &T::CollectionId,
125 ) -> Result<CollectionConfigFor<T, I>, DispatchError> {
126 let config =
127 CollectionConfigOf::<T, I>::get(&collection_id).ok_or(Error::<T, I>::NoConfig)?;
128 Ok(config)
129 }
130
131 /// Get the configuration for a specific item within a collection.
132 ///
133 /// - `collection_id`: The ID of the collection to which the item belongs.
134 /// - `item_id`: The ID of the item for which to retrieve the configuration.
135 ///
136 /// This function attempts to fetch the configuration (`ItemConfig`) associated with the given
137 /// `collection_id` and `item_id`. If the configuration exists, it returns `Ok(config)`,
138 /// otherwise, it returns a `DispatchError` with `Error::UnknownItem`.
139 pub(crate) fn get_item_config(
140 collection_id: &T::CollectionId,
141 item_id: &T::ItemId,
142 ) -> Result<ItemConfig, DispatchError> {
143 let config = ItemConfigOf::<T, I>::get(&collection_id, &item_id)
144 .ok_or(Error::<T, I>::UnknownItem)?;
145 Ok(config)
146 }
147
148 /// Get the default item settings for a specific collection.
149 ///
150 /// - `collection_id`: The ID of the collection for which to retrieve the default item settings.
151 ///
152 /// This function fetches the `default_item_settings` from the collection configuration
153 /// associated with the given `collection_id`. If the collection configuration exists, it
154 /// returns `Ok(default_item_settings)`, otherwise, it returns a `DispatchError` with
155 /// `Error::NoConfig`.
156 pub(crate) fn get_default_item_settings(
157 collection_id: &T::CollectionId,
158 ) -> Result<ItemSettings, DispatchError> {
159 let collection_config = Self::get_collection_config(collection_id)?;
160 Ok(collection_config.mint_settings.default_item_settings)
161 }
162
163 /// Check if a specified pallet feature is enabled.
164 ///
165 /// - `feature`: The feature to check.
166 ///
167 /// This function checks if the given `feature` is enabled in the runtime using the
168 /// pallet's `T::Features::get()` function. It returns `true` if the feature is enabled,
169 /// otherwise it returns `false`.
170 pub(crate) fn is_pallet_feature_enabled(feature: PalletFeature) -> bool {
171 let features = T::Features::get();
172 return features.is_enabled(feature)
173 }
174}