difftreelog
feat(rmrk-rpc) nft resources and priorities
in: master
6 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
@@ -486,9 +486,8 @@
}
}
- // should this even be here, might displace it to common/nonfungible -- but they did not need it, only rmrk does
pub fn collection_exists(collection_id: CollectionId) -> bool {
- <pallet_common::CollectionById<T>>::contains_key(collection_id)
+ <CollectionHandle<T>>::try_get(collection_id).is_ok()
}
pub fn nft_exists(collection_id: CollectionId, nft_id: TokenId) -> bool {
pallets/proxy-rmrk-core/src/misc.rsdiffbeforeafterboth--- a/pallets/proxy-rmrk-core/src/misc.rs
+++ b/pallets/proxy-rmrk-core/src/misc.rs
@@ -26,18 +26,6 @@
}
}
-pub trait RmrkRebind<T, S> {
- fn rebind(&self) -> BoundedVec<u8, S>;
-}
-
-impl<T, S> RmrkRebind<T, S> for BoundedVec<u8, T> where BoundedVec<u8, S>: TryFrom<Vec<u8>> {
- fn rebind(&self) -> BoundedVec<u8, S> {
- BoundedVec::<u8, S>::try_from(
- self.clone().into_inner()
- ).unwrap_or_default()
- }
-}
-
#[derive(Encode, Decode, PartialEq, Eq)]
pub enum CollectionType {
Regular,
primitives/data-structs/src/lib.rsdiffbeforeafterboth--- a/primitives/data-structs/src/lib.rs
+++ b/primitives/data-structs/src/lib.rs
@@ -49,6 +49,7 @@
},
NftChild as RmrkNftChild, AccountIdOrCollectionNftTuple as RmrkAccountIdOrCollectionNftTuple,
FixedPart as RmrkFixedPart, SlotPart as RmrkSlotPart, EquippableList as RmrkEquippableList,
+ BasicResource as RmrkBasicResource, ComposableResource as RmrkComposableResource, SlotResource as RmrkSlotResource,
};
mod bounded;
@@ -925,17 +926,14 @@
}
}
-pub type RmrkCollectionSymbol = BoundedVec<u8, RmrkCollectionSymbolLimit>;
pub type RmrkCollectionInfo<AccountId> =
CollectionInfo<RmrkString, RmrkCollectionSymbol, AccountId>;
pub type RmrkInstanceInfo<AccountId> = NftInfo<AccountId, Permill, RmrkString>;
pub type RmrkResourceInfo = ResourceInfo<
- BoundedVec<u8, RmrkResourceSymbolLimit>,
+ RmrkBoundedResource,
RmrkString,
- BoundedVec<RmrkPartId, RmrkPartsLimit>,
+ RmrkBoundedParts,
>;
-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 =
@@ -943,6 +941,13 @@
pub type RmrkThemeProperty = ThemeProperty<RmrkString>;
pub type RmrkTheme = Theme<RmrkString, Vec<RmrkThemeProperty>>;
+pub type RmrkCollectionSymbol = BoundedVec<u8, RmrkCollectionSymbolLimit>;
+pub type RmrkKeyString = BoundedVec<u8, RmrkKeyLimit>;
+pub type RmrkValueString = BoundedVec<u8, RmrkValueLimit>;
+
+type RmrkBoundedResource = BoundedVec<u8, RmrkResourceSymbolLimit>;
+type RmrkBoundedParts = BoundedVec<RmrkPartId, RmrkPartsLimit>;
+
pub type RmrkRpcString = Vec<u8>;
pub type RmrkThemeName = RmrkRpcString;
pub type RmrkPropertyKey = RmrkRpcString;
primitives/data-structs/src/rmrk.rsdiffbeforeafterboth--- a/primitives/data-structs/src/rmrk.rs
+++ b/primitives/data-structs/src/rmrk.rs
@@ -154,7 +154,7 @@
pub value: BoundedValue,
}
-#[derive(Encode, Decode, Eq, PartialEq, Clone, Debug, TypeInfo, MaxEncodedLen)]
+#[derive(Encode, Decode, Default, Eq, PartialEq, Clone, Debug, TypeInfo, MaxEncodedLen)]
#[cfg_attr(feature = "std", derive(Serialize))]
#[cfg_attr(
feature = "std",
@@ -275,7 +275,7 @@
pub thumb: Option<BoundedString>,
}
-#[derive(Encode, Decode, Eq, PartialEq, Clone, Debug, TypeInfo, MaxEncodedLen)]
+#[derive(Encode, Decode, Derivative, Eq, PartialEq, Clone, Debug, TypeInfo, MaxEncodedLen)]
#[cfg_attr(feature = "std", derive(Serialize))]
#[cfg_attr(
feature = "std",
@@ -286,7 +286,9 @@
"#
)
)]
-pub enum ResourceTypes<BoundedString, BoundedParts> {
+#[derivative(Default(bound=""))]
+pub enum ResourceTypes<BoundedString: Default, BoundedParts> {
+ #[derivative(Default)]
Basic(BasicResource<BoundedString>),
Composable(ComposableResource<BoundedString, BoundedParts>),
Slot(SlotResource<BoundedString>),
@@ -305,7 +307,7 @@
"#
)
)]
-pub struct ResourceInfo<BoundedResource, BoundedString, BoundedParts> {
+pub struct ResourceInfo<BoundedResource, BoundedString: Default, BoundedParts> {
/// id is a 5-character string of reasonable uniqueness.
/// The combination of base ID and resource id should be unique across the entire RMRK
/// ecosystem which
runtime/common/src/runtime_apis.rsdiffbeforeafterboth146 }146 }147147148 fn collection_by_id(collection_id: RmrkCollectionId) -> Result<Option<RmrkCollectionInfo<AccountId>>, DispatchError> {148 fn collection_by_id(collection_id: RmrkCollectionId) -> Result<Option<RmrkCollectionInfo<AccountId>>, DispatchError> {149 use frame_support::BoundedVec;150 use scale_info::prelude::string::String;151 use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, RmrkRebind, RmrkDecode}};149 use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, RmrkDecode}};152150153 let collection_id = CollectionId(collection_id);151 let collection_id = CollectionId(collection_id);154 let collection = match RmrkCore::get_typed_nft_collection(collection_id, CollectionType::Regular) {152 let collection = match RmrkCore::get_typed_nft_collection(collection_id, CollectionType::Regular) {155 Ok(c) => c,153 Ok(c) => c,156 Err(_) => return Ok(None),154 Err(_) => return Ok(None),157 };155 };158156159 let nfts_count = (dispatch_unique_runtime!(collection_id.total_supply()) as Result<u32, DispatchError>)?;157 let nfts_count = dispatch_unique_runtime!(collection_id.total_supply())?;160 //<Runtime as up_rpc::UniqueApi>::total_supply(collection_id); // todo can't find UniqueApi with disabled default features161158162 Ok(Some(RmrkCollectionInfo {159 Ok(Some(RmrkCollectionInfo {163 issuer: collection.owner.clone(),160 issuer: collection.owner.clone(),164 metadata: RmrkCore::get_collection_property(collection_id, RmrkProperty::Metadata)?.decode_or_default(),161 metadata: RmrkCore::get_collection_property(collection_id, RmrkProperty::Metadata)?.decode_or_default(),165 max: collection.limits.token_limit,162 max: collection.limits.token_limit,166 symbol: collection.token_prefix.rebind(), // change163 symbol: collection.token_prefix.decode_or_default(),167 nfts_count164 nfts_count168 }))165 }))169 }166 }170167171 fn nft_by_id(collection_id: RmrkCollectionId, nft_by_id: RmrkNftId) -> Result<Option<RmrkInstanceInfo<AccountId>>, DispatchError> {168 fn nft_by_id(collection_id: RmrkCollectionId, nft_by_id: RmrkNftId) -> Result<Option<RmrkInstanceInfo<AccountId>>, DispatchError> {172 use frame_support::BoundedVec;173 use up_data_structs::mapping::TokenAddressMapping;169 use up_data_structs::mapping::TokenAddressMapping;174 use pallet_proxy_rmrk_core::{RmrkProperty, misc::RmrkDecode};170 use pallet_proxy_rmrk_core::{RmrkProperty, misc::RmrkDecode};175171176 let collection_id = CollectionId(collection_id);172 let collection_id = CollectionId(collection_id);177 let nft_id = TokenId(nft_by_id);173 let nft_id = TokenId(nft_by_id);178 if !RmrkCore::nft_exists(collection_id, nft_id) { return Ok(None); }174 if !RmrkCore::nft_exists(collection_id, nft_id) { return Ok(None); }179175180 let owner = match (dispatch_unique_runtime!(collection_id.token_owner(nft_id)) as Result<Option<CrossAccountId>, DispatchError>)? {176 let owner = match dispatch_unique_runtime!(collection_id.token_owner(nft_id))? {181 Some(owner) => match <Runtime as pallet_common::Config>::CrossTokenAddressMapping::address_to_token(&owner) {177 Some(owner) => match <Runtime as pallet_common::Config>::CrossTokenAddressMapping::address_to_token(&owner) {182 Some((col, tok)) => RmrkAccountIdOrCollectionNftTuple::CollectionAndNftTuple(col.0, tok.0),178 Some((col, tok)) => RmrkAccountIdOrCollectionNftTuple::CollectionAndNftTuple(col.0, tok.0),183 None => RmrkAccountIdOrCollectionNftTuple::AccountId(owner.as_sub().clone())179 None => RmrkAccountIdOrCollectionNftTuple::AccountId(owner.as_sub().clone())197 }193 }198194199 fn account_tokens(account_id: AccountId, collection_id: RmrkCollectionId) -> Result<Vec<RmrkNftId>, DispatchError> {195 fn account_tokens(account_id: AccountId, collection_id: RmrkCollectionId) -> Result<Vec<RmrkNftId>, DispatchError> {196 use pallet_proxy_rmrk_core::misc::CollectionType;197200 let cross_account_id = CrossAccountId::from_sub(account_id);198 let cross_account_id = CrossAccountId::from_sub(account_id);201 let collection_id = CollectionId(collection_id);199 let collection_id = CollectionId(collection_id);202 if !RmrkCore::collection_exists(collection_id) { return Ok(Vec::new()); }200 if RmrkCore::ensure_collection_type(collection_id, CollectionType::Regular).is_err() { return Ok(Vec::new()); }203201204 Ok(202 Ok(205 (dispatch_unique_runtime!(collection_id.account_tokens(cross_account_id)) as Result<Vec<TokenId>, DispatchError>)?203 dispatch_unique_runtime!(collection_id.account_tokens(cross_account_id))?206 //<Runtime as up_rpc::UniqueApi<Block, CrossAccountId, AccountId>>::account_tokens(collection_id, cross_account_id)?207 .into_iter()204 .into_iter()208 .map(|token| token.0)205 .map(|token| token.0)209 .collect::<Vec<_>>()206 .collect()210 )207 )211 }208 }212209277273278 fn nft_resources(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkResourceInfo>, DispatchError> {274 fn nft_resources(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkResourceInfo>, DispatchError> {279 use frame_support::BoundedVec;275 use frame_support::BoundedVec;280 use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, NftType}};276 use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, NftType, RmrkDecode}};281277282 let collection_id = CollectionId(collection_id);278 let collection_id = CollectionId(collection_id);283 if RmrkCore::ensure_collection_type(collection_id, CollectionType::Resource).is_err() { return Ok(Vec::new()); }279 if !RmrkCore::collection_exists(collection_id) { return Ok(Vec::new()); } // todo make sure the collection type doesn't matter284280285 let nft_id = TokenId(nft_id);281 let nft_id = TokenId(nft_id);286 if RmrkCore::ensure_nft_type(collection_id, nft_id, NftType::Resource).is_err() { return Ok(Vec::new()); }282 if RmrkCore::ensure_nft_type(collection_id, nft_id, NftType::Resource).is_err() { return Ok(Vec::new()); }287283284 let resource_collection_id: CollectionId = RmrkCore::get_nft_property(collection_id, nft_id, RmrkProperty::ResourceCollection)285 .unwrap()286 .decode_or_default();288 Ok(Vec::new(/*[RmrkResourceInfo {287 if RmrkCore::ensure_collection_type(collection_id, CollectionType::Resource).is_err() { return Ok(Vec::new()); }289288290 }]*/))289 let resources = pallet_nonfungible::TokenProperties::<Runtime>::iter_prefix((resource_collection_id,))290 .filter_map(|(resource_id, properties)| Some(RmrkResourceInfo {291 id: BoundedVec::default(), // todo ResourceId property292 pending: RmrkCore::get_nft_property(resource_collection_id, resource_id, RmrkProperty::PendingResourceAccept).unwrap().decode_or_default(),293 pending_removal: RmrkCore::get_nft_property(resource_collection_id, resource_id, RmrkProperty::PendingResourceRemoval).unwrap().decode_or_default(),294 resource: RmrkCore::get_nft_property(resource_collection_id, resource_id, RmrkProperty::ResourceType).unwrap().decode_or_default(),/* {295 RmrkResourceTypes::Basic(resource) => RmrkResourceTypes::Basic(),/*(RmrkBasicResource {296 src: RmrkCore::get_nft_property_inner(properties, RmrkProperty::Src).unwrap().decode_or_default(),297 metadata: RmrkCore::get_nft_property_inner(properties, RmrkProperty::Metadata).unwrap().decode_or_default(),298 license: RmrkCore::get_nft_property_inner(properties, RmrkProperty::License).unwrap().decode_or_default(),299 thumb: RmrkCore::get_nft_property_inner(properties, RmrkProperty::Thumb).unwrap().decode_or_default(),300 },*///BasicResource<BoundedString>)301 _ => todo!(), //RmrkResourceTypes::Composable(ComposableResource<BoundedString, BoundedParts>),302 //RmrkResourceTypes::Slot(SlotResource<BoundedString>),303 },*/304 }))305 .collect();306307 Ok(resources)291 }308 }292309293 fn nft_resource_priorities(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkResourceId>, DispatchError> {310 fn nft_resource_priorities(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkResourceId>, DispatchError> {311 use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, NftType, RmrkDecode}};312313 let collection_id = CollectionId(collection_id);294 todo!()314 if !RmrkCore::collection_exists(collection_id) { return Ok(Vec::new()); } // todo ensure the collection type doesn't matter315316 let nft_id = TokenId(nft_id);317 if RmrkCore::ensure_nft_type(collection_id, nft_id, NftType::Resource).is_err() { return Ok(Vec::new()); }318319 /*let resource_collection_id: CollectionId = RmrkCore::get_nft_property(collection_id, nft_id, RmrkProperty::ResourceCollection)320 .unwrap()321 .decode_or_default();322 if RmrkCore::ensure_collection_type(collection_id, CollectionType::Resource).is_err() { return Ok(Vec::new()); }323324 let resources = pallet_nonfungible::TokenProperties::<Runtime>::iter_prefix((resource_collection_id,))325 .filter_map(|(resource_id, properties)| Some((326 resource_id, // ResourceId property327 RmrkCore::get_nft_property(resource_collection_id, resource_id, RmrkProperty::Priority).unwrap().decode_or_default(),328 )))329 .collect()330 .sort_by_key(|(_, index)| *index)331 .into_iter().map(|(resource_id, _)| resource_id)*/332 let priorities = RmrkCore::get_nft_property(collection_id, nft_id, RmrkProperty::ResourcePriorities)?.decode_or_default();333334 Ok(priorities)295 }335 }296336297 fn base(base_id: RmrkBaseId) -> Result<Option<RmrkBaseInfo<AccountId>>, DispatchError> {337 fn base(base_id: RmrkBaseId) -> Result<Option<RmrkBaseInfo<AccountId>>, DispatchError> {298 use frame_support::BoundedVec;299 use scale_info::prelude::string::String;300 use pallet_proxy_rmrk_core::{338 use pallet_proxy_rmrk_core::{301 RmrkProperty, misc::{CollectionType, RmrkRebind, RmrkDecode},339 RmrkProperty, misc::{CollectionType, RmrkDecode},302 };340 };303341304 let collection_id = CollectionId(base_id);342 let collection_id = CollectionId(base_id);310 Ok(Some(RmrkBaseInfo {348 Ok(Some(RmrkBaseInfo {311 issuer: collection.owner.clone(),349 issuer: collection.owner.clone(),312 base_type: RmrkCore::get_collection_property(collection_id, RmrkProperty::BaseType)?.decode_or_default(),350 base_type: RmrkCore::get_collection_property(collection_id, RmrkProperty::BaseType)?.decode_or_default(),313 symbol: collection.token_prefix.rebind(),351 symbol: collection.token_prefix.decode_or_default(),314 }))352 }))315 }353 }316354317 fn base_parts(base_id: RmrkBaseId) -> Result<Vec<RmrkPartType>, DispatchError> {355 fn base_parts(base_id: RmrkBaseId) -> Result<Vec<RmrkPartType>, DispatchError> {318 use frame_support::BoundedVec;319 use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, NftType, RmrkDecode}};356 use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, NftType, RmrkDecode}};320357321 let collection_id = CollectionId(base_id);358 let collection_id = CollectionId(base_id);322 if RmrkCore::ensure_collection_type(collection_id, CollectionType::Base).is_err() { return Ok(Vec::new()); }359 if RmrkCore::ensure_collection_type(collection_id, CollectionType::Base).is_err() { return Ok(Vec::new()); }323360324 let parts = (dispatch_unique_runtime!(collection_id.collection_tokens()))?361 let parts = dispatch_unique_runtime!(collection_id.collection_tokens())?325 .into_iter()362 .into_iter()326 .filter_map(|token_id| {363 .filter_map(|token_id| {327 let nft_type = RmrkCore::get_nft_type(collection_id, token_id).ok()?;364 let nft_type = RmrkCore::get_nft_type(collection_id, token_id).ok()?;347 }384 }348385349 fn theme_names(base_id: RmrkBaseId) -> Result<Vec<RmrkThemeName>, DispatchError> {386 fn theme_names(base_id: RmrkBaseId) -> Result<Vec<RmrkThemeName>, DispatchError> {350 use frame_support::BoundedVec;351 use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, RmrkDecode}};387 use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, RmrkDecode}};352388353 let collection_id = CollectionId(base_id);389 let collection_id = CollectionId(base_id);354 if RmrkCore::ensure_collection_type(collection_id, CollectionType::Base).is_err() {390 if RmrkCore::ensure_collection_type(collection_id, CollectionType::Base).is_err() {355 return Ok(Vec::new());391 return Ok(Vec::new());356 }392 }357393358 let theme_names = (dispatch_unique_runtime!(collection_id.collection_tokens()))?394 let theme_names = dispatch_unique_runtime!(collection_id.collection_tokens())?359 .iter()395 .iter()360 .filter_map(|token_id| {396 .filter_map(|token_id| {361 let nft_type = RmrkCore::get_nft_type(collection_id, *token_id).unwrap();397 let nft_type = RmrkCore::get_nft_type(collection_id, *token_id).unwrap();373 }409 }374410375 fn theme(base_id: RmrkBaseId, theme_name: RmrkThemeName, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Option<RmrkTheme>, DispatchError> {411 fn theme(base_id: RmrkBaseId, theme_name: RmrkThemeName, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Result<Option<RmrkTheme>, DispatchError> {376 use frame_support::BoundedVec;377 use pallet_proxy_rmrk_core::{412 use pallet_proxy_rmrk_core::{378 RmrkProperty,413 RmrkProperty,379 misc::{CollectionType, NftType, RmrkDecode}414 misc::{CollectionType, NftType, RmrkDecode}384 return Ok(None);419 return Ok(None);385 }420 }386421387 let theme_info = (dispatch_unique_runtime!(collection_id.collection_tokens()))?422 let theme_info = dispatch_unique_runtime!(collection_id.collection_tokens())?388 .into_iter()423 .into_iter()389 .find_map(|token_id| {424 .find_map(|token_id| {390 RmrkCore::ensure_nft_type(collection_id, token_id, NftType::Theme).ok()?;425 RmrkCore::ensure_nft_type(collection_id, token_id, NftType::Theme).ok()?;tests/src/nesting/properties.test.tsdiffbeforeafterboth--- a/tests/src/nesting/properties.test.ts
+++ b/tests/src/nesting/properties.test.ts
@@ -711,7 +711,7 @@
});
});
- it('Forbids changing/deleting properties of a token if the property is permanent (constant)', async () => {
+ it('Forbids changing/deleting properties of a token if the property is permanent (immutable)', async () => {
await usingApi(async api => {
let i = -1;
for (const permission of constitution) {