From 8268719cc3131a7cb107b0c516068ea44ef81cf4 Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Thu, 9 Mar 2023 15:15:53 +0200 Subject: [PATCH 1/6] Rename owner_of_item to owned_item --- frame/nfts/src/lib.rs | 6 +++--- frame/nfts/src/tests.rs | 6 +++--- frame/nfts/src/types.rs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/frame/nfts/src/lib.rs b/frame/nfts/src/lib.rs index 681d908423da6..d170c665c46e5 100644 --- a/frame/nfts/src/lib.rs +++ b/frame/nfts/src/lib.rs @@ -809,13 +809,13 @@ pub mod pallet { match mint_settings.mint_type { MintType::Issuer => return Err(Error::::NoPermission.into()), MintType::HolderOf(collection_id) => { - let MintWitness { owner_of_item } = + let MintWitness { owned_item } = witness_data.ok_or(Error::::BadWitness)?; let owns_item = Account::::contains_key(( &caller, &collection_id, - &owner_of_item, + &owned_item, )); ensure!(owns_item, Error::::BadWitness); @@ -824,7 +824,7 @@ pub mod pallet { let key = ( &collection_id, - Some(owner_of_item), + Some(owned_item), AttributeNamespace::Pallet, &Self::construct_attribute_key(pallet_attribute.encode())?, ); diff --git a/frame/nfts/src/tests.rs b/frame/nfts/src/tests.rs index 8d937b0f7fe68..e44e4151f84a0 100644 --- a/frame/nfts/src/tests.rs +++ b/frame/nfts/src/tests.rs @@ -335,7 +335,7 @@ fn mint_should_work() { 1, 42, account(2), - Some(MintWitness { owner_of_item: 42 }) + Some(MintWitness { owned_item: 42 }) ), Error::::BadWitness ); @@ -344,7 +344,7 @@ fn mint_should_work() { 1, 42, account(2), - Some(MintWitness { owner_of_item: 43 }) + Some(MintWitness { owned_item: 43 }) )); // can't mint twice @@ -354,7 +354,7 @@ fn mint_should_work() { 1, 46, account(2), - Some(MintWitness { owner_of_item: 43 }) + Some(MintWitness { owned_item: 43 }) ), Error::::AlreadyClaimed ); diff --git a/frame/nfts/src/types.rs b/frame/nfts/src/types.rs index 8c43024cdaceb..93e0519de0840 100644 --- a/frame/nfts/src/types.rs +++ b/frame/nfts/src/types.rs @@ -124,7 +124,7 @@ impl CollectionDetails { #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo)] pub struct MintWitness { /// Provide the id of the item in a required collection. - pub owner_of_item: ItemId, + pub owned_item: ItemId, } /// Information concerning the ownership of a single unique item. From 5bf0dfc8398c5d400cc59027cd41b9f9903d21e5 Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Thu, 9 Mar 2023 15:17:12 +0200 Subject: [PATCH 2/6] Move AttributeNamespace into the types file --- frame/nfts/src/lib.rs | 4 +--- frame/nfts/src/types.rs | 15 +++++++++++++++ frame/support/src/traits/tokens.rs | 5 ++--- frame/support/src/traits/tokens/misc.rs | 15 --------------- 4 files changed, 18 insertions(+), 21 deletions(-) diff --git a/frame/nfts/src/lib.rs b/frame/nfts/src/lib.rs index d170c665c46e5..cd0c0731edab2 100644 --- a/frame/nfts/src/lib.rs +++ b/frame/nfts/src/lib.rs @@ -45,9 +45,7 @@ pub mod weights; use codec::{Decode, Encode}; use frame_support::traits::{ - tokens::{AttributeNamespace, Locker}, - BalanceStatus::Reserved, - Currency, EnsureOriginWithArg, ReservableCurrency, + tokens::Locker, BalanceStatus::Reserved, Currency, EnsureOriginWithArg, ReservableCurrency, }; use frame_system::Config as SystemConfig; use sp_runtime::{ diff --git a/frame/nfts/src/types.rs b/frame/nfts/src/types.rs index 93e0519de0840..44f1f1b58f830 100644 --- a/frame/nfts/src/types.rs +++ b/frame/nfts/src/types.rs @@ -317,6 +317,21 @@ impl Default for MintSettings { + /// An attribute was set by the pallet. + Pallet, + /// An attribute was set by collection's owner. + CollectionOwner, + /// An attribute was set by item's owner. + ItemOwner, + /// An attribute was set by pre-approved account. + Account(AccountId), +} + /// A witness data to cancel attributes approval operation. #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo)] pub struct CancelAttributesApprovalWitness { diff --git a/frame/support/src/traits/tokens.rs b/frame/support/src/traits/tokens.rs index f8dcf68159f1a..e1a96f621bd4f 100644 --- a/frame/support/src/traits/tokens.rs +++ b/frame/support/src/traits/tokens.rs @@ -28,7 +28,6 @@ pub mod nonfungibles; pub mod nonfungibles_v2; pub use imbalance::Imbalance; pub use misc::{ - AssetId, AttributeNamespace, Balance, BalanceConversion, BalanceStatus, ConvertRank, - DepositConsequence, ExistenceRequirement, GetSalary, Locker, WithdrawConsequence, - WithdrawReasons, + AssetId, Balance, BalanceConversion, BalanceStatus, ConvertRank, DepositConsequence, + ExistenceRequirement, GetSalary, Locker, WithdrawConsequence, WithdrawReasons, }; diff --git a/frame/support/src/traits/tokens/misc.rs b/frame/support/src/traits/tokens/misc.rs index eff65f3620a32..6113642c83460 100644 --- a/frame/support/src/traits/tokens/misc.rs +++ b/frame/support/src/traits/tokens/misc.rs @@ -126,21 +126,6 @@ pub enum BalanceStatus { Reserved, } -/// Attribute namespaces for non-fungible tokens. -#[derive( - Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, scale_info::TypeInfo, MaxEncodedLen, -)] -pub enum AttributeNamespace { - /// An attribute was set by the pallet. - Pallet, - /// An attribute was set by collection's owner. - CollectionOwner, - /// An attribute was set by item's owner. - ItemOwner, - /// An attribute was set by pre-approved account. - Account(AccountId), -} - bitflags::bitflags! { /// Reasons for moving funds out of an account. #[derive(Encode, Decode, MaxEncodedLen)] From 6a1a239c9f5249e977cd5f28f9873d97d4ff0a7b Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Thu, 9 Mar 2023 15:17:47 +0200 Subject: [PATCH 3/6] Simplify collection's creation and add new trait methods to manage the settings --- frame/nfts/src/features/lock.rs | 12 +++-- frame/nfts/src/impl_nonfungibles.rs | 43 ++++++++++----- frame/nfts/src/lib.rs | 15 +++--- frame/nfts/src/tests.rs | 53 ++++++++++++++++++- frame/nfts/src/types.rs | 30 ++++++++--- .../src/traits/tokens/nonfungibles_v2.rs | 35 +++++++++++- 6 files changed, 153 insertions(+), 35 deletions(-) diff --git a/frame/nfts/src/features/lock.rs b/frame/nfts/src/features/lock.rs index c28fdda983774..7db295d847f57 100644 --- a/frame/nfts/src/features/lock.rs +++ b/frame/nfts/src/features/lock.rs @@ -20,14 +20,16 @@ use frame_support::pallet_prelude::*; impl, I: 'static> Pallet { pub(crate) fn do_lock_collection( - origin: T::AccountId, + maybe_check_origin: Option, collection: T::CollectionId, lock_settings: CollectionSettings, ) -> DispatchResult { - ensure!( - Self::has_role(&collection, &origin, CollectionRole::Freezer), - Error::::NoPermission - ); + if let Some(check_origin) = &maybe_check_origin { + ensure!( + Self::has_role(&collection, &check_origin, CollectionRole::Freezer), + Error::::NoPermission + ); + } ensure!( !lock_settings.is_disabled(CollectionSetting::DepositRequired), Error::::WrongSetting diff --git a/frame/nfts/src/impl_nonfungibles.rs b/frame/nfts/src/impl_nonfungibles.rs index ef6bbe7656ef8..396acb37484f3 100644 --- a/frame/nfts/src/impl_nonfungibles.rs +++ b/frame/nfts/src/impl_nonfungibles.rs @@ -19,7 +19,6 @@ use super::*; use frame_support::{ - ensure, storage::KeyPrefixIterator, traits::{tokens::nonfungibles_v2::*, Get}, BoundedSlice, @@ -130,21 +129,12 @@ impl, I: 'static> Inspect<::AccountId> for Palle } } -impl, I: 'static> Create<::AccountId, CollectionConfigFor> - for Pallet -{ +impl, I: 'static> Create<::AccountId> for Pallet { /// Create a `collection` of nonfungible items to be owned by `who` and managed by `admin`. fn create_collection( who: &T::AccountId, admin: &T::AccountId, - config: &CollectionConfigFor, ) -> Result { - // DepositRequired can be disabled by calling the force_create() only - ensure!( - !config.has_disabled_setting(CollectionSetting::DepositRequired), - Error::::WrongSetting - ); - let collection = NextCollectionId::::get().unwrap_or(T::CollectionId::initial_value()); @@ -152,7 +142,7 @@ impl, I: 'static> Create<::AccountId, Collection collection, who.clone(), admin.clone(), - *config, + CollectionConfigFor::::default(), T::CollectionDeposit::get(), Event::Created { collection, creator: who.clone(), owner: admin.clone() }, )?; @@ -314,6 +304,35 @@ impl, I: 'static> Mutate<::AccountId, ItemConfig } } +impl, I: 'static> + MutateCollectionSettings< + ::AccountId, + MintSettingsFor, + CollectionSettings, + > for Pallet +{ + /// Set the maximum number of items a `collection` could have. + fn set_max_supply(collection: &Self::CollectionId, max_supply: u32) -> DispatchResult { + Self::do_set_collection_max_supply(None, *collection, max_supply) + } + + /// Update mint settings for the `collection`. + fn update_mint_settings( + collection: &Self::CollectionId, + mint_settings: MintSettingsFor, + ) -> DispatchResult { + Self::do_update_mint_settings(None, *collection, mint_settings) + } + + /// Disable `collection` settings. + fn disable_collection_settings( + collection: &Self::CollectionId, + disable_settings: CollectionSettings, + ) -> DispatchResult { + Self::do_lock_collection(None, *collection, disable_settings) + } +} + impl, I: 'static> Transfer for Pallet { fn transfer( collection: &Self::CollectionId, diff --git a/frame/nfts/src/lib.rs b/frame/nfts/src/lib.rs index cd0c0731edab2..490d897c65a82 100644 --- a/frame/nfts/src/lib.rs +++ b/frame/nfts/src/lib.rs @@ -1086,7 +1086,8 @@ pub mod pallet { /// Disallows specified settings for the whole collection. /// - /// Origin must be Signed and the sender should be the Freezer of the `collection`. + /// Origin must be either `ForceOrigin` or `Signed` and the sender should be the Freezer of + /// the `collection`. /// /// - `collection`: The collection to be locked. /// - `lock_settings`: The settings to be locked. @@ -1102,8 +1103,10 @@ pub mod pallet { collection: T::CollectionId, lock_settings: CollectionSettings, ) -> DispatchResult { - let origin = ensure_signed(origin)?; - Self::do_lock_collection(origin, collection, lock_settings) + let maybe_check_origin = T::ForceOrigin::try_origin(origin) + .map(|_| None) + .or_else(|origin| ensure_signed(origin).map(Some).map_err(DispatchError::from))?; + Self::do_lock_collection(maybe_check_origin, collection, lock_settings) } /// Change the Owner of a collection. @@ -1652,11 +1655,7 @@ pub mod pallet { pub fn update_mint_settings( origin: OriginFor, collection: T::CollectionId, - mint_settings: MintSettings< - BalanceOf, - ::BlockNumber, - T::CollectionId, - >, + mint_settings: MintSettingsFor, ) -> DispatchResult { let maybe_check_owner = T::ForceOrigin::try_origin(origin) .map(|_| None) diff --git a/frame/nfts/src/tests.rs b/frame/nfts/src/tests.rs index e44e4151f84a0..3016036265c45 100644 --- a/frame/nfts/src/tests.rs +++ b/frame/nfts/src/tests.rs @@ -23,7 +23,7 @@ use frame_support::{ assert_noop, assert_ok, dispatch::Dispatchable, traits::{ - tokens::nonfungibles_v2::{Destroy, Mutate}, + tokens::nonfungibles_v2::{Create, Destroy, Mutate, MutateCollectionSettings}, Currency, Get, }, }; @@ -245,6 +245,57 @@ fn lifecycle_should_work() { }); } +#[test] +fn change_config_via_traits_should_work() { + new_test_ext().execute_with(|| { + Balances::make_free_balance_be(&account(1), 100); + Balances::make_free_balance_be(&account(2), 100); + + assert_ok!(::AccountId>>::create_collection( + &account(1), + &account(1), + )); + assert_eq!(collections(), vec![(account(1), 0)]); + + assert_ok!(::AccountId, + MintSettingsFor, + CollectionSettings, + >>::set_max_supply(&0, 1)); + + assert_noop!( + Nfts::mint(RuntimeOrigin::signed(account(2)), 0, 0, account(2), None), + Error::::NoPermission + ); + + assert_ok!(::AccountId, + MintSettingsFor, + CollectionSettings, + >>::update_mint_settings( + &0, MintSettings { mint_type: MintType::Public, ..Default::default() } + )); + assert_ok!(::AccountId, + MintSettingsFor, + CollectionSettings, + >>::disable_collection_settings( + &0, + CollectionSettings::from_disabled(CollectionSetting::TransferableItems.into()) + )); + + assert_ok!(Nfts::mint(RuntimeOrigin::signed(account(2)), 0, 0, account(2), None)); + assert_noop!( + Nfts::transfer(RuntimeOrigin::signed(account(2)), 0, 0, account(1)), + Error::::ItemsNonTransferable + ); + assert_noop!( + Nfts::mint(RuntimeOrigin::signed(account(2)), 0, 1, account(2), None), + Error::::MaxSupplyReached + ); + }); +} + #[test] fn destroy_with_bad_witness_should_not_work() { new_test_ext().execute_with(|| { diff --git a/frame/nfts/src/types.rs b/frame/nfts/src/types.rs index 44f1f1b58f830..5ed019b28467b 100644 --- a/frame/nfts/src/types.rs +++ b/frame/nfts/src/types.rs @@ -61,6 +61,8 @@ pub(super) type CollectionConfigFor = CollectionConfig< ::BlockNumber, >::CollectionId, >; +pub(super) type MintSettingsFor = + MintSettings, ::BlockNumber, >::CollectionId>; pub(super) type PreSignedMintOf = PreSignedMint< >::CollectionId, >::ItemId, @@ -347,9 +349,7 @@ pub enum PalletAttributes { } /// Collection's configuration. -#[derive( - Clone, Copy, Decode, Default, Encode, MaxEncodedLen, PartialEq, RuntimeDebug, TypeInfo, -)] +#[derive(Clone, Copy, Decode, Encode, MaxEncodedLen, PartialEq, RuntimeDebug, TypeInfo)] pub struct CollectionConfig { /// Collection's settings. pub settings: CollectionSettings, @@ -359,6 +359,18 @@ pub struct CollectionConfig { pub mint_settings: MintSettings, } +impl Default + for CollectionConfig +{ + fn default() -> Self { + Self { + settings: CollectionSettings::default(), + max_supply: None, + mint_settings: MintSettings::default(), + } + } +} + impl CollectionConfig { pub fn is_setting_enabled(&self, setting: CollectionSetting) -> bool { !self.settings.is_disabled(setting) @@ -409,12 +421,16 @@ impl ItemSettings { impl_codec_bitflags!(ItemSettings, u64, ItemSetting); /// Item's configuration. -#[derive( - Encode, Decode, Default, PartialEq, RuntimeDebug, Clone, Copy, MaxEncodedLen, TypeInfo, -)] +#[derive(Encode, Decode, PartialEq, RuntimeDebug, Clone, Copy, MaxEncodedLen, TypeInfo)] pub struct ItemConfig { /// Item's settings. - pub(super) settings: ItemSettings, + pub settings: ItemSettings, +} + +impl Default for ItemConfig { + fn default() -> Self { + Self { settings: ItemSettings::default() } + } } impl ItemConfig { diff --git a/frame/support/src/traits/tokens/nonfungibles_v2.rs b/frame/support/src/traits/tokens/nonfungibles_v2.rs index 5deb0c568f431..5ad7cee779120 100644 --- a/frame/support/src/traits/tokens/nonfungibles_v2.rs +++ b/frame/support/src/traits/tokens/nonfungibles_v2.rs @@ -181,12 +181,11 @@ pub trait InspectEnumerable: Inspect { } /// Trait for providing the ability to create collections of nonfungible items. -pub trait Create: Inspect { +pub trait Create: Inspect { /// Create a `collection` of nonfungible items to be owned by `who` and managed by `admin`. fn create_collection( who: &AccountId, admin: &AccountId, - config: &CollectionConfig, ) -> Result; } @@ -330,6 +329,38 @@ pub trait Mutate: Inspect { } } +/// Trait for providing the ability to change the settings of the collections of nonfungible items. +pub trait MutateCollectionSettings: + Inspect +{ + /// Set the maximum number of items a `collection` could have. + /// + /// By default, this is not a supported operation. + fn set_max_supply(_collection: &Self::CollectionId, _max_supply: u32) -> DispatchResult { + Err(TokenError::Unsupported.into()) + } + + /// Update mint settings for the `collection`. + /// + /// By default, this is not a supported operation. + fn update_mint_settings( + _collection: &Self::CollectionId, + _mint_settings: MintSettings, + ) -> DispatchResult { + Err(TokenError::Unsupported.into()) + } + + /// Disable `collection` settings. + /// + /// By default, this is not a supported operation. + fn disable_collection_settings( + _collection: &Self::CollectionId, + _disable_settings: CollectionSettings, + ) -> DispatchResult { + Err(TokenError::Unsupported.into()) + } +} + /// Trait for transferring non-fungible sets of items. pub trait Transfer: Inspect { /// Transfer `item` of `collection` into `destination` account. From de99879f465041ac2ba5add3f21e66e9a21e9c53 Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Fri, 10 Mar 2023 12:08:53 +0200 Subject: [PATCH 4/6] Try 2 --- frame/nfts/src/features/lock.rs | 12 ++-- frame/nfts/src/impl_nonfungibles.rs | 65 ++++++++++--------- frame/nfts/src/lib.rs | 15 +++-- frame/nfts/src/tests.rs | 53 +-------------- frame/nfts/src/types.rs | 2 - .../src/traits/tokens/nonfungibles_v2.rs | 48 ++++---------- 6 files changed, 62 insertions(+), 133 deletions(-) diff --git a/frame/nfts/src/features/lock.rs b/frame/nfts/src/features/lock.rs index 7db295d847f57..c28fdda983774 100644 --- a/frame/nfts/src/features/lock.rs +++ b/frame/nfts/src/features/lock.rs @@ -20,16 +20,14 @@ use frame_support::pallet_prelude::*; impl, I: 'static> Pallet { pub(crate) fn do_lock_collection( - maybe_check_origin: Option, + origin: T::AccountId, collection: T::CollectionId, lock_settings: CollectionSettings, ) -> DispatchResult { - if let Some(check_origin) = &maybe_check_origin { - ensure!( - Self::has_role(&collection, &check_origin, CollectionRole::Freezer), - Error::::NoPermission - ); - } + ensure!( + Self::has_role(&collection, &origin, CollectionRole::Freezer), + Error::::NoPermission + ); ensure!( !lock_settings.is_disabled(CollectionSetting::DepositRequired), Error::::WrongSetting diff --git a/frame/nfts/src/impl_nonfungibles.rs b/frame/nfts/src/impl_nonfungibles.rs index 396acb37484f3..614e76d9f6f47 100644 --- a/frame/nfts/src/impl_nonfungibles.rs +++ b/frame/nfts/src/impl_nonfungibles.rs @@ -19,6 +19,7 @@ use super::*; use frame_support::{ + ensure, storage::KeyPrefixIterator, traits::{tokens::nonfungibles_v2::*, Get}, BoundedSlice, @@ -129,8 +130,39 @@ impl, I: 'static> Inspect<::AccountId> for Palle } } -impl, I: 'static> Create<::AccountId> for Pallet { - /// Create a `collection` of nonfungible items to be owned by `who` and managed by `admin`. +impl, I: 'static> Create<::AccountId, CollectionConfigFor> + for Pallet +{ + /// Create a `collection` of nonfungible items to be owned by `who` and managed by `admin` with + /// collection settings provided in `config`. + fn create_collection( + who: &T::AccountId, + admin: &T::AccountId, + config: &CollectionConfigFor, + ) -> Result { + // DepositRequired can be disabled by calling the force_create() only + ensure!( + !config.has_disabled_setting(CollectionSetting::DepositRequired), + Error::::WrongSetting + ); + + let collection = + NextCollectionId::::get().unwrap_or(T::CollectionId::initial_value()); + + Self::do_create_collection( + collection, + who.clone(), + admin.clone(), + *config, + T::CollectionDeposit::get(), + Event::Created { collection, creator: who.clone(), owner: admin.clone() }, + )?; + Ok(collection) + } +} +impl, I: 'static> CreateSimplified<::AccountId> for Pallet { + /// Create a `collection` of nonfungible items to be owned by `who` and managed by `admin` with + /// default collection settings. fn create_collection( who: &T::AccountId, admin: &T::AccountId, @@ -304,35 +336,6 @@ impl, I: 'static> Mutate<::AccountId, ItemConfig } } -impl, I: 'static> - MutateCollectionSettings< - ::AccountId, - MintSettingsFor, - CollectionSettings, - > for Pallet -{ - /// Set the maximum number of items a `collection` could have. - fn set_max_supply(collection: &Self::CollectionId, max_supply: u32) -> DispatchResult { - Self::do_set_collection_max_supply(None, *collection, max_supply) - } - - /// Update mint settings for the `collection`. - fn update_mint_settings( - collection: &Self::CollectionId, - mint_settings: MintSettingsFor, - ) -> DispatchResult { - Self::do_update_mint_settings(None, *collection, mint_settings) - } - - /// Disable `collection` settings. - fn disable_collection_settings( - collection: &Self::CollectionId, - disable_settings: CollectionSettings, - ) -> DispatchResult { - Self::do_lock_collection(None, *collection, disable_settings) - } -} - impl, I: 'static> Transfer for Pallet { fn transfer( collection: &Self::CollectionId, diff --git a/frame/nfts/src/lib.rs b/frame/nfts/src/lib.rs index dea40cb12827b..2d19cf0455ad4 100644 --- a/frame/nfts/src/lib.rs +++ b/frame/nfts/src/lib.rs @@ -1086,8 +1086,7 @@ pub mod pallet { /// Disallows specified settings for the whole collection. /// - /// Origin must be either `ForceOrigin` or `Signed` and the sender should be the Freezer of - /// the `collection`. + /// Origin must be Signed and the sender should be the Freezer of the `collection`. /// /// - `collection`: The collection to be locked. /// - `lock_settings`: The settings to be locked. @@ -1103,10 +1102,8 @@ pub mod pallet { collection: T::CollectionId, lock_settings: CollectionSettings, ) -> DispatchResult { - let maybe_check_origin = T::ForceOrigin::try_origin(origin) - .map(|_| None) - .or_else(|origin| ensure_signed(origin).map(Some).map_err(DispatchError::from))?; - Self::do_lock_collection(maybe_check_origin, collection, lock_settings) + let origin = ensure_signed(origin)?; + Self::do_lock_collection(origin, collection, lock_settings) } /// Change the Owner of a collection. @@ -1655,7 +1652,11 @@ pub mod pallet { pub fn update_mint_settings( origin: OriginFor, collection: T::CollectionId, - mint_settings: MintSettingsFor, + mint_settings: MintSettings< + BalanceOf, + ::BlockNumber, + T::CollectionId, + >, ) -> DispatchResult { let maybe_check_owner = T::ForceOrigin::try_origin(origin) .map(|_| None) diff --git a/frame/nfts/src/tests.rs b/frame/nfts/src/tests.rs index 3016036265c45..e44e4151f84a0 100644 --- a/frame/nfts/src/tests.rs +++ b/frame/nfts/src/tests.rs @@ -23,7 +23,7 @@ use frame_support::{ assert_noop, assert_ok, dispatch::Dispatchable, traits::{ - tokens::nonfungibles_v2::{Create, Destroy, Mutate, MutateCollectionSettings}, + tokens::nonfungibles_v2::{Destroy, Mutate}, Currency, Get, }, }; @@ -245,57 +245,6 @@ fn lifecycle_should_work() { }); } -#[test] -fn change_config_via_traits_should_work() { - new_test_ext().execute_with(|| { - Balances::make_free_balance_be(&account(1), 100); - Balances::make_free_balance_be(&account(2), 100); - - assert_ok!(::AccountId>>::create_collection( - &account(1), - &account(1), - )); - assert_eq!(collections(), vec![(account(1), 0)]); - - assert_ok!(::AccountId, - MintSettingsFor, - CollectionSettings, - >>::set_max_supply(&0, 1)); - - assert_noop!( - Nfts::mint(RuntimeOrigin::signed(account(2)), 0, 0, account(2), None), - Error::::NoPermission - ); - - assert_ok!(::AccountId, - MintSettingsFor, - CollectionSettings, - >>::update_mint_settings( - &0, MintSettings { mint_type: MintType::Public, ..Default::default() } - )); - assert_ok!(::AccountId, - MintSettingsFor, - CollectionSettings, - >>::disable_collection_settings( - &0, - CollectionSettings::from_disabled(CollectionSetting::TransferableItems.into()) - )); - - assert_ok!(Nfts::mint(RuntimeOrigin::signed(account(2)), 0, 0, account(2), None)); - assert_noop!( - Nfts::transfer(RuntimeOrigin::signed(account(2)), 0, 0, account(1)), - Error::::ItemsNonTransferable - ); - assert_noop!( - Nfts::mint(RuntimeOrigin::signed(account(2)), 0, 1, account(2), None), - Error::::MaxSupplyReached - ); - }); -} - #[test] fn destroy_with_bad_witness_should_not_work() { new_test_ext().execute_with(|| { diff --git a/frame/nfts/src/types.rs b/frame/nfts/src/types.rs index 5ed019b28467b..e63076e2f13b0 100644 --- a/frame/nfts/src/types.rs +++ b/frame/nfts/src/types.rs @@ -61,8 +61,6 @@ pub(super) type CollectionConfigFor = CollectionConfig< ::BlockNumber, >::CollectionId, >; -pub(super) type MintSettingsFor = - MintSettings, ::BlockNumber, >::CollectionId>; pub(super) type PreSignedMintOf = PreSignedMint< >::CollectionId, >::ItemId, diff --git a/frame/support/src/traits/tokens/nonfungibles_v2.rs b/frame/support/src/traits/tokens/nonfungibles_v2.rs index 773103afc0a82..27bb76369c5c3 100644 --- a/frame/support/src/traits/tokens/nonfungibles_v2.rs +++ b/frame/support/src/traits/tokens/nonfungibles_v2.rs @@ -181,8 +181,20 @@ pub trait InspectEnumerable: Inspect { } /// Trait for providing the ability to create collections of nonfungible items. -pub trait Create: Inspect { - /// Create a `collection` of nonfungible items to be owned by `who` and managed by `admin`. +pub trait Create: Inspect { + /// Create a `collection` of nonfungible items to be owned by `who` and managed by `admin` with + /// collection settings provided in `config`. + fn create_collection( + who: &AccountId, + admin: &AccountId, + config: &CollectionConfig, + ) -> Result; +} + +/// A simplified trait for providing the ability to create collections of nonfungible items. +pub trait CreateSimplified: Inspect { + /// Create a `collection` of nonfungible items to be owned by `who` and managed by `admin` with + /// default collection settings. fn create_collection( who: &AccountId, admin: &AccountId, @@ -329,38 +341,6 @@ pub trait Mutate: Inspect { } } -/// Trait for providing the ability to change the settings of the collections of nonfungible items. -pub trait MutateCollectionSettings: - Inspect -{ - /// Set the maximum number of items a `collection` could have. - /// - /// By default, this is not a supported operation. - fn set_max_supply(_collection: &Self::CollectionId, _max_supply: u32) -> DispatchResult { - Err(TokenError::Unsupported.into()) - } - - /// Update mint settings for the `collection`. - /// - /// By default, this is not a supported operation. - fn update_mint_settings( - _collection: &Self::CollectionId, - _mint_settings: MintSettings, - ) -> DispatchResult { - Err(TokenError::Unsupported.into()) - } - - /// Disable `collection` settings. - /// - /// By default, this is not a supported operation. - fn disable_collection_settings( - _collection: &Self::CollectionId, - _disable_settings: CollectionSettings, - ) -> DispatchResult { - Err(TokenError::Unsupported.into()) - } -} - /// Trait for transferring non-fungible sets of items. pub trait Transfer: Inspect { /// Transfer `item` of `collection` into `destination` account. From adb473cf1cb38bed692bd521213e723698405ac2 Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Fri, 10 Mar 2023 12:23:44 +0200 Subject: [PATCH 5/6] Remove ambiguity --- frame/nfts/src/types.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/nfts/src/types.rs b/frame/nfts/src/types.rs index e63076e2f13b0..5bfae2e089837 100644 --- a/frame/nfts/src/types.rs +++ b/frame/nfts/src/types.rs @@ -362,7 +362,7 @@ impl Default { fn default() -> Self { Self { - settings: CollectionSettings::default(), + settings: CollectionSettings::all_enabled(), max_supply: None, mint_settings: MintSettings::default(), } @@ -427,7 +427,7 @@ pub struct ItemConfig { impl Default for ItemConfig { fn default() -> Self { - Self { settings: ItemSettings::default() } + Self { settings: ItemSettings::all_enabled() } } } From 4e1808058170740c12ec0f1272fd2fc6749869a0 Mon Sep 17 00:00:00 2001 From: Jegor Sidorenko Date: Fri, 10 Mar 2023 12:24:17 +0200 Subject: [PATCH 6/6] Make item's config optional --- frame/nfts/src/impl_nonfungibles.rs | 8 ++++++-- frame/support/src/traits/tokens/nonfungible_v2.rs | 5 +++-- frame/support/src/traits/tokens/nonfungibles_v2.rs | 3 ++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/frame/nfts/src/impl_nonfungibles.rs b/frame/nfts/src/impl_nonfungibles.rs index 614e76d9f6f47..865d0681880bb 100644 --- a/frame/nfts/src/impl_nonfungibles.rs +++ b/frame/nfts/src/impl_nonfungibles.rs @@ -203,9 +203,13 @@ impl, I: 'static> Mutate<::AccountId, ItemConfig collection: &Self::CollectionId, item: &Self::ItemId, who: &T::AccountId, - item_config: &ItemConfig, + item_config: Option<&ItemConfig>, deposit_collection_owner: bool, ) -> DispatchResult { + let item_config = match item_config { + Some(item_config) => *item_config, + None => ItemConfig { settings: Self::get_default_item_settings(&collection)? }, + }; Self::do_mint( *collection, *item, @@ -214,7 +218,7 @@ impl, I: 'static> Mutate<::AccountId, ItemConfig false => Some(who.clone()), }, who.clone(), - *item_config, + item_config, |_, _| Ok(()), ) } diff --git a/frame/support/src/traits/tokens/nonfungible_v2.rs b/frame/support/src/traits/tokens/nonfungible_v2.rs index c23bf3e4055b1..b0fdd8a6aac61 100644 --- a/frame/support/src/traits/tokens/nonfungible_v2.rs +++ b/frame/support/src/traits/tokens/nonfungible_v2.rs @@ -122,12 +122,13 @@ pub trait InspectEnumerable: Inspect { /// attributes set on them. pub trait Mutate: Inspect { /// Mint some `item` to be owned by `who`. + /// When `config` set to `None` it will use the collection's default_item_settings. /// /// By default, this is not a supported operation. fn mint_into( _item: &Self::ItemId, _who: &AccountId, - _config: &ItemConfig, + _config: Option<&ItemConfig>, _deposit_collection_owner: bool, ) -> DispatchResult { Err(TokenError::Unsupported.into()) @@ -257,7 +258,7 @@ impl< fn mint_into( item: &Self::ItemId, who: &AccountId, - config: &ItemConfig, + config: Option<&ItemConfig>, deposit_collection_owner: bool, ) -> DispatchResult { >::mint_into( diff --git a/frame/support/src/traits/tokens/nonfungibles_v2.rs b/frame/support/src/traits/tokens/nonfungibles_v2.rs index 27bb76369c5c3..df31f8517291c 100644 --- a/frame/support/src/traits/tokens/nonfungibles_v2.rs +++ b/frame/support/src/traits/tokens/nonfungibles_v2.rs @@ -230,13 +230,14 @@ pub trait Destroy: Inspect { /// minted, burned and/or have attributes set on them. pub trait Mutate: Inspect { /// Mint some `item` of `collection` to be owned by `who`. + /// When `config` set to `None` it will use the collection's default_item_settings. /// /// By default, this is not a supported operation. fn mint_into( _collection: &Self::CollectionId, _item: &Self::ItemId, _who: &AccountId, - _config: &ItemConfig, + _config: Option<&ItemConfig>, _deposit_collection_owner: bool, ) -> DispatchResult { Err(TokenError::Unsupported.into())