difftreelog
refactor iterate rmrk props, add rmrk proxy set_propertty
in: master
5 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
@@ -24,6 +24,7 @@
use pallet_common::{Pallet as PalletCommon, Error as CommonError, CollectionHandle, CommonCollectionOperations};
use pallet_nonfungible::{Pallet as PalletNft, NonfungibleHandle, TokenData};
use pallet_evm::account::CrossAccountId;
+use core::convert::AsRef;
pub use pallet::*;
@@ -85,6 +86,12 @@
owner: T::AccountId,
nft_id: RmrkNftId,
},
+ PropertySet {
+ collection_id: RmrkCollectionId,
+ maybe_nft_id: Option<RmrkNftId>,
+ key: RmrkKeyString,
+ value: RmrkValueString,
+ },
}
#[pallet::error]
@@ -291,7 +298,7 @@
collection_id: RmrkCollectionId,
nft_id: RmrkNftId,
) -> DispatchResult {
- let sender = ensure_signed(origin.clone())?;
+ let sender = ensure_signed(origin)?;
let cross_sender = T::CrossAccountId::from_sub(sender.clone());
Self::destroy_nft(
@@ -305,6 +312,62 @@
Ok(())
}
+
+ #[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]
+ #[transactional]
+ pub fn set_property(
+ origin: OriginFor<T>,
+ #[pallet::compact] rmrk_collection_id: RmrkCollectionId,
+ maybe_nft_id: Option<RmrkNftId>,
+ key: RmrkKeyString,
+ value: RmrkValueString,
+ ) -> DispatchResult {
+ let sender = ensure_signed(origin)?;
+ let sender = T::CrossAccountId::from_sub(sender);
+
+ let collection_id: CollectionId = rmrk_collection_id.into();
+
+ match maybe_nft_id {
+ Some(nft_id) => {
+ let token_id: TokenId = nft_id.into();
+
+ Self::ensure_nft_owner(collection_id, token_id, &sender)?;
+ Self::ensure_nft_type(collection_id, token_id, NftType::Regular)?;
+
+ <PalletNft<T>>::set_scoped_token_property(
+ collection_id,
+ token_id,
+ PropertyScope::Rmrk,
+ Self::rmrk_property(UserProperty(key.as_slice()), &value)?
+ )?;
+ },
+ None => {
+ let collection = Self::get_typed_nft_collection(
+ collection_id,
+ misc::CollectionType::Regular
+ )?;
+
+ Self::check_collection_owner(&collection, &sender)?;
+
+ <PalletCommon<T>>::set_scoped_collection_property(
+ collection_id,
+ PropertyScope::Rmrk,
+ Self::rmrk_property(UserProperty(key.as_slice()), &value)?
+ )?;
+ }
+ }
+
+ Self::deposit_event(
+ Event::PropertySet {
+ collection_id: rmrk_collection_id,
+ maybe_nft_id,
+ key,
+ value
+ }
+ );
+
+ Ok(())
+ }
}
}
@@ -477,65 +540,91 @@
pub fn ensure_nft_type(collection_id: CollectionId, token_id: TokenId, nft_type: NftType) -> DispatchResult {
let actual_type = Self::get_nft_type(collection_id, token_id)?;
- ensure!(actual_type == nft_type, <CommonError<T>>::NoPermission);
+ ensure!(actual_type == nft_type, <Error<T>>::NoPermission);
Ok(())
}
- pub fn filter_theme_properties(
+ pub fn ensure_nft_owner(
collection_id: CollectionId,
token_id: TokenId,
- filter_keys: Option<Vec<RmrkPropertyKey>>
- ) -> Result<Vec<RmrkThemeProperty>, DispatchError> {
+ possible_owner: &T::CrossAccountId
+ ) -> DispatchResult {
+ let token_data = <TokenData<T>>::get((collection_id, token_id))
+ .ok_or(<Error<T>>::NoAvailableNftId)?;
+
+ ensure!(token_data.owner == *possible_owner, <Error<T>>::NoPermission);
+
+ Ok(())
+ }
+
+ pub fn filter_user_properties<Key, Value, R, Mapper>(
+ collection_id: CollectionId,
+ token_id: Option<TokenId>,
+ filter_keys: Option<Vec<RmrkPropertyKey>>,
+ mapper: Mapper,
+ ) -> Result<Vec<R>, DispatchError>
+ where
+ Key: TryFrom<RmrkPropertyKey> + AsRef<[u8]>,
+ Value: Decode + Default,
+ Mapper: Fn(Key, Value) -> R
+ {
filter_keys.map(|keys| {
let properties = keys.into_iter()
.filter_map(|key| {
- let key: RmrkString = key.try_into().ok()?;
+ let key: Key = key.try_into().ok()?;
- let value = Self::get_nft_property(
- collection_id,
- token_id,
- ThemeProperty(&key)
- ).ok()?.decode_or_default();
-
- let property = RmrkThemeProperty {
- key,
- value
- };
+ let value = match token_id {
+ Some(token_id) => Self::get_nft_property(
+ collection_id,
+ token_id,
+ UserProperty(key.as_ref())
+ ),
+ None => Self::get_collection_property(
+ collection_id,
+ UserProperty(key.as_ref())
+ )
+ }.ok()?.decode_or_default();
- Some(property)
+ Some(mapper(key, value))
})
.collect();
Ok(properties)
}).unwrap_or_else(|| {
- let properties = Self::iterate_theme_properties(collection_id, token_id)?
+ let properties = Self::iterate_user_properties(collection_id, token_id, mapper)?
.collect();
Ok(properties)
})
}
- pub fn iterate_theme_properties(
+ pub fn iterate_user_properties<Key, Value, R, Mapper>(
collection_id: CollectionId,
- token_id: TokenId
- ) -> Result<impl Iterator<Item=RmrkThemeProperty>, DispatchError> {
- let key_prefix = Self::rmrk_property_key(ThemeProperty(&RmrkString::default()))?;
+ token_id: Option<TokenId>,
+ mapper: Mapper,
+ ) -> Result<impl Iterator<Item=R>, DispatchError>
+ where
+ Key: TryFrom<RmrkPropertyKey> + AsRef<[u8]>,
+ Value: Decode + Default,
+ Mapper: Fn(Key, Value) -> R
+ {
+ let key_prefix = Self::rmrk_property_key(UserProperty(b""))?;
- let properties = <PalletNft<T>>::token_properties((collection_id, token_id))
+ let properties = match token_id {
+ Some(token_id) => <PalletNft<T>>::token_properties((collection_id, token_id)),
+ None => <PalletCommon<T>>::collection_properties(collection_id)
+ };
+
+ let properties = properties
.into_iter()
.filter_map(move |(key, value)| {
let key = key.as_slice().strip_prefix(key_prefix.as_slice())?;
- let key: RmrkString = key.to_vec().try_into().ok()?;
- let value: RmrkString = value.decode_or_default();
+ let key: Key = key.to_vec().try_into().ok()?;
+ let value: Value = value.decode_or_default();
- let property = RmrkThemeProperty {
- key,
- value
- };
-
- Some(property)
+ Some(mapper(key, value))
});
Ok(properties)
pallets/proxy-rmrk-core/src/property.rsdiffbeforeafterboth--- a/pallets/proxy-rmrk-core/src/property.rs
+++ b/pallets/proxy-rmrk-core/src/property.rs
@@ -23,8 +23,8 @@
EquippableList,
ZIndex,
ThemeName,
- ThemeProperty(&'r RmrkString),
ThemeInherit,
+ UserProperty(&'r [u8]),
}
impl<'r> RmrkProperty<'r> {
@@ -66,8 +66,8 @@
Self::EquippableList => key!("equippable-list"),
Self::ZIndex => key!("z-index"),
Self::ThemeName => key!("theme-name"),
- Self::ThemeProperty(name) => key!("theme-property-", name),
Self::ThemeInherit => key!("theme-inherit"),
+ Self::UserProperty(name) => key!("userprop-", name),
}
}
}
pallets/proxy-rmrk-equip/src/lib.rsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617#![cfg_attr(not(feature = "std"), no_std)]1819use frame_support::{pallet_prelude::*, transactional, BoundedVec, dispatch::DispatchResult};20use frame_system::{pallet_prelude::*, ensure_signed};21use sp_runtime::DispatchError;22use up_data_structs::*;23use pallet_common::{Pallet as PalletCommon, Error as CommonError};24use pallet_rmrk_core::{Pallet as PalletCore, misc::{self, *}, property::RmrkProperty::*};25use pallet_nonfungible::{Pallet as PalletNft, NonfungibleHandle};26use pallet_evm::account::CrossAccountId;2728pub use pallet::*;2930#[frame_support::pallet]31pub mod pallet {32 use super::*;3334 #[pallet::config]35 pub trait Config: frame_system::Config36 + pallet_rmrk_core::Config {37 type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;38 }3940 #[pallet::storage]41 #[pallet::getter(fn internal_part_id)]42 pub type InernalPartId<T: Config> = StorageDoubleMap<43 _,44 Twox64Concat,45 CollectionId,46 Twox64Concat,47 RmrkPartId,48 TokenId49 >;5051 #[pallet::storage]52 #[pallet::getter(fn base_has_default_theme)]53 pub type BaseHasDefaultTheme<T: Config> = StorageMap<54 _,55 Twox64Concat,56 CollectionId,57 bool,58 ValueQuery59 >;6061 #[pallet::pallet]62 #[pallet::generate_store(pub(super) trait Store)]63 pub struct Pallet<T>(_);6465 #[pallet::event]66 #[pallet::generate_deposit(pub(super) fn deposit_event)]67 pub enum Event<T: Config> {68 BaseCreated {69 issuer: T::AccountId,70 base_id: RmrkBaseId,71 },72 }7374 #[pallet::error]75 pub enum Error<T> {76 PermissionError,77 NoAvailableBaseId,78 NoAvailablePartId,79 BaseDoesntExist,80 NeedsDefaultThemeFirst,81 }8283 #[pallet::call]84 impl<T: Config> Pallet<T> {85 #[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]86 #[transactional]87 pub fn create_base(88 origin: OriginFor<T>,89 base_type: RmrkString,90 symbol: RmrkString,91 parts: BoundedVec<RmrkPartType, RmrkPartsLimit>,92 ) -> DispatchResult {93 let sender = ensure_signed(origin)?;94 let cross_sender = T::CrossAccountId::from_sub(sender.clone());9596 let data = CreateCollectionData {97 limits: None,98 token_prefix: symbol.into_inner()99 .try_into()100 .map_err(|_| <CommonError<T>>::CollectionTokenPrefixLimitExceeded)?,101 ..Default::default()102 };103104 let collection_id_res = <PalletNft<T>>::init_collection(sender.clone(), data);105106 if let Err(DispatchError::Arithmetic(_)) = &collection_id_res {107 return Err(<Error<T>>::NoAvailableBaseId.into());108 }109110 let collection_id = collection_id_res?;111112 <PalletCommon<T>>::set_scoped_collection_properties(113 collection_id,114 PropertyScope::Rmrk,115 [116 <PalletCore<T>>::rmrk_property(CollectionType, &misc::CollectionType::Base)?,117 <PalletCore<T>>::rmrk_property(BaseType, &base_type)?,118 ].into_iter()119 )?;120121 let collection = <PalletCore<T>>::get_nft_collection(collection_id)?;122123 for part in parts {124 let part_id = part.id();125 let part_token_id = Self::create_part(126 &cross_sender,127 &collection,128 part129 )?;130131 <InernalPartId<T>>::insert(collection_id, part_id, part_token_id);132133 <PalletNft<T>>::set_scoped_token_property(134 collection_id,135 part_token_id,136 PropertyScope::Rmrk,137 <PalletCore<T>>::rmrk_property(ExternalPartId, &part_id)?138 )?;139 }140141 Self::deposit_event(Event::BaseCreated { issuer: sender, base_id: collection_id.0 });142143 Ok(())144 }145146 #[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]147 #[transactional]148 pub fn theme_add(149 origin: OriginFor<T>,150 base_id: RmrkBaseId,151 theme: RmrkTheme,152 ) -> DispatchResult {153 let sender = ensure_signed(origin)?;154155 let sender = T::CrossAccountId::from_sub(sender);156 let owner = &sender;157158 let collection_id: CollectionId = base_id.into();159160 let collection = <PalletCore<T>>::get_typed_nft_collection(161 collection_id,162 misc::CollectionType::Base163 ).map_err(|_| <Error<T>>::BaseDoesntExist)?;164165 if theme.name.as_slice() == b"default" {166 <BaseHasDefaultTheme<T>>::insert(collection_id, true);167 } else if !Self::base_has_default_theme(collection_id) {168 return Err(<Error<T>>::NeedsDefaultThemeFirst.into());169 }170171 let token_id = <PalletCore<T>>::create_nft(172 &sender,173 owner,174 &collection,175 NftType::Theme,176 [177 <PalletCore<T>>::rmrk_property(ThemeName, &theme.name)?,178 <PalletCore<T>>::rmrk_property(ThemeInherit, &theme.inherit)?179 ].into_iter()180 ).map_err(|_| <Error<T>>::PermissionError)?;181182 for property in theme.properties {183 <PalletNft<T>>::set_scoped_token_property(184 collection_id,185 token_id,186 PropertyScope::Rmrk,187 <PalletCore<T>>::rmrk_property(188 ThemeProperty(&property.key),189 &property.value190 )?191 )?;192 }193194 Ok(())195 }196 }197}198199impl<T: Config> Pallet<T> {200 fn create_part(201 sender: &T::CrossAccountId,202 collection: &NonfungibleHandle<T>,203 part: RmrkPartType204 ) -> Result<TokenId, DispatchError> {205 let owner = sender;206207 let src = part.src();208 let z_index = part.z_index();209210 let nft_type = match part {211 RmrkPartType::FixedPart(_) => NftType::FixedPart,212 RmrkPartType::SlotPart(_) => NftType::SlotPart,213 };214215 let token_id = <PalletCore<T>>::create_nft(216 sender,217 owner,218 collection,219 nft_type,220 [221 <PalletCore<T>>::rmrk_property(Src, &src)?,222 <PalletCore<T>>::rmrk_property(ZIndex, &z_index)?223 ].into_iter()224 ).map_err(|err| match err {225 DispatchError::Arithmetic(_) => <Error<T>>::NoAvailablePartId.into(),226 err => err227 })?;228229 if let RmrkPartType::SlotPart(part) = part {230 <PalletNft<T>>::set_scoped_token_property(231 collection.id,232 token_id,233 PropertyScope::Rmrk,234 <PalletCore<T>>::rmrk_property(EquippableList, &part.equippable)?235 )?;236 }237238 Ok(token_id)239 }240}1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617#![cfg_attr(not(feature = "std"), no_std)]1819use frame_support::{pallet_prelude::*, transactional, BoundedVec, dispatch::DispatchResult};20use frame_system::{pallet_prelude::*, ensure_signed};21use sp_runtime::DispatchError;22use up_data_structs::*;23use pallet_common::{Pallet as PalletCommon, Error as CommonError};24use pallet_rmrk_core::{Pallet as PalletCore, misc::{self, *}, property::RmrkProperty::*};25use pallet_nonfungible::{Pallet as PalletNft, NonfungibleHandle};26use pallet_evm::account::CrossAccountId;2728pub use pallet::*;2930#[frame_support::pallet]31pub mod pallet {32 use super::*;3334 #[pallet::config]35 pub trait Config: frame_system::Config36 + pallet_rmrk_core::Config {37 type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;38 }3940 #[pallet::storage]41 #[pallet::getter(fn internal_part_id)]42 pub type InernalPartId<T: Config> = StorageDoubleMap<43 _,44 Twox64Concat,45 CollectionId,46 Twox64Concat,47 RmrkPartId,48 TokenId49 >;5051 #[pallet::storage]52 #[pallet::getter(fn base_has_default_theme)]53 pub type BaseHasDefaultTheme<T: Config> = StorageMap<54 _,55 Twox64Concat,56 CollectionId,57 bool,58 ValueQuery59 >;6061 #[pallet::pallet]62 #[pallet::generate_store(pub(super) trait Store)]63 pub struct Pallet<T>(_);6465 #[pallet::event]66 #[pallet::generate_deposit(pub(super) fn deposit_event)]67 pub enum Event<T: Config> {68 BaseCreated {69 issuer: T::AccountId,70 base_id: RmrkBaseId,71 },72 }7374 #[pallet::error]75 pub enum Error<T> {76 PermissionError,77 NoAvailableBaseId,78 NoAvailablePartId,79 BaseDoesntExist,80 NeedsDefaultThemeFirst,81 }8283 #[pallet::call]84 impl<T: Config> Pallet<T> {85 #[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]86 #[transactional]87 pub fn create_base(88 origin: OriginFor<T>,89 base_type: RmrkString,90 symbol: RmrkString,91 parts: BoundedVec<RmrkPartType, RmrkPartsLimit>,92 ) -> DispatchResult {93 let sender = ensure_signed(origin)?;94 let cross_sender = T::CrossAccountId::from_sub(sender.clone());9596 let data = CreateCollectionData {97 limits: None,98 token_prefix: symbol.into_inner()99 .try_into()100 .map_err(|_| <CommonError<T>>::CollectionTokenPrefixLimitExceeded)?,101 ..Default::default()102 };103104 let collection_id_res = <PalletNft<T>>::init_collection(sender.clone(), data);105106 if let Err(DispatchError::Arithmetic(_)) = &collection_id_res {107 return Err(<Error<T>>::NoAvailableBaseId.into());108 }109110 let collection_id = collection_id_res?;111112 <PalletCommon<T>>::set_scoped_collection_properties(113 collection_id,114 PropertyScope::Rmrk,115 [116 <PalletCore<T>>::rmrk_property(CollectionType, &misc::CollectionType::Base)?,117 <PalletCore<T>>::rmrk_property(BaseType, &base_type)?,118 ].into_iter()119 )?;120121 let collection = <PalletCore<T>>::get_nft_collection(collection_id)?;122123 for part in parts {124 let part_id = part.id();125 let part_token_id = Self::create_part(126 &cross_sender,127 &collection,128 part129 )?;130131 <InernalPartId<T>>::insert(collection_id, part_id, part_token_id);132133 <PalletNft<T>>::set_scoped_token_property(134 collection_id,135 part_token_id,136 PropertyScope::Rmrk,137 <PalletCore<T>>::rmrk_property(ExternalPartId, &part_id)?138 )?;139 }140141 Self::deposit_event(Event::BaseCreated { issuer: sender, base_id: collection_id.0 });142143 Ok(())144 }145146 #[pallet::weight(10_000 + T::DbWeight::get().reads_writes(1,1))]147 #[transactional]148 pub fn theme_add(149 origin: OriginFor<T>,150 base_id: RmrkBaseId,151 theme: RmrkTheme,152 ) -> DispatchResult {153 let sender = ensure_signed(origin)?;154155 let sender = T::CrossAccountId::from_sub(sender);156 let owner = &sender;157158 let collection_id: CollectionId = base_id.into();159160 let collection = <PalletCore<T>>::get_typed_nft_collection(161 collection_id,162 misc::CollectionType::Base163 ).map_err(|_| <Error<T>>::BaseDoesntExist)?;164165 if theme.name.as_slice() == b"default" {166 <BaseHasDefaultTheme<T>>::insert(collection_id, true);167 } else if !Self::base_has_default_theme(collection_id) {168 return Err(<Error<T>>::NeedsDefaultThemeFirst.into());169 }170171 let token_id = <PalletCore<T>>::create_nft(172 &sender,173 owner,174 &collection,175 NftType::Theme,176 [177 <PalletCore<T>>::rmrk_property(ThemeName, &theme.name)?,178 <PalletCore<T>>::rmrk_property(ThemeInherit, &theme.inherit)?179 ].into_iter()180 ).map_err(|_| <Error<T>>::PermissionError)?;181182 for property in theme.properties {183 <PalletNft<T>>::set_scoped_token_property(184 collection_id,185 token_id,186 PropertyScope::Rmrk,187 <PalletCore<T>>::rmrk_property(188 UserProperty(property.key.as_slice()),189 &property.value190 )?191 )?;192 }193194 Ok(())195 }196 }197}198199impl<T: Config> Pallet<T> {200 fn create_part(201 sender: &T::CrossAccountId,202 collection: &NonfungibleHandle<T>,203 part: RmrkPartType204 ) -> Result<TokenId, DispatchError> {205 let owner = sender;206207 let src = part.src();208 let z_index = part.z_index();209210 let nft_type = match part {211 RmrkPartType::FixedPart(_) => NftType::FixedPart,212 RmrkPartType::SlotPart(_) => NftType::SlotPart,213 };214215 let token_id = <PalletCore<T>>::create_nft(216 sender,217 owner,218 collection,219 nft_type,220 [221 <PalletCore<T>>::rmrk_property(Src, &src)?,222 <PalletCore<T>>::rmrk_property(ZIndex, &z_index)?223 ].into_iter()224 ).map_err(|err| match err {225 DispatchError::Arithmetic(_) => <Error<T>>::NoAvailablePartId.into(),226 err => err227 })?;228229 if let RmrkPartType::SlotPart(part) = part {230 <PalletNft<T>>::set_scoped_token_property(231 collection.id,232 token_id,233 PropertyScope::Rmrk,234 <PalletCore<T>>::rmrk_property(EquippableList, &part.equippable)?235 )?;236 }237238 Ok(token_id)239 }240}primitives/data-structs/src/lib.rsdiffbeforeafterboth--- a/primitives/data-structs/src/lib.rs
+++ b/primitives/data-structs/src/lib.rs
@@ -934,8 +934,9 @@
RmrkString,
BoundedVec<RmrkPartId, RmrkPartsLimit>,
>;
-pub type RmrkPropertyInfo =
- PropertyInfo<BoundedVec<u8, RmrkKeyLimit>, BoundedVec<u8, RmrkValueLimit>>;
+pub type RmrkKeyString = BoundedVec<u8, RmrkKeyLimit>;
+pub type RmrkValueString = BoundedVec<u8, RmrkValueLimit>;
+pub type RmrkPropertyInfo = PropertyInfo<RmrkKeyString, RmrkValueString>;
pub type RmrkBaseInfo<AccountId> = BaseInfo<AccountId, RmrkString>;
pub type RmrkPartType =
PartType<RmrkString, BoundedVec<RmrkCollectionId, RmrkMaxCollectionsEquippablePerPart>>;
runtime/common/src/runtime_apis.rsdiffbeforeafterboth--- a/runtime/common/src/runtime_apis.rs
+++ b/runtime/common/src/runtime_apis.rs
@@ -232,78 +232,47 @@
}
fn collection_properties(collection_id: RmrkCollectionId, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
- use pallet_proxy_rmrk_core::misc::RmrkDecode;
+ use pallet_proxy_rmrk_core::misc::CollectionType;
let collection_id = CollectionId(collection_id);
- if !RmrkCore::collection_exists(collection_id) { return Ok(Vec::new()); }
-
- let properties = Common::collection_properties(collection_id);
-
- // todo repeated code
- return Ok(match filter_keys {
- Some(keys) => {
- let keys = Common::bytes_keys_to_property_keys(keys)?;
- let properties = keys
- .into_iter()
- .filter_map(|key| {
- properties.get(&key).map(|value| RmrkPropertyInfo {
- key: key.decode_or_default(),
- value: value.decode_or_default(),
- })
- })
- .collect();
+ if RmrkCore::ensure_collection_type(collection_id, CollectionType::Regular).is_err() {
+ return Ok(Vec::new());
+ }
- properties
- }
- None => {
- properties
- .into_iter()
- .filter_map(|(key, value)| Some(RmrkPropertyInfo {
- key: key.decode_or_default(),
- value: value.decode_or_default(),
- }))
- .collect()
+ let properties = RmrkCore::filter_user_properties(
+ collection_id,
+ /* token_id = */ None,
+ filter_keys,
+ |key, value| RmrkPropertyInfo {
+ key,
+ value
}
- });
+ )?;
+
+ Ok(properties)
}
fn nft_properties(collection_id: RmrkCollectionId, nft_id: RmrkNftId, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Vec<RmrkPropertyInfo>, DispatchError> {
- use frame_support::BoundedVec;
- use pallet_proxy_rmrk_core::misc::RmrkDecode;
+ use pallet_proxy_rmrk_core::misc::NftType;
let collection_id = CollectionId(collection_id);
let token_id = TokenId(nft_id);
- if !RmrkCore::nft_exists(collection_id, token_id) { return Ok(Vec::new()); }
- let properties = Nonfungible::token_properties((collection_id, token_id));
- // todo look into this usage of pallet_nonfungible
+ if RmrkCore::ensure_nft_type(collection_id, token_id, NftType::Regular).is_err() {
+ return Ok(Vec::new());
+ }
- // todo displace to a function? redundant code piece with collection props
- return Ok(match filter_keys {
- Some(keys) => {
- let keys = Common::bytes_keys_to_property_keys(keys)?;
- let properties = keys
- .into_iter()
- .filter_map(|key| {
- properties.get(&key).map(|value| RmrkPropertyInfo {
- key: key.decode_or_default(),
- value: value.decode_or_default(),
- })
- })
- .collect();
+ let properties = RmrkCore::filter_user_properties(
+ collection_id,
+ Some(token_id),
+ filter_keys,
+ |key, value| RmrkPropertyInfo {
+ key,
+ value
+ }
+ )?;
- properties
- }
- None => {
- properties
- .into_iter()
- .filter_map(|(key, value)| Some(RmrkPropertyInfo {
- key: key.decode_or_default(),
- value: value.decode_or_default(),
- }))
- .collect()
- }
- });
+ Ok(properties)
}
fn nft_resources(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkResourceInfo>, DispatchError> {
@@ -436,7 +405,15 @@
None => return Ok(None)
};
- let properties = RmrkCore::filter_theme_properties(collection_id, theme_id, filter_keys)?;
+ let properties = RmrkCore::filter_user_properties(
+ collection_id,
+ Some(theme_id),
+ filter_keys,
+ |key, value| RmrkThemeProperty {
+ key,
+ value
+ }
+ )?;
let inherit = RmrkCore::get_nft_property(
collection_id,