difftreelog
feat(rmrk) add equippable extrinsic
in: master
4 files changed
pallets/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(
pallets/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)
+ }
}
pallets/proxy-rmrk-equip/src/weights.rsdiffbeforeafterboth3//! Autogenerated weights for pallet_proxy_rmrk_equip3//! Autogenerated weights for pallet_proxy_rmrk_equip4//!4//!5//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev5//! 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: `[]`6//! DATE: 2022-06-20, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`7//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 10247//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024889// Executed Command:9// Executed Command:35pub trait WeightInfo {35pub trait WeightInfo {36 fn create_base(b: u32, ) -> Weight;36 fn create_base(b: u32, ) -> Weight;37 fn theme_add(b: u32, ) -> Weight;37 fn theme_add(b: u32, ) -> Weight;38 fn equippable() -> Weight;38}39}394040/// Weights for pallet_proxy_rmrk_equip using the Substrate node and recommended hardware.41/// Weights for pallet_proxy_rmrk_equip using the Substrate node and recommended hardware.53 // Storage: Nonfungible Owned (r:0 w:1)54 // Storage: Nonfungible Owned (r:0 w:1)54 // Storage: RmrkEquip InernalPartId (r:0 w:1)55 // Storage: RmrkEquip InernalPartId (r:0 w:1)55 fn create_base(b: u32, ) -> Weight {56 fn create_base(b: u32, ) -> Weight {56 (43_216_000 as Weight)57 (44_632_000 as Weight)57 // Standard Error: 10_00058 // Standard Error: 10_00058 .saturating_add((16_253_000 as Weight).saturating_mul(b as Weight))59 .saturating_add((16_912_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(6 as Weight))60 .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))61 .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(8 as Weight))62 .saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(b as Weight)))63 .saturating_add(T::DbWeight::get().writes((4 as Weight).saturating_mul(b as Weight)))63 }64 }64 // Storage: Common CollectionProperties (r:1 w:0)65 // Storage: Common CollectionProperties (r:1 w:0)65 // Storage: Common CollectionById (r:1 w:0)66 // Storage: Common CollectionById (r:1 w:0)70 // Storage: Nonfungible TokenData (r:0 w:1)71 // Storage: Nonfungible TokenData (r:0 w:1)71 // Storage: Nonfungible Owned (r:0 w:1)72 // Storage: Nonfungible Owned (r:0 w:1)72 fn theme_add(b: u32, ) -> Weight {73 fn theme_add(b: u32, ) -> Weight {73 (39_467_000 as Weight)74 (39_525_000 as Weight)74 // Standard Error: 15_00075 // Standard Error: 12_00075 .saturating_add((2_332_000 as Weight).saturating_mul(b as Weight))76 .saturating_add((2_494_000 as Weight).saturating_mul(b as Weight))76 .saturating_add(T::DbWeight::get().reads(6 as Weight))77 .saturating_add(T::DbWeight::get().reads(6 as Weight))77 .saturating_add(T::DbWeight::get().writes(5 as Weight))78 .saturating_add(T::DbWeight::get().writes(5 as Weight))78 }79 }80 // Storage: Common CollectionProperties (r:1 w:0)81 // Storage: Common CollectionById (r:1 w:0)82 // Storage: RmrkEquip InernalPartId (r:1 w:0)83 // Storage: Nonfungible TokenProperties (r:1 w:1)84 fn equippable() -> Weight {85 (27_371_000 as Weight)86 .saturating_add(T::DbWeight::get().reads(4 as Weight))87 .saturating_add(T::DbWeight::get().writes(1 as Weight))88 }79}89}809081// For backwards compatibility and tests91// For backwards compatibility and tests93 // Storage: Nonfungible Owned (r:0 w:1)103 // Storage: Nonfungible Owned (r:0 w:1)94 // Storage: RmrkEquip InernalPartId (r:0 w:1)104 // Storage: RmrkEquip InernalPartId (r:0 w:1)95 fn create_base(b: u32, ) -> Weight {105 fn create_base(b: u32, ) -> Weight {96 (43_216_000 as Weight)106 (44_632_000 as Weight)97 // Standard Error: 10_000107 // Standard Error: 10_00098 .saturating_add((16_253_000 as Weight).saturating_mul(b as Weight))108 .saturating_add((16_912_000 as Weight).saturating_mul(b as Weight))99 .saturating_add(RocksDbWeight::get().reads(6 as Weight))109 .saturating_add(RocksDbWeight::get().reads(6 as Weight))100 .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))110 .saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))101 .saturating_add(RocksDbWeight::get().writes(9 as Weight))111 .saturating_add(RocksDbWeight::get().writes(8 as Weight))102 .saturating_add(RocksDbWeight::get().writes((3 as Weight).saturating_mul(b as Weight)))112 .saturating_add(RocksDbWeight::get().writes((4 as Weight).saturating_mul(b as Weight)))103 }113 }104 // Storage: Common CollectionProperties (r:1 w:0)114 // Storage: Common CollectionProperties (r:1 w:0)105 // Storage: Common CollectionById (r:1 w:0)115 // Storage: Common CollectionById (r:1 w:0)110 // Storage: Nonfungible TokenData (r:0 w:1)120 // Storage: Nonfungible TokenData (r:0 w:1)111 // Storage: Nonfungible Owned (r:0 w:1)121 // Storage: Nonfungible Owned (r:0 w:1)112 fn theme_add(b: u32, ) -> Weight {122 fn theme_add(b: u32, ) -> Weight {113 (39_467_000 as Weight)123 (39_525_000 as Weight)114 // Standard Error: 15_000124 // Standard Error: 12_000115 .saturating_add((2_332_000 as Weight).saturating_mul(b as Weight))125 .saturating_add((2_494_000 as Weight).saturating_mul(b as Weight))116 .saturating_add(RocksDbWeight::get().reads(6 as Weight))126 .saturating_add(RocksDbWeight::get().reads(6 as Weight))117 .saturating_add(RocksDbWeight::get().writes(5 as Weight))127 .saturating_add(RocksDbWeight::get().writes(5 as Weight))118 }128 }129 // Storage: Common CollectionProperties (r:1 w:0)130 // Storage: Common CollectionById (r:1 w:0)131 // Storage: RmrkEquip InernalPartId (r:1 w:0)132 // Storage: Nonfungible TokenProperties (r:1 w:1)133 fn equippable() -> Weight {134 (27_371_000 as Weight)135 .saturating_add(RocksDbWeight::get().reads(4 as Weight))136 .saturating_add(RocksDbWeight::get().writes(1 as Weight))137 }119}138}120139primitives/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>>;