git.delta.rocks / unique-network / refs/commits / 23942aa9dbcc

difftreelog

source

pallets/nonfungible/src/common.rs7.8 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};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	) -> DispatchResultWithPostInfo {196		ensure!(amount <= 1, <Error<T>>::NonfungibleItemsHaveNoAmount);197198		if amount == 1 {199			with_weight(200				<Pallet<T>>::transfer_from(self, &sender, &from, &to, token),201				<CommonWeights<T>>::transfer_from(),202			)203		} else {204			Ok(().into())205		}206	}207208	fn burn_from(209		&self,210		sender: T::CrossAccountId,211		from: T::CrossAccountId,212		token: TokenId,213		amount: u128,214	) -> DispatchResultWithPostInfo {215		ensure!(amount <= 1, <Error<T>>::NonfungibleItemsHaveNoAmount);216217		if amount == 1 {218			with_weight(219				<Pallet<T>>::burn_from(self, &sender, &from, token),220				<CommonWeights<T>>::burn_from(),221			)222		} else {223			Ok(().into())224		}225	}226227	fn set_variable_metadata(228		&self,229		sender: T::CrossAccountId,230		token: TokenId,231		data: BoundedVec<u8, CustomDataLimit>,232	) -> DispatchResultWithPostInfo {233		let len = data.len();234		with_weight(235			<Pallet<T>>::set_variable_metadata(self, &sender, token, data),236			<CommonWeights<T>>::set_variable_metadata(len as u32),237		)238	}239240	fn nest_token(241		&self,242		sender: T::CrossAccountId,243		(from, _): (CollectionId, TokenId),244		under: TokenId,245	) -> sp_runtime::DispatchResult {246		<Pallet<T>>::nest_token(self, sender, from, under)247	}248249	fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {250		<Owned<T>>::iter_prefix((self.id, account))251			.map(|(id, _)| id)252			.collect()253	}254255	fn token_exists(&self, token: TokenId) -> bool {256		<Pallet<T>>::token_exists(self, token)257	}258259	fn last_token_id(&self) -> TokenId {260		TokenId(<TokensMinted<T>>::get(self.id))261	}262263	fn token_owner(&self, token: TokenId) -> Option<T::CrossAccountId> {264		<TokenData<T>>::get((self.id, token)).map(|t| t.owner)265	}266	fn const_metadata(&self, token: TokenId) -> Vec<u8> {267		<TokenData<T>>::get((self.id, token))268			.map(|t| t.const_data)269			.unwrap_or_default()270			.into_inner()271	}272	fn variable_metadata(&self, token: TokenId) -> Vec<u8> {273		<TokenData<T>>::get((self.id, token))274			.map(|t| t.variable_data)275			.unwrap_or_default()276			.into_inner()277	}278279	fn collection_tokens(&self) -> u32 {280		<Pallet<T>>::total_supply(self)281	}282283	fn account_balance(&self, account: T::CrossAccountId) -> u32 {284		<AccountBalance<T>>::get((self.id, account))285	}286287	fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {288		if <TokenData<T>>::get((self.id, token))289			.map(|a| a.owner == account)290			.unwrap_or(false)291		{292			1293		} else {294			0295		}296	}297298	fn allowance(299		&self,300		sender: T::CrossAccountId,301		spender: T::CrossAccountId,302		token: TokenId,303	) -> u128 {304		if <TokenData<T>>::get((self.id, token))305			.map(|a| a.owner != sender)306			.unwrap_or(true)307		{308			0309		} else if <Allowance<T>>::get((self.id, token)) == Some(spender) {310			1311		} else {312			0313		}314	}315}