123456#![recursion_limit = "1024"]7#![cfg_attr(not(feature = "std"), no_std)]8#![allow(9 clippy::too_many_arguments,10 clippy::unnecessary_mut_passed,11 clippy::unused_unit12)]1314extern crate alloc;1516pub use serde::{Serialize, Deserialize};1718pub use frame_support::{19 construct_runtime, decl_module, decl_storage, decl_error, decl_event,20 dispatch::DispatchResult,21 ensure, fail, parameter_types,22 traits::{23 ExistenceRequirement, Get, Imbalance, KeyOwnerProofSystem, OnUnbalanced, Randomness,24 IsSubType, WithdrawReasons,25 },26 weights::{27 constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},28 DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight,29 WeightToFeePolynomial, DispatchClass,30 },31 StorageValue, transactional,32 pallet_prelude::{DispatchResultWithPostInfo, ConstU32},33 BoundedVec,34};35use scale_info::TypeInfo;36use frame_system::{self as system, ensure_signed};37use sp_runtime::{sp_std::prelude::Vec};38use up_data_structs::{39 MAX_DECIMAL_POINTS, MAX_SPONSOR_TIMEOUT, MAX_TOKEN_OWNERSHIP, CUSTOM_DATA_LIMIT,40 VARIABLE_ON_CHAIN_SCHEMA_LIMIT, CONST_ON_CHAIN_SCHEMA_LIMIT, OFFCHAIN_SCHEMA_LIMIT,41 FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,42 NFT_SPONSOR_TRANSFER_TIMEOUT, MAX_COLLECTION_NAME_LENGTH, MAX_COLLECTION_DESCRIPTION_LENGTH,43 MAX_TOKEN_PREFIX_LENGTH, AccessMode, Collection, CreateItemData, CollectionLimits,44 CollectionId, CollectionMode, TokenId, SchemaVersion, SponsorshipState, MetaUpdatePermission,45 CustomDataLimit,46};47use pallet_common::{48 account::CrossAccountId, CollectionHandle, Pallet as PalletCommon, Error as CommonError,49 CommonWeightInfo,50};51use pallet_refungible::{Pallet as PalletRefungible, RefungibleHandle};52use pallet_fungible::{Pallet as PalletFungible, FungibleHandle};53use pallet_nonfungible::{Pallet as PalletNonfungible, NonfungibleHandle};5455#[cfg(test)]56mod mock;5758#[cfg(test)]59mod tests;6061mod eth;62mod sponsorship;63pub use sponsorship::UniqueSponsorshipHandler;64pub use eth::sponsoring::UniqueEthSponsorshipHandler;6566pub use eth::UniqueErcSupport;6768pub mod common;69use common::CommonWeights;70pub mod dispatch;71use dispatch::dispatch_call;7273#[cfg(feature = "runtime-benchmarks")]74mod benchmarking;75pub mod weights;76use weights::WeightInfo;7778decl_error! {79 80 pub enum Error for Module<T: Config> {81 82 CollectionDecimalPointLimitExceeded,83 84 ConfirmUnsetSponsorFail,85 86 EmptyArgument,87 88 CollectionLimitBoundsExceeded,89 90 OwnerPermissionsCantBeReverted,91 }92}9394pub trait Config:95 system::Config96 + pallet_evm_coder_substrate::Config97 + pallet_common::Config98 + pallet_nonfungible::Config99 + pallet_refungible::Config100 + pallet_fungible::Config101 + Sized102 + TypeInfo103{104 type Event: From<Event<Self>> + Into<<Self as frame_system::Config>::Event>;105106 107 type WeightInfo: WeightInfo;108}109110decl_event! {111 pub enum Event<T>112 where113 <T as frame_system::Config>::AccountId,114 <T as pallet_common::Config>::CrossAccountId,115 {116 117 118 119 120 121 CollectionSponsorRemoved(CollectionId),122123 124 125 126 127 128 129 130 CollectionAdminAdded(CollectionId, CrossAccountId),131132 133 134 135 136 137 138 139 CollectionOwnedChanged(CollectionId, AccountId),140141 142 143 144 145 146 147 148 CollectionSponsorSet(CollectionId, AccountId),149150 151 152 153 154 155 ConstOnChainSchemaSet(CollectionId),156157 158 159 160 161 162 163 164 SponsorshipConfirmed(CollectionId, AccountId),165166 167 168 169 170 171 172 173 CollectionAdminRemoved(CollectionId, CrossAccountId),174175 176 177 178 179 180 181 182 AllowListAddressRemoved(CollectionId, CrossAccountId),183184 185 186 187 188 189 190 191 AllowListAddressAdded(CollectionId, CrossAccountId),192193 194 195 196 197 198 CollectionLimitSet(CollectionId),199200 201 202 203 204 205 MintPermissionSet(CollectionId),206207 208 209 210 211 212 OffchainSchemaSet(CollectionId),213214 215 216 217 218 219 220 221 PublicAccessModeSet(CollectionId, AccessMode),222223 224 225 226 227 228 SchemaVersionSet(CollectionId),229230 231 232 233 234 235 VariableOnChainSchemaSet(CollectionId),236 }237}238239type SelfWeightOf<T> = <T as Config>::WeightInfo;240241242243244245246247248249250251252253254255256257258259260261262263decl_storage! {264 trait Store for Module<T: Config> as Unique {265266 267 268 ChainVersion: u64;269 270271 272 273 274 pub CreateItemBasket get(fn create_item_basket): map hasher(blake2_128_concat) (CollectionId, T::AccountId) => Option<T::BlockNumber>;275 276 pub NftTransferBasket get(fn nft_transfer_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => Option<T::BlockNumber>;277 278 pub FungibleTransferBasket get(fn fungible_transfer_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(twox_64_concat) T::AccountId => Option<T::BlockNumber>;279 280 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>;281 282283 284 285 pub VariableMetaDataBasket get(fn variable_meta_data_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => Option<T::BlockNumber>;286 287 pub NftApproveBasket get(fn nft_approve_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => Option<T::BlockNumber>;288 pub FungibleApproveBasket get(fn fungible_approve_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(twox_64_concat) T::AccountId => Option<T::BlockNumber>;289 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>;290 }291}292293decl_module! {294 pub struct Module<T: Config> for enum Call295 where296 origin: T::Origin297 {298 type Error = Error<T>;299300 fn deposit_event() = default;301302 fn on_initialize(_now: T::BlockNumber) -> Weight {303 0304 }305306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 #[weight = <SelfWeightOf<T>>::create_collection()]323 #[transactional]324 pub fn create_collection(origin,325 collection_name: BoundedVec<u16, ConstU32<MAX_COLLECTION_NAME_LENGTH>>,326 collection_description: BoundedVec<u16, ConstU32<MAX_COLLECTION_DESCRIPTION_LENGTH>>,327 token_prefix: BoundedVec<u8, ConstU32<MAX_TOKEN_PREFIX_LENGTH>>,328 mode: CollectionMode) -> DispatchResult {329330 331 let who = ensure_signed(origin)?;332333 334 let new_collection = Collection {335 owner: who,336 name: collection_name,337 mode: mode.clone(),338 mint_mode: false,339 access: AccessMode::Normal,340 description: collection_description,341 token_prefix,342 offchain_schema: BoundedVec::default(),343 schema_version: SchemaVersion::ImageURL,344 sponsorship: SponsorshipState::Disabled,345 variable_on_chain_schema: BoundedVec::default(),346 const_on_chain_schema: BoundedVec::default(),347 limits: Default::default(),348 meta_update_permission: Default::default(),349 };350351 let _id = match mode {352 CollectionMode::NFT => {<PalletNonfungible<T>>::init_collection(new_collection)?},353 CollectionMode::Fungible(decimal_points) => {354 355 ensure!(decimal_points <= MAX_DECIMAL_POINTS, Error::<T>::CollectionDecimalPointLimitExceeded);356 <PalletFungible<T>>::init_collection(new_collection)?357 }358 CollectionMode::ReFungible => {359 <PalletRefungible<T>>::init_collection(new_collection)?360 }361 };362363 Ok(())364 }365366 367 368 369 370 371 372 373 374 375 #[weight = <SelfWeightOf<T>>::destroy_collection()]376 #[transactional]377 pub fn destroy_collection(origin, collection_id: CollectionId) -> DispatchResult {378 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);379380 let collection = <CollectionHandle<T>>::try_get(collection_id)?;381 collection.check_is_owner(&sender)?;382383 384385 match collection.mode {386 CollectionMode::ReFungible => PalletRefungible::destroy_collection(RefungibleHandle::cast(collection), &sender)?,387 CollectionMode::Fungible(_) => PalletFungible::destroy_collection(FungibleHandle::cast(collection), &sender)?,388 CollectionMode::NFT => PalletNonfungible::destroy_collection(NonfungibleHandle::cast(collection), &sender)?,389 }390391 <NftTransferBasket<T>>::remove_prefix(collection_id, None);392 <FungibleTransferBasket<T>>::remove_prefix(collection_id, None);393 <ReFungibleTransferBasket<T>>::remove_prefix((collection_id,), None);394395 <VariableMetaDataBasket<T>>::remove_prefix(collection_id, None);396 <NftApproveBasket<T>>::remove_prefix(collection_id, None);397 <FungibleApproveBasket<T>>::remove_prefix(collection_id, None);398 <RefungibleApproveBasket<T>>::remove_prefix((collection_id,), None);399400 Ok(())401 }402403 404 405 406 407 408 409 410 411 412 413 414 415 #[weight = <SelfWeightOf<T>>::add_to_allow_list()]416 #[transactional]417 pub fn add_to_allow_list(origin, collection_id: CollectionId, address: T::CrossAccountId) -> DispatchResult{418419 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);420 let collection = <CollectionHandle<T>>::try_get(collection_id)?;421422 <PalletCommon<T>>::toggle_allowlist(423 &collection,424 &sender,425 &address,426 true,427 )?;428429 Self::deposit_event(Event::<T>::AllowListAddressAdded(430 collection_id,431 address432 ));433434 Ok(())435 }436437 438 439 440 441 442 443 444 445 446 447 448 449 #[weight = <SelfWeightOf<T>>::remove_from_allow_list()]450 #[transactional]451 pub fn remove_from_allow_list(origin, collection_id: CollectionId, address: T::CrossAccountId) -> DispatchResult{452453 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);454 let collection = <CollectionHandle<T>>::try_get(collection_id)?;455456 <PalletCommon<T>>::toggle_allowlist(457 &collection,458 &sender,459 &address,460 false,461 )?;462463 <Pallet<T>>::deposit_event(Event::<T>::AllowListAddressRemoved(464 collection_id,465 address466 ));467468 Ok(())469 }470471 472 473 474 475 476 477 478 479 480 481 482 #[weight = <SelfWeightOf<T>>::set_public_access_mode()]483 #[transactional]484 pub fn set_public_access_mode(origin, collection_id: CollectionId, mode: AccessMode) -> DispatchResult485 {486 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);487488 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;489 target_collection.check_is_owner(&sender)?;490491 target_collection.access = mode.clone();492493 <Pallet<T>>::deposit_event(Event::<T>::PublicAccessModeSet(494 collection_id,495 mode496 ));497498 target_collection.save()499 }500501 502 503 504 505 506 507 508 509 510 511 512 513 514 #[weight = <SelfWeightOf<T>>::set_mint_permission()]515 #[transactional]516 pub fn set_mint_permission(origin, collection_id: CollectionId, mint_permission: bool) -> DispatchResult517 {518 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);519520 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;521 target_collection.check_is_owner(&sender)?;522523 target_collection.mint_mode = mint_permission;524525 <Pallet<T>>::deposit_event(Event::<T>::MintPermissionSet(526 collection_id527 ));528529 target_collection.save()530 }531532 533 534 535 536 537 538 539 540 541 542 543 #[weight = <SelfWeightOf<T>>::change_collection_owner()]544 #[transactional]545 pub fn change_collection_owner(origin, collection_id: CollectionId, new_owner: T::AccountId) -> DispatchResult {546547 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);548549 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;550 target_collection.check_is_owner(&sender)?;551552 target_collection.owner = new_owner.clone();553 <Pallet<T>>::deposit_event(Event::<T>::CollectionOwnedChanged(554 collection_id,555 new_owner556 ));557558 target_collection.save()559 }560561 562 563 564 565 566 567 568 569 570 571 572 573 574 #[weight = <SelfWeightOf<T>>::add_collection_admin()]575 #[transactional]576 pub fn add_collection_admin(origin, collection_id: CollectionId, new_admin_id: T::CrossAccountId) -> DispatchResult {577 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);578 let collection = <CollectionHandle<T>>::try_get(collection_id)?;579580 <Pallet<T>>::deposit_event(Event::<T>::CollectionAdminAdded(581 collection_id,582 new_admin_id.clone()583 ));584585 <PalletCommon<T>>::toggle_admin(&collection, &sender, &new_admin_id, true)586 }587588 589 590 591 592 593 594 595 596 597 598 599 600 #[weight = <SelfWeightOf<T>>::remove_collection_admin()]601 #[transactional]602 pub fn remove_collection_admin(origin, collection_id: CollectionId, account_id: T::CrossAccountId) -> DispatchResult {603 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);604 let collection = <CollectionHandle<T>>::try_get(collection_id)?;605606 <Pallet<T>>::deposit_event(Event::<T>::CollectionAdminRemoved(607 collection_id,608 account_id.clone()609 ));610611 <PalletCommon<T>>::toggle_admin(&collection, &sender, &account_id, false)612 }613614 615 616 617 618 619 620 621 622 623 #[weight = <SelfWeightOf<T>>::set_collection_sponsor()]624 #[transactional]625 pub fn set_collection_sponsor(origin, collection_id: CollectionId, new_sponsor: T::AccountId) -> DispatchResult {626 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);627628 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;629 target_collection.check_is_owner(&sender)?;630631 target_collection.sponsorship = SponsorshipState::Unconfirmed(new_sponsor.clone());632633 <Pallet<T>>::deposit_event(Event::<T>::CollectionSponsorSet(634 collection_id,635 new_sponsor636 ));637638 target_collection.save()639 }640641 642 643 644 645 646 647 648 #[weight = <SelfWeightOf<T>>::confirm_sponsorship()]649 #[transactional]650 pub fn confirm_sponsorship(origin, collection_id: CollectionId) -> DispatchResult {651 let sender = ensure_signed(origin)?;652653 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;654 ensure!(655 target_collection.sponsorship.pending_sponsor() == Some(&sender),656 Error::<T>::ConfirmUnsetSponsorFail657 );658659 target_collection.sponsorship = SponsorshipState::Confirmed(sender.clone());660661 <Pallet<T>>::deposit_event(Event::<T>::SponsorshipConfirmed(662 collection_id,663 sender664 ));665666 target_collection.save()667 }668669 670 671 672 673 674 675 676 677 678 #[weight = <SelfWeightOf<T>>::remove_collection_sponsor()]679 #[transactional]680 pub fn remove_collection_sponsor(origin, collection_id: CollectionId) -> DispatchResult {681 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);682683 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;684 target_collection.check_is_owner(&sender)?;685686 target_collection.sponsorship = SponsorshipState::Disabled;687688 <Pallet<T>>::deposit_event(Event::<T>::CollectionSponsorRemoved(689 collection_id690 ));691 target_collection.save()692 }693694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 #[weight = <CommonWeights<T>>::create_item()]713 #[transactional]714 pub fn create_item(origin, collection_id: CollectionId, owner: T::CrossAccountId, data: CreateItemData) -> DispatchResultWithPostInfo {715 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);716717 dispatch_call::<T, _>(collection_id, |d| d.create_item(sender, owner, data))718 }719720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 #[weight = <CommonWeights<T>>::create_multiple_items(items_data.len() as u32)]739 #[transactional]740 pub fn create_multiple_items(origin, collection_id: CollectionId, owner: T::CrossAccountId, items_data: Vec<CreateItemData>) -> DispatchResultWithPostInfo {741 ensure!(!items_data.is_empty(), Error::<T>::EmptyArgument);742 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);743744 dispatch_call::<T, _>(collection_id, |d| d.create_multiple_items(sender, owner, items_data))745 }746747 748749 750 751 752 753 754 755 756 757 758 759 760 #[weight = <SelfWeightOf<T>>::set_transfers_enabled_flag()]761 #[transactional]762 pub fn set_transfers_enabled_flag(origin, collection_id: CollectionId, value: bool) -> DispatchResult {763 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);764 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;765 target_collection.check_is_owner(&sender)?;766767 768769 target_collection.limits.transfers_enabled = Some(value);770 target_collection.save()771 }772773 774 775 776 777 778 779 780 781 782 783 784 785 786 #[weight = <CommonWeights<T>>::burn_item()]787 #[transactional]788 pub fn burn_item(origin, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResultWithPostInfo {789 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);790791 let post_info = dispatch_call::<T, _>(collection_id, |d| d.burn_item(sender, item_id, value))?;792 if value == 1 {793 <NftTransferBasket<T>>::remove(collection_id, item_id);794 <NftApproveBasket<T>>::remove(collection_id, item_id);795 }796 797 798 799 Ok(post_info)800 }801802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 #[weight = <CommonWeights<T>>::burn_from()]819 #[transactional]820 pub fn burn_from(origin, collection_id: CollectionId, from: T::CrossAccountId, item_id: TokenId, value: u128) -> DispatchResultWithPostInfo {821 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);822823 dispatch_call::<T, _>(collection_id, |d| d.burn_from(sender, from, item_id, value))824 }825826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 #[weight = <CommonWeights<T>>::transfer()]850 #[transactional]851 pub fn transfer(origin, recipient: T::CrossAccountId, collection_id: CollectionId, item_id: TokenId, value: u128) -> DispatchResultWithPostInfo {852 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);853854 dispatch_call::<T, _>(collection_id, |d| d.transfer(sender, recipient, item_id, value))855 }856857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 #[weight = <CommonWeights<T>>::approve()]873 #[transactional]874 pub fn approve(origin, spender: T::CrossAccountId, collection_id: CollectionId, item_id: TokenId, amount: u128) -> DispatchResultWithPostInfo {875 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);876877 dispatch_call::<T, _>(collection_id, |d| d.approve(sender, spender, item_id, amount))878 }879880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 #[weight = <CommonWeights<T>>::transfer_from()]900 #[transactional]901 pub fn transfer_from(origin, from: T::CrossAccountId, recipient: T::CrossAccountId, collection_id: CollectionId, item_id: TokenId, value: u128 ) -> DispatchResultWithPostInfo {902 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);903904 dispatch_call::<T, _>(collection_id, |d| d.transfer_from(sender, from, recipient, item_id, value))905 }906907 908 909 910 911 912 913 914 915 916 917 918 919 #[weight = <CommonWeights<T>>::set_variable_metadata(data.len() as u32)]920 #[transactional]921 pub fn set_variable_meta_data (922 origin,923 collection_id: CollectionId,924 item_id: TokenId,925 data: BoundedVec<u8, CustomDataLimit>,926 ) -> DispatchResultWithPostInfo {927 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);928929 dispatch_call::<T, _>(collection_id, |d| d.set_variable_metadata(sender, item_id, data))930 }931932 933 934 935 936 937 938 939 940 941 942 943 #[weight = <SelfWeightOf<T>>::set_meta_update_permission_flag()]944 #[transactional]945 pub fn set_meta_update_permission_flag(origin, collection_id: CollectionId, value: MetaUpdatePermission) -> DispatchResult {946 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);947 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;948949 ensure!(950 target_collection.meta_update_permission != MetaUpdatePermission::None,951 <CommonError<T>>::MetadataFlagFrozen,952 );953 target_collection.check_is_owner(&sender)?;954955 target_collection.meta_update_permission = value;956957 target_collection.save()958 }959960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 #[weight = <SelfWeightOf<T>>::set_schema_version()]975 #[transactional]976 pub fn set_schema_version(977 origin,978 collection_id: CollectionId,979 version: SchemaVersion980 ) -> DispatchResult {981 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);982 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;983 target_collection.check_is_owner_or_admin(&sender)?;984 target_collection.schema_version = version;985986 <Pallet<T>>::deposit_event(Event::<T>::SchemaVersionSet(987 collection_id988 ));989990 target_collection.save()991 }992993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 #[weight = <SelfWeightOf<T>>::set_offchain_schema(schema.len() as u32)]1006 #[transactional]1007 pub fn set_offchain_schema(1008 origin,1009 collection_id: CollectionId,1010 schema: BoundedVec<u8, ConstU32<OFFCHAIN_SCHEMA_LIMIT>>,1011 ) -> DispatchResult {1012 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);1013 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;1014 target_collection.check_is_owner_or_admin(&sender)?;10151016 target_collection.offchain_schema = schema;10171018 <Pallet<T>>::deposit_event(Event::<T>::OffchainSchemaSet(1019 collection_id1020 ));10211022 target_collection.save()1023 }10241025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 #[weight = <SelfWeightOf<T>>::set_const_on_chain_schema(schema.len() as u32)]1038 #[transactional]1039 pub fn set_const_on_chain_schema (1040 origin,1041 collection_id: CollectionId,1042 schema: BoundedVec<u8, ConstU32<CONST_ON_CHAIN_SCHEMA_LIMIT>>1043 ) -> DispatchResult {1044 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);1045 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;1046 target_collection.check_is_owner_or_admin(&sender)?;10471048 target_collection.const_on_chain_schema = schema;10491050 <Pallet<T>>::deposit_event(Event::<T>::ConstOnChainSchemaSet(1051 collection_id1052 ));10531054 target_collection.save()1055 }10561057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 #[weight = <SelfWeightOf<T>>::set_const_on_chain_schema(schema.len() as u32)]1070 #[transactional]1071 pub fn set_variable_on_chain_schema (1072 origin,1073 collection_id: CollectionId,1074 schema: BoundedVec<u8, ConstU32<VARIABLE_ON_CHAIN_SCHEMA_LIMIT>>1075 ) -> DispatchResult {1076 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);1077 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;1078 target_collection.check_is_owner_or_admin(&sender)?;10791080 target_collection.variable_on_chain_schema = schema;10811082 <Pallet<T>>::deposit_event(Event::<T>::VariableOnChainSchemaSet(1083 collection_id1084 ));10851086 target_collection.save()1087 }10881089 #[weight = <SelfWeightOf<T>>::set_collection_limits()]1090 #[transactional]1091 pub fn set_collection_limits(1092 origin,1093 collection_id: CollectionId,1094 new_limit: CollectionLimits,1095 ) -> DispatchResult {1096 let mut new_limit = new_limit;1097 let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);1098 let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;1099 target_collection.check_is_owner(&sender)?;1100 let old_limit = &target_collection.limits;11011102 macro_rules! limit_default {1103 ($old:ident, $new:ident, $($field:ident $(($arg:expr))? => $check:expr),* $(,)?) => {{1104 $(1105 if let Some($new) = $new.$field {1106 let $old = $old.$field($($arg)?);1107 let _ = $new;1108 let _ = $old;1109 $check1110 } else {1111 $new.$field = $old.$field1112 }1113 )*1114 }};1115 }11161117 limit_default!(old_limit, new_limit,1118 account_token_ownership_limit => ensure!(1119 new_limit <= MAX_TOKEN_OWNERSHIP,1120 <Error<T>>::CollectionLimitBoundsExceeded,1121 ),1122 sponsor_transfer_timeout(match target_collection.mode {1123 CollectionMode::NFT => NFT_SPONSOR_TRANSFER_TIMEOUT,1124 CollectionMode::Fungible(_) => FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,1125 CollectionMode::ReFungible => REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,1126 }) => ensure!(1127 new_limit <= MAX_SPONSOR_TIMEOUT,1128 <Error<T>>::CollectionLimitBoundsExceeded,1129 ),1130 sponsored_data_size => ensure!(1131 new_limit <= CUSTOM_DATA_LIMIT,1132 <Error<T>>::CollectionLimitBoundsExceeded,1133 ),1134 token_limit => ensure!(1135 old_limit >= new_limit && new_limit > 0,1136 <CommonError<T>>::CollectionTokenLimitExceeded1137 ),1138 owner_can_transfer => ensure!(1139 old_limit || !new_limit,1140 <Error<T>>::OwnerPermissionsCantBeReverted,1141 ),1142 owner_can_destroy => ensure!(1143 old_limit || !new_limit,1144 <Error<T>>::OwnerPermissionsCantBeReverted,1145 ),1146 sponsored_data_rate_limit => {},1147 transfers_enabled => {},1148 );11491150 target_collection.limits = new_limit;11511152 <Pallet<T>>::deposit_event(Event::<T>::CollectionLimitSet(1153 collection_id1154 ));11551156 target_collection.save()1157 }1158 }1159}