git.delta.rocks / unique-network / refs/commits / feb145783dcf

difftreelog

source

primitives/nft/src/lib.rs9.9 KiBsourcehistory
1#![cfg_attr(not(feature = "std"), no_std)]23#[cfg(feature = "serde")]4pub use serde::{Serialize, Deserialize};56use sp_runtime::sp_std::prelude::Vec;7use codec::{Decode, Encode, MaxEncodedLen};8pub use frame_support::{9	BoundedVec, construct_runtime, decl_event, decl_module, decl_storage, decl_error,10	dispatch::DispatchResult,11	ensure, fail, parameter_types,12	traits::{13		Currency, ExistenceRequirement, Get, Imbalance, KeyOwnerProofSystem, OnUnbalanced,14		Randomness, IsSubType, WithdrawReasons,15	},16	weights::{17		constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},18		DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight,19		WeightToFeePolynomial, DispatchClass,20	},21	StorageValue, transactional,22};23use derivative::Derivative;24use scale_info::TypeInfo;2526pub const MAX_DECIMAL_POINTS: DecimalPoints = 30;27pub const MAX_REFUNGIBLE_PIECES: u128 = 1_000_000_000_000_000_000_000;28pub const MAX_SPONSOR_TIMEOUT: u32 = 10_368_000;29pub const MAX_TOKEN_OWNERSHIP: u32 = 10_000_000;3031pub const COLLECTION_NUMBER_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {32	10000033} else {34	1035};36pub const CUSTOM_DATA_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {37	204838} else {39	1040};41pub const COLLECTION_ADMINS_LIMIT: u64 = 5;42pub const ACCOUNT_TOKEN_OWNERSHIP_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {43	100000044} else {45	1046};4748// Timeouts for item types in passed blocks49pub const NFT_SPONSOR_TRANSFER_TIMEOUT: u32 = 5;50pub const FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT: u32 = 5;51pub const REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT: u32 = 5;5253// Schema limits54pub const OFFCHAIN_SCHEMA_LIMIT: u32 = 1024;55pub const VARIABLE_ON_CHAIN_SCHEMA_LIMIT: u32 = 1024;56pub const CONST_ON_CHAIN_SCHEMA_LIMIT: u32 = 1024;5758pub const MAX_COLLECTION_NAME_LENGTH: usize = 64;59pub const MAX_COLLECTION_DESCRIPTION_LENGTH: usize = 256;60pub const MAX_TOKEN_PREFIX_LENGTH: usize = 16;6162/// How much items can be created per single63/// create_many call64pub const MAX_ITEMS_PER_BATCH: u32 = 200;6566parameter_types! {67	pub const CustomDataLimit: u32 = CUSTOM_DATA_LIMIT;68}6970pub type CollectionId = u32;71pub type TokenId = u32;72pub type DecimalPoints = u8;7374#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq, TypeInfo)]75#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]76pub enum CollectionMode {77	NFT,78	// decimal points79	Fungible(DecimalPoints),80	ReFungible,81}8283impl CollectionMode {84	pub fn id(&self) -> u8 {85		match self {86			CollectionMode::NFT => 1,87			CollectionMode::Fungible(_) => 2,88			CollectionMode::ReFungible => 3,89		}90	}91}9293pub trait SponsoringResolve<AccountId, Call> {94	fn resolve(who: &AccountId, call: &Call) -> Option<AccountId>;95}9697#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq, TypeInfo)]98#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]99pub enum AccessMode {100	Normal,101	WhiteList,102}103impl Default for AccessMode {104	fn default() -> Self {105		Self::Normal106	}107}108109#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq, TypeInfo)]110#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]111pub enum SchemaVersion {112	ImageURL,113	Unique,114}115impl Default for SchemaVersion {116	fn default() -> Self {117		Self::ImageURL118	}119}120121#[derive(Encode, Decode, Default, Debug, Clone, PartialEq, TypeInfo)]122#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]123pub struct Ownership<AccountId> {124	pub owner: AccountId,125	pub fraction: u128,126}127128#[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo)]129#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]130pub enum SponsorshipState<AccountId> {131	/// The fees are applied to the transaction sender132	Disabled,133	Unconfirmed(AccountId),134	/// Transactions are sponsored by specified account135	Confirmed(AccountId),136}137138impl<AccountId> SponsorshipState<AccountId> {139	pub fn sponsor(&self) -> Option<&AccountId> {140		match self {141			Self::Confirmed(sponsor) => Some(sponsor),142			_ => None,143		}144	}145146	pub fn pending_sponsor(&self) -> Option<&AccountId> {147		match self {148			Self::Unconfirmed(sponsor) | Self::Confirmed(sponsor) => Some(sponsor),149			_ => None,150		}151	}152153	pub fn confirmed(&self) -> bool {154		matches!(self, Self::Confirmed(_))155	}156}157158impl<T> Default for SponsorshipState<T> {159	fn default() -> Self {160		Self::Disabled161	}162}163164#[derive(Encode, Decode, Clone, PartialEq, TypeInfo)]165#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]166pub struct Collection<T: frame_system::Config> {167	pub owner: T::AccountId,168	pub mode: CollectionMode,169	pub access: AccessMode,170	pub decimal_points: DecimalPoints,171	pub name: Vec<u16>,        // 64 include null escape char172	pub description: Vec<u16>, // 256 include null escape char173	pub token_prefix: Vec<u8>, // 16 include null escape char174	pub mint_mode: bool,175	pub offchain_schema: Vec<u8>,176	pub schema_version: SchemaVersion,177	pub sponsorship: SponsorshipState<T::AccountId>,178	pub limits: CollectionLimits<T::BlockNumber>, // Collection private restrictions179	pub variable_on_chain_schema: Vec<u8>,        //180	pub const_on_chain_schema: Vec<u8>,           //181	pub meta_update_permission: MetaUpdatePermission,182	pub transfers_enabled: bool,183}184185#[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo)]186#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]187pub struct NftItemType<AccountId> {188	pub owner: AccountId,189	pub const_data: Vec<u8>,190	pub variable_data: Vec<u8>,191}192193#[derive(Encode, Decode, Default, Debug, Clone, PartialEq, TypeInfo)]194#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]195pub struct FungibleItemType {196	pub value: u128,197}198199#[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo)]200#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]201pub struct ReFungibleItemType<AccountId> {202	pub owner: Vec<Ownership<AccountId>>,203	pub const_data: Vec<u8>,204	pub variable_data: Vec<u8>,205}206207#[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo)]208#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]209pub struct CollectionLimits<BlockNumber: Encode + Decode> {210	pub account_token_ownership_limit: u32,211	pub sponsored_data_size: u32,212	/// None - setVariableMetadata is not sponsored213	/// Some(v) - setVariableMetadata is sponsored214	///           if there is v block between txs215	pub sponsored_data_rate_limit: Option<BlockNumber>,216	pub token_limit: u32,217218	// Timeouts for item types in passed blocks219	pub sponsor_transfer_timeout: u32,220	pub owner_can_transfer: bool,221	pub owner_can_destroy: bool,222}223224impl<BlockNumber: Encode + Decode> Default for CollectionLimits<BlockNumber> {225	fn default() -> Self {226		Self {227			account_token_ownership_limit: 10_000_000,228			token_limit: u32::max_value(),229			sponsored_data_size: u32::MAX,230			sponsored_data_rate_limit: None,231			sponsor_transfer_timeout: 14400,232			owner_can_transfer: true,233			owner_can_destroy: true,234		}235	}236}237238/// BoundedVec doesn't supports serde239#[cfg(feature = "serde1")]240mod bounded_serde {241	use core::convert::TryFrom;242	use frame_support::{BoundedVec, traits::Get};243	use serde::{244		ser::{self, Serialize},245		de::{self, Deserialize, Error},246	};247	use sp_std::vec::Vec;248249	pub fn serialize<D, V, S>(value: &BoundedVec<V, S>, serializer: D) -> Result<D::Ok, D::Error>250	where251		D: ser::Serializer,252		V: Serialize,253	{254		let vec: &Vec<_> = &value;255		vec.serialize(serializer)256	}257258	pub fn deserialize<'de, D, V, S>(deserializer: D) -> Result<BoundedVec<V, S>, D::Error>259	where260		D: de::Deserializer<'de>,261		V: de::Deserialize<'de>,262		S: Get<u32>,263	{264		// TODO: Implement custom visitor, which will limit vec size at parse time? Will serde only be used by chainspec?265		let vec = <Vec<V>>::deserialize(deserializer)?;266		let len = vec.len();267		TryFrom::try_from(vec).map_err(|_| D::Error::invalid_length(len, &"lesser size"))268	}269}270271#[derive(Encode, Decode, MaxEncodedLen, Default, PartialEq, Clone, Derivative, TypeInfo)]272#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]273#[derivative(Debug)]274pub struct CreateNftData {275	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]276	#[derivative(Debug = "ignore")]277	pub const_data: BoundedVec<u8, CustomDataLimit>,278	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]279	#[derivative(Debug = "ignore")]280	pub variable_data: BoundedVec<u8, CustomDataLimit>,281}282283#[derive(Encode, Decode, MaxEncodedLen, Default, Debug, Clone, PartialEq, TypeInfo)]284#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]285pub struct CreateFungibleData {286	pub value: u128,287}288289#[derive(Encode, Decode, MaxEncodedLen, Default, PartialEq, Clone, Derivative, TypeInfo)]290#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]291#[derivative(Debug)]292pub struct CreateReFungibleData {293	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]294	#[derivative(Debug = "ignore")]295	pub const_data: BoundedVec<u8, CustomDataLimit>,296	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]297	#[derivative(Debug = "ignore")]298	pub variable_data: BoundedVec<u8, CustomDataLimit>,299	pub pieces: u128,300}301302#[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo)]303#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]304pub enum MetaUpdatePermission {305	ItemOwner,306	Admin,307	None,308}309310impl Default for MetaUpdatePermission {311	fn default() -> Self {312		Self::ItemOwner313	}314}315316#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, Debug, TypeInfo)]317#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]318pub enum CreateItemData {319	NFT(CreateNftData),320	Fungible(CreateFungibleData),321	ReFungible(CreateReFungibleData),322}323324impl CreateItemData {325	pub fn data_size(&self) -> usize {326		match self {327			CreateItemData::NFT(data) => data.variable_data.len() + data.const_data.len(),328			CreateItemData::ReFungible(data) => data.variable_data.len() + data.const_data.len(),329			_ => 0,330		}331	}332}333334impl From<CreateNftData> for CreateItemData {335	fn from(item: CreateNftData) -> Self {336		CreateItemData::NFT(item)337	}338}339340impl From<CreateReFungibleData> for CreateItemData {341	fn from(item: CreateReFungibleData) -> Self {342		CreateItemData::ReFungible(item)343	}344}345346impl From<CreateFungibleData> for CreateItemData {347	fn from(item: CreateFungibleData) -> Self {348		CreateItemData::Fungible(item)349	}350}