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
before · pallets/proxy-rmrk-equip/src/weights.rs
1// Template adopted from https://github.com/paritytech/substrate/blob/master/.maintain/frame-weight-template.hbs23//! Autogenerated weights for pallet_proxy_rmrk_equip4//!5//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev6//! DATE: 2022-06-16, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`7//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 102489// Executed Command:10// target/release/unique-collator11// benchmark12// pallet13// --pallet14// pallet-proxy-rmrk-equip15// --wasm-execution16// compiled17// --extrinsic18// *19// --template20// .maintain/frame-weight-template.hbs21// --steps=5022// --repeat=8023// --heap-pages=409624// --output=./pallets/proxy-rmrk-equip/src/weights.rs2526#![cfg_attr(rustfmt, rustfmt_skip)]27#![allow(unused_parens)]28#![allow(unused_imports)]29#![allow(clippy::unnecessary_cast)]3031use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};32use sp_std::marker::PhantomData;3334/// Weight functions needed for pallet_proxy_rmrk_equip.35pub trait WeightInfo {36	fn create_base(b: u32, ) -> Weight;37	fn theme_add(b: u32, ) -> Weight;38}3940/// Weights for pallet_proxy_rmrk_equip using the Substrate node and recommended hardware.41pub struct SubstrateWeight<T>(PhantomData<T>);42impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {43	// Storage: Common CreatedCollectionCount (r:1 w:1)44	// Storage: Common DestroyedCollectionCount (r:1 w:0)45	// Storage: System Account (r:2 w:2)46	// Storage: Common CollectionPropertyPermissions (r:0 w:1)47	// Storage: Common CollectionProperties (r:0 w:1)48	// Storage: Common CollectionById (r:0 w:1)49	// Storage: Nonfungible TokensMinted (r:1 w:1)50	// Storage: Nonfungible AccountBalance (r:1 w:1)51	// Storage: Nonfungible TokenProperties (r:1 w:1)52	// Storage: Nonfungible TokenData (r:0 w:1)53	// Storage: Nonfungible Owned (r:0 w:1)54	// Storage: RmrkEquip InernalPartId (r:0 w:1)55	fn create_base(b: u32, ) -> Weight {56		(43_216_000 as Weight)57			// Standard Error: 10_00058			.saturating_add((16_253_000 as Weight).saturating_mul(b as Weight))59			.saturating_add(T::DbWeight::get().reads(6 as Weight))60			.saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))61			.saturating_add(T::DbWeight::get().writes(9 as Weight))62			.saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(b as Weight)))63	}64	// Storage: Common CollectionProperties (r:1 w:0)65	// Storage: Common CollectionById (r:1 w:0)66	// Storage: RmrkEquip BaseHasDefaultTheme (r:1 w:0)67	// Storage: Nonfungible TokensMinted (r:1 w:1)68	// Storage: Nonfungible AccountBalance (r:1 w:1)69	// Storage: Nonfungible TokenProperties (r:1 w:1)70	// Storage: Nonfungible TokenData (r:0 w:1)71	// Storage: Nonfungible Owned (r:0 w:1)72	fn theme_add(b: u32, ) -> Weight {73		(39_467_000 as Weight)74			// Standard Error: 15_00075			.saturating_add((2_332_000 as Weight).saturating_mul(b as Weight))76			.saturating_add(T::DbWeight::get().reads(6 as Weight))77			.saturating_add(T::DbWeight::get().writes(5 as Weight))78	}79}8081// For backwards compatibility and tests82impl WeightInfo for () {83	// Storage: Common CreatedCollectionCount (r:1 w:1)84	// Storage: Common DestroyedCollectionCount (r:1 w:0)85	// Storage: System Account (r:2 w:2)86	// Storage: Common CollectionPropertyPermissions (r:0 w:1)87	// Storage: Common CollectionProperties (r:0 w:1)88	// Storage: Common CollectionById (r:0 w:1)89	// Storage: Nonfungible TokensMinted (r:1 w:1)90	// Storage: Nonfungible AccountBalance (r:1 w:1)91	// Storage: Nonfungible TokenProperties (r:1 w:1)92	// Storage: Nonfungible TokenData (r:0 w:1)93	// Storage: Nonfungible Owned (r:0 w:1)94	// Storage: RmrkEquip InernalPartId (r:0 w:1)95	fn create_base(b: u32, ) -> Weight {96		(43_216_000 as Weight)97			// Standard Error: 10_00098			.saturating_add((16_253_000 as Weight).saturating_mul(b as Weight))99			.saturating_add(RocksDbWeight::get().reads(6 as Weight))100			.saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))101			.saturating_add(RocksDbWeight::get().writes(9 as Weight))102			.saturating_add(RocksDbWeight::get().writes((3 as Weight).saturating_mul(b as Weight)))103	}104	// Storage: Common CollectionProperties (r:1 w:0)105	// Storage: Common CollectionById (r:1 w:0)106	// Storage: RmrkEquip BaseHasDefaultTheme (r:1 w:0)107	// Storage: Nonfungible TokensMinted (r:1 w:1)108	// Storage: Nonfungible AccountBalance (r:1 w:1)109	// Storage: Nonfungible TokenProperties (r:1 w:1)110	// Storage: Nonfungible TokenData (r:0 w:1)111	// Storage: Nonfungible Owned (r:0 w:1)112	fn theme_add(b: u32, ) -> Weight {113		(39_467_000 as Weight)114			// Standard Error: 15_000115			.saturating_add((2_332_000 as Weight).saturating_mul(b as Weight))116			.saturating_add(RocksDbWeight::get().reads(6 as Weight))117			.saturating_add(RocksDbWeight::get().writes(5 as Weight))118	}119}
modifiedprimitives/data-structs/src/lib.rsdiffbeforeafterboth
--- a/primitives/data-structs/src/lib.rs
+++ b/primitives/data-structs/src/lib.rs
@@ -39,15 +39,15 @@
 // RMRK
 use rmrk_traits::{
 	CollectionInfo, NftInfo, ResourceInfo, PropertyInfo, BaseInfo, PartType, Theme, ThemeProperty,
-	ResourceTypes, BasicResource, ComposableResource, SlotResource,
+	ResourceTypes, BasicResource, ComposableResource, SlotResource, EquippableList,
 };
 pub use rmrk_traits::{
 	primitives::{
 		CollectionId as RmrkCollectionId, NftId as RmrkNftId, BaseId as RmrkBaseId,
-		PartId as RmrkPartId, ResourceId as RmrkResourceId,
+		SlotId as RmrkSlotId, PartId as RmrkPartId, ResourceId as RmrkResourceId,
 	},
 	NftChild as RmrkNftChild, AccountIdOrCollectionNftTuple as RmrkAccountIdOrCollectionNftTuple,
-	FixedPart as RmrkFixedPart, SlotPart as RmrkSlotPart, EquippableList as RmrkEquippableList,
+	FixedPart as RmrkFixedPart, SlotPart as RmrkSlotPart,
 };
 
 mod bounded;
@@ -987,8 +987,9 @@
 pub type RmrkResourceInfo = ResourceInfo<RmrkString, RmrkBoundedParts>;
 pub type RmrkPropertyInfo = PropertyInfo<RmrkKeyString, RmrkValueString>;
 pub type RmrkBaseInfo<AccountId> = BaseInfo<AccountId, RmrkString>;
-pub type RmrkPartType =
-	PartType<RmrkString, BoundedVec<RmrkCollectionId, RmrkMaxCollectionsEquippablePerPart>>;
+pub type BoundedEquippableCollectionIds = BoundedVec<RmrkCollectionId, RmrkMaxCollectionsEquippablePerPart>;
+pub type RmrkPartType = PartType<RmrkString, BoundedEquippableCollectionIds>;
+pub type RmrkEquippableList = EquippableList<BoundedEquippableCollectionIds>;
 pub type RmrkThemeProperty = ThemeProperty<RmrkString>;
 pub type RmrkTheme = Theme<RmrkString, Vec<RmrkThemeProperty>>;
 pub type RmrkBoundedTheme = Theme<RmrkString, BoundedVec<RmrkThemeProperty, MaxPropertiesPerTheme>>;