12345678910111213141516171819use pallet_common::CollectionHandle;20use pallet_evm::account::CrossAccountId;21use pallet_fungible::Config as FungibleConfig;22use pallet_refungible::Config as RefungibleConfig;23use pallet_nonfungible::Config as NonfungibleConfig;24use pallet_unique::Config as UniqueConfig;25use up_data_structs::{CreateItemData, CreateNftData, TokenId};2627use super::common;28use crate::runtime_common::sponsoring::*;2930use pallet_refungible::{31 erc::{32 ERC721BurnableCall, ERC721Call, ERC721EnumerableCall, ERC721MetadataCall,33 ERC721UniqueExtensionsCall, ERC721UniqueMintableCall, TokenPropertiesCall,34 UniqueRefungibleCall,35 },36 erc_token::{37 ERC1633Call, ERC20Call, ERC20UniqueExtensionsCall, RefungibleTokenHandle,38 UniqueRefungibleTokenCall,39 },40};4142pub fn call_sponsor<T>(43 call: UniqueRefungibleCall<T>,44 collection: CollectionHandle<T>,45 who: &T::CrossAccountId,46) -> Option<()>47where48 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,49{50 use UniqueRefungibleCall::*;5152 match call {53 54 ERC165Call(_, _) => None,5556 ERC721Enumerable(call) => erc721::enumerable_call_sponsor(call, collection, who),57 ERC721Burnable(call) => erc721::burnable_call_sponsor(call, collection, who),58 ERC721Metadata(call) => erc721::metadata_call_sponsor(call, collection, who),59 Collection(call) => common::collection_call_sponsor(call, collection, who),60 ERC721(call) => erc721::call_sponsor(call, collection, who),61 ERC721UniqueExtensions(call) => {62 erc721::unique_extensions_call_sponsor(call, collection, who)63 }64 ERC721UniqueMintable(call) => erc721::unique_mintable_call_sponsor(call, collection, who),65 TokenProperties(call) => token_properties_call_sponsor(call, collection, who),66 }67}6869pub fn token_properties_call_sponsor<T>(70 call: TokenPropertiesCall<T>,71 collection: CollectionHandle<T>,72 who: &T::CrossAccountId,73) -> Option<()>74where75 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,76{77 use TokenPropertiesCall::*;7879 match call {80 81 ERC165Call(_, _) | Property { .. } | TokenPropertyPermissions => None,8283 84 SetTokenPropertyPermission { .. }85 | SetTokenPropertyPermissions { .. }86 | SetProperties { .. }87 | DeleteProperty { .. }88 | DeleteProperties { .. } => None,8990 SetProperty {91 token_id,92 key,93 value,94 ..95 } => {96 let token_id = TokenId::try_from(token_id).ok()?;97 withdraw_set_token_property::<T>(&collection, who, &token_id, key.len() + value.len())98 }99 }100}101102pub fn token_call_sponsor<T>(103 call: UniqueRefungibleTokenCall<T>,104 token: RefungibleTokenHandle<T>,105 who: &T::CrossAccountId,106) -> Option<()>107where108 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,109{110 use UniqueRefungibleTokenCall::*;111112 match call {113 114 ERC165Call(_, _) => None,115116 ERC20(call) => erc20::call_sponsor(call, token, who),117 ERC20UniqueExtensions(call) => erc20::unique_extensions_call_sponsor(call, token, who),118 ERC1633(call) => erc1633::call_sponsor(call, token, who),119 }120}121122mod erc721 {123 use super::*;124125 pub fn call_sponsor<T>(126 call: ERC721Call<T>,127 collection: CollectionHandle<T>,128 _who: &T::CrossAccountId,129 ) -> Option<()>130 where131 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,132 {133 use ERC721Call::*;134135 match call {136 137 ERC165Call(_, _)138 | BalanceOf { .. }139 | OwnerOf { .. }140 | GetApproved { .. }141 | IsApprovedForAll { .. } => None,142143 144 SafeTransferFromWithData { .. }145 | SafeTransferFrom { .. }146 | SetApprovalForAll { .. } => None,147148 TransferFrom { token_id, from, .. } => {149 let token_id = TokenId::try_from(token_id).ok()?;150 let from = T::CrossAccountId::from_eth(from);151 withdraw_transfer::<T>(&collection, &from, &token_id)152 }153154 155 Approve { .. } => None,156 }157 }158159 pub fn enumerable_call_sponsor<T>(160 call: ERC721EnumerableCall<T>,161 _collection: CollectionHandle<T>,162 _who: &T::CrossAccountId,163 ) -> Option<()>164 where165 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,166 {167 use ERC721EnumerableCall::*;168169 match call {170 171 ERC165Call(_, _) | TokenByIndex { .. } | TokenOfOwnerByIndex { .. } | TotalSupply => {172 None173 }174 }175 }176177 pub fn burnable_call_sponsor<T>(178 call: ERC721BurnableCall<T>,179 _collection: CollectionHandle<T>,180 _who: &T::CrossAccountId,181 ) -> Option<()>182 where183 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,184 {185 use ERC721BurnableCall::*;186187 match call {188 189 ERC165Call(_, _) => None,190191 192 Burn { .. } => None,193 }194 }195196 pub fn metadata_call_sponsor<T>(197 call: ERC721MetadataCall<T>,198 _collection: CollectionHandle<T>,199 _who: &T::CrossAccountId,200 ) -> Option<()>201 where202 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,203 {204 use ERC721MetadataCall::*;205206 match call {207 208 ERC165Call(_, _) | NameProxy | SymbolProxy | TokenUri { .. } => None,209 }210 }211212 pub fn unique_extensions_call_sponsor<T>(213 call: ERC721UniqueExtensionsCall<T>,214 collection: CollectionHandle<T>,215 who: &T::CrossAccountId,216 ) -> Option<()>217 where218 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,219 {220 use ERC721UniqueExtensionsCall::*;221222 match call {223 224 ERC165Call(_, _)225 | Name226 | Symbol227 | Description228 | CrossOwnerOf { .. }229 | OwnerOfCross { .. }230 | BalanceOfCross { .. }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 withdraw_transfer::<T>(&handle, who, &token_id)314 }315 TransferFrom { from, .. } => {316 let RefungibleTokenHandle(handle, token_id) = token;317 let from = T::CrossAccountId::from_eth(from);318 withdraw_transfer::<T>(&handle, &from, &token_id)319 }320 Approve { .. } => {321 let RefungibleTokenHandle(handle, token_id) = token;322 withdraw_approve::<T>(&handle, who.as_sub(), &token_id)323 }324 }325 }326327 pub fn unique_extensions_call_sponsor<T>(328 call: ERC20UniqueExtensionsCall<T>,329 token: RefungibleTokenHandle<T>,330 who: &T::CrossAccountId,331 ) -> Option<()>332 where333 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,334 {335 use ERC20UniqueExtensionsCall::*;336337 match call {338 339 ERC165Call(_, _) => None,340341 342 AllowanceCross { .. }343 | BalanceOfCross { .. }344 | BurnFrom { .. }345 | BurnFromCross { .. }346 | Repartition { .. } => None,347348 TransferCross { .. } | TransferFromCross { .. } => {349 let RefungibleTokenHandle(handle, token_id) = token;350 withdraw_transfer::<T>(&handle, who, &token_id)351 }352353 ApproveCross { .. } => {354 let RefungibleTokenHandle(handle, token_id) = token;355 withdraw_approve::<T>(&handle, who.as_sub(), &token_id)356 }357 }358 }359}360361mod erc1633 {362 use super::*;363364 pub fn call_sponsor<T>(365 call: ERC1633Call<T>,366 _token: RefungibleTokenHandle<T>,367 _who: &T::CrossAccountId,368 ) -> Option<()>369 where370 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,371 {372 use ERC1633Call::*;373374 match call {375 376 ERC165Call(_, _) | ParentToken | ParentTokenId => None,377 }378 }379}