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

difftreelog

feat implement theme RMRK RPC

Daniel Shiposha2022-05-25parent: #3cd2ab6.patch.diff
in: master

7 files changed

modifiedpallets/proxy-rmrk-core/src/lib.rsdiffbeforeafterboth
443 <TokenData<T>>::get((collection_id, token_id))443 <TokenData<T>>::get((collection_id, token_id))
444 .unwrap()444 .unwrap()
445 .rmrk_nft_type()445 .rmrk_nft_type()
446 .ok_or(<Error<T>>::NoAvailableNftId.into())446 .ok_or_else(|| <Error<T>>::NoAvailableNftId.into())
447 }447 }
448448
449 pub fn ensure_nft_type(collection_id: CollectionId, token_id: TokenId, nft_type: NftType) -> DispatchResult {449 pub fn ensure_nft_type(collection_id: CollectionId, token_id: TokenId, nft_type: NftType) -> DispatchResult {
453 Ok(())453 Ok(())
454 }454 }
455
456 pub fn filter_theme_properties(
457 collection_id: CollectionId,
458 token_id: TokenId,
459 filter_keys: Option<Vec<RmrkPropertyKey>>
460 ) -> Result<Vec<RmrkThemeProperty>, DispatchError> {
461 filter_keys.map(|keys| {
462 let properties = keys.into_iter()
463 .filter_map(|key| {
464 let key: RmrkString = key.try_into().ok()?;
465
466 let value = Self::get_nft_property(
467 collection_id,
468 token_id,
469 RmrkProperty::ThemeProperty(&key)
470 ).ok()?.decode_or_default();
471
472 let property = RmrkThemeProperty {
473 key,
474 value
475 };
476
477 Some(property)
478 })
479 .collect();
480
481 Ok(properties)
482 }).unwrap_or_else(|| {
483 let properties = Self::iterate_theme_properties(collection_id, token_id)?
484 .collect();
485
486 Ok(properties)
487 })
488 }
489
490 pub fn iterate_theme_properties(
491 collection_id: CollectionId,
492 token_id: TokenId
493 ) -> Result<impl Iterator<Item=RmrkThemeProperty>, DispatchError> {
494 let key_prefix = rmrk_property!(Config=T, key: ThemeProperty(&RmrkString::default()))?;
495
496 let properties = <PalletNft<T>>::token_properties((collection_id, token_id))
497 .into_iter()
498 .filter_map(move |(key, value)| {
499 let key = key.as_slice().strip_prefix(key_prefix.as_slice())?;
500
501 let key: RmrkString = key.to_vec().try_into().ok()?;
502 let value: RmrkString = value.decode_or_default();
503
504 let property = RmrkThemeProperty {
505 key,
506 value
507 };
508
509 Some(property)
510 });
511
512 Ok(properties)
513 }
455514
456 pub fn get_typed_nft_collection(515 pub fn get_typed_nft_collection(
457 collection_id: CollectionId,516 collection_id: CollectionId,
modifiedpallets/proxy-rmrk-core/src/property.rsdiffbeforeafterboth
1use super::*;1use super::*;
2use core::convert::AsRef;2use core::convert::AsRef;
33
4pub enum RmrkProperty {4pub enum RmrkProperty<'r> {
5 Metadata,5 Metadata,
6 CollectionType,6 CollectionType,
7 RoyaltyInfo,7 RoyaltyInfo,
23 EquippableList,23 EquippableList,
24 ZIndex,24 ZIndex,
25 ThemeName,25 ThemeName,
26 ThemeProperty(RmrkString),26 ThemeProperty(&'r RmrkString),
27 ThemeInherit,27 ThemeInherit,
28}28}
2929
30impl RmrkProperty {30impl<'r> RmrkProperty<'r> {
31 pub fn to_key<T: Config>(self) -> Result<PropertyKey, Error<T>> {31 pub fn to_key<T: Config>(self) -> Result<PropertyKey, Error<T>> {
32 fn get_bytes<T: AsRef<[u8]>>(container: &T) -> &[u8] {32 fn get_bytes<T: AsRef<[u8]>>(container: &T) -> &[u8] {
33 container.as_ref()33 container.as_ref()
modifiedprimitives/data-structs/src/lib.rsdiffbeforeafterboth
775 self.0.iter()775 self.0.iter()
776 }776 }
777
778 pub fn into_iter(self) -> impl Iterator<Item = (PropertyKey, Value)> {
779 self.0.into_iter()
780 }
777781
778 fn check_property_key(key: &PropertyKey) -> Result<(), PropertiesError> {782 fn check_property_key(key: &PropertyKey) -> Result<(), PropertiesError> {
779 if key.is_empty() {783 if key.is_empty() {
849 self.map.iter()853 self.map.iter()
850 }854 }
855
856 pub fn into_iter(self) -> impl Iterator<Item = (PropertyKey, PropertyValue)> {
857 self.map.into_iter()
858 }
851}859}
852860
853impl TrySetProperty for Properties {861impl TrySetProperty for Properties {
936pub type RmrkBaseInfo<AccountId> = BaseInfo<AccountId, RmrkString>;944pub type RmrkBaseInfo<AccountId> = BaseInfo<AccountId, RmrkString>;
937pub type RmrkPartType =945pub type RmrkPartType =
938 PartType<RmrkString, BoundedVec<RmrkCollectionId, RmrkMaxCollectionsEquippablePerPart>>;946 PartType<RmrkString, BoundedVec<RmrkCollectionId, RmrkMaxCollectionsEquippablePerPart>>;
947pub type RmrkThemeProperty = ThemeProperty<RmrkString>;
939pub type RmrkTheme = Theme<RmrkString, Vec<ThemeProperty<RmrkString>>>;948pub type RmrkTheme = Theme<RmrkString, Vec<RmrkThemeProperty>>;
940949
941pub type RmrkRpcString = Vec<u8>;950pub type RmrkRpcString = Vec<u8>;
942pub type RmrkThemeName = RmrkRpcString;951pub type RmrkThemeName = RmrkRpcString;
modifiedruntime/common/src/runtime_apis.rsdiffbeforeafterboth
379379
380 fn theme_names(base_id: RmrkBaseId) -> Result<Vec<RmrkThemeName>, DispatchError> {380 fn theme_names(base_id: RmrkBaseId) -> Result<Vec<RmrkThemeName>, DispatchError> {
381 use frame_support::BoundedVec;381 use frame_support::BoundedVec;
382 use pallet_proxy_rmrk_core::{RmrkProperty, misc::{RmrkNft, RmrkDecode}};382 use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, RmrkNft, RmrkDecode}};
383383
384 let collection_id = CollectionId(base_id);384 let collection_id = CollectionId(base_id);
385 // todo make sure this is theme385 if RmrkCore::ensure_collection_type(collection_id, CollectionType::Base).is_err() {
386 return Ok(Vec::new());
387 }
386388
387 let theme_names = (dispatch_unique_runtime!(collection_id.collection_tokens()) as Result<Vec<TokenId>, DispatchError>)?389 let theme_names = (dispatch_unique_runtime!(collection_id.collection_tokens()))?
388 .iter()390 .iter()
389 .filter_map(|token_id| {391 .filter_map(|token_id| {
390 let nft_type = RmrkCore::get_nft_type(collection_id, *token_id).unwrap();392 let nft_type = RmrkCore::get_nft_type(collection_id, *token_id).unwrap();
396 _ => None398 _ => None
397 }399 }
398 })400 })
399 .collect::<Vec<RmrkThemeName>>();401 .collect();
400402
401 Ok(theme_names)403 Ok(theme_names)
402 }404 }
403405
404 fn theme(base_id: RmrkBaseId, theme_name: RmrkThemeName, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Option<RmrkTheme>, DispatchError> {406 fn theme(base_id: RmrkBaseId, theme_name: RmrkThemeName, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Option<RmrkTheme>, DispatchError> {
405 use frame_support::BoundedVec;407 use frame_support::BoundedVec;
408 use pallet_proxy_rmrk_core::{
409 RmrkProperty,
410 misc::{CollectionType, NftType, RmrkNft, RmrkDecode}
411 };
406412
407 let collection_id = CollectionId(base_id);413 let collection_id = CollectionId(base_id);
408414 if RmrkCore::ensure_collection_type(collection_id, CollectionType::Base).is_err() {
409 // todo one theme. filter collection tokens according to theme name, should result in one415 return Ok(None);
410 // (is it possible to search with iter_prefix for part of a struct that satisfies?..)416 }
411 // filter properties according to filter_keys and load them into resulting theme.properties417
412 let themes = (dispatch_unique_runtime!(collection_id.collection_tokens()) as Result<Vec<TokenId>, DispatchError>)?418 let theme_info = (dispatch_unique_runtime!(collection_id.collection_tokens()))?
413 .iter()419 .into_iter()
414 .filter_map(|token_id| {420 .find_map(|token_id| {
415 let properties = Nonfungible::token_properties((collection_id, token_id));421 RmrkCore::ensure_nft_type(collection_id, token_id, NftType::Theme).ok()?;
416422
417 // todo ping properties for "rmrk:nft-type"
418 // if none, skip, None
419 // ugh gonna go through ALL properties, searching for matches for "rmrk:theme-property-<key>"
420 let nft_type = "theme";423 let name: RmrkString = RmrkCore::get_nft_property(
421 match nft_type {
422 "theme" => Some(RmrkTheme {
423 name: BoundedVec::try_from(
424 <pallet_nonfungible::TokenData<Runtime>>::get((collection_id, token_id))424 collection_id, token_id, RmrkProperty::ThemeName
425 .map(|t| t.const_data)425 ).ok()?.decode_or_default();
426 .unwrap_or_default()426
427 .into_inner()427 if name == theme_name {
428 ).unwrap(),
429 // todo? (dispatch_unique_runtime!(collection_id.const_metadata(token_id)) as Result<Vec<u8>, DispatchError>)?,
430 properties: Vec::new(), // pain in the ass428 Some((name, token_id))
431 inherit: false, // "rmrk:theme-inherit"429 } else {
432 }),
433 _ => None430 None
434 }431 }
435 })432 });
433
434 let (name, theme_id) = match theme_info {
435 Some((name, theme_id)) => (name, theme_id),
436 None => return Ok(None)
437 };
438
436 .collect::<Vec<_>>();439 let properties = RmrkCore::filter_theme_properties(collection_id, theme_id, filter_keys)?;
437440
438 // todo441 let inherit = RmrkCore::get_nft_property(
442 collection_id,
443 theme_id,
444 RmrkProperty::ThemeInherit
445 )?.decode_or_default();
446
447 let theme = RmrkTheme {
448 name,
449 properties,
450 inherit,
451 };
452
439 Ok(Some(themes[0].clone()))453 Ok(Some(theme))
440 }454 }
441 }455 }
442456
modifiedruntime/opal/src/lib.rsdiffbeforeafterboth
1149 let collection = <Runtime as pallet_common::Config>::CollectionDispatch::dispatch(<pallet_common::CollectionHandle<Runtime>>::try_get($collection)?);1149 let collection = <Runtime as pallet_common::Config>::CollectionDispatch::dispatch(<pallet_common::CollectionHandle<Runtime>>::try_get($collection)?);
1150 let dispatch = collection.as_dyn();1150 let dispatch = collection.as_dyn();
11511151
1152 Ok(dispatch.$method($($name),*))1152 Ok::<_, DispatchError>(dispatch.$method($($name),*))
1153 }};1153 }};
1154}1154}
11551155
modifiedruntime/quartz/src/lib.rsdiffbeforeafterboth
1122 let collection = <Runtime as pallet_common::Config>::CollectionDispatch::dispatch(<pallet_common::CollectionHandle<Runtime>>::try_get($collection)?);1122 let collection = <Runtime as pallet_common::Config>::CollectionDispatch::dispatch(<pallet_common::CollectionHandle<Runtime>>::try_get($collection)?);
1123 let dispatch = collection.as_dyn();1123 let dispatch = collection.as_dyn();
11241124
1125 Ok(dispatch.$method($($name),*))1125 Ok::<_, DispatchError>(dispatch.$method($($name),*))
1126 }};1126 }};
1127}1127}
11281128
modifiedruntime/unique/src/lib.rsdiffbeforeafterboth
1127 let collection = <Runtime as pallet_common::Config>::CollectionDispatch::dispatch(<pallet_common::CollectionHandle<Runtime>>::try_get($collection)?);1127 let collection = <Runtime as pallet_common::Config>::CollectionDispatch::dispatch(<pallet_common::CollectionHandle<Runtime>>::try_get($collection)?);
1128 let dispatch = collection.as_dyn();1128 let dispatch = collection.as_dyn();
11291129
1130 Ok(dispatch.$method($($name),*))1130 Ok::<_, DispatchError>(dispatch.$method($($name),*))
1131 }};1131 }};
1132}1132}
11331133