git.delta.rocks / unique-network / refs/commits / 5d82f750c78d

difftreelog

feat(rmrk) refactor resources

Daniel Shiposha2022-06-15parent: #f9272dd.patch.diff
in: master

5 files changed

modifiedpallets/proxy-rmrk-core/src/lib.rsdiffbeforeafterboth
154 NftTypeEncodeError,154 NftTypeEncodeError,
155 RmrkPropertyKeyIsTooLong,155 RmrkPropertyKeyIsTooLong,
156 RmrkPropertyValueIsTooLong,156 RmrkPropertyValueIsTooLong,
157 RmrkPropertyIsNotFound,
157 UnableToDecodeRmrkData,158 UnableToDecodeRmrkData,
158159
159 /* RMRK compatible events */160 /* RMRK compatible events */
169 CannotAcceptNonOwnedNft,170 CannotAcceptNonOwnedNft,
170 CannotRejectNonOwnedNft,171 CannotRejectNonOwnedNft,
171 ResourceNotPending,172 ResourceNotPending,
173 NoAvailableResourceId,
172 }174 }
173175
174 #[pallet::call]176 #[pallet::call]
381 Self::rmrk_property(RoyaltyInfo, &royalty_info)?,383 Self::rmrk_property(RoyaltyInfo, &royalty_info)?,
382 Self::rmrk_property(Metadata, &metadata)?,384 Self::rmrk_property(Metadata, &metadata)?,
383 Self::rmrk_property(Equipped, &false)?,385 Self::rmrk_property(Equipped, &false)?,
384 Self::rmrk_property(ResourceCollection, &None::<CollectionId>)?,
385 Self::rmrk_property(ResourcePriorities, &<Vec<u8>>::new())?,386 Self::rmrk_property(ResourcePriorities, &<Vec<u8>>::new())?,
387 Self::rmrk_property(NextResourceId, &(0 as RmrkResourceId))?,
386 ]388 ]
387 .into_iter(),389 .into_iter(),
388 )390 )
653 collection.check_is_external()?;655 collection.check_is_external()?;
654656
655 ensure!(657 ensure!(
658 <TokenData<T>>::get((collection_id, nft_id)).is_some(),
659 <Error<T>>::NoAvailableNftId
660 );
661
662 ensure!(
656 Self::get_nft_property_decoded(663 Self::get_nft_property_decoded(
657 collection_id,664 collection_id,
658 nft_id,665 nft_id,
686 origin: OriginFor<T>,693 origin: OriginFor<T>,
687 rmrk_collection_id: RmrkCollectionId,694 rmrk_collection_id: RmrkCollectionId,
688 rmrk_nft_id: RmrkNftId,695 rmrk_nft_id: RmrkNftId,
689 rmrk_resource_id: RmrkResourceId,696 resource_id: RmrkResourceId,
690 ) -> DispatchResult {697 ) -> DispatchResult {
691 let sender = ensure_signed(origin)?;698 let sender = ensure_signed(origin)?;
692 let cross_sender = T::CrossAccountId::from_sub(sender);699 let cross_sender = T::CrossAccountId::from_sub(sender);
698 collection.check_is_external()?;705 collection.check_is_external()?;
699706
700 let nft_id = rmrk_nft_id.into();707 let nft_id = rmrk_nft_id.into();
701 let resource_id = rmrk_resource_id.into();
702708
703 let budget = budget::Value::new(NESTING_BUDGET);709 let budget = budget::Value::new(NESTING_BUDGET);
704710
705 let nft_owner =711 let nft_owner =
706 <PalletStructure<T>>::find_topmost_owner(collection_id, nft_id, &budget)712 <PalletStructure<T>>::find_topmost_owner(collection_id, nft_id, &budget)
707 .map_err(|_| <Error<T>>::ResourceDoesntExist)?;713 .map_err(|_| <Error<T>>::ResourceDoesntExist)?;
708714
709 let resource_collection_id: Option<CollectionId> =715 Self::try_mutate_resource_info(collection_id, nft_id, resource_id, |res| {
710 Self::get_nft_property_decoded(collection_id, nft_id, ResourceCollection)716 ensure!(res.pending, <Error<T>>::ResourceNotPending);
711 .map_err(|_| <Error<T>>::ResourceDoesntExist)?;717 ensure!(cross_sender == nft_owner, <Error<T>>::NoPermission);
712718
713 let resource_collection_id =719 res.pending = false;
714 resource_collection_id.ok_or(<Error<T>>::ResourceDoesntExist)?;
715720
716 let is_pending: bool = Self::get_nft_property_decoded(721 Ok(())
717 resource_collection_id,
718 resource_id,
719 PendingResourceAccept,
720 )
721 .map_err(|_| <Error<T>>::ResourceDoesntExist)?;722 })?;
722723
723 ensure!(is_pending, <Error<T>>::ResourceNotPending);
724
725 ensure!(cross_sender == nft_owner, <Error<T>>::NoPermission);
726
727 <PalletNft<T>>::set_scoped_token_property(
728 resource_collection_id,
729 rmrk_resource_id.into(),
730 PropertyScope::Rmrk,
731 Self::rmrk_property(PendingResourceAccept, &false)?,
732 )?;
733
734 Self::deposit_event(Event::<T>::ResourceAccepted {724 Self::deposit_event(Event::<T>::ResourceAccepted {
735 nft_id: rmrk_nft_id,725 nft_id: rmrk_nft_id,
736 resource_id: rmrk_resource_id,726 resource_id,
737 });727 });
738728
739 Ok(())729 Ok(())
746 origin: OriginFor<T>,736 origin: OriginFor<T>,
747 rmrk_collection_id: RmrkCollectionId,737 rmrk_collection_id: RmrkCollectionId,
748 rmrk_nft_id: RmrkNftId,738 rmrk_nft_id: RmrkNftId,
749 rmrk_resource_id: RmrkResourceId,739 resource_id: RmrkResourceId,
750 ) -> DispatchResult {740 ) -> DispatchResult {
751 let sender = ensure_signed(origin)?;741 let sender = ensure_signed(origin)?;
752 let cross_sender = T::CrossAccountId::from_sub(sender);742 let cross_sender = T::CrossAccountId::from_sub(sender);
758 collection.check_is_external()?;748 collection.check_is_external()?;
759749
760 let nft_id = rmrk_nft_id.into();750 let nft_id = rmrk_nft_id.into();
761 let resource_id = rmrk_resource_id.into();
762751
763 let budget = budget::Value::new(NESTING_BUDGET);752 let budget = budget::Value::new(NESTING_BUDGET);
764753
768757
769 ensure!(cross_sender == nft_owner, <Error<T>>::NoPermission);758 ensure!(cross_sender == nft_owner, <Error<T>>::NoPermission);
770759
771 let resource_collection_id: Option<CollectionId> =760 let resource_id_key = Self::rmrk_property_key(ResourceId(resource_id))?;
772 Self::get_nft_property_decoded(collection_id, nft_id, ResourceCollection)
773 .map_err(|_| <Error<T>>::ResourceDoesntExist)?;
774761
775 let resource_collection_id =762 let resource_info = <PalletNft<T>>::token_sys_property((
776 resource_collection_id.ok_or(<Error<T>>::ResourceDoesntExist)?;763 collection_id,
764 nft_id,
765 PropertyScope::Rmrk,
766 resource_id_key.clone(),
767 ))
768 .ok_or(<Error<T>>::ResourceDoesntExist)?;
777769
778 let is_pending: bool = Self::get_nft_property_decoded(770 let resource_info: RmrkResourceInfo = Self::decode_property(&resource_info)?;
779 resource_collection_id,
780 resource_id,
781 PendingResourceRemoval,
782 )
783 .map_err(|_| <Error<T>>::ResourceDoesntExist)?;
784771
785 ensure!(is_pending, <Error<T>>::ResourceNotPending);772 ensure!(
773 resource_info.pending_removal,
774 <Error<T>>::ResourceNotPending
775 );
786776
787 let resource_collection = Self::get_typed_nft_collection(777 <PalletNft<T>>::remove_token_sys_property(
788 resource_collection_id,778 collection_id,
789 misc::CollectionType::Resource,779 nft_id,
780 PropertyScope::Rmrk,
781 resource_id_key,
790 )?;782 );
791783
792 let resource_data = <TokenData<T>>::get((resource_collection_id, resource_id))
793 .ok_or(<Error<T>>::ResourceDoesntExist)?;
794
795 let resource_owner = resource_data.owner;
796
797 <PalletNft<T>>::burn(
798 &resource_collection,
799 &resource_owner,
800 rmrk_resource_id.into(),
801 )
802 .map_err(Self::map_unique_err_to_proxy)?;
803
804 Self::deposit_event(Event::<T>::ResourceRemovalAccepted {784 Self::deposit_event(Event::<T>::ResourceRemovalAccepted {
805 nft_id: rmrk_nft_id,785 nft_id: rmrk_nft_id,
806 resource_id: rmrk_resource_id,786 resource_id,
807 });787 });
808788
809 Ok(())789 Ok(())
1014 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;994 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;
1015 collection.check_is_external()?;995 collection.check_is_external()?;
1016996
1017 Self::resource_remove(sender, collection_id, nft_id.into(), resource_id.into())?;997 Self::resource_remove(sender, collection_id, nft_id.into(), resource_id)?;
1018998
1019 Self::deposit_event(Event::ResourceRemoval {999 Self::deposit_event(Event::ResourceRemoval {
1020 nft_id,1000 nft_id,
1043 ) -> Result<Property, DispatchError> {1023 ) -> Result<Property, DispatchError> {
1044 let key = rmrk_key.to_key::<T>()?;1024 let key = rmrk_key.to_key::<T>()?;
10451025
1026 let value = Self::encode_property(value)?;
1027
1028 let property = Property { key, value };
1029
1030 Ok(property)
1031 }
1032
1033 pub fn encode_property<E: Encode, S: Get<u32>>(
1034 value: &E,
1035 ) -> Result<BoundedBytes<S>, DispatchError> {
1046 let value = value1036 let value = value
1047 .encode()1037 .encode()
1048 .try_into()1038 .try_into()
1049 .map_err(|_| <Error<T>>::RmrkPropertyValueIsTooLong)?;1039 .map_err(|_| <Error<T>>::RmrkPropertyValueIsTooLong)?;
10501040
1051 let property = Property { key, value };1041 Ok(value)
1052
1053 Ok(property)
1054 }1042 }
10551043
1056 pub fn decode_property<D: Decode>(vec: PropertyValue) -> Result<D, DispatchError> {1044 pub fn decode_property<D: Decode, S: Get<u32>>(
1045 vec: &BoundedBytes<S>,
1046 ) -> Result<D, DispatchError> {
1057 vec.decode()1047 vec.decode()
1058 .map_err(|_| <Error<T>>::UnableToDecodeRmrkData.into())1048 .map_err(|_| <Error<T>>::UnableToDecodeRmrkData.into())
1059 }1049 }
1153 )1143 )
1154 }1144 }
11551145
1156 fn resource_add(1146 fn acquire_next_resource_id(
1157 sender: T::AccountId,
1158 collection_id: CollectionId,1147 collection_id: CollectionId,
1159 nft_id: TokenId,1148 nft_id: TokenId,
1160 resource: RmrkResourceTypes,
1161 ) -> Result<RmrkResourceId, DispatchError> {1149 ) -> Result<RmrkResourceId, DispatchError> {
1162 match resource {1150 let resource_id: RmrkResourceId =
1163 RmrkResourceTypes::Basic(resource) => Self::resource_add_helper(
1164 sender,1151 Self::get_nft_property_decoded(collection_id, nft_id, NextResourceId)?;
1165 collection_id,1152
1166 nft_id,
1167 [
1168 Self::rmrk_property(TokenType, &NftType::Resource)?,
1169 Self::rmrk_property(ResourceType, &misc::ResourceType::Basic)?,
1170 Self::rmrk_property(Src, &resource.src)?,
1171 Self::rmrk_property(Metadata, &resource.metadata)?,1153 let next_id = resource_id
1172 Self::rmrk_property(License, &resource.license)?,
1173 Self::rmrk_property(Thumb, &resource.thumb)?,
1174 ]
1175 .into_iter(),
1176 ),
1177 RmrkResourceTypes::Composable(resource) => Self::resource_add_helper(
1178 sender,1154 .checked_add(1)
1179 collection_id,
1180 nft_id.into(),
1181 [1155 .ok_or(<Error<T>>::NoAvailableResourceId)?;
1182 Self::rmrk_property(TokenType, &NftType::Resource)?,1156
1183 Self::rmrk_property(ResourceType, &misc::ResourceType::Composable)?,
1184 Self::rmrk_property(Parts, &resource.parts)?,
1185 Self::rmrk_property(Base, &resource.base)?,
1186 Self::rmrk_property(Src, &resource.src)?,
1187 Self::rmrk_property(Metadata, &resource.metadata)?,
1188 Self::rmrk_property(License, &resource.license)?,1157 <PalletNft<T>>::set_scoped_token_property(
1189 Self::rmrk_property(Thumb, &resource.thumb)?,
1190 ]
1191 .into_iter(),
1192 ),
1193 RmrkResourceTypes::Slot(resource) => Self::resource_add_helper(
1194 sender,1158 collection_id,
1195 collection_id,
1196 nft_id.into(),1159 nft_id,
1197 [1160 PropertyScope::Rmrk,
1198 Self::rmrk_property(TokenType, &NftType::Resource)?,
1199 Self::rmrk_property(ResourceType, &misc::ResourceType::Slot)?,1161 Self::rmrk_property(NextResourceId, &next_id)?,
1200 Self::rmrk_property(Base, &resource.base)?,1162 )?;
1201 Self::rmrk_property(Src, &resource.src)?,1163
1202 Self::rmrk_property(Metadata, &resource.metadata)?,1164 Ok(resource_id)
1203 Self::rmrk_property(Slot, &resource.slot)?,
1204 Self::rmrk_property(License, &resource.license)?,
1205 Self::rmrk_property(Thumb, &resource.thumb)?,
1206 ]
1207 .into_iter(),
1208 ),
1209 }
1210 }1165 }
12111166
1212 fn resource_add_helper(1167 fn resource_add(
1213 sender: T::AccountId,1168 sender: T::AccountId,
1214 collection_id: CollectionId,1169 collection_id: CollectionId,
1215 token_id: TokenId,1170 nft_id: TokenId,
1216 resource_properties: impl Iterator<Item = Property>,1171 resource: RmrkResourceTypes,
1217 ) -> Result<RmrkResourceId, DispatchError> {1172 ) -> Result<RmrkResourceId, DispatchError> {
1218 let collection =1173 let collection =
1219 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1174 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;
1222 let sender = T::CrossAccountId::from_sub(sender);1177 let sender = T::CrossAccountId::from_sub(sender);
1223 let budget = budget::Value::new(NESTING_BUDGET);1178 let budget = budget::Value::new(NESTING_BUDGET);
12241179
1225 let nft_owner = <PalletStructure<T>>::find_topmost_owner(collection_id, token_id, &budget)1180 let nft_owner = <PalletStructure<T>>::find_topmost_owner(collection_id, nft_id, &budget)
1226 .map_err(Self::map_unique_err_to_proxy)?;1181 .map_err(Self::map_unique_err_to_proxy)?;
12271182
1228 let pending = sender != nft_owner;1183 let pending = sender != nft_owner;
12291184
1230 let resource_collection_id: Option<CollectionId> =1185 let id = Self::acquire_next_resource_id(collection_id, nft_id)?;
1231 Self::get_nft_property_decoded(collection_id, token_id, ResourceCollection)?;
12321186
1233 let resource_collection_id = match resource_collection_id {1187 let resource_info = RmrkResourceInfo {
1234 Some(id) => id,1188 id,
1235 None => {1189 resource,
1236 let resource_collection_id = Self::init_collection(
1237 sender.clone(),
1238 CreateCollectionData {1190 pending,
1239 ..Default::default()
1240 },
1241 [Self::rmrk_property(1191 pending_removal: false,
1242 CollectionType,
1243 &misc::CollectionType::Resource,
1244 )?]
1245 .into_iter(),
1246 )?;
1247
1248 <PalletNft<T>>::set_scoped_token_property(
1249 collection_id,
1250 token_id,
1251 PropertyScope::Rmrk,
1252 Self::rmrk_property(ResourceCollection, &Some(resource_collection_id))?,
1253 )?;
1254
1255 resource_collection_id
1256 }
1257 };1192 };
12581193
1259 let resource_collection =1194 <PalletNft<T>>::try_mutate_token_sys_property(
1260 Self::get_typed_nft_collection(resource_collection_id, misc::CollectionType::Resource)?;1195 collection_id,
1196 nft_id,
1197 PropertyScope::Rmrk,
1198 Self::rmrk_property_key(ResourceId(id))?,
1199 |value| -> DispatchResult {
1200 *value = Some(Self::encode_property(&resource_info)?);
12611201
1262 // todo probably add extra connections to bases, slots, etc., when RMRK starts to use them1202 Ok(())
1203 },
1204 )?;
12631205
1264 let resource_id = Self::create_nft(1206 Ok(id)
1265 &sender,
1266 &nft_owner,
1267 &resource_collection,
1268 resource_properties.chain(
1269 [
1270 Self::rmrk_property(PendingResourceAccept, &pending)?,
1271 Self::rmrk_property(PendingResourceRemoval, &false)?,
1272 ]
1273 .into_iter(),
1274 ),
1275 )
1276 .map_err(|err| match err {
1277 DispatchError::Arithmetic(_) => <Error<T>>::NoAvailableNftId.into(),
1278 err => Self::map_unique_err_to_proxy(err),
1279 })?;
1280
1281 Ok(resource_id.0)
1282 }1207 }
12831208
1284 fn resource_remove(1209 fn resource_remove(
1285 sender: T::AccountId,1210 sender: T::AccountId,
1286 collection_id: CollectionId,1211 collection_id: CollectionId,
1287 nft_id: TokenId,1212 nft_id: TokenId,
1288 resource_id: TokenId,1213 resource_id: RmrkResourceId,
1289 ) -> DispatchResult {1214 ) -> DispatchResult {
1290 let collection =1215 let collection =
1291 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1216 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;
1292 ensure!(collection.owner == sender, Error::<T>::NoPermission);1217 ensure!(collection.owner == sender, Error::<T>::NoPermission);
12931218
1294 let resource_collection_id: Option<CollectionId> =1219 let resource_id_key = Self::rmrk_property_key(ResourceId(resource_id))?;
1295 Self::get_nft_property_decoded(collection_id, nft_id, ResourceCollection)?;1220 let scope = PropertyScope::Rmrk;
12961221
1297 let resource_collection_id =
1298 resource_collection_id.ok_or(Error::<T>::ResourceDoesntExist)?;
1299
1300 let resource_collection =
1301 Self::get_typed_nft_collection(resource_collection_id, misc::CollectionType::Resource)?;
1302 ensure!(1222 ensure!(
1303 <PalletNft<T>>::token_exists(&resource_collection, resource_id),1223 <PalletNft<T>>::token_sys_property((
1224 collection_id,
1225 nft_id,
1226 scope,
1227 resource_id_key.clone()
1228 ))
1229 .is_some(),
1304 Error::<T>::ResourceDoesntExist1230 <Error<T>>::ResourceDoesntExist
1305 );1231 );
13061232
1307 let budget = up_data_structs::budget::Value::new(NESTING_BUDGET);1233 let budget = up_data_structs::budget::Value::new(NESTING_BUDGET);
13101236
1311 let sender = T::CrossAccountId::from_sub(sender);1237 let sender = T::CrossAccountId::from_sub(sender);
1312 if topmost_owner == sender {1238 if topmost_owner == sender {
1313 <PalletNft<T>>::burn(&resource_collection, &sender, resource_id)1239 <PalletNft<T>>::remove_token_sys_property(
1314 .map_err(Self::map_unique_err_to_proxy)?;
1315 } else {
1316 <PalletNft<T>>::set_scoped_token_property(
1317 resource_collection_id,1240 collection_id,
1318 resource_id,1241 nft_id,
1319 PropertyScope::Rmrk,1242 PropertyScope::Rmrk,
1320 Self::rmrk_property(PendingResourceRemoval, &true)?,1243 Self::rmrk_property_key(ResourceId(resource_id))?,
1244 );
1245 } else {
1246 Self::try_mutate_resource_info(collection_id, nft_id, resource_id, |res| {
1247 res.pending_removal = true;
1248
1249 Ok(())
1321 )?;1250 })?;
1322 }1251 }
13231252
1324 Ok(())1253 Ok(())
1254 }
1255
1256 fn try_mutate_resource_info(
1257 collection_id: CollectionId,
1258 nft_id: TokenId,
1259 resource_id: RmrkResourceId,
1260 f: impl FnOnce(&mut RmrkResourceInfo) -> DispatchResult,
1261 ) -> DispatchResult {
1262 <PalletNft<T>>::try_mutate_token_sys_property(
1263 collection_id,
1264 nft_id,
1265 PropertyScope::Rmrk,
1266 Self::rmrk_property_key(ResourceId(resource_id))?,
1267 |value| match value {
1268 Some(value) => {
1269 let mut resource_info: RmrkResourceInfo = Self::decode_property(value)?;
1270
1271 f(&mut resource_info)?;
1272
1273 *value = Self::encode_property(&resource_info)?;
1274
1275 Ok(())
1276 }
1277 None => Err(<Error<T>>::ResourceDoesntExist.into()),
1278 },
1279 )
1325 }1280 }
13261281
1327 fn change_collection_owner(1282 fn change_collection_owner(
1397 collection_id: CollectionId,1352 collection_id: CollectionId,
1398 key: RmrkProperty,1353 key: RmrkProperty,
1399 ) -> Result<V, DispatchError> {1354 ) -> Result<V, DispatchError> {
1400 Self::decode_property(Self::get_collection_property(collection_id, key)?)1355 Self::decode_property(&Self::get_collection_property(collection_id, key)?)
1401 }1356 }
14021357
1403 pub fn get_collection_type(1358 pub fn get_collection_type(
1450 ) -> Result<PropertyValue, DispatchError> {1405 ) -> Result<PropertyValue, DispatchError> {
1451 let nft_property = <PalletNft<T>>::token_properties((collection_id, nft_id))1406 let nft_property = <PalletNft<T>>::token_properties((collection_id, nft_id))
1452 .get(&Self::rmrk_property_key(key)?)1407 .get(&Self::rmrk_property_key(key)?)
1453 .ok_or(<Error<T>>::NoAvailableNftId)? // todo replace with better error?1408 .ok_or(<Error<T>>::RmrkPropertyIsNotFound)?
1454 .clone();1409 .clone();
14551410
1456 Ok(nft_property)1411 Ok(nft_property)
1461 nft_id: TokenId,1416 nft_id: TokenId,
1462 key: RmrkProperty,1417 key: RmrkProperty,
1463 ) -> Result<V, DispatchError> {1418 ) -> Result<V, DispatchError> {
1464 Self::decode_property(Self::get_nft_property(collection_id, nft_id, key)?)1419 Self::decode_property(&Self::get_nft_property(collection_id, nft_id, key)?)
1465 }1420 }
14661421
1467 pub fn nft_exists(collection_id: CollectionId, nft_id: TokenId) -> bool {1422 pub fn nft_exists(collection_id: CollectionId, nft_id: TokenId) -> bool {
modifiedpallets/proxy-rmrk-core/src/misc.rsdiffbeforeafterboth
61#[derive(Encode, Decode, PartialEq, Eq)]61#[derive(Encode, Decode, PartialEq, Eq)]
62pub enum CollectionType {62pub enum CollectionType {
63 Regular,63 Regular,
64 Resource,
65 Base,64 Base,
66}65}
6766
68#[derive(Encode, Decode, PartialEq, Eq)]67#[derive(Encode, Decode, PartialEq, Eq)]
69pub enum NftType {68pub enum NftType {
70 Regular,69 Regular,
71 Resource,
72 FixedPart,70 FixedPart,
73 SlotPart,71 SlotPart,
74 Theme,72 Theme,
75}73}
76
77#[derive(Encode, Decode, PartialEq, Eq)]
78pub enum ResourceType {
79 Basic,
80 Composable,
81 Slot,
82}
8374
modifiedpallets/proxy-rmrk-core/src/property.rsdiffbeforeafterboth
17use super::*;17use super::*;
18use core::convert::AsRef;18use core::convert::AsRef;
19
20const RESOURCE_ID_PREFIX: &str = "rsid-";
1921
20pub enum RmrkProperty<'r> {22pub enum RmrkProperty<'r> {
21 Metadata,23 Metadata,
25 Transferable,27 Transferable,
26 RoyaltyInfo,28 RoyaltyInfo,
27 Equipped,29 Equipped,
28 ResourceCollection,
29 ResourcePriorities,30 ResourcePriorities,
30 ResourceType,31 NextResourceId,
32 ResourceId(RmrkResourceId),
31 PendingNftAccept,33 PendingNftAccept,
32 PendingResourceAccept,
33 PendingResourceRemoval,
34 Parts,34 Parts,
35 Base,35 Base,
36 Src,36 Src,
37 Slot,
38 License,
39 Thumb,
40 EquippedNft,37 EquippedNft,
41 BaseType,38 BaseType,
42 ExternalPartId,39 ExternalPartId,
72 Self::Transferable => key!("transferable"),69 Self::Transferable => key!("transferable"),
73 Self::RoyaltyInfo => key!("royalty-info"),70 Self::RoyaltyInfo => key!("royalty-info"),
74 Self::Equipped => key!("equipped"),71 Self::Equipped => key!("equipped"),
75 Self::ResourceCollection => key!("resource-collection"),
76 Self::ResourcePriorities => key!("resource-priorities"),72 Self::ResourcePriorities => key!("resource-priorities"),
77 Self::ResourceType => key!("resource-type"),73 Self::NextResourceId => key!("next-resource-id"),
74 Self::ResourceId(id) => key!(RESOURCE_ID_PREFIX, id.to_le_bytes()),
78 Self::PendingNftAccept => key!("pending-nft-accept"),75 Self::PendingNftAccept => key!("pending-nft-accept"),
79 Self::PendingResourceAccept => key!("pending-resource-accept"),
80 Self::PendingResourceRemoval => key!("pending-resource-removal"),
81 Self::Parts => key!("parts"),76 Self::Parts => key!("parts"),
82 Self::Base => key!("base"),77 Self::Base => key!("base"),
83 Self::Src => key!("src"),78 Self::Src => key!("src"),
84 Self::Slot => key!("slot"),
85 Self::License => key!("license"),
86 Self::Thumb => key!("thumb"),
87 Self::EquippedNft => key!("equipped-nft"),79 Self::EquippedNft => key!("equipped-nft"),
88 Self::BaseType => key!("base-type"),80 Self::BaseType => key!("base-type"),
89 Self::ExternalPartId => key!("ext-part-id"),81 Self::ExternalPartId => key!("ext-part-id"),
modifiedruntime/opal/src/lib.rsdiffbeforeafterboth
75 mapping::{EvmTokenAddressMapping, CrossTokenAddressMapping},75 mapping::{EvmTokenAddressMapping, CrossTokenAddressMapping},
76 TokenChild, RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo,76 TokenChild, RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo,
77 RmrkBaseInfo, RmrkPartType, RmrkTheme, RmrkThemeName, RmrkThemeProperty, RmrkCollectionId,77 RmrkBaseInfo, RmrkPartType, RmrkTheme, RmrkThemeName, RmrkThemeProperty, RmrkCollectionId,
78 RmrkNftId, RmrkAccountIdOrCollectionNftTuple, RmrkNftChild, RmrkPropertyKey, RmrkResourceTypes,78 RmrkNftId, RmrkAccountIdOrCollectionNftTuple, RmrkNftChild, RmrkPropertyKey, RmrkResourceId,
79 RmrkBasicResource, RmrkComposableResource, RmrkSlotResource, RmrkResourceId, RmrkBaseId,79 RmrkBaseId, RmrkFixedPart, RmrkSlotPart, RmrkString,
80 RmrkFixedPart, RmrkSlotPart, RmrkString,
81};80};
8281
1501 }1500 }
15021501
1503 fn nft_resources(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkResourceInfo>, DispatchError> {1502 fn nft_resources(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkResourceInfo>, DispatchError> {
1504 use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, NftType, ResourceType}};1503 use pallet_proxy_rmrk_core::misc::{CollectionType, NftType};
1505 use pallet_common::CommonCollectionOperations;1504 use up_data_structs::PropertyScope;
15061505
1507 let collection_id = match RmrkCore::unique_collection_id(collection_id) {1506 let collection_id = match RmrkCore::unique_collection_id(collection_id) {
1508 Ok(id) => id,1507 Ok(id) => id,
1513 let nft_id = TokenId(nft_id);1512 let nft_id = TokenId(nft_id);
1514 if RmrkCore::ensure_nft_type(collection_id, nft_id, NftType::Regular).is_err() { return Ok(Vec::new()); }1513 if RmrkCore::ensure_nft_type(collection_id, nft_id, NftType::Regular).is_err() { return Ok(Vec::new()); }
15151514
1516 let res_collection_id: Option<CollectionId> = RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::ResourceCollection)?;1515 let resources = <pallet_nonfungible::Pallet<Runtime>>::iterate_token_sys_properties(
15171516 collection_id, nft_id, PropertyScope::Rmrk
1518 let res_collection_id = match res_collection_id {
1519 Some(id) => id,
1520 None => return Ok(Vec::new())
1521 };
1522
1523 let resource_collection = RmrkCore::get_typed_nft_collection(res_collection_id, CollectionType::Resource)?;
1524
1525 let resources = resource_collection
1526 .collection_tokens()
1527 .iter()
1528 .filter_map(|res_id| Some(RmrkResourceInfo {1517 ).filter_map(|(_, value)| {
1529 id: res_id.0,
1530 pending: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::PendingResourceAccept).ok()?,
1531 pending_removal: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::PendingResourceRemoval).ok()?,
1532 resource: match RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::ResourceType).ok()? {
1533 ResourceType::Basic => RmrkResourceTypes::Basic(RmrkBasicResource {
1534 src: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Src).ok()?,1518 let resource_info: RmrkResourceInfo = RmrkCore::decode_property(&value).ok()?;
1535 metadata: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Metadata).ok()?,1519
1536 license: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::License).ok()?,
1537 thumb: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Thumb).ok()?,
1538 }),
1539 ResourceType::Composable => RmrkResourceTypes::Composable(RmrkComposableResource {
1540 parts: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Parts).ok()?,
1541 base: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Base).ok()?,
1542 src: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Src).ok()?,
1543 metadata: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Metadata).ok()?,
1544 license: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::License).ok()?,
1545 thumb: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Thumb).ok()?,
1546 }),
1547 ResourceType::Slot => RmrkResourceTypes::Slot(RmrkSlotResource {
1548 base: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Base).ok()?,
1549 src: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Src).ok()?,
1550 metadata: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Metadata).ok()?,
1551 slot: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Slot).ok()?,
1552 license: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::License).ok()?,
1553 thumb: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Thumb).ok()?,1520 Some(resource_info)
1554 }),
1555 },1521 }).collect();
1556 }))
1557 .collect();
15581522
1559 Ok(resources)1523 Ok(resources)
modifiedruntime/quartz/src/lib.rsdiffbeforeafterboth
75 mapping::{EvmTokenAddressMapping, CrossTokenAddressMapping},75 mapping::{EvmTokenAddressMapping, CrossTokenAddressMapping},
76 TokenChild, RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo,76 TokenChild, RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo,
77 RmrkBaseInfo, RmrkPartType, RmrkTheme, RmrkThemeName, RmrkThemeProperty, RmrkCollectionId,77 RmrkBaseInfo, RmrkPartType, RmrkTheme, RmrkThemeName, RmrkThemeProperty, RmrkCollectionId,
78 RmrkNftId, RmrkAccountIdOrCollectionNftTuple, RmrkNftChild, RmrkPropertyKey, RmrkResourceTypes,78 RmrkNftId, RmrkAccountIdOrCollectionNftTuple, RmrkNftChild, RmrkPropertyKey, RmrkResourceId,
79 RmrkBasicResource, RmrkComposableResource, RmrkSlotResource, RmrkResourceId, RmrkBaseId,79 RmrkBaseId, RmrkFixedPart, RmrkSlotPart, RmrkString,
80 RmrkFixedPart, RmrkSlotPart, RmrkString,
81};80};
8281
1501 }1500 }
15021501
1503 fn nft_resources(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkResourceInfo>, DispatchError> {1502 fn nft_resources(collection_id: RmrkCollectionId, nft_id: RmrkNftId) -> Result<Vec<RmrkResourceInfo>, DispatchError> {
1504 use pallet_proxy_rmrk_core::{RmrkProperty, misc::{CollectionType, NftType, ResourceType}};1503 use pallet_proxy_rmrk_core::misc::{CollectionType, NftType};
1505 use pallet_common::CommonCollectionOperations;1504 use up_data_structs::PropertyScope;
15061505
1507 let collection_id = match RmrkCore::unique_collection_id(collection_id) {1506 let collection_id = match RmrkCore::unique_collection_id(collection_id) {
1508 Ok(id) => id,1507 Ok(id) => id,
1513 let nft_id = TokenId(nft_id);1512 let nft_id = TokenId(nft_id);
1514 if RmrkCore::ensure_nft_type(collection_id, nft_id, NftType::Regular).is_err() { return Ok(Vec::new()); }1513 if RmrkCore::ensure_nft_type(collection_id, nft_id, NftType::Regular).is_err() { return Ok(Vec::new()); }
15151514
1516 let res_collection_id: Option<CollectionId> = RmrkCore::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::ResourceCollection)?;1515 let resources = <pallet_nonfungible::Pallet<Runtime>>::iterate_token_sys_properties(
15171516 collection_id, nft_id, PropertyScope::Rmrk
1518 let res_collection_id = match res_collection_id {
1519 Some(id) => id,
1520 None => return Ok(Vec::new())
1521 };
1522
1523 let resource_collection = RmrkCore::get_typed_nft_collection(res_collection_id, CollectionType::Resource)?;
1524
1525 let resources = resource_collection
1526 .collection_tokens()
1527 .iter()
1528 .filter_map(|res_id| Some(RmrkResourceInfo {1517 ).filter_map(|(_, value)| {
1529 id: res_id.0,
1530 pending: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::PendingResourceAccept).ok()?,
1531 pending_removal: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::PendingResourceRemoval).ok()?,
1532 resource: match RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::ResourceType).ok()? {
1533 ResourceType::Basic => RmrkResourceTypes::Basic(RmrkBasicResource {
1534 src: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Src).ok()?,1518 let resource_info: RmrkResourceInfo = RmrkCore::decode_property(&value).ok()?;
1535 metadata: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Metadata).ok()?,1519
1536 license: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::License).ok()?,
1537 thumb: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Thumb).ok()?,
1538 }),
1539 ResourceType::Composable => RmrkResourceTypes::Composable(RmrkComposableResource {
1540 parts: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Parts).ok()?,
1541 base: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Base).ok()?,
1542 src: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Src).ok()?,
1543 metadata: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Metadata).ok()?,
1544 license: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::License).ok()?,
1545 thumb: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Thumb).ok()?,
1546 }),
1547 ResourceType::Slot => RmrkResourceTypes::Slot(RmrkSlotResource {
1548 base: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Base).ok()?,
1549 src: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Src).ok()?,
1550 metadata: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Metadata).ok()?,
1551 slot: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Slot).ok()?,
1552 license: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::License).ok()?,
1553 thumb: RmrkCore::get_nft_property_decoded(res_collection_id, *res_id, RmrkProperty::Thumb).ok()?,1520 Some(resource_info)
1554 }),
1555 },1521 }).collect();
1556 }))
1557 .collect();
15581522
1559 Ok(resources)1523 Ok(resources)