git.delta.rocks / unique-network / refs/commits / 2f9c8d434e2f

difftreelog

source

pallets/nonfungible/src/common.rs7.6 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};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 account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {241		<Owned<T>>::iter_prefix((self.id, account))242			.map(|(id, _)| id)243			.collect()244	}245246	fn token_exists(&self, token: TokenId) -> bool {247		<Pallet<T>>::token_exists(self, token)248	}249250	fn last_token_id(&self) -> TokenId {251		TokenId(<TokensMinted<T>>::get(self.id))252	}253254	fn token_owner(&self, token: TokenId) -> Option<T::CrossAccountId> {255		<TokenData<T>>::get((self.id, token)).map(|t| t.owner)256	}257	fn const_metadata(&self, token: TokenId) -> Vec<u8> {258		<TokenData<T>>::get((self.id, token))259			.map(|t| t.const_data)260			.unwrap_or_default()261			.into_inner()262	}263	fn variable_metadata(&self, token: TokenId) -> Vec<u8> {264		<TokenData<T>>::get((self.id, token))265			.map(|t| t.variable_data)266			.unwrap_or_default()267			.into_inner()268	}269270	fn collection_tokens(&self) -> u32 {271		<Pallet<T>>::total_supply(self)272	}273274	fn account_balance(&self, account: T::CrossAccountId) -> u32 {275		<AccountBalance<T>>::get((self.id, account))276	}277278	fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {279		if <TokenData<T>>::get((self.id, token))280			.map(|a| a.owner == account)281			.unwrap_or(false)282		{283			1284		} else {285			0286		}287	}288289	fn allowance(290		&self,291		sender: T::CrossAccountId,292		spender: T::CrossAccountId,293		token: TokenId,294	) -> u128 {295		if <TokenData<T>>::get((self.id, token))296			.map(|a| a.owner != sender)297			.unwrap_or(true)298		{299			0300		} else if <Allowance<T>>::get((self.id, token)) == Some(spender) {301			1302		} else {303			0304		}305	}306}