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 { .. } => None,8384 85 SetTokenPropertyPermission { .. }86 | SetProperties { .. }87 | DeleteProperty { .. }88 | DeleteProperties { .. } => None,8990 SetProperty {91 token_id,92 key,93 value,94 ..95 } => {96 let token_id: TokenId = token_id.try_into().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 { .. }142 | CollectionHelperAddress => None,143144 145 SafeTransferFromWithData { .. }146 | SafeTransferFrom { .. }147 | SetApprovalForAll { .. } => None,148149 TransferFrom { token_id, from, .. } => {150 let token_id: TokenId = token_id.try_into().ok()?;151 let from = T::CrossAccountId::from_eth(from);152 withdraw_transfer::<T>(&collection, &from, &token_id)153 }154 Approve { _token_id, .. } => {155 let token_id: TokenId = _token_id.try_into().ok()?;156 withdraw_approve::<T>(&collection, who.as_sub(), &token_id)157 }158 }159 }160161 pub fn enumerable_call_sponsor<T>(162 call: ERC721EnumerableCall<T>,163 _collection: CollectionHandle<T>,164 _who: &T::CrossAccountId,165 ) -> Option<()>166 where167 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,168 {169 use ERC721EnumerableCall::*;170171 match call {172 173 ERC165Call(_, _) | TokenByIndex { .. } | TokenOfOwnerByIndex { .. } | TotalSupply => {174 None175 }176 }177 }178179 pub fn burnable_call_sponsor<T>(180 call: ERC721BurnableCall<T>,181 _collection: CollectionHandle<T>,182 _who: &T::CrossAccountId,183 ) -> Option<()>184 where185 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,186 {187 use ERC721BurnableCall::*;188189 match call {190 191 ERC165Call(_, _) => None,192193 194 Burn { .. } => None,195 }196 }197198 pub fn metadata_call_sponsor<T>(199 call: ERC721MetadataCall<T>,200 _collection: CollectionHandle<T>,201 _who: &T::CrossAccountId,202 ) -> Option<()>203 where204 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,205 {206 use ERC721MetadataCall::*;207208 match call {209 210 ERC165Call(_, _) | NameProxy | SymbolProxy | TokenUri { .. } => None,211 }212 }213214 pub fn unique_extensions_call_sponsor<T>(215 call: ERC721UniqueExtensionsCall<T>,216 collection: CollectionHandle<T>,217 who: &T::CrossAccountId,218 ) -> Option<()>219 where220 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,221 {222 use ERC721UniqueExtensionsCall::*;223224 match call {225 226 ERC165Call(_, _)227 | Name228 | Symbol229 | Description230 | CrossOwnerOf { .. }231 | Properties { .. }232 | NextTokenId233 | TokenContractAddress { .. } => None,234235 236 TransferCross { .. }237 | TransferFromCross { .. }238 | BurnFrom { .. }239 | BurnFromCross { .. }240 | MintBulk { .. }241 | MintBulkWithTokenUri { .. } => None,242243 Transfer { token_id, .. } => {244 let token_id: TokenId = token_id.try_into().ok()?;245 withdraw_transfer::<T>(&collection, &who, &token_id)246 }247 }248 }249250 pub fn unique_mintable_call_sponsor<T>(251 call: ERC721UniqueMintableCall<T>,252 collection: CollectionHandle<T>,253 who: &T::CrossAccountId,254 ) -> Option<()>255 where256 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,257 {258 use ERC721UniqueMintableCall::*;259260 match call {261 262 ERC165Call(_, _) | MintingFinished => None,263264 265 FinishMinting => None,266267 Mint { .. }268 | MintCheckId { .. }269 | MintWithTokenUri { .. }270 | MintWithTokenUriCheckId { .. } => withdraw_create_item::<T>(271 &collection,272 &who,273 &CreateItemData::NFT(CreateNftData::default()),274 ),275 }276 }277}278279mod erc20 {280 use super::*;281282 pub fn call_sponsor<T>(283 call: ERC20Call<T>,284 token: RefungibleTokenHandle<T>,285 who: &T::CrossAccountId,286 ) -> Option<()>287 where288 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,289 {290 use ERC20Call::*;291292 match call {293 294 ERC165Call(_, _)295 | Name296 | Symbol297 | TotalSupply298 | Decimals299 | BalanceOf { .. }300 | Allowance { .. } => None,301302 Transfer { .. } => {303 let RefungibleTokenHandle(handle, token_id) = token;304 let token_id = token_id.try_into().ok()?;305 withdraw_transfer::<T>(&handle, &who, &token_id)306 }307 TransferFrom { from, .. } => {308 let RefungibleTokenHandle(handle, token_id) = token;309 let token_id = token_id.try_into().ok()?;310 let from = T::CrossAccountId::from_eth(from);311 withdraw_transfer::<T>(&handle, &from, &token_id)312 }313 Approve { .. } => {314 let RefungibleTokenHandle(handle, token_id) = token;315 let token_id = token_id.try_into().ok()?;316 withdraw_approve::<T>(&handle, who.as_sub(), &token_id)317 }318 }319 }320321 pub fn unique_extensions_call_sponsor<T>(322 call: ERC20UniqueExtensionsCall<T>,323 _token: RefungibleTokenHandle<T>,324 _who: &T::CrossAccountId,325 ) -> Option<()>326 where327 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,328 {329 use ERC20UniqueExtensionsCall::*;330331 match call {332 333 ERC165Call(_, _) => None,334335 336 BurnFrom { .. } | Repartition { .. } => None,337 }338 }339}340341mod erc1633 {342 use super::*;343344 pub fn call_sponsor<T>(345 call: ERC1633Call<T>,346 _token: RefungibleTokenHandle<T>,347 _who: &T::CrossAccountId,348 ) -> Option<()>349 where350 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,351 {352 use ERC1633Call::*;353354 match call {355 356 ERC165Call(_, _) | ParentToken | ParentTokenId => None,357 }358 }359}