difftreelog
feat(rmrk-rpc) decoding properties
in: master
3 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
@@ -420,7 +420,7 @@
Ok(())
}
- fn get_typed_nft_collection(
+ pub fn get_typed_nft_collection(
collection_id: CollectionId,
collection_type: CollectionType
) -> Result<NonfungibleHandle<T>, DispatchError> {
pallets/proxy-rmrk-core/src/misc.rsdiffbeforeafterboth--- a/pallets/proxy-rmrk-core/src/misc.rs
+++ b/pallets/proxy-rmrk-core/src/misc.rs
@@ -82,6 +82,18 @@
}
}
+pub trait RmrkDecode<T: Decode> {
+ fn decode_property(&self) -> Option<T>;
+}
+
+impl<T: Decode> RmrkDecode<T> for RmrkString {
+ fn decode_property(&self) -> Option<T> { // todo access runtime errors? // but then rmrk_nft_type must have it too
+ let mut value = self.as_slice();
+
+ T::decode(&mut value).ok()
+ }
+}
+
#[derive(Encode, Decode, PartialEq, Eq)]
pub enum CollectionType {
Regular,
runtime/common/src/runtime_apis.rsdiffbeforeafterboth148 // TODO decide on displacement to palettes -- does RMRK belong there, spread across common and nonfungible?148 // TODO decide on displacement to palettes -- does RMRK belong there, spread across common and nonfungible?149 use frame_support::BoundedVec;149 use frame_support::BoundedVec;150 use scale_info::prelude::string::String;150 use scale_info::prelude::string::String;151 use pallet_proxy_rmrk_core::RmrkProperty;151 use pallet_proxy_rmrk_core::{RmrkProperty, misc::CollectionType};152152153 // todo check if this is a rmrk collection? or simply trust and provide anyway?153 // todo check if this is a rmrk standard collection? or simply trust and provide anyway?154 // client-is-always-right / enforce authority and order ?154 // client-is-always-right / enforce authority and order ?155155156 let collection_id = CollectionId(collection_id);156 let collection_id = CollectionId(collection_id);157 let collection = <pallet_proxy_rmrk_core::Pallet<Runtime>>::get_nft_collection(collection_id)?;157 let collection = <pallet_proxy_rmrk_core::Pallet<Runtime>>::get_typed_nft_collection(collection_id, CollectionType::Regular)?;158 // todo Vec::from(["rmrk:metadata", "rmrk:collection-type"])158 159 let metadata = BoundedVec::try_from(159 let metadata = BoundedVec::try_from(160 <pallet_proxy_rmrk_core::Pallet<Runtime>>::get_collection_property(collection_id, RmrkProperty::Metadata)?.into_inner()160 <pallet_proxy_rmrk_core::Pallet<Runtime>>::get_collection_property(collection_id, RmrkProperty::Metadata)?.into_inner()161 ).map_err(|_| <pallet_common::Error<Runtime>>::PropertyKeyIsTooLong)?;//unwrap_or_default();161 ).map_err(|_| <pallet_common::Error<Runtime>>::PropertyKeyIsTooLong)?;162162 let nfts_count = (dispatch_unique_runtime!(collection_id.total_supply()) as Result<u32, DispatchError>)?; // todo? <Runtime>::total_supply(collection_id)163 let nfts_count = (dispatch_unique_runtime!(collection_id.total_supply()) as Result<u32, DispatchError>)?; // todo? <Runtime>::total_supply(collection_id)163164174 fn nft_by_id(collection_id: RmrkCollectionId, nft_by_id: RmrkNftId) -> Result<Option<RmrkInstanceInfo<AccountId>>, DispatchError> {175 fn nft_by_id(collection_id: RmrkCollectionId, nft_by_id: RmrkNftId) -> Result<Option<RmrkInstanceInfo<AccountId>>, DispatchError> {175 use frame_support::BoundedVec;176 use frame_support::BoundedVec;176 use up_data_structs::mapping::TokenAddressMapping;177 use up_data_structs::mapping::TokenAddressMapping;177 use pallet_proxy_rmrk_core::RmrkProperty;178 use pallet_proxy_rmrk_core::{RmrkProperty, misc::RmrkDecode};178179179 let collection_id = CollectionId(collection_id);180 let collection_id = CollectionId(collection_id);180 let nft_id = TokenId(nft_by_id);181 let nft_id = TokenId(nft_by_id);187 None => return Ok(None)188 None => return Ok(None)188 };189 };189190191 // todo displace querying property key array to rmrk proxy pallet190 let keys = [192 let keys = [191 RmrkProperty::RoyaltyInfo,193 RmrkProperty::RoyaltyInfo,192 RmrkProperty::Metadata,194 RmrkProperty::Metadata,196198197 let properties = keys.into_iter().map(199 let properties = keys.into_iter().map(198 |key| BoundedVec::try_from(200 |key| BoundedVec::try_from(199 // todo nft property, not collection200 <pallet_proxy_rmrk_core::Pallet<Runtime>>::get_nft_property(collection_id, nft_id, key).unwrap().into_inner()201 <pallet_proxy_rmrk_core::Pallet<Runtime>>::get_nft_property(collection_id, nft_id, key).unwrap().into_inner()201 ).unwrap()202 ).unwrap()202 )203 )203 .collect::<Vec<RmrkString>>();204 .collect::<Vec<RmrkString>>();205 206 let allowance = pallet_nonfungible::Allowance::<Runtime>::get((collection_id, nft_id));204207205 Ok(Some(RmrkInstanceInfo {208 Ok(Some(RmrkInstanceInfo {206 owner: owner,209 owner: owner,207 //recipient: , // prop?210 //recipient: , // prop?208 royalty: None,//Permill::from_percent(0), // prop, decode211 royalty: properties[0].clone().decode_property().unwrap(),209 metadata: properties[1].clone(),212 metadata: properties[1].clone(),210 equipped: false, // prop, decode213 equipped: properties[2].clone().decode_property().unwrap(),211 pending: false, // prop, decode214 pending: allowance.is_some(),212 }))215 }))213 }216 }214 fn account_tokens(account_id: AccountId, collection_id: RmrkCollectionId) -> Result<Vec<RmrkNftId>, DispatchError> {217 fn account_tokens(account_id: AccountId, collection_id: RmrkCollectionId) -> Result<Vec<RmrkNftId>, DispatchError> {234 Ok(237 Ok(235 pallet_nonfungible::Owned::<Runtime>::iter_prefix((collection_id, cross_account_id))238 pallet_nonfungible::Owned::<Runtime>::iter_prefix((collection_id, cross_account_id))236 .map(|(child_id, _)| RmrkNftChild {239 .map(|(child_id, _)| RmrkNftChild {237 collection_id: collection_id.0, // todo make sure they're always from this collection240 collection_id: collection_id.0, // todo make sure they're always from this collection // spoiler: they're not238 nft_id: child_id.0,241 nft_id: child_id.0,239 })242 })240 .collect()243 .collect()315 let nft_id = TokenId(nft_id);318 let nft_id = TokenId(nft_id);316319317 // let keys = [320 // let keys = [318 // RmrkProperty::Royalty,321 // RmrkProperty::RoyaltyInfo,319 // RmrkProperty::Metadata,322 // RmrkProperty::Metadata,320 // RmrkProperty::Equipped,323 // RmrkProperty::Equipped,321 // RmrkProperty::Pending,324 // RmrkProperty::Pending,339 fn base(base_id: RmrkBaseId) -> Result<Option<RmrkBaseInfo<AccountId>>, DispatchError> {342 fn base(base_id: RmrkBaseId) -> Result<Option<RmrkBaseInfo<AccountId>>, DispatchError> {340 use frame_support::BoundedVec;343 use frame_support::BoundedVec;341 use scale_info::prelude::string::String;344 use scale_info::prelude::string::String;342 use pallet_proxy_rmrk_core::RmrkProperty;345 use pallet_proxy_rmrk_core::{RmrkProperty, misc::CollectionType};343346344 let collection_id = CollectionId(base_id);347 let collection_id = CollectionId(base_id);345 let collection = <pallet_proxy_rmrk_core::Pallet<Runtime>>::get_nft_collection(collection_id)?;348 let collection = <pallet_proxy_rmrk_core::Pallet<Runtime>>::get_typed_nft_collection(collection_id, CollectionType::Base)?;349 // todo check prop for being a base346350347 // todo export to macro? redundancy351 // todo export to macro? redundancy348 let keys = [352 let keys = [368 }372 }369 fn base_parts(base_id: RmrkBaseId) -> Result<Vec<RmrkPartType>, DispatchError> {373 fn base_parts(base_id: RmrkBaseId) -> Result<Vec<RmrkPartType>, DispatchError> {370 use frame_support::BoundedVec;374 use frame_support::BoundedVec;371 use pallet_proxy_rmrk_core::RmrkProperty;375 use pallet_proxy_rmrk_core::{RmrkProperty, misc::{RmrkNft, RmrkDecode}};372376373 let collection_id = CollectionId(base_id);377 let collection_id = CollectionId(base_id);374378 // todo check prop for being a base375 let keys = [376 //RmrkProperty::NftType)?,377 //RmrkProperty::PartId)?,378 RmrkProperty::Src,379 RmrkProperty::ZIndex,380 RmrkProperty::EquippableList,381 ];382379383 let parts = (dispatch_unique_runtime!(collection_id.collection_tokens()) as Result<Vec<TokenId>, DispatchError>)?380 let parts = (dispatch_unique_runtime!(collection_id.collection_tokens()) as Result<Vec<TokenId>, DispatchError>)?384 .iter()381 .iter()385 .filter_map(|token_id| {382 .filter_map(|token_id| {386 /*let properties = keys.into_iter().map(387 |key| BoundedVec::try_from(388 <pallet_proxy_rmrk_core::Pallet<Runtime>>::get_nft_property(collection_id, *token_id, key).unwrap().into_inner()389 ).unwrap()390 ).collect::<Vec<RmrkString>>();*/391392 // todo ping properties for "rmrk:nft-type"393 // if none, skip, None394 let nft_type = "fixed-part";383 let nft_type = <pallet_nonfungible::TokenData<Runtime>>::get((collection_id, token_id))384 //.map_err(|_| ) // no need, tis a filter_map385 .unwrap()386 .rmrk_nft_type()?;387 388 // dislocate to rmrkproxycore and simply send an array of keys389 let keys = [390 //RmrkProperty::PartId)?,391 RmrkProperty::Src,392 RmrkProperty::ZIndex,393 RmrkProperty::EquippableList,394 ];395 396 let properties = keys.into_iter().map(397 |key| BoundedVec::try_from(398 <pallet_proxy_rmrk_core::Pallet<Runtime>>::get_nft_property(collection_id, *token_id, key).unwrap().into_inner()399 ).unwrap()400 ).collect::<Vec<RmrkString>>();395401396 match nft_type {402 match nft_type {397 "fixed-part" => Some(RmrkPartType::FixedPart(RmrkFixedPart {403 FixedPart => Some(RmrkPartType::FixedPart(RmrkFixedPart {398 id: token_id.0,404 id: token_id.0,399 src: BoundedVec::default(), // "rmrk:src"405 src: properties[0].clone().decode_property().unwrap(),400 z: 0, // "rmrk:z-index"406 z: properties[1].clone().decode_property().unwrap(),401 })),407 })),402 "slot-part" => Some(RmrkPartType::SlotPart(RmrkSlotPart {408 SlotPart => Some(RmrkPartType::SlotPart(RmrkSlotPart {403 id: token_id.0,409 id: token_id.0,404 equippable: RmrkEquippableList::Empty, // "rmrk:equippable-list" ?405 src: BoundedVec::default(), // "rmrk:src"410 src: properties[0].clone().decode_property().unwrap(),406 z: 0, // "rmrk:z-index"411 z: properties[1].clone().decode_property().unwrap(),412 equippable: properties[2].clone().decode_property().unwrap(),407 })),413 })),408 _ => None414 _ => None409 }415 }415 }420 }416 fn theme_names(base_id: RmrkBaseId) -> Result<Vec<RmrkThemeName>, DispatchError> {421 fn theme_names(base_id: RmrkBaseId) -> Result<Vec<RmrkThemeName>, DispatchError> {417 use frame_support::BoundedVec;422 use frame_support::BoundedVec;423 use pallet_proxy_rmrk_core::{RmrkProperty, misc::{RmrkNft, RmrkDecode}};418424419 let collection_id = CollectionId(base_id);425 let collection_id = CollectionId(base_id);426 // todo make sure this is theme420427421 let theme_names = (dispatch_unique_runtime!(collection_id.collection_tokens()) as Result<Vec<TokenId>, DispatchError>)?428 let theme_names = (dispatch_unique_runtime!(collection_id.collection_tokens()) as Result<Vec<TokenId>, DispatchError>)?422 .iter()429 .iter()423 .filter_map(|token_id| {430 .filter_map(|token_id| {424 let properties = pallet_nonfungible::Pallet::<Runtime>::token_properties((collection_id, token_id));431 let nft_type = <pallet_nonfungible::TokenData<Runtime>>::get((collection_id, token_id))425432 .unwrap()426 // todo ping property for "rmrk:nft-type"433 .rmrk_nft_type()?;427 // if none or not "theme", skip, None434 428 let nft_type = "theme";435 match nft_type {429 // can't call dispatch_unique_runtime! from here??436 Theme => Some(430 <pallet_nonfungible::TokenData<Runtime>>::get((collection_id, token_id))437 <pallet_proxy_rmrk_core::Pallet<Runtime>>::get_nft_property(438 collection_id, *token_id, RmrkProperty::ThemeName431 .map(|t| t.const_data.into_inner())439 ).unwrap()432 //.unwrap_or_default()440 .into_inner()433 // todo rework to reduce independence441 ),442 _ => None443 }434 })444 })435 .collect();445 .collect::<Vec<RmrkThemeName>>();436446437 Ok(theme_names)447 Ok(theme_names)438 }448 }