git.delta.rocks / unique-network / refs/commits / 41ba3ece5caf

difftreelog

source

primitives/nft/src/lib.rs9.6 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;2425pub const MAX_DECIMAL_POINTS: DecimalPoints = 30;26pub const MAX_REFUNGIBLE_PIECES: u128 = 1_000_000_000_000_000_000_000;27pub const MAX_SPONSOR_TIMEOUT: u32 = 10_368_000;28pub const MAX_TOKEN_OWNERSHIP: u32 = 10_000_000;2930pub const COLLECTION_NUMBER_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {31	10000032} else {33	1034};35pub const CUSTOM_DATA_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {36	204837} else {38	1039};40pub const COLLECTION_ADMINS_LIMIT: u64 = 5;41pub const ACCOUNT_TOKEN_OWNERSHIP_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {42	100000043} else {44	1045};4647// Timeouts for item types in passed blocks48pub const NFT_SPONSOR_TRANSFER_TIMEOUT: u32 = 5;49pub const FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT: u32 = 5;50pub const REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT: u32 = 5;5152// Schema limits53pub const OFFCHAIN_SCHEMA_LIMIT: u32 = 1024;54pub const VARIABLE_ON_CHAIN_SCHEMA_LIMIT: u32 = 1024;55pub const CONST_ON_CHAIN_SCHEMA_LIMIT: u32 = 1024;5657pub const MAX_COLLECTION_NAME_LENGTH: usize = 64;58pub const MAX_COLLECTION_DESCRIPTION_LENGTH: usize = 256;59pub const MAX_TOKEN_PREFIX_LENGTH: usize = 16;6061/// How much items can be created per single62/// create_many call63pub const MAX_ITEMS_PER_BATCH: u32 = 200;6465parameter_types! {66	pub const CustomDataLimit: u32 = CUSTOM_DATA_LIMIT;67}6869pub type CollectionId = u32;70pub type TokenId = u32;71pub type DecimalPoints = u8;7273#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]74#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]75pub enum CollectionMode {76	Invalid,77	NFT,78	// decimal points79	Fungible(DecimalPoints),80	ReFungible,81}8283impl Default for CollectionMode {84	fn default() -> Self {85		Self::Invalid86	}87}8889impl CollectionMode {90	pub fn id(&self) -> u8 {91		match self {92			CollectionMode::Invalid => 0,93			CollectionMode::NFT => 1,94			CollectionMode::Fungible(_) => 2,95			CollectionMode::ReFungible => 3,96		}97	}98}99100pub trait SponsoringResolve<AccountId, Call> {101	fn resolve(who: &AccountId, call: &Call) -> Option<AccountId>;102}103104#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]105#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]106pub enum AccessMode {107	Normal,108	WhiteList,109}110impl Default for AccessMode {111	fn default() -> Self {112		Self::Normal113	}114}115116#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]117#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]118pub enum SchemaVersion {119	ImageURL,120	Unique,121}122impl Default for SchemaVersion {123	fn default() -> Self {124		Self::ImageURL125	}126}127128#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]129#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]130pub struct Ownership<AccountId> {131	pub owner: AccountId,132	pub fraction: u128,133}134135#[derive(Encode, Decode, Debug, Clone, PartialEq)]136#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]137pub enum SponsorshipState<AccountId> {138	/// The fees are applied to the transaction sender139	Disabled,140	Unconfirmed(AccountId),141	/// Transactions are sponsored by specified account142	Confirmed(AccountId),143}144145impl<AccountId> SponsorshipState<AccountId> {146	pub fn sponsor(&self) -> Option<&AccountId> {147		match self {148			Self::Confirmed(sponsor) => Some(sponsor),149			_ => None,150		}151	}152153	pub fn pending_sponsor(&self) -> Option<&AccountId> {154		match self {155			Self::Unconfirmed(sponsor) | Self::Confirmed(sponsor) => Some(sponsor),156			_ => None,157		}158	}159160	pub fn confirmed(&self) -> bool {161		matches!(self, Self::Confirmed(_))162	}163}164165impl<T> Default for SponsorshipState<T> {166	fn default() -> Self {167		Self::Disabled168	}169}170171#[derive(Encode, Decode, Clone, PartialEq)]172#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]173pub struct Collection<T: frame_system::Config> {174	pub owner: T::AccountId,175	pub mode: CollectionMode,176	pub access: AccessMode,177	pub decimal_points: DecimalPoints,178	pub name: Vec<u16>,        // 64 include null escape char179	pub description: Vec<u16>, // 256 include null escape char180	pub token_prefix: Vec<u8>, // 16 include null escape char181	pub mint_mode: bool,182	pub offchain_schema: Vec<u8>,183	pub schema_version: SchemaVersion,184	pub sponsorship: SponsorshipState<T::AccountId>,185	pub limits: CollectionLimits<T::BlockNumber>, // Collection private restrictions186	pub variable_on_chain_schema: Vec<u8>,        //187	pub const_on_chain_schema: Vec<u8>,           //188	pub transfers_enabled: bool,189}190191#[derive(Encode, Decode, Debug, Clone, PartialEq)]192#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]193pub struct NftItemType<AccountId> {194	pub owner: AccountId,195	pub const_data: Vec<u8>,196	pub variable_data: Vec<u8>,197}198199#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]200#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]201pub struct FungibleItemType {202	pub value: u128,203}204205#[derive(Encode, Decode, Debug, Clone, PartialEq)]206#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]207pub struct ReFungibleItemType<AccountId> {208	pub owner: Vec<Ownership<AccountId>>,209	pub const_data: Vec<u8>,210	pub variable_data: Vec<u8>,211}212213#[derive(Encode, Decode, Debug, Clone, PartialEq)]214#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]215pub struct CollectionLimits<BlockNumber: Encode + Decode> {216	pub account_token_ownership_limit: u32,217	pub sponsored_data_size: u32,218	/// None - setVariableMetadata is not sponsored219	/// Some(v) - setVariableMetadata is sponsored220	///           if there is v block between txs221	pub sponsored_data_rate_limit: Option<BlockNumber>,222	pub token_limit: u32,223224	// Timeouts for item types in passed blocks225	pub sponsor_transfer_timeout: u32,226	pub owner_can_transfer: bool,227	pub owner_can_destroy: bool,228}229230impl<BlockNumber: Encode + Decode> Default for CollectionLimits<BlockNumber> {231	fn default() -> Self {232		Self {233			account_token_ownership_limit: 10_000_000,234			token_limit: u32::max_value(),235			sponsored_data_size: u32::MAX,236			sponsored_data_rate_limit: None,237			sponsor_transfer_timeout: 14400,238			owner_can_transfer: true,239			owner_can_destroy: true,240		}241	}242}243244/// BoundedVec doesn't supports serde245#[cfg(feature = "serde1")]246mod bounded_serde {247	use core::convert::TryFrom;248	use frame_support::{BoundedVec, traits::Get};249	use serde::{250		ser::{self, Serialize},251		de::{self, Deserialize, Error},252	};253	use sp_std::vec::Vec;254255	pub fn serialize<D, V, S>(value: &BoundedVec<V, S>, serializer: D) -> Result<D::Ok, D::Error>256	where257		D: ser::Serializer,258		V: Serialize,259	{260		let vec: &Vec<_> = &value;261		vec.serialize(serializer)262	}263264	pub fn deserialize<'de, D, V, S>(deserializer: D) -> Result<BoundedVec<V, S>, D::Error>265	where266		D: de::Deserializer<'de>,267		V: de::Deserialize<'de>,268		S: Get<u32>,269	{270		// TODO: Implement custom visitor, which will limit vec size at parse time? Will serde only be used by chainspec?271		let vec = <Vec<V>>::deserialize(deserializer)?;272		let len = vec.len();273		TryFrom::try_from(vec).map_err(|_| D::Error::invalid_length(len, &"lesser size"))274	}275}276277#[derive(Encode, Decode, MaxEncodedLen, Default, PartialEq, Clone, Derivative)]278#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]279#[derivative(Debug)]280pub struct CreateNftData {281	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]282	#[derivative(Debug = "ignore")]283	pub const_data: BoundedVec<u8, CustomDataLimit>,284	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]285	#[derivative(Debug = "ignore")]286	pub variable_data: BoundedVec<u8, CustomDataLimit>,287}288289#[derive(Encode, Decode, MaxEncodedLen, Default, Debug, Clone, PartialEq)]290#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]291pub struct CreateFungibleData {292	pub value: u128,293}294295#[derive(Encode, Decode, MaxEncodedLen, Default, PartialEq, Clone, Derivative)]296#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]297#[derivative(Debug)]298pub struct CreateReFungibleData {299	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]300	#[derivative(Debug = "ignore")]301	pub const_data: BoundedVec<u8, CustomDataLimit>,302	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]303	#[derivative(Debug = "ignore")]304	pub variable_data: BoundedVec<u8, CustomDataLimit>,305	pub pieces: u128,306}307308#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, Debug)]309#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]310pub enum CreateItemData {311	NFT(CreateNftData),312	Fungible(CreateFungibleData),313	ReFungible(CreateReFungibleData),314}315316impl CreateItemData {317	pub fn data_size(&self) -> usize {318		match self {319			CreateItemData::NFT(data) => data.variable_data.len() + data.const_data.len(),320			CreateItemData::ReFungible(data) => data.variable_data.len() + data.const_data.len(),321			_ => 0,322		}323	}324}325326impl From<CreateNftData> for CreateItemData {327	fn from(item: CreateNftData) -> Self {328		CreateItemData::NFT(item)329	}330}331332impl From<CreateReFungibleData> for CreateItemData {333	fn from(item: CreateReFungibleData) -> Self {334		CreateItemData::ReFungible(item)335	}336}337338impl From<CreateFungibleData> for CreateItemData {339	fn from(item: CreateFungibleData) -> Self {340		CreateItemData::Fungible(item)341	}342}