git.delta.rocks / unique-network / refs/commits / da5e7f48f1a3

difftreelog

feat(rmrk) add equippable extrinsic

Daniel Shiposha2022-06-20parent: #960c108.patch.diff
in: master

4 files changed

modifiedpallets/proxy-rmrk-core/src/lib.rsdiffbeforeafterboth
--- a/pallets/proxy-rmrk-core/src/lib.rs
+++ b/pallets/proxy-rmrk-core/src/lib.rs
@@ -1298,7 +1298,7 @@
 		collection.save()
 	}
 
-	fn check_collection_owner(
+	pub fn check_collection_owner(
 		collection: &NonfungibleHandle<T>,
 		account: &T::CrossAccountId,
 	) -> DispatchResult {
@@ -1363,7 +1363,11 @@
 		collection_id: CollectionId,
 	) -> Result<misc::CollectionType, DispatchError> {
 		Self::get_collection_property_decoded(collection_id, CollectionType)
-			.map_err(|_| <Error<T>>::CorruptedCollectionType.into())
+			.map_err(|err| if err != <Error<T>>::CollectionUnknown.into() {
+				<Error<T>>::CorruptedCollectionType.into()
+			} else {
+				err
+			})
 	}
 
 	pub fn ensure_collection_type(
modifiedpallets/proxy-rmrk-equip/src/lib.rsdiffbeforeafterboth
--- a/pallets/proxy-rmrk-equip/src/lib.rs
+++ b/pallets/proxy-rmrk-equip/src/lib.rs
@@ -23,6 +23,7 @@
 use pallet_common::{Pallet as PalletCommon, Error as CommonError};
 use pallet_rmrk_core::{
 	Pallet as PalletCore,
+	Error as CoreError,
 	misc::{self, *},
 	property::RmrkProperty::*,
 };
@@ -70,6 +71,10 @@
 			issuer: T::AccountId,
 			base_id: RmrkBaseId,
 		},
+		EquippablesUpdated {
+			base_id: RmrkBaseId,
+			slot_id: RmrkSlotId,
+		},
 	}
 
 	#[pallet::error]
@@ -79,6 +84,8 @@
 		NoAvailablePartId,
 		BaseDoesntExist,
 		NeedsDefaultThemeFirst,
+		PartDoesntExist,
+		NoEquippableOnFixedPart,
 	}
 
 	#[pallet::call]
@@ -182,12 +189,7 @@
 
 			let collection_id: CollectionId = base_id.into();
 
-			let collection = <PalletCore<T>>::get_typed_nft_collection(
-				collection_id,
-				misc::CollectionType::Base,
-			)
-			.map_err(|_| <Error<T>>::BaseDoesntExist)?;
-			collection.check_is_external()?;
+			let collection = Self::get_base(collection_id)?;
 
 			if theme.name.as_slice() == b"default" {
 				<BaseHasDefaultTheme<T>>::insert(collection_id, true);
@@ -222,6 +224,53 @@
 
 			Ok(())
 		}
+
+		#[transactional]
+		#[pallet::weight(<SelfWeightOf<T>>::equippable())]
+		pub fn equippable(
+			origin: OriginFor<T>,
+			base_id: RmrkBaseId,
+			slot_id: RmrkSlotId,
+			equippables: RmrkEquippableList,
+		) -> DispatchResult {
+			let sender = ensure_signed(origin)?;
+
+			let base_collection_id = base_id.into();
+			let collection = Self::get_base(base_collection_id)?;
+
+			<PalletCore<T>>::check_collection_owner(&collection, &T::CrossAccountId::from_sub(sender))
+				.map_err(|err| if err == <CoreError<T>>::NoPermission.into() {
+					<Error<T>>::PermissionError.into()
+				} else {
+					err
+				})?;
+
+			let part_id = Self::internal_part_id(base_collection_id, slot_id)
+				.ok_or(<Error<T>>::PartDoesntExist)?;
+
+			let nft_type = <PalletCore<T>>::get_nft_type(base_collection_id, part_id)
+				.map_err(|_| <Error<T>>::PartDoesntExist)?;
+
+			match nft_type {
+				NftType::Regular | NftType::Theme => return Err(<Error<T>>::PermissionError.into()),
+				NftType::FixedPart => return Err(<Error<T>>::NoEquippableOnFixedPart.into()),
+				NftType::SlotPart => {
+					<PalletNft<T>>::set_scoped_token_property(
+						base_collection_id,
+						part_id,
+						PropertyScope::Rmrk,
+						<PalletCore<T>>::rmrk_property(EquippableList, &equippables)?,
+					)?;
+				}
+			}
+
+			Self::deposit_event(Event::EquippablesUpdated {
+				base_id,
+				slot_id,
+			});
+
+			Ok(())
+		}
 	}
 }
 
@@ -268,4 +317,16 @@
 
 		Ok(token_id)
 	}
+
+	fn get_base(base_id: CollectionId) -> Result<NonfungibleHandle<T>, DispatchError> {
+		let collection = <PalletCore<T>>::get_typed_nft_collection(base_id, misc::CollectionType::Base)
+			.map_err(|err| if err == <CoreError<T>>::CollectionUnknown.into() {
+				<Error<T>>::BaseDoesntExist.into()
+			} else {
+				err
+			})?;
+		collection.check_is_external()?;
+
+		Ok(collection)
+	}
 }
modifiedpallets/proxy-rmrk-equip/src/weights.rsdiffbeforeafterboth
--- a/pallets/proxy-rmrk-equip/src/weights.rs
+++ b/pallets/proxy-rmrk-equip/src/weights.rs
@@ -3,7 +3,7 @@
 //! Autogenerated weights for pallet_proxy_rmrk_equip
 //!
 //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2022-06-16, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2022-06-20, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024
 
 // Executed Command:
@@ -35,6 +35,7 @@
 pub trait WeightInfo {
 	fn create_base(b: u32, ) -> Weight;
 	fn theme_add(b: u32, ) -> Weight;
+	fn equippable() -> Weight;
 }
 
 /// Weights for pallet_proxy_rmrk_equip using the Substrate node and recommended hardware.
@@ -53,13 +54,13 @@
 	// Storage: Nonfungible Owned (r:0 w:1)
 	// Storage: RmrkEquip InernalPartId (r:0 w:1)
 	fn create_base(b: u32, ) -> Weight {
-		(43_216_000 as Weight)
+		(44_632_000 as Weight)
 			// Standard Error: 10_000
-			.saturating_add((16_253_000 as Weight).saturating_mul(b as Weight))
+			.saturating_add((16_912_000 as Weight).saturating_mul(b as Weight))
 			.saturating_add(T::DbWeight::get().reads(6 as Weight))
 			.saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
-			.saturating_add(T::DbWeight::get().writes(9 as Weight))
-			.saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(b as Weight)))
+			.saturating_add(T::DbWeight::get().writes(8 as Weight))
+			.saturating_add(T::DbWeight::get().writes((4 as Weight).saturating_mul(b as Weight)))
 	}
 	// Storage: Common CollectionProperties (r:1 w:0)
 	// Storage: Common CollectionById (r:1 w:0)
@@ -70,12 +71,21 @@
 	// Storage: Nonfungible TokenData (r:0 w:1)
 	// Storage: Nonfungible Owned (r:0 w:1)
 	fn theme_add(b: u32, ) -> Weight {
-		(39_467_000 as Weight)
-			// Standard Error: 15_000
-			.saturating_add((2_332_000 as Weight).saturating_mul(b as Weight))
+		(39_525_000 as Weight)
+			// Standard Error: 12_000
+			.saturating_add((2_494_000 as Weight).saturating_mul(b as Weight))
 			.saturating_add(T::DbWeight::get().reads(6 as Weight))
 			.saturating_add(T::DbWeight::get().writes(5 as Weight))
 	}
+	// Storage: Common CollectionProperties (r:1 w:0)
+	// Storage: Common CollectionById (r:1 w:0)
+	// Storage: RmrkEquip InernalPartId (r:1 w:0)
+	// Storage: Nonfungible TokenProperties (r:1 w:1)
+	fn equippable() -> Weight {
+		(27_371_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(4 as Weight))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+	}
 }
 
 // For backwards compatibility and tests
@@ -93,13 +103,13 @@
 	// Storage: Nonfungible Owned (r:0 w:1)
 	// Storage: RmrkEquip InernalPartId (r:0 w:1)
 	fn create_base(b: u32, ) -> Weight {
-		(43_216_000 as Weight)
+		(44_632_000 as Weight)
 			// Standard Error: 10_000
-			.saturating_add((16_253_000 as Weight).saturating_mul(b as Weight))
+			.saturating_add((16_912_000 as Weight).saturating_mul(b as Weight))
 			.saturating_add(RocksDbWeight::get().reads(6 as Weight))
 			.saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
-			.saturating_add(RocksDbWeight::get().writes(9 as Weight))
-			.saturating_add(RocksDbWeight::get().writes((3 as Weight).saturating_mul(b as Weight)))
+			.saturating_add(RocksDbWeight::get().writes(8 as Weight))
+			.saturating_add(RocksDbWeight::get().writes((4 as Weight).saturating_mul(b as Weight)))
 	}
 	// Storage: Common CollectionProperties (r:1 w:0)
 	// Storage: Common CollectionById (r:1 w:0)
@@ -110,10 +120,19 @@
 	// Storage: Nonfungible TokenData (r:0 w:1)
 	// Storage: Nonfungible Owned (r:0 w:1)
 	fn theme_add(b: u32, ) -> Weight {
-		(39_467_000 as Weight)
-			// Standard Error: 15_000
-			.saturating_add((2_332_000 as Weight).saturating_mul(b as Weight))
+		(39_525_000 as Weight)
+			// Standard Error: 12_000
+			.saturating_add((2_494_000 as Weight).saturating_mul(b as Weight))
 			.saturating_add(RocksDbWeight::get().reads(6 as Weight))
 			.saturating_add(RocksDbWeight::get().writes(5 as Weight))
 	}
+	// Storage: Common CollectionProperties (r:1 w:0)
+	// Storage: Common CollectionById (r:1 w:0)
+	// Storage: RmrkEquip InernalPartId (r:1 w:0)
+	// Storage: Nonfungible TokenProperties (r:1 w:1)
+	fn equippable() -> Weight {
+		(27_371_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(4 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+	}
 }
modifiedprimitives/data-structs/src/lib.rsdiffbeforeafterboth
39// RMRK39// RMRK
40use rmrk_traits::{40use rmrk_traits::{
41 CollectionInfo, NftInfo, ResourceInfo, PropertyInfo, BaseInfo, PartType, Theme, ThemeProperty,41 CollectionInfo, NftInfo, ResourceInfo, PropertyInfo, BaseInfo, PartType, Theme, ThemeProperty,
42 ResourceTypes, BasicResource, ComposableResource, SlotResource,42 ResourceTypes, BasicResource, ComposableResource, SlotResource, EquippableList,
43};43};
44pub use rmrk_traits::{44pub use rmrk_traits::{
45 primitives::{45 primitives::{
46 CollectionId as RmrkCollectionId, NftId as RmrkNftId, BaseId as RmrkBaseId,46 CollectionId as RmrkCollectionId, NftId as RmrkNftId, BaseId as RmrkBaseId,
47 PartId as RmrkPartId, ResourceId as RmrkResourceId,47 SlotId as RmrkSlotId, PartId as RmrkPartId, ResourceId as RmrkResourceId,
48 },48 },
49 NftChild as RmrkNftChild, AccountIdOrCollectionNftTuple as RmrkAccountIdOrCollectionNftTuple,49 NftChild as RmrkNftChild, AccountIdOrCollectionNftTuple as RmrkAccountIdOrCollectionNftTuple,
50 FixedPart as RmrkFixedPart, SlotPart as RmrkSlotPart, EquippableList as RmrkEquippableList,50 FixedPart as RmrkFixedPart, SlotPart as RmrkSlotPart,
51};51};
5252
53mod bounded;53mod bounded;
987pub type RmrkResourceInfo = ResourceInfo<RmrkString, RmrkBoundedParts>;987pub type RmrkResourceInfo = ResourceInfo<RmrkString, RmrkBoundedParts>;
988pub type RmrkPropertyInfo = PropertyInfo<RmrkKeyString, RmrkValueString>;988pub type RmrkPropertyInfo = PropertyInfo<RmrkKeyString, RmrkValueString>;
989pub type RmrkBaseInfo<AccountId> = BaseInfo<AccountId, RmrkString>;989pub type RmrkBaseInfo<AccountId> = BaseInfo<AccountId, RmrkString>;
990pub type RmrkPartType =990pub type BoundedEquippableCollectionIds = BoundedVec<RmrkCollectionId, RmrkMaxCollectionsEquippablePerPart>;
991 PartType<RmrkString, BoundedVec<RmrkCollectionId, RmrkMaxCollectionsEquippablePerPart>>;991pub type RmrkPartType = PartType<RmrkString, BoundedEquippableCollectionIds>;
992pub type RmrkEquippableList = EquippableList<BoundedEquippableCollectionIds>;
992pub type RmrkThemeProperty = ThemeProperty<RmrkString>;993pub type RmrkThemeProperty = ThemeProperty<RmrkString>;
993pub type RmrkTheme = Theme<RmrkString, Vec<RmrkThemeProperty>>;994pub type RmrkTheme = Theme<RmrkString, Vec<RmrkThemeProperty>>;
994pub type RmrkBoundedTheme = Theme<RmrkString, BoundedVec<RmrkThemeProperty, MaxPropertiesPerTheme>>;995pub type RmrkBoundedTheme = Theme<RmrkString, BoundedVec<RmrkThemeProperty, MaxPropertiesPerTheme>>;