123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566#![recursion_limit = "1024"]67#![cfg_attr(not(feature = "std"), no_std)]68#![allow(69 clippy::too_many_arguments,70 clippy::unnecessary_mut_passed,71 clippy::unused_unit72)]7374extern crate alloc;7576use frame_support::{77 decl_module, decl_storage, decl_error,78 dispatch::DispatchResult,79 ensure, fail,80 weights::{Weight},81 pallet_prelude::{DispatchResultWithPostInfo, ConstU32},82 BoundedVec,83};84use scale_info::TypeInfo;85use frame_system::{self as system, ensure_signed};86use sp_std::{vec, vec::Vec};87use up_data_structs::{88 MAX_COLLECTION_NAME_LENGTH, MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_TOKEN_PREFIX_LENGTH,89 MAX_PROPERTIES_PER_ITEM, MAX_PROPERTY_KEY_LENGTH, MAX_PROPERTY_VALUE_LENGTH,90 MAX_COLLECTION_PROPERTIES_SIZE, COLLECTION_ADMINS_LIMIT, MAX_TOKEN_PROPERTIES_SIZE,91 CreateItemData, CollectionLimits, CollectionPermissions, CollectionId, CollectionMode, TokenId,92 CreateCollectionData, CreateItemExData, budget, Property, PropertyKey, PropertyKeyPermission,93};94use pallet_evm::account::CrossAccountId;95use pallet_common::{96 CollectionHandle, Pallet as PalletCommon, CommonWeightInfo, dispatch::dispatch_tx,97 dispatch::CollectionDispatch, RefungibleExtensionsWeightInfo,98};99pub mod eth;100101#[cfg(feature = "runtime-benchmarks")]102pub mod benchmarking;103pub mod weights;104use weights::WeightInfo;105106107pub const NESTING_BUDGET: u32 = 5;108109decl_error! {110 111 pub enum Error for Module<T: Config> {112 113 CollectionDecimalPointLimitExceeded,114 115 EmptyArgument,116 117 RepartitionCalledOnNonRefungibleCollection,118 }119}120121122pub trait Config: system::Config + pallet_common::Config + Sized + TypeInfo {123 124 type WeightInfo: WeightInfo;125126 127 type CommonWeightInfo: CommonWeightInfo<Self::CrossAccountId>;128129 130 type RefungibleExtensionsWeightInfo: RefungibleExtensionsWeightInfo;131}132133type SelfWeightOf<T> = <T as Config>::WeightInfo;134135136137138139140141142143144145146147148149150151152153154155156157decl_storage! {158 trait Store for Module<T: Config> as Unique {159160 161 162 ChainVersion: u64;163 164165 166 167 168 pub CreateItemBasket get(fn create_item_basket): map hasher(blake2_128_concat) (CollectionId, T::AccountId) => Option<T::BlockNumber>;169 170 pub NftTransferBasket get(fn nft_transfer_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => Option<T::BlockNumber>;171 172 pub FungibleTransferBasket get(fn fungible_transfer_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(twox_64_concat) T::AccountId => Option<T::BlockNumber>;173 174 pub ReFungibleTransferBasket get(fn refungible_transfer_basket): nmap hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId, hasher(twox_64_concat) T::AccountId => Option<T::BlockNumber>;175 176177 178 179 #[deprecated]180 pub VariableMetaDataBasket get(fn variable_meta_data_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => Option<T::BlockNumber>;181 182 pub TokenPropertyBasket get(fn token_property_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => Option<T::BlockNumber>;183184 185 pub NftApproveBasket get(fn nft_approve_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => Option<T::BlockNumber>;186 187 pub FungibleApproveBasket get(fn fungible_approve_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(twox_64_concat) T::AccountId => Option<T::BlockNumber>;188 189 pub RefungibleApproveBasket get(fn refungible_approve_basket): nmap hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId, hasher(twox_64_concat) T::AccountId => Option<T::BlockNumber>;190 }191}192193decl_module! {194 195 pub struct Module<T: Config> for enum Call196 where197 origin: T::RuntimeOrigin198 {199 type Error = Error<T>;200201 #[doc = "A maximum number of levels of depth in the token nesting tree."]202 const NESTING_BUDGET: u32 = NESTING_BUDGET;203204 #[doc = "Maximal length of a collection name."]205 const MAX_COLLECTION_NAME_LENGTH: u32 = MAX_COLLECTION_NAME_LENGTH;206207 #[doc = "Maximal length of a collection description."]208 const MAX_COLLECTION_DESCRIPTION_LENGTH: u32 = MAX_COLLECTION_DESCRIPTION_LENGTH;209210 #[doc = "Maximal length of a token prefix."]211 const MAX_TOKEN_PREFIX_LENGTH: u32 = MAX_TOKEN_PREFIX_LENGTH;212213 #[doc = "Maximum admins per collection."]214 const COLLECTION_ADMINS_LIMIT: u32 = COLLECTION_ADMINS_LIMIT;215216 #[doc = "Maximal length of a property key."]217 const MAX_PROPERTY_KEY_LENGTH: u32 = MAX_PROPERTY_KEY_LENGTH;218219 #[doc = "Maximal length of a property value."]220 const MAX_PROPERTY_VALUE_LENGTH: u32 = MAX_PROPERTY_VALUE_LENGTH;221222 #[doc = "A maximum number of token properties."]223 const MAX_PROPERTIES_PER_ITEM: u32 = MAX_PROPERTIES_PER_ITEM;224225 #[doc = "Maximum size for all collection properties."]226 const MAX_COLLECTION_PROPERTIES_SIZE: u32 = MAX_COLLECTION_PROPERTIES_SIZE;227228 #[doc = "Maximum size of all token properties."]229 const MAX_TOKEN_PROPERTIES_SIZE: u32 = MAX_TOKEN_PROPERTIES_SIZE;230231 #[doc = "Default NFT collection limit."]232 const NFT_DEFAULT_COLLECTION_LIMITS: CollectionLimits = CollectionLimits::with_default_limits(CollectionMode::NFT);233234 #[doc = "Default RFT collection limit."]235 const RFT_DEFAULT_COLLECTION_LIMITS: CollectionLimits = CollectionLimits::with_default_limits(CollectionMode::ReFungible);236237 #[doc = "Default FT collection limit."]238 const FT_DEFAULT_COLLECTION_LIMITS: CollectionLimits = CollectionLimits::with_default_limits(CollectionMode::Fungible(0));239240 fn on_initialize(_now: T::BlockNumber) -> Weight {241 Weight::zero()242 }243244 fn on_runtime_upgrade() -> Weight {245 Weight::zero()246 }247248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 #[weight = <SelfWeightOf<T>>::create_collection()]271 #[deprecated(note = "`create_collection_ex` is more up-to-date and advanced, prefer it instead")]272 pub fn create_collection(273 origin,274 collection_name: BoundedVec<u16, ConstU32<MAX_COLLECTION_NAME_LENGTH>>,275 collection_description: BoundedVec<u16, ConstU32<MAX_COLLECTION_DESCRIPTION_LENGTH>>,276 token_prefix: BoundedVec<u8, ConstU32<MAX_TOKEN_PREFIX_LENGTH>>,277 mode: CollectionMode278 ) -> DispatchResult {279 let data: CreateCollectionData<T::AccountId> = CreateCollectionData {280 name: collection_name,281 description: collection_description,282 token_prefix,283 mode,284 ..Default::default()285 };286 Self::create_collection_ex(origin, data)287 }288289 290 291 292 293 294 295 296 297 298 299 300 #[weight = <SelfWeightOf<T>>::create_collection()]301 pub fn create_collection_ex(origin, data: CreateCollectionData<T::AccountId>) -> DispatchResult {302 let sender = ensure_signed(origin)?;303304 305 let sender = T::CrossAccountId::from_sub(sender);306 let _id = T::CollectionDispatch::create(sender.clone(), sender, data, Default::default())?;307308 Ok(())309 }310311 312 313 314 315 316 317 318 319 320 #[weight = <SelfWeightOf<T>>::destroy_collection()]321 pub fn destroy_collection(origin, collection_id: CollectionId) -> DispatchResult {322 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);323324 Self::destroy_collection_internal(sender, collection_id)325 }326327 328 329 330 331 332 333 334 335 336 337 338 #[weight = <SelfWeightOf<T>>::add_to_allow_list()]339 pub fn add_to_allow_list(origin, collection_id: CollectionId, address: T::CrossAccountId) -> DispatchResult{340341 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);342 let collection = <CollectionHandle<T>>::try_get(collection_id)?;343 collection.check_is_internal()?;344345 <PalletCommon<T>>::toggle_allowlist(346 &collection,347 &sender,348 &address,349 true,350 )?;351352 Ok(())353 }354355 356 357 358 359 360 361 362 363 364 365 366 #[weight = <SelfWeightOf<T>>::remove_from_allow_list()]367 pub fn remove_from_allow_list(origin, collection_id: CollectionId, address: T::CrossAccountId) -> DispatchResult{368369 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);370 let collection = <CollectionHandle<T>>::try_get(collection_id)?;371 collection.check_is_internal()?;372373 <PalletCommon<T>>::toggle_allowlist(374 &collection,375 &sender,376 &address,377 false,378 )?;379380 Ok(())381 }382383 384 385 386 387 388 389 390 391 392 393 #[weight = <SelfWeightOf<T>>::change_collection_owner()]394 pub fn change_collection_owner(origin, collection_id: CollectionId, new_owner: T::AccountId) -> DispatchResult {395 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);396 let new_owner = T::CrossAccountId::from_sub(new_owner);397 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;398 target_collection.change_owner(sender, new_owner.clone())399 }400401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 #[weight = <SelfWeightOf<T>>::add_collection_admin()]418 pub fn add_collection_admin(origin, collection_id: CollectionId, new_admin_id: T::CrossAccountId) -> DispatchResult {419 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);420 let collection = <CollectionHandle<T>>::try_get(collection_id)?;421 <PalletCommon<T>>::toggle_admin(&collection, &sender, &new_admin_id, true)422 }423424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 #[weight = <SelfWeightOf<T>>::remove_collection_admin()]439 pub fn remove_collection_admin(origin, collection_id: CollectionId, account_id: T::CrossAccountId) -> DispatchResult {440 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);441 let collection = <CollectionHandle<T>>::try_get(collection_id)?;442 <PalletCommon<T>>::toggle_admin(&collection, &sender, &account_id, false)443 }444445 446 447 448 449 450 451 452 453 454 455 456 457 458 #[weight = <SelfWeightOf<T>>::set_collection_sponsor()]459 pub fn set_collection_sponsor(origin, collection_id: CollectionId, new_sponsor: T::AccountId) -> DispatchResult {460 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);461 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;462 target_collection.set_sponsor(&sender, new_sponsor.clone())463 }464465 466 467 468 469 470 471 472 473 474 475 476 477 478 #[weight = <SelfWeightOf<T>>::confirm_sponsorship()]479 pub fn confirm_sponsorship(origin, collection_id: CollectionId) -> DispatchResult {480 let sender = ensure_signed(origin)?;481 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;482 target_collection.confirm_sponsorship(&sender)483 }484485 486 487 488 489 490 491 492 493 494 #[weight = <SelfWeightOf<T>>::remove_collection_sponsor()]495 pub fn remove_collection_sponsor(origin, collection_id: CollectionId) -> DispatchResult {496 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);497 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;498 target_collection.remove_sponsor(&sender)499 }500501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 #[weight = T::CommonWeightInfo::create_item()]520 pub fn create_item(origin, collection_id: CollectionId, owner: T::CrossAccountId, data: CreateItemData) -> DispatchResultWithPostInfo {521 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);522 let budget = budget::Value::new(NESTING_BUDGET);523524 dispatch_tx::<T, _>(collection_id, |d| d.create_item(sender, owner, data, &budget))525 }526527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 #[weight = T::CommonWeightInfo::create_multiple_items(&items_data)]546 pub fn create_multiple_items(origin, collection_id: CollectionId, owner: T::CrossAccountId, items_data: Vec<CreateItemData>) -> DispatchResultWithPostInfo {547 ensure!(!items_data.is_empty(), Error::<T>::EmptyArgument);548 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);549 let budget = budget::Value::new(NESTING_BUDGET);550551 dispatch_tx::<T, _>(collection_id, |d| d.create_multiple_items(sender, owner, items_data, &budget))552 }553554 555 556 557 558 559 560 561 562 563 564 565 566 #[weight = T::CommonWeightInfo::set_collection_properties(properties.len() as u32)]567 pub fn set_collection_properties(568 origin,569 collection_id: CollectionId,570 properties: Vec<Property>571 ) -> DispatchResultWithPostInfo {572 ensure!(!properties.is_empty(), Error::<T>::EmptyArgument);573574 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);575576 dispatch_tx::<T, _>(collection_id, |d| d.set_collection_properties(sender, properties))577 }578579 580 581 582 583 584 585 586 587 588 589 590 591 #[weight = T::CommonWeightInfo::delete_collection_properties(property_keys.len() as u32)]592 pub fn delete_collection_properties(593 origin,594 collection_id: CollectionId,595 property_keys: Vec<PropertyKey>,596 ) -> DispatchResultWithPostInfo {597 ensure!(!property_keys.is_empty(), Error::<T>::EmptyArgument);598599 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);600601 dispatch_tx::<T, _>(collection_id, |d| d.delete_collection_properties(&sender, property_keys))602 }603604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 #[weight = T::CommonWeightInfo::set_token_properties(properties.len() as u32)]623 pub fn set_token_properties(624 origin,625 collection_id: CollectionId,626 token_id: TokenId,627 properties: Vec<Property>628 ) -> DispatchResultWithPostInfo {629 ensure!(!properties.is_empty(), Error::<T>::EmptyArgument);630631 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);632 let budget = budget::Value::new(NESTING_BUDGET);633634 dispatch_tx::<T, _>(collection_id, |d| d.set_token_properties(sender, token_id, properties, &budget))635 }636637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 #[weight = T::CommonWeightInfo::delete_token_properties(property_keys.len() as u32)]653 pub fn delete_token_properties(654 origin,655 collection_id: CollectionId,656 token_id: TokenId,657 property_keys: Vec<PropertyKey>658 ) -> DispatchResultWithPostInfo {659 ensure!(!property_keys.is_empty(), Error::<T>::EmptyArgument);660661 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);662 let budget = budget::Value::new(NESTING_BUDGET);663664 dispatch_tx::<T, _>(collection_id, |d| d.delete_token_properties(sender, token_id, property_keys, &budget))665 }666667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 #[weight = T::CommonWeightInfo::set_token_property_permissions(property_permissions.len() as u32)]683 pub fn set_token_property_permissions(684 origin,685 collection_id: CollectionId,686 property_permissions: Vec<PropertyKeyPermission>,687 ) -> DispatchResultWithPostInfo {688 ensure!(!property_permissions.is_empty(), Error::<T>::EmptyArgument);689690 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);691692 dispatch_tx::<T, _>(collection_id, |d| d.set_token_property_permissions(&sender, property_permissions))693 }694695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 #[weight = T::CommonWeightInfo::create_multiple_items_ex(&data)]711 pub fn create_multiple_items_ex(origin, collection_id: CollectionId, data: CreateItemExData<T::CrossAccountId>) -> DispatchResultWithPostInfo {712 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);713 let budget = budget::Value::new(NESTING_BUDGET);714715 dispatch_tx::<T, _>(collection_id, |d| d.create_multiple_items_ex(sender, data, &budget))716 }717718 719 720 721 722 723 724 725 726 727 728 #[weight = <SelfWeightOf<T>>::set_transfers_enabled_flag()]729 pub fn set_transfers_enabled_flag(origin, collection_id: CollectionId, value: bool) -> DispatchResult {730 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);731 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;732 target_collection.check_is_internal()?;733 target_collection.check_is_owner(&sender)?;734735 736737 target_collection.limits.transfers_enabled = Some(value);738 target_collection.save()739 }740741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 #[weight = T::CommonWeightInfo::burn_item()]758 pub fn burn_item(origin, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResultWithPostInfo {759 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);760761 let post_info = dispatch_tx::<T, _>(collection_id, |d| d.burn_item(sender, item_id, value))?;762 if value == 1 {763 <NftTransferBasket<T>>::remove(collection_id, item_id);764 <NftApproveBasket<T>>::remove(collection_id, item_id);765 }766 767 768 769 Ok(post_info)770 }771772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 #[weight = T::CommonWeightInfo::burn_from()]796 pub fn burn_from(origin, collection_id: CollectionId, from: T::CrossAccountId, item_id: TokenId, value: u128) -> DispatchResultWithPostInfo {797 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);798 let budget = budget::Value::new(NESTING_BUDGET);799800 dispatch_tx::<T, _>(collection_id, |d| d.burn_from(sender, from, item_id, value, &budget))801 }802803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 #[weight = T::CommonWeightInfo::transfer()]825 pub fn transfer(origin, recipient: T::CrossAccountId, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResultWithPostInfo {826 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);827 let budget = budget::Value::new(NESTING_BUDGET);828829 dispatch_tx::<T, _>(collection_id, |d| d.transfer(sender, recipient, item_id, value, &budget))830 }831832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 #[weight = T::CommonWeightInfo::approve()]848 pub fn approve(origin, spender: T::CrossAccountId, collection_id: CollectionId, item_id: TokenId, amount: u128) -> DispatchResultWithPostInfo {849 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);850851 dispatch_tx::<T, _>(collection_id, |d| d.approve(sender, spender, item_id, amount))852 }853854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 #[weight = T::CommonWeightInfo::transfer_from()]879 pub fn transfer_from(origin, from: T::CrossAccountId, recipient: T::CrossAccountId, collection_id: CollectionId, item_id: TokenId, value: u128 ) -> DispatchResultWithPostInfo {880 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);881 let budget = budget::Value::new(NESTING_BUDGET);882883 dispatch_tx::<T, _>(collection_id, |d| d.transfer_from(sender, from, recipient, item_id, value, &budget))884 }885886 887 888 889 890 891 892 893 894 895 896 897 898 #[weight = <SelfWeightOf<T>>::set_collection_limits()]899 pub fn set_collection_limits(900 origin,901 collection_id: CollectionId,902 new_limit: CollectionLimits,903 ) -> DispatchResult {904 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);905 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;906 <PalletCommon<T>>::update_limits(&sender, &mut target_collection, new_limit)907 }908909 910 911 912 913 914 915 916 917 918 919 920 921 #[weight = <SelfWeightOf<T>>::set_collection_limits()]922 pub fn set_collection_permissions(923 origin,924 collection_id: CollectionId,925 new_permission: CollectionPermissions,926 ) -> DispatchResult {927 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);928 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;929 <PalletCommon<T>>::update_permissions(930 &sender,931 &mut target_collection,932 new_permission933 )934 }935936 937 938 939 940 941 942 943 944 945 946 947 #[weight = T::RefungibleExtensionsWeightInfo::repartition()]948 pub fn repartition(949 origin,950 collection_id: CollectionId,951 token_id: TokenId,952 amount: u128,953 ) -> DispatchResultWithPostInfo {954 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);955 dispatch_tx::<T, _>(collection_id, |d| {956 if let Some(refungible_extensions) = d.refungible_extensions() {957 refungible_extensions.repartition(&sender, token_id, amount)958 } else {959 fail!(<Error<T>>::RepartitionCalledOnNonRefungibleCollection)960 }961 })962 }963964 965 966 967 968 969 970 971 972 973 #[weight = T::CommonWeightInfo::set_allowance_for_all()]974 pub fn set_allowance_for_all(975 origin,976 collection_id: CollectionId,977 operator: T::CrossAccountId,978 approve: bool,979 ) -> DispatchResultWithPostInfo {980 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);981 dispatch_tx::<T, _>(collection_id, |d| {982 d.set_allowance_for_all(sender, operator, approve)983 })984 }985 }986}987988impl<T: Config> Pallet<T> {989 990 991 992 993 994 995 996 997 998 pub fn force_set_sponsor(sponsor: T::AccountId, collection_id: CollectionId) -> DispatchResult {999 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;1000 target_collection.force_set_sponsor(sponsor.clone())1001 }10021003 1004 1005 1006 1007 1008 1009 1010 1011 pub fn force_remove_collection_sponsor(collection_id: CollectionId) -> DispatchResult {1012 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;1013 target_collection.force_remove_sponsor()1014 }10151016 #[inline(always)]1017 pub(crate) fn destroy_collection_internal(1018 sender: T::CrossAccountId,1019 collection_id: CollectionId,1020 ) -> DispatchResult {1021 let collection = <CollectionHandle<T>>::try_get(collection_id)?;1022 collection.check_is_internal()?;10231024 T::CollectionDispatch::destroy(sender, collection)?;10251026 1027 10281029 let _ = <NftTransferBasket<T>>::clear_prefix(collection_id, u32::MAX, None);1030 let _ = <FungibleTransferBasket<T>>::clear_prefix(collection_id, u32::MAX, None);1031 let _ = <ReFungibleTransferBasket<T>>::clear_prefix((collection_id,), u32::MAX, None);10321033 let _ = <NftApproveBasket<T>>::clear_prefix(collection_id, u32::MAX, None);1034 let _ = <FungibleApproveBasket<T>>::clear_prefix(collection_id, u32::MAX, None);1035 let _ = <RefungibleApproveBasket<T>>::clear_prefix((collection_id,), u32::MAX, None);10361037 Ok(())1038 }1039}