12345678910111213141516171819use core::convert::TryInto;20use pallet_common::CollectionHandle;21use pallet_evm::account::CrossAccountId;22use pallet_fungible::Config as FungibleConfig;23use pallet_refungible::Config as RefungibleConfig;24use pallet_nonfungible::Config as NonfungibleConfig;25use pallet_unique::Config as UniqueConfig;26use up_data_structs::{CreateItemData, CreateNftData, TokenId};2728use super::common;29use crate::runtime_common::sponsoring::*;3031use pallet_refungible::{32 erc::{33 ERC721BurnableCall, ERC721Call, ERC721EnumerableCall, ERC721MetadataCall,34 ERC721UniqueExtensionsCall, ERC721UniqueMintableCall, TokenPropertiesCall,35 UniqueRefungibleCall,36 },37 erc_token::{38 ERC1633Call, ERC20Call, ERC20UniqueExtensionsCall, RefungibleTokenHandle,39 UniqueRefungibleTokenCall,40 },41};4243pub fn call_sponsor<T>(44 call: UniqueRefungibleCall<T>,45 collection: CollectionHandle<T>,46 who: &T::CrossAccountId,47) -> Option<()>48where49 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,50{51 use UniqueRefungibleCall::*;5253 match call {54 55 ERC165Call(_, _) => None,5657 ERC721Enumerable(call) => erc721::enumerable_call_sponsor(call, collection, who),58 ERC721Burnable(call) => erc721::burnable_call_sponsor(call, collection, who),59 ERC721Metadata(call) => erc721::metadata_call_sponsor(call, collection, who),60 Collection(call) => common::collection_call_sponsor(call, collection, who),61 ERC721(call) => erc721::call_sponsor(call, collection, who),62 ERC721UniqueExtensions(call) => {63 erc721::unique_extensions_call_sponsor(call, collection, who)64 }65 ERC721UniqueMintable(call) => erc721::unique_mintable_call_sponsor(call, collection, who),66 TokenProperties(call) => token_properties_call_sponsor(call, collection, who),67 }68}6970pub fn token_properties_call_sponsor<T>(71 call: TokenPropertiesCall<T>,72 collection: CollectionHandle<T>,73 who: &T::CrossAccountId,74) -> Option<()>75where76 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,77{78 use TokenPropertiesCall::*;7980 match call {81 82 ERC165Call(_, _) | Property { .. } | TokenPropertyPermissions => None,8384 85 SetTokenPropertyPermission { .. }86 | SetTokenPropertyPermissions { .. }87 | SetProperties { .. }88 | DeleteProperty { .. }89 | DeleteProperties { .. } => None,9091 SetProperty {92 token_id,93 key,94 value,95 ..96 } => {97 let token_id = TokenId::try_from(token_id).ok()?;98 withdraw_set_token_property::<T>(&collection, &who, &token_id, key.len() + value.len())99 }100 }101}102103pub fn token_call_sponsor<T>(104 call: UniqueRefungibleTokenCall<T>,105 token: RefungibleTokenHandle<T>,106 who: &T::CrossAccountId,107) -> Option<()>108where109 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,110{111 use UniqueRefungibleTokenCall::*;112113 match call {114 115 ERC165Call(_, _) => None,116117 ERC20(call) => erc20::call_sponsor(call, token, who),118 ERC20UniqueExtensions(call) => erc20::unique_extensions_call_sponsor(call, token, who),119 ERC1633(call) => erc1633::call_sponsor(call, token, who),120 }121}122123mod erc721 {124 use super::*;125126 pub fn call_sponsor<T>(127 call: ERC721Call<T>,128 collection: CollectionHandle<T>,129 _who: &T::CrossAccountId,130 ) -> Option<()>131 where132 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,133 {134 use ERC721Call::*;135136 match call {137 138 ERC165Call(_, _)139 | BalanceOf { .. }140 | OwnerOf { .. }141 | GetApproved { .. }142 | IsApprovedForAll { .. } => None,143144 145 SafeTransferFromWithData { .. }146 | SafeTransferFrom { .. }147 | SetApprovalForAll { .. } => None,148149 TransferFrom { token_id, from, .. } => {150 let token_id = TokenId::try_from(token_id).ok()?;151 let from = T::CrossAccountId::from_eth(from);152 withdraw_transfer::<T>(&collection, &from, &token_id)153 }154155 156 Approve { .. } => None,157 }158 }159160 pub fn enumerable_call_sponsor<T>(161 call: ERC721EnumerableCall<T>,162 _collection: CollectionHandle<T>,163 _who: &T::CrossAccountId,164 ) -> Option<()>165 where166 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,167 {168 use ERC721EnumerableCall::*;169170 match call {171 172 ERC165Call(_, _) | TokenByIndex { .. } | TokenOfOwnerByIndex { .. } | TotalSupply => {173 None174 }175 }176 }177178 pub fn burnable_call_sponsor<T>(179 call: ERC721BurnableCall<T>,180 _collection: CollectionHandle<T>,181 _who: &T::CrossAccountId,182 ) -> Option<()>183 where184 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,185 {186 use ERC721BurnableCall::*;187188 match call {189 190 ERC165Call(_, _) => None,191192 193 Burn { .. } => None,194 }195 }196197 pub fn metadata_call_sponsor<T>(198 call: ERC721MetadataCall<T>,199 _collection: CollectionHandle<T>,200 _who: &T::CrossAccountId,201 ) -> Option<()>202 where203 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,204 {205 use ERC721MetadataCall::*;206207 match call {208 209 ERC165Call(_, _) | NameProxy | SymbolProxy | TokenUri { .. } => None,210 }211 }212213 pub fn unique_extensions_call_sponsor<T>(214 call: ERC721UniqueExtensionsCall<T>,215 collection: CollectionHandle<T>,216 who: &T::CrossAccountId,217 ) -> Option<()>218 where219 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,220 {221 use ERC721UniqueExtensionsCall::*;222223 match call {224 225 ERC165Call(_, _)226 | Name227 | Symbol228 | Description229 | CrossOwnerOf { .. }230 | CrossBalanceOf { .. }231 | Properties { .. }232 | NextTokenId233 | TokenContractAddress { .. }234 | CollectionHelperAddress => None,235236 237 BurnFrom { .. }238 | BurnFromCross { .. }239 | MintBulk { .. }240 | MintBulkWithTokenUri { .. } => None,241242 MintCross { .. } => withdraw_create_item::<T>(243 &collection,244 &who,245 &CreateItemData::NFT(CreateNftData::default()),246 ),247248 TransferCross { token_id, .. }249 | TransferFromCross { token_id, .. }250 | Transfer { token_id, .. } => {251 let token_id = TokenId::try_from(token_id).ok()?;252 withdraw_transfer::<T>(&collection, &who, &token_id)253 }254 }255 }256257 pub fn unique_mintable_call_sponsor<T>(258 call: ERC721UniqueMintableCall<T>,259 collection: CollectionHandle<T>,260 who: &T::CrossAccountId,261 ) -> Option<()>262 where263 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,264 {265 use ERC721UniqueMintableCall::*;266267 match call {268 269 ERC165Call(_, _) => None,270271 272 Mint { .. }273 | MintCheckId { .. }274 | MintWithTokenUri { .. }275 | MintWithTokenUriCheckId { .. } => withdraw_create_item::<T>(276 &collection,277 &who,278 &CreateItemData::NFT(CreateNftData::default()),279 ),280 }281 }282}283284285286287288mod erc20 {289 use super::*;290291 pub fn call_sponsor<T>(292 call: ERC20Call<T>,293 token: RefungibleTokenHandle<T>,294 who: &T::CrossAccountId,295 ) -> Option<()>296 where297 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,298 {299 use ERC20Call::*;300301 match call {302 303 ERC165Call(_, _)304 | Name305 | Symbol306 | TotalSupply307 | Decimals308 | BalanceOf { .. }309 | Allowance { .. } => None,310311 Transfer { .. } => {312 let RefungibleTokenHandle(handle, token_id) = token;313 let token_id = token_id.try_into().ok()?;314 withdraw_transfer::<T>(&handle, &who, &token_id)315 }316 TransferFrom { from, .. } => {317 let RefungibleTokenHandle(handle, token_id) = token;318 let token_id = token_id.try_into().ok()?;319 let from = T::CrossAccountId::from_eth(from);320 withdraw_transfer::<T>(&handle, &from, &token_id)321 }322 Approve { .. } => {323 let RefungibleTokenHandle(handle, token_id) = token;324 let token_id = token_id.try_into().ok()?;325 withdraw_approve::<T>(&handle, who.as_sub(), &token_id)326 }327 }328 }329330 pub fn unique_extensions_call_sponsor<T>(331 call: ERC20UniqueExtensionsCall<T>,332 token: RefungibleTokenHandle<T>,333 who: &T::CrossAccountId,334 ) -> Option<()>335 where336 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,337 {338 use ERC20UniqueExtensionsCall::*;339340 match call {341 342 ERC165Call(_, _) => None,343344 345 AllowanceCross { .. } | BurnFrom { .. } | BurnFromCross { .. } | Repartition { .. } => {346 None347 }348349 TransferCross { .. } | TransferFromCross { .. } => {350 let RefungibleTokenHandle(handle, token_id) = token;351 let token_id = token_id.try_into().ok()?;352 withdraw_transfer::<T>(&handle, &who, &token_id)353 }354355 ApproveCross { .. } => {356 let RefungibleTokenHandle(handle, token_id) = token;357 let token_id = token_id.try_into().ok()?;358 withdraw_approve::<T>(&handle, who.as_sub(), &token_id)359 }360 }361 }362}363364mod erc1633 {365 use super::*;366367 pub fn call_sponsor<T>(368 call: ERC1633Call<T>,369 _token: RefungibleTokenHandle<T>,370 _who: &T::CrossAccountId,371 ) -> Option<()>372 where373 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,374 {375 use ERC1633Call::*;376377 match call {378 379 ERC165Call(_, _) | ParentToken | ParentTokenId => None,380 }381 }382}