git.delta.rocks / unique-network / refs/commits / 7a034de544fd

difftreelog

source

primitives/nft/src/lib.rs9.3 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 = 100000;32pub const CUSTOM_DATA_LIMIT: u32 = 2048;33pub const COLLECTION_ADMINS_LIMIT: u64 = 5;34pub const ACCOUNT_TOKEN_OWNERSHIP_LIMIT: u32 = 1000000;3536// Timeouts for item types in passed blocks37pub const NFT_SPONSOR_TRANSFER_TIMEOUT: u32 = 5;38pub const FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT: u32 = 5;39pub const REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT: u32 = 5;4041// Schema limits42pub const OFFCHAIN_SCHEMA_LIMIT: u32 = 1024;43pub const VARIABLE_ON_CHAIN_SCHEMA_LIMIT: u32 = 1024;44pub const CONST_ON_CHAIN_SCHEMA_LIMIT: u32 = 1024;4546/// How much items can be created per single47/// create_many call48pub const MAX_ITEMS_PER_BATCH: u32 = 200;4950parameter_types! {51	pub const CustomDataLimit: u32 = CUSTOM_DATA_LIMIT;52}5354pub type CollectionId = u32;55pub type TokenId = u32;56pub type DecimalPoints = u8;5758#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]59#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]60pub enum CollectionMode {61	Invalid,62	NFT,63	// decimal points64	Fungible(DecimalPoints),65	ReFungible,66}6768impl Default for CollectionMode {69	fn default() -> Self {70		Self::Invalid71	}72}7374impl CollectionMode {75	pub fn id(&self) -> u8 {76		match self {77			CollectionMode::Invalid => 0,78			CollectionMode::NFT => 1,79			CollectionMode::Fungible(_) => 2,80			CollectionMode::ReFungible => 3,81		}82	}83}8485pub trait SponsoringResolve<AccountId, Call> {86	fn resolve(who: &AccountId, call: &Call) -> Option<AccountId>;87}8889#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]90#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]91pub enum AccessMode {92	Normal,93	WhiteList,94}95impl Default for AccessMode {96	fn default() -> Self {97		Self::Normal98	}99}100101#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]102#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]103pub enum SchemaVersion {104	ImageURL,105	Unique,106}107impl Default for SchemaVersion {108	fn default() -> Self {109		Self::ImageURL110	}111}112113#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]114#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]115pub struct Ownership<AccountId> {116	pub owner: AccountId,117	pub fraction: u128,118}119120#[derive(Encode, Decode, Debug, Clone, PartialEq)]121#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]122pub enum SponsorshipState<AccountId> {123	/// The fees are applied to the transaction sender124	Disabled,125	Unconfirmed(AccountId),126	/// Transactions are sponsored by specified account127	Confirmed(AccountId),128}129130impl<AccountId> SponsorshipState<AccountId> {131	pub fn sponsor(&self) -> Option<&AccountId> {132		match self {133			Self::Confirmed(sponsor) => Some(sponsor),134			_ => None,135		}136	}137138	pub fn pending_sponsor(&self) -> Option<&AccountId> {139		match self {140			Self::Unconfirmed(sponsor) | Self::Confirmed(sponsor) => Some(sponsor),141			_ => None,142		}143	}144145	pub fn confirmed(&self) -> bool {146		matches!(self, Self::Confirmed(_))147	}148}149150impl<T> Default for SponsorshipState<T> {151	fn default() -> Self {152		Self::Disabled153	}154}155156#[derive(Encode, Decode, Clone, PartialEq)]157#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]158pub struct Collection<T: frame_system::Config> {159	pub owner: T::AccountId,160	pub mode: CollectionMode,161	pub access: AccessMode,162	pub decimal_points: DecimalPoints,163	pub name: Vec<u16>,        // 64 include null escape char164	pub description: Vec<u16>, // 256 include null escape char165	pub token_prefix: Vec<u8>, // 16 include null escape char166	pub mint_mode: bool,167	pub offchain_schema: Vec<u8>,168	pub schema_version: SchemaVersion,169	pub sponsorship: SponsorshipState<T::AccountId>,170	pub limits: CollectionLimits<T::BlockNumber>, // Collection private restrictions171	pub variable_on_chain_schema: Vec<u8>,        //172	pub const_on_chain_schema: Vec<u8>,           //173	pub transfers_enabled: bool,174}175176#[derive(Encode, Decode, Debug, Clone, PartialEq)]177#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]178pub struct NftItemType<AccountId> {179	pub owner: AccountId,180	pub const_data: Vec<u8>,181	pub variable_data: Vec<u8>,182}183184#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]185#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]186pub struct FungibleItemType {187	pub value: u128,188}189190#[derive(Encode, Decode, Debug, Clone, PartialEq)]191#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]192pub struct ReFungibleItemType<AccountId> {193	pub owner: Vec<Ownership<AccountId>>,194	pub const_data: Vec<u8>,195	pub variable_data: Vec<u8>,196}197198#[derive(Encode, Decode, Debug, Clone, PartialEq)]199#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]200pub struct CollectionLimits<BlockNumber: Encode + Decode> {201	pub account_token_ownership_limit: u32,202	pub sponsored_data_size: u32,203	/// None - setVariableMetadata is not sponsored204	/// Some(v) - setVariableMetadata is sponsored205	///           if there is v block between txs206	pub sponsored_data_rate_limit: Option<BlockNumber>,207	pub token_limit: u32,208209	// Timeouts for item types in passed blocks210	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: true,225		}226	}227}228229/// BoundedVec doesn't supports serde230#[cfg(feature = "serde1")]231mod bounded_serde {232	use core::convert::TryFrom;233	use frame_support::{BoundedVec, traits::Get};234	use serde::{235		ser::{self, Serialize},236		de::{self, Deserialize, Error},237	};238	use sp_std::vec::Vec;239240	pub fn serialize<D, V, S>(value: &BoundedVec<V, S>, serializer: D) -> Result<D::Ok, D::Error>241	where242		D: ser::Serializer,243		V: Serialize,244	{245		let vec: &Vec<_> = &value;246		vec.serialize(serializer)247	}248249	pub fn deserialize<'de, D, V, S>(deserializer: D) -> Result<BoundedVec<V, S>, D::Error>250	where251		D: de::Deserializer<'de>,252		V: de::Deserialize<'de>,253		S: Get<u32>,254	{255		// TODO: Implement custom visitor, which will limit vec size at parse time? Will serde only be used by chainspec?256		let vec = <Vec<V>>::deserialize(deserializer)?;257		let len = vec.len();258		TryFrom::try_from(vec).map_err(|_| D::Error::invalid_length(len, &"lesser size"))259	}260}261262#[derive(Encode, Decode, MaxEncodedLen, Default, PartialEq, Clone, Derivative)]263#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]264#[derivative(Debug)]265pub struct CreateNftData {266	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]267	#[derivative(Debug = "ignore")]268	pub const_data: BoundedVec<u8, CustomDataLimit>,269	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]270	#[derivative(Debug = "ignore")]271	pub variable_data: BoundedVec<u8, CustomDataLimit>,272}273274#[derive(Encode, Decode, MaxEncodedLen, Default, Debug, Clone, PartialEq)]275#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]276pub struct CreateFungibleData {277	pub value: u128,278}279280#[derive(Encode, Decode, MaxEncodedLen, Default, PartialEq, Clone, Derivative)]281#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]282#[derivative(Debug)]283pub struct CreateReFungibleData {284	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]285	#[derivative(Debug = "ignore")]286	pub const_data: BoundedVec<u8, CustomDataLimit>,287	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]288	#[derivative(Debug = "ignore")]289	pub variable_data: BoundedVec<u8, CustomDataLimit>,290	pub pieces: u128,291}292293#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, Debug)]294#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]295pub enum CreateItemData {296	NFT(CreateNftData),297	Fungible(CreateFungibleData),298	ReFungible(CreateReFungibleData),299}300301impl CreateItemData {302	pub fn data_size(&self) -> usize {303		match self {304			CreateItemData::NFT(data) => data.variable_data.len() + data.const_data.len(),305			CreateItemData::ReFungible(data) => data.variable_data.len() + data.const_data.len(),306			_ => 0,307		}308	}309}310311impl From<CreateNftData> for CreateItemData {312	fn from(item: CreateNftData) -> Self {313		CreateItemData::NFT(item)314	}315}316317impl From<CreateReFungibleData> for CreateItemData {318	fn from(item: CreateReFungibleData) -> Self {319		CreateItemData::ReFungible(item)320	}321}322323impl From<CreateFungibleData> for CreateItemData {324	fn from(item: CreateFungibleData) -> Self {325		CreateItemData::Fungible(item)326	}327}