1#![cfg_attr(not(feature = "std"), no_std)]23pub use serde::{Serialize, Deserialize};45use sp_runtime::sp_std::prelude::Vec;6use codec::{Decode, Encode};7pub use frame_support::{8 construct_runtime, decl_event, decl_module, decl_storage, decl_error,9 dispatch::DispatchResult,10 ensure, fail, parameter_types,11 traits::{12 Currency, ExistenceRequirement, Get, Imbalance, KeyOwnerProofSystem, OnUnbalanced,13 Randomness, IsSubType, WithdrawReasons,14 },15 weights::{16 constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},17 DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight,18 WeightToFeePolynomial, DispatchClass,19 },20 StorageValue, transactional,21};2223pub const MAX_DECIMAL_POINTS: DecimalPoints = 30;24pub const MAX_REFUNGIBLE_PIECES: u128 = 1_000_000_000_000_000_000_000;25pub const MAX_SPONSOR_TIMEOUT: u32 = 10_368_000;26pub const MAX_TOKEN_OWNERSHIP: u32 = 10_000_000;2728pub type CollectionId = u32;29pub type TokenId = u32;30pub type DecimalPoints = u8;3132#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]33#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]34pub enum CollectionMode {35 Invalid,36 NFT,37 38 Fungible(DecimalPoints),39 ReFungible,40}4142impl Default for CollectionMode {43 fn default() -> Self {44 Self::Invalid45 }46}4748impl CollectionMode {49 pub fn id(&self) -> u8 {50 match self {51 CollectionMode::Invalid => 0,52 CollectionMode::NFT => 1,53 CollectionMode::Fungible(_) => 2,54 CollectionMode::ReFungible => 3,55 }56 }57}5859pub trait SponsoringResolve<AccountId, Call> {60 fn resolve(who: &AccountId, call: &Call) -> Option<AccountId>;61}6263#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]64#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]65pub enum AccessMode {66 Normal,67 WhiteList,68}69impl Default for AccessMode {70 fn default() -> Self {71 Self::Normal72 }73}7475#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]76#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]77pub enum SchemaVersion {78 ImageURL,79 Unique,80}81impl Default for SchemaVersion {82 fn default() -> Self {83 Self::ImageURL84 }85}8687#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]88#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]89pub struct Ownership<AccountId> {90 pub owner: AccountId,91 pub fraction: u128,92}9394#[derive(Encode, Decode, Debug, Clone, PartialEq)]95#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]96pub enum SponsorshipState<AccountId> {97 98 Disabled,99 Unconfirmed(AccountId),100 101 Confirmed(AccountId),102}103104impl<AccountId> SponsorshipState<AccountId> {105 pub fn sponsor(&self) -> Option<&AccountId> {106 match self {107 Self::Confirmed(sponsor) => Some(sponsor),108 _ => None,109 }110 }111112 pub fn pending_sponsor(&self) -> Option<&AccountId> {113 match self {114 Self::Unconfirmed(sponsor) | Self::Confirmed(sponsor) => Some(sponsor),115 _ => None,116 }117 }118119 pub fn confirmed(&self) -> bool {120 matches!(self, Self::Confirmed(_))121 }122}123124impl<T> Default for SponsorshipState<T> {125 fn default() -> Self {126 Self::Disabled127 }128}129130#[derive(Encode, Decode, Clone, PartialEq)]131#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]132pub struct Collection<T: frame_system::Config> {133 pub owner: T::AccountId,134 pub mode: CollectionMode,135 pub access: AccessMode,136 pub decimal_points: DecimalPoints,137 pub name: Vec<u16>, 138 pub description: Vec<u16>, 139 pub token_prefix: Vec<u8>, 140 pub mint_mode: bool,141 pub offchain_schema: Vec<u8>,142 pub schema_version: SchemaVersion,143 pub sponsorship: SponsorshipState<T::AccountId>,144 pub limits: CollectionLimits<T::BlockNumber>, 145 pub variable_on_chain_schema: Vec<u8>, 146 pub const_on_chain_schema: Vec<u8>, 147}148149#[derive(Encode, Decode, Debug, Clone, PartialEq)]150#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]151pub struct NftItemType<AccountId> {152 pub owner: AccountId,153 pub const_data: Vec<u8>,154 pub variable_data: Vec<u8>,155}156157#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]158#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]159pub struct FungibleItemType {160 pub value: u128,161}162163#[derive(Encode, Decode, Debug, Clone, PartialEq)]164#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]165pub struct ReFungibleItemType<AccountId> {166 pub owner: Vec<Ownership<AccountId>>,167 pub const_data: Vec<u8>,168 pub variable_data: Vec<u8>,169}170171#[derive(Encode, Decode, Debug, Clone, PartialEq)]172#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]173pub struct CollectionLimits<BlockNumber: Encode + Decode> {174 pub account_token_ownership_limit: u32,175 pub sponsored_data_size: u32,176 177 178 179 pub sponsored_data_rate_limit: Option<BlockNumber>,180 pub token_limit: u32,181182 183 pub sponsor_transfer_timeout: u32,184 pub owner_can_transfer: bool,185 pub owner_can_destroy: bool,186}187188impl<BlockNumber: Encode + Decode> Default for CollectionLimits<BlockNumber> {189 fn default() -> Self {190 Self {191 account_token_ownership_limit: 10_000_000,192 token_limit: u32::max_value(),193 sponsored_data_size: u32::MAX,194 sponsored_data_rate_limit: None,195 sponsor_transfer_timeout: 14400,196 owner_can_transfer: true,197 owner_can_destroy: true,198 }199 }200}201202#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]203#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]204pub struct ChainLimits {205 pub collection_numbers_limit: u32,206 pub account_token_ownership_limit: u32,207 pub collections_admins_limit: u64,208 pub custom_data_limit: u32,209210 211 pub nft_sponsor_transfer_timeout: u32,212 pub fungible_sponsor_transfer_timeout: u32,213 pub refungible_sponsor_transfer_timeout: u32,214215 216 pub offchain_schema_limit: u32,217 pub variable_on_chain_schema_limit: u32,218 pub const_on_chain_schema_limit: u32,219}220221#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]222#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]223pub struct CreateNftData {224 pub const_data: Vec<u8>,225 pub variable_data: Vec<u8>,226}227228#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]229#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]230pub struct CreateFungibleData {231 pub value: u128,232}233234#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]235#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]236pub struct CreateReFungibleData {237 pub const_data: Vec<u8>,238 pub variable_data: Vec<u8>,239 pub pieces: u128,240}241242#[derive(Encode, Decode, Debug, Clone, PartialEq)]243#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]244pub enum CreateItemData {245 NFT(CreateNftData),246 Fungible(CreateFungibleData),247 ReFungible(CreateReFungibleData),248}249250impl CreateItemData {251 pub fn data_size(&self) -> usize {252 match self {253 CreateItemData::NFT(data) => data.variable_data.len() + data.const_data.len(),254 CreateItemData::ReFungible(data) => data.variable_data.len() + data.const_data.len(),255 _ => 0,256 }257 }258}259260impl From<CreateNftData> for CreateItemData {261 fn from(item: CreateNftData) -> Self {262 CreateItemData::NFT(item)263 }264}265266impl From<CreateReFungibleData> for CreateItemData {267 fn from(item: CreateReFungibleData) -> Self {268 CreateItemData::ReFungible(item)269 }270}271272impl From<CreateFungibleData> for CreateItemData {273 fn from(item: CreateFungibleData) -> Self {274 CreateItemData::Fungible(item)275 }276}