1#![cfg_attr(not(feature = "std"), no_std)]23use codec::{Decode, Encode};45#[cfg(feature = "std")]6use serde::{Deserialize, Serialize};78use frame_system;9use core::ops::{Deref, DerefMut};10use sp_runtime::sp_std::prelude::Vec;11pub use frame_support::{12 construct_runtime, decl_event, decl_module, decl_storage, decl_error,13 dispatch::DispatchResult,14 ensure, fail, parameter_types,15 traits::{16 Currency, ExistenceRequirement, Get, Imbalance, KeyOwnerProofSystem, OnUnbalanced,17 Randomness, IsSubType, WithdrawReasons,18 },19 weights::{20 constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},21 DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight,22 WeightToFeePolynomial, DispatchClass,23 },24 StorageValue,25 transactional,26};2728pub const MAX_DECIMAL_POINTS: DecimalPoints = 30;29pub const MAX_REFUNGIBLE_PIECES: u128 = 1_000_000_000_000_000_000_000;30pub const MAX_SPONSOR_TIMEOUT: u32 = 10_368_000;31pub const MAX_TOKEN_OWNERSHIP: u32 = 10_000_000;3233pub type CollectionId = u32;34pub type TokenId = u32;35pub type DecimalPoints = u8;3637#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]38#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]39pub enum CollectionMode {40 Invalid,41 NFT,42 43 Fungible(DecimalPoints),44 ReFungible,45}4647impl Default for CollectionMode {48 fn default() -> Self {49 Self::Invalid50 }51}5253impl Into<u8> for CollectionMode {54 fn into(self) -> u8 {55 match self {56 CollectionMode::Invalid => 0,57 CollectionMode::NFT => 1,58 CollectionMode::Fungible(_) => 2,59 CollectionMode::ReFungible => 3,60 }61 }62}6364pub trait SponsoringResolve<AccountId, Call> {65 fn resolve(66 who: &AccountId,67 call: &Call) -> Option<AccountId>;68}6970#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]71#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]72pub enum AccessMode {73 Normal,74 WhiteList,75}76impl Default for AccessMode {77 fn default() -> Self {78 Self::Normal79 }80}8182#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]83#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]84pub enum SchemaVersion {85 ImageURL,86 Unique,87}88impl Default for SchemaVersion {89 fn default() -> Self {90 Self::ImageURL91 }92}9394#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]95#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]96pub struct Ownership<AccountId> {97 pub owner: AccountId,98 pub fraction: u128,99}100101#[derive(Encode, Decode, Debug, Clone, PartialEq)]102#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]103pub enum SponsorshipState<AccountId> {104 105 Disabled,106 Unconfirmed(AccountId),107 108 Confirmed(AccountId),109}110111impl<AccountId> SponsorshipState<AccountId> {112 pub fn sponsor(&self) -> Option<&AccountId> {113 match self {114 Self::Confirmed(sponsor) => Some(sponsor),115 _ => None,116 }117 }118119 pub fn pending_sponsor(&self) -> Option<&AccountId> {120 match self {121 Self::Unconfirmed(sponsor) | Self::Confirmed(sponsor) => Some(sponsor),122 _ => None,123 }124 }125126 pub fn confirmed(&self) -> bool {127 matches!(self, Self::Confirmed(_))128 }129}130131impl<T> Default for SponsorshipState<T> {132 fn default() -> Self {133 Self::Disabled134 }135}136137#[derive(Encode, Decode, Clone, PartialEq)]138#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]139pub struct Collection<T: frame_system::Config> {140 pub owner: T::AccountId,141 pub mode: CollectionMode,142 pub access: AccessMode,143 pub decimal_points: DecimalPoints,144 pub name: Vec<u16>, 145 pub description: Vec<u16>, 146 pub token_prefix: Vec<u8>, 147 pub mint_mode: bool,148 pub offchain_schema: Vec<u8>,149 pub schema_version: SchemaVersion,150 pub sponsorship: SponsorshipState<T::AccountId>,151 pub limits: CollectionLimits<T::BlockNumber>, 152 pub variable_on_chain_schema: Vec<u8>, 153 pub const_on_chain_schema: Vec<u8>, 154}155156pub struct CollectionHandle<T: frame_system::Config> {157 pub id: CollectionId,158 pub collection: Collection<T>,159}160161impl<T: frame_system::Config> Deref for CollectionHandle<T> {162 type Target = Collection<T>;163164 fn deref(&self) -> &Self::Target {165 &self.collection166 }167}168169impl<T: frame_system::Config> DerefMut for CollectionHandle<T> {170 fn deref_mut(&mut self) -> &mut Self::Target {171 &mut self.collection172 }173}174175#[derive(Encode, Decode, Debug, Clone, PartialEq)]176#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]177pub struct NftItemType<AccountId> {178 pub owner: AccountId,179 pub const_data: Vec<u8>,180 pub variable_data: Vec<u8>,181}182183#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]184#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]185pub struct FungibleItemType {186 pub value: u128,187}188189#[derive(Encode, Decode, Debug, Clone, PartialEq)]190#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]191pub struct ReFungibleItemType<AccountId> {192 pub owner: Vec<Ownership<AccountId>>,193 pub const_data: Vec<u8>,194 pub variable_data: Vec<u8>,195}196197198#[derive(Encode, Decode, Debug, Clone, PartialEq)]199#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]200pub struct CollectionLimits<BlockNumber: Encode + Decode> {201 pub account_token_ownership_limit: u32,202 pub sponsored_data_size: u32,203 204 205 206 pub sponsored_data_rate_limit: Option<BlockNumber>,207 pub token_limit: u32,208209 210 pub sponsor_transfer_timeout: u32,211 pub owner_can_transfer: bool,212 pub owner_can_destroy: bool,213}214215impl<BlockNumber: Encode + Decode> Default for CollectionLimits<BlockNumber> {216 fn default() -> Self {217 Self { 218 account_token_ownership_limit: 10_000_000, 219 token_limit: u32::max_value(),220 sponsored_data_size: u32::MAX, 221 sponsored_data_rate_limit: None,222 sponsor_transfer_timeout: 14400,223 owner_can_transfer: true,224 owner_can_destroy: true225 }226 }227}228229#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]230#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]231pub struct ChainLimits {232 pub collection_numbers_limit: u32,233 pub account_token_ownership_limit: u32,234 pub collections_admins_limit: u64,235 pub custom_data_limit: u32,236237 238 pub nft_sponsor_transfer_timeout: u32,239 pub fungible_sponsor_transfer_timeout: u32,240 pub refungible_sponsor_transfer_timeout: u32,241242 243 pub offchain_schema_limit: u32,244 pub variable_on_chain_schema_limit: u32,245 pub const_on_chain_schema_limit: u32,246}247248249#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]250#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]251pub struct CreateNftData {252 pub const_data: Vec<u8>,253 pub variable_data: Vec<u8>,254}255256#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]257#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]258pub struct CreateFungibleData {259 pub value: u128,260}261262#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]263#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]264pub struct CreateReFungibleData {265 pub const_data: Vec<u8>,266 pub variable_data: Vec<u8>,267 pub pieces: u128,268}269270#[derive(Encode, Decode, Debug, Clone, PartialEq)]271#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]272pub enum CreateItemData {273 NFT(CreateNftData),274 Fungible(CreateFungibleData),275 ReFungible(CreateReFungibleData),276}277278impl CreateItemData {279 pub fn len(&self) -> usize {280 let len = match self {281 CreateItemData::NFT(data) => data.variable_data.len() + data.const_data.len(),282 CreateItemData::ReFungible(data) => data.variable_data.len() + data.const_data.len(),283 _ => 0284 };285 286 return len;287 }288}289290impl From<CreateNftData> for CreateItemData {291 fn from(item: CreateNftData) -> Self {292 CreateItemData::NFT(item)293 }294}295296impl From<CreateReFungibleData> for CreateItemData {297 fn from(item: CreateReFungibleData) -> Self {298 CreateItemData::ReFungible(item)299 }300}301302impl From<CreateFungibleData> for CreateItemData {303 fn from(item: CreateFungibleData) -> Self {304 CreateItemData::Fungible(item)305 }306}