git.delta.rocks / unique-network / refs/commits / 81e625cae2fb

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};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;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)]75#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]76pub enum CollectionMode {77	Invalid,78	NFT,79	// decimal points80	Fungible(DecimalPoints),81	ReFungible,82}8384impl Default for CollectionMode {85	fn default() -> Self {86		Self::Invalid87	}88}8990impl CollectionMode {91	pub fn id(&self) -> u8 {92		match self {93			CollectionMode::Invalid => 0,94			CollectionMode::NFT => 1,95			CollectionMode::Fungible(_) => 2,96			CollectionMode::ReFungible => 3,97		}98	}99}100101pub trait SponsoringResolve<AccountId, Call> {102	fn resolve(who: &AccountId, call: &Call) -> Option<AccountId>;103}104105#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]106#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]107pub enum AccessMode {108	Normal,109	WhiteList,110}111impl Default for AccessMode {112	fn default() -> Self {113		Self::Normal114	}115}116117#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]118#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]119pub enum SchemaVersion {120	ImageURL,121	Unique,122}123impl Default for SchemaVersion {124	fn default() -> Self {125		Self::ImageURL126	}127}128129#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]130#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]131pub struct Ownership<AccountId> {132	pub owner: AccountId,133	pub fraction: u128,134}135136#[derive(Encode, Decode, Debug, Clone, PartialEq)]137#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]138pub enum SponsorshipState<AccountId> {139	/// The fees are applied to the transaction sender140	Disabled,141	Unconfirmed(AccountId),142	/// Transactions are sponsored by specified account143	Confirmed(AccountId),144}145146impl<AccountId> SponsorshipState<AccountId> {147	pub fn sponsor(&self) -> Option<&AccountId> {148		match self {149			Self::Confirmed(sponsor) => Some(sponsor),150			_ => None,151		}152	}153154	pub fn pending_sponsor(&self) -> Option<&AccountId> {155		match self {156			Self::Unconfirmed(sponsor) | Self::Confirmed(sponsor) => Some(sponsor),157			_ => None,158		}159	}160161	pub fn confirmed(&self) -> bool {162		matches!(self, Self::Confirmed(_))163	}164}165166impl<T> Default for SponsorshipState<T> {167	fn default() -> Self {168		Self::Disabled169	}170}171172#[derive(Encode, Decode, Clone, PartialEq)]173#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]174pub struct Collection<T: frame_system::Config> {175	pub owner: T::AccountId,176	pub mode: CollectionMode,177	pub access: AccessMode,178	pub decimal_points: DecimalPoints,179	pub name: Vec<u16>,        // 64 include null escape char180	pub description: Vec<u16>, // 256 include null escape char181	pub token_prefix: Vec<u8>, // 16 include null escape char182	pub mint_mode: bool,183	pub offchain_schema: Vec<u8>,184	pub schema_version: SchemaVersion,185	pub sponsorship: SponsorshipState<T::AccountId>,186	pub limits: CollectionLimits<T::BlockNumber>, // Collection private restrictions187	pub variable_on_chain_schema: Vec<u8>,        //188	pub const_on_chain_schema: Vec<u8>,           //189	pub meta_update_permission: MetaUpdatePermission,190	pub transfers_enabled: bool,191}192193#[derive(Encode, Decode, Debug, Clone, PartialEq)]194#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]195pub struct NftItemType<AccountId> {196	pub owner: AccountId,197	pub const_data: Vec<u8>,198	pub variable_data: Vec<u8>,199}200201#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]202#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]203pub struct FungibleItemType {204	pub value: u128,205}206207#[derive(Encode, Decode, Debug, Clone, PartialEq)]208#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]209pub struct ReFungibleItemType<AccountId> {210	pub owner: Vec<Ownership<AccountId>>,211	pub const_data: Vec<u8>,212	pub variable_data: Vec<u8>,213}214215#[derive(Encode, Decode, Debug, Clone, PartialEq)]216#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]217pub struct CollectionLimits<BlockNumber: Encode + Decode> {218	pub account_token_ownership_limit: u32,219	pub sponsored_data_size: u32,220	/// None - setVariableMetadata is not sponsored221	/// Some(v) - setVariableMetadata is sponsored222	///           if there is v block between txs223	pub sponsored_data_rate_limit: Option<BlockNumber>,224	pub token_limit: u32,225226	// Timeouts for item types in passed blocks227	pub sponsor_transfer_timeout: u32,228	pub owner_can_transfer: bool,229	pub owner_can_destroy: bool,230}231232impl<BlockNumber: Encode + Decode> Default for CollectionLimits<BlockNumber> {233	fn default() -> Self {234		Self {235			account_token_ownership_limit: 10_000_000,236			token_limit: u32::max_value(),237			sponsored_data_size: u32::MAX,238			sponsored_data_rate_limit: None,239			sponsor_transfer_timeout: 14400,240			owner_can_transfer: true,241			owner_can_destroy: true,242		}243	}244}245246/// BoundedVec doesn't supports serde247#[cfg(feature = "serde1")]248mod bounded_serde {249	use core::convert::TryFrom;250	use frame_support::{BoundedVec, traits::Get};251	use serde::{252		ser::{self, Serialize},253		de::{self, Deserialize, Error},254	};255	use sp_std::vec::Vec;256257	pub fn serialize<D, V, S>(value: &BoundedVec<V, S>, serializer: D) -> Result<D::Ok, D::Error>258	where259		D: ser::Serializer,260		V: Serialize,261	{262		let vec: &Vec<_> = &value;263		vec.serialize(serializer)264	}265266	pub fn deserialize<'de, D, V, S>(deserializer: D) -> Result<BoundedVec<V, S>, D::Error>267	where268		D: de::Deserializer<'de>,269		V: de::Deserialize<'de>,270		S: Get<u32>,271	{272		// TODO: Implement custom visitor, which will limit vec size at parse time? Will serde only be used by chainspec?273		let vec = <Vec<V>>::deserialize(deserializer)?;274		let len = vec.len();275		TryFrom::try_from(vec).map_err(|_| D::Error::invalid_length(len, &"lesser size"))276	}277}278279#[derive(Encode, Decode, MaxEncodedLen, Default, PartialEq, Clone, Derivative)]280#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]281#[derivative(Debug)]282pub struct CreateNftData {283	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]284	#[derivative(Debug = "ignore")]285	pub const_data: BoundedVec<u8, CustomDataLimit>,286	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]287	#[derivative(Debug = "ignore")]288	pub variable_data: BoundedVec<u8, CustomDataLimit>,289}290291#[derive(Encode, Decode, MaxEncodedLen, Default, Debug, Clone, PartialEq)]292#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]293pub struct CreateFungibleData {294	pub value: u128,295}296297#[derive(Encode, Decode, MaxEncodedLen, Default, PartialEq, Clone, Derivative)]298#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]299#[derivative(Debug)]300pub struct CreateReFungibleData {301	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]302	#[derivative(Debug = "ignore")]303	pub const_data: BoundedVec<u8, CustomDataLimit>,304	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]305	#[derivative(Debug = "ignore")]306	pub variable_data: BoundedVec<u8, CustomDataLimit>,307	pub pieces: u128,308}309310#[derive(Encode, Decode, Debug, Clone, PartialEq)]311#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]312pub enum MetaUpdatePermission {313	ItemOwner,314	Admin,315	None,316}317318impl Default for MetaUpdatePermission {319	fn default() -> Self {320		Self::ItemOwner321	}322}323324#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, Debug)]325#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]326pub enum CreateItemData {327	NFT(CreateNftData),328	Fungible(CreateFungibleData),329	ReFungible(CreateReFungibleData),330}331332impl CreateItemData {333	pub fn data_size(&self) -> usize {334		match self {335			CreateItemData::NFT(data) => data.variable_data.len() + data.const_data.len(),336			CreateItemData::ReFungible(data) => data.variable_data.len() + data.const_data.len(),337			_ => 0,338		}339	}340}341342impl From<CreateNftData> for CreateItemData {343	fn from(item: CreateNftData) -> Self {344		CreateItemData::NFT(item)345	}346}347348impl From<CreateReFungibleData> for CreateItemData {349	fn from(item: CreateReFungibleData) -> Self {350		CreateItemData::ReFungible(item)351	}352}353354impl From<CreateFungibleData> for CreateItemData {355	fn from(item: CreateFungibleData) -> Self {356		CreateItemData::Fungible(item)357	}358}