git.delta.rocks / unique-network / refs/commits / 51d879bd4a84

difftreelog

source

primitives/nft/src/lib.rs9.4 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};8use max_encoded_len::MaxEncodedLen;9pub use frame_support::{10	BoundedVec, construct_runtime, decl_event, decl_module, decl_storage, decl_error,11	dispatch::DispatchResult,12	ensure, fail, parameter_types,13	traits::{14		Currency, ExistenceRequirement, Get, Imbalance, KeyOwnerProofSystem, OnUnbalanced,15		Randomness, IsSubType, WithdrawReasons,16	},17	weights::{18		constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},19		DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight,20		WeightToFeePolynomial, DispatchClass,21	},22	StorageValue, transactional,23};24use derivative::Derivative;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;5758/// How much items can be created per single59/// create_many call60pub const MAX_ITEMS_PER_BATCH: u32 = 200;6162parameter_types! {63	pub const CustomDataLimit: u32 = CUSTOM_DATA_LIMIT;64}6566pub type CollectionId = u32;67pub type TokenId = u32;68pub type DecimalPoints = u8;6970#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]71#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]72pub enum CollectionMode {73	Invalid,74	NFT,75	// decimal points76	Fungible(DecimalPoints),77	ReFungible,78}7980impl Default for CollectionMode {81	fn default() -> Self {82		Self::Invalid83	}84}8586impl CollectionMode {87	pub fn id(&self) -> u8 {88		match self {89			CollectionMode::Invalid => 0,90			CollectionMode::NFT => 1,91			CollectionMode::Fungible(_) => 2,92			CollectionMode::ReFungible => 3,93		}94	}95}9697pub trait SponsoringResolve<AccountId, Call> {98	fn resolve(who: &AccountId, call: &Call) -> Option<AccountId>;99}100101#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]102#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]103pub enum AccessMode {104	Normal,105	WhiteList,106}107impl Default for AccessMode {108	fn default() -> Self {109		Self::Normal110	}111}112113#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]114#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]115pub enum SchemaVersion {116	ImageURL,117	Unique,118}119impl Default for SchemaVersion {120	fn default() -> Self {121		Self::ImageURL122	}123}124125#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]126#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]127pub struct Ownership<AccountId> {128	pub owner: AccountId,129	pub fraction: u128,130}131132#[derive(Encode, Decode, Debug, Clone, PartialEq)]133#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]134pub enum SponsorshipState<AccountId> {135	/// The fees are applied to the transaction sender136	Disabled,137	Unconfirmed(AccountId),138	/// Transactions are sponsored by specified account139	Confirmed(AccountId),140}141142impl<AccountId> SponsorshipState<AccountId> {143	pub fn sponsor(&self) -> Option<&AccountId> {144		match self {145			Self::Confirmed(sponsor) => Some(sponsor),146			_ => None,147		}148	}149150	pub fn pending_sponsor(&self) -> Option<&AccountId> {151		match self {152			Self::Unconfirmed(sponsor) | Self::Confirmed(sponsor) => Some(sponsor),153			_ => None,154		}155	}156157	pub fn confirmed(&self) -> bool {158		matches!(self, Self::Confirmed(_))159	}160}161162impl<T> Default for SponsorshipState<T> {163	fn default() -> Self {164		Self::Disabled165	}166}167168#[derive(Encode, Decode, Clone, PartialEq)]169#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]170pub struct Collection<T: frame_system::Config> {171	pub owner: T::AccountId,172	pub mode: CollectionMode,173	pub access: AccessMode,174	pub decimal_points: DecimalPoints,175	pub name: Vec<u16>,        // 64 include null escape char176	pub description: Vec<u16>, // 256 include null escape char177	pub token_prefix: Vec<u8>, // 16 include null escape char178	pub mint_mode: bool,179	pub offchain_schema: Vec<u8>,180	pub schema_version: SchemaVersion,181	pub sponsorship: SponsorshipState<T::AccountId>,182	pub limits: CollectionLimits<T::BlockNumber>, // Collection private restrictions183	pub variable_on_chain_schema: Vec<u8>,        //184	pub const_on_chain_schema: Vec<u8>,           //185	pub transfers_enabled: bool,186}187188#[derive(Encode, Decode, Debug, Clone, PartialEq)]189#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]190pub struct NftItemType<AccountId> {191	pub owner: AccountId,192	pub const_data: Vec<u8>,193	pub variable_data: Vec<u8>,194}195196#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]197#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]198pub struct FungibleItemType {199	pub value: u128,200}201202#[derive(Encode, Decode, Debug, Clone, PartialEq)]203#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]204pub struct ReFungibleItemType<AccountId> {205	pub owner: Vec<Ownership<AccountId>>,206	pub const_data: Vec<u8>,207	pub variable_data: Vec<u8>,208}209210#[derive(Encode, Decode, Debug, Clone, PartialEq)]211#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]212pub struct CollectionLimits<BlockNumber: Encode + Decode> {213	pub account_token_ownership_limit: u32,214	pub sponsored_data_size: u32,215	/// None - setVariableMetadata is not sponsored216	/// Some(v) - setVariableMetadata is sponsored217	///           if there is v block between txs218	pub sponsored_data_rate_limit: Option<BlockNumber>,219	pub token_limit: u32,220221	// Timeouts for item types in passed blocks222	pub sponsor_transfer_timeout: u32,223	pub owner_can_transfer: bool,224	pub owner_can_destroy: bool,225}226227impl<BlockNumber: Encode + Decode> Default for CollectionLimits<BlockNumber> {228	fn default() -> Self {229		Self {230			account_token_ownership_limit: 10_000_000,231			token_limit: u32::max_value(),232			sponsored_data_size: u32::MAX,233			sponsored_data_rate_limit: None,234			sponsor_transfer_timeout: 14400,235			owner_can_transfer: true,236			owner_can_destroy: true,237		}238	}239}240241/// BoundedVec doesn't supports serde242#[cfg(feature = "serde1")]243mod bounded_serde {244	use core::convert::TryFrom;245	use frame_support::{BoundedVec, traits::Get};246	use serde::{247		ser::{self, Serialize},248		de::{self, Deserialize, Error},249	};250	use sp_std::vec::Vec;251252	pub fn serialize<D, V, S>(value: &BoundedVec<V, S>, serializer: D) -> Result<D::Ok, D::Error>253	where254		D: ser::Serializer,255		V: Serialize,256	{257		let vec: &Vec<_> = &value;258		vec.serialize(serializer)259	}260261	pub fn deserialize<'de, D, V, S>(deserializer: D) -> Result<BoundedVec<V, S>, D::Error>262	where263		D: de::Deserializer<'de>,264		V: de::Deserialize<'de>,265		S: Get<u32>,266	{267		// TODO: Implement custom visitor, which will limit vec size at parse time? Will serde only be used by chainspec?268		let vec = <Vec<V>>::deserialize(deserializer)?;269		let len = vec.len();270		TryFrom::try_from(vec).map_err(|_| D::Error::invalid_length(len, &"lesser size"))271	}272}273274#[derive(Encode, Decode, MaxEncodedLen, Default, PartialEq, Clone, Derivative)]275#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]276#[derivative(Debug)]277pub struct CreateNftData {278	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]279	#[derivative(Debug = "ignore")]280	pub const_data: BoundedVec<u8, CustomDataLimit>,281	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]282	#[derivative(Debug = "ignore")]283	pub variable_data: BoundedVec<u8, CustomDataLimit>,284}285286#[derive(Encode, Decode, MaxEncodedLen, Default, Debug, Clone, PartialEq)]287#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]288pub struct CreateFungibleData {289	pub value: u128,290}291292#[derive(Encode, Decode, MaxEncodedLen, Default, PartialEq, Clone, Derivative)]293#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]294#[derivative(Debug)]295pub struct CreateReFungibleData {296	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]297	#[derivative(Debug = "ignore")]298	pub const_data: BoundedVec<u8, CustomDataLimit>,299	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]300	#[derivative(Debug = "ignore")]301	pub variable_data: BoundedVec<u8, CustomDataLimit>,302	pub pieces: u128,303}304305#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, Debug)]306#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]307pub enum CreateItemData {308	NFT(CreateNftData),309	Fungible(CreateFungibleData),310	ReFungible(CreateReFungibleData),311}312313impl CreateItemData {314	pub fn data_size(&self) -> usize {315		match self {316			CreateItemData::NFT(data) => data.variable_data.len() + data.const_data.len(),317			CreateItemData::ReFungible(data) => data.variable_data.len() + data.const_data.len(),318			_ => 0,319		}320	}321}322323impl From<CreateNftData> for CreateItemData {324	fn from(item: CreateNftData) -> Self {325		CreateItemData::NFT(item)326	}327}328329impl From<CreateReFungibleData> for CreateItemData {330	fn from(item: CreateReFungibleData) -> Self {331		CreateItemData::ReFungible(item)332	}333}334335impl From<CreateFungibleData> for CreateItemData {336	fn from(item: CreateFungibleData) -> Self {337		CreateItemData::Fungible(item)338	}339}