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

difftreelog

source

pallets/nonfungible/src/common.rs7.9 KiBsourcehistory
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617use core::marker::PhantomData;1819use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight, BoundedVec};20use up_data_structs::{TokenId, CustomDataLimit, CreateItemExData, CollectionId, budget::Budget};21use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};22use sp_runtime::DispatchError;23use sp_std::vec::Vec;2425use crate::{26	AccountBalance, Allowance, Config, CreateItemData, Error, NonfungibleHandle, Owned, Pallet,27	SelfWeightOf, TokenData, weights::WeightInfo, TokensMinted,28};2930pub struct CommonWeights<T: Config>(PhantomData<T>);31impl<T: Config> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T> {32	fn create_item() -> Weight {33		<SelfWeightOf<T>>::create_item()34	}3536	fn create_multiple_items_ex(data: &CreateItemExData<T::CrossAccountId>) -> Weight {37		match data {38			CreateItemExData::NFT(t) => <SelfWeightOf<T>>::create_multiple_items_ex(t.len() as u32),39			_ => 0,40		}41	}4243	fn create_multiple_items(amount: u32) -> Weight {44		<SelfWeightOf<T>>::create_multiple_items(amount)45	}4647	fn burn_item() -> Weight {48		<SelfWeightOf<T>>::burn_item()49	}5051	fn transfer() -> Weight {52		<SelfWeightOf<T>>::transfer()53	}5455	fn approve() -> Weight {56		<SelfWeightOf<T>>::approve()57	}5859	fn transfer_from() -> Weight {60		<SelfWeightOf<T>>::transfer_from()61	}6263	fn burn_from() -> Weight {64		<SelfWeightOf<T>>::burn_from()65	}6667	fn set_variable_metadata(bytes: u32) -> Weight {68		<SelfWeightOf<T>>::set_variable_metadata(bytes)69	}70}7172fn map_create_data<T: Config>(73	data: up_data_structs::CreateItemData,74	to: &T::CrossAccountId,75) -> Result<CreateItemData<T>, DispatchError> {76	match data {77		up_data_structs::CreateItemData::NFT(data) => Ok(CreateItemData::<T> {78			const_data: data.const_data,79			variable_data: data.variable_data,80			owner: to.clone(),81		}),82		_ => fail!(<Error<T>>::NotNonfungibleDataUsedToMintFungibleCollectionToken),83	}84}8586impl<T: Config> CommonCollectionOperations<T> for NonfungibleHandle<T> {87	fn create_item(88		&self,89		sender: T::CrossAccountId,90		to: T::CrossAccountId,91		data: up_data_structs::CreateItemData,92	) -> DispatchResultWithPostInfo {93		with_weight(94			<Pallet<T>>::create_item(self, &sender, map_create_data::<T>(data, &to)?),95			<CommonWeights<T>>::create_item(),96		)97	}9899	fn create_multiple_items(100		&self,101		sender: T::CrossAccountId,102		to: T::CrossAccountId,103		data: Vec<up_data_structs::CreateItemData>,104	) -> DispatchResultWithPostInfo {105		let data = data106			.into_iter()107			.map(|d| map_create_data::<T>(d, &to))108			.collect::<Result<Vec<_>, DispatchError>>()?;109110		let amount = data.len();111		with_weight(112			<Pallet<T>>::create_multiple_items(self, &sender, data),113			<CommonWeights<T>>::create_multiple_items(amount as u32),114		)115	}116117	fn create_multiple_items_ex(118		&self,119		sender: <T>::CrossAccountId,120		data: up_data_structs::CreateItemExData<<T>::CrossAccountId>,121	) -> DispatchResultWithPostInfo {122		let weight = <CommonWeights<T>>::create_multiple_items_ex(&data);123		let data = match data {124			up_data_structs::CreateItemExData::NFT(nft) => nft,125			_ => fail!(Error::<T>::NotNonfungibleDataUsedToMintFungibleCollectionToken),126		};127128		with_weight(129			<Pallet<T>>::create_multiple_items(self, &sender, data.into_inner()),130			weight,131		)132	}133134	fn burn_item(135		&self,136		sender: T::CrossAccountId,137		token: TokenId,138		amount: u128,139	) -> DispatchResultWithPostInfo {140		ensure!(amount <= 1, <Error<T>>::NonfungibleItemsHaveNoAmount);141		if amount == 1 {142			with_weight(143				<Pallet<T>>::burn(self, &sender, token),144				<CommonWeights<T>>::burn_item(),145			)146		} else {147			Ok(().into())148		}149	}150151	fn transfer(152		&self,153		from: T::CrossAccountId,154		to: T::CrossAccountId,155		token: TokenId,156		amount: u128,157	) -> DispatchResultWithPostInfo {158		ensure!(amount <= 1, <Error<T>>::NonfungibleItemsHaveNoAmount);159		if amount == 1 {160			with_weight(161				<Pallet<T>>::transfer(self, &from, &to, token),162				<CommonWeights<T>>::transfer(),163			)164		} else {165			Ok(().into())166		}167	}168169	fn approve(170		&self,171		sender: T::CrossAccountId,172		spender: T::CrossAccountId,173		token: TokenId,174		amount: u128,175	) -> DispatchResultWithPostInfo {176		ensure!(amount <= 1, <Error<T>>::NonfungibleItemsHaveNoAmount);177178		with_weight(179			if amount == 1 {180				<Pallet<T>>::set_allowance(self, &sender, token, Some(&spender))181			} else {182				<Pallet<T>>::set_allowance(self, &sender, token, None)183			},184			<CommonWeights<T>>::approve(),185		)186	}187188	fn transfer_from(189		&self,190		sender: T::CrossAccountId,191		from: T::CrossAccountId,192		to: T::CrossAccountId,193		token: TokenId,194		amount: u128,195		nesting_budget: &dyn Budget,196	) -> DispatchResultWithPostInfo {197		ensure!(amount <= 1, <Error<T>>::NonfungibleItemsHaveNoAmount);198199		if amount == 1 {200			with_weight(201				<Pallet<T>>::transfer_from(self, &sender, &from, &to, token, nesting_budget),202				<CommonWeights<T>>::transfer_from(),203			)204		} else {205			Ok(().into())206		}207	}208209	fn burn_from(210		&self,211		sender: T::CrossAccountId,212		from: T::CrossAccountId,213		token: TokenId,214		amount: u128,215		nesting_budget: &dyn Budget,216	) -> DispatchResultWithPostInfo {217		ensure!(amount <= 1, <Error<T>>::NonfungibleItemsHaveNoAmount);218219		if amount == 1 {220			with_weight(221				<Pallet<T>>::burn_from(self, &sender, &from, token, nesting_budget),222				<CommonWeights<T>>::burn_from(),223			)224		} else {225			Ok(().into())226		}227	}228229	fn set_variable_metadata(230		&self,231		sender: T::CrossAccountId,232		token: TokenId,233		data: BoundedVec<u8, CustomDataLimit>,234	) -> DispatchResultWithPostInfo {235		let len = data.len();236		with_weight(237			<Pallet<T>>::set_variable_metadata(self, &sender, token, data),238			<CommonWeights<T>>::set_variable_metadata(len as u32),239		)240	}241242	fn nest_token(243		&self,244		sender: T::CrossAccountId,245		(from, _): (CollectionId, TokenId),246		under: TokenId,247	) -> sp_runtime::DispatchResult {248		<Pallet<T>>::nest_token(self, sender, from, under)249	}250251	fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {252		<Owned<T>>::iter_prefix((self.id, account))253			.map(|(id, _)| id)254			.collect()255	}256257	fn token_exists(&self, token: TokenId) -> bool {258		<Pallet<T>>::token_exists(self, token)259	}260261	fn last_token_id(&self) -> TokenId {262		TokenId(<TokensMinted<T>>::get(self.id))263	}264265	fn token_owner(&self, token: TokenId) -> Option<T::CrossAccountId> {266		<TokenData<T>>::get((self.id, token)).map(|t| t.owner)267	}268	fn const_metadata(&self, token: TokenId) -> Vec<u8> {269		<TokenData<T>>::get((self.id, token))270			.map(|t| t.const_data)271			.unwrap_or_default()272			.into_inner()273	}274	fn variable_metadata(&self, token: TokenId) -> Vec<u8> {275		<TokenData<T>>::get((self.id, token))276			.map(|t| t.variable_data)277			.unwrap_or_default()278			.into_inner()279	}280281	fn collection_tokens(&self) -> u32 {282		<Pallet<T>>::total_supply(self)283	}284285	fn account_balance(&self, account: T::CrossAccountId) -> u32 {286		<AccountBalance<T>>::get((self.id, account))287	}288289	fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {290		if <TokenData<T>>::get((self.id, token))291			.map(|a| a.owner == account)292			.unwrap_or(false)293		{294			1295		} else {296			0297		}298	}299300	fn allowance(301		&self,302		sender: T::CrossAccountId,303		spender: T::CrossAccountId,304		token: TokenId,305	) -> u128 {306		if <TokenData<T>>::get((self.id, token))307			.map(|a| a.owner != sender)308			.unwrap_or(true)309		{310			0311		} else if <Allowance<T>>::get((self.id, token)) == Some(spender) {312			1313		} else {314			0315		}316	}317}