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_existing_token_property::<T>(98 &collection,99 who,100 &token_id,101 key.len() + value.len(),102 )103 }104 }105}106107pub fn token_call_sponsor<T>(108 call: UniqueRefungibleTokenCall<T>,109 token: RefungibleTokenHandle<T>,110 who: &T::CrossAccountId,111) -> Option<()>112where113 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,114{115 use UniqueRefungibleTokenCall::*;116117 match call {118 119 ERC165Call(_, _) => None,120121 ERC20(call) => erc20::call_sponsor(call, token, who),122 ERC20UniqueExtensions(call) => erc20::unique_extensions_call_sponsor(call, token, who),123 ERC1633(call) => erc1633::call_sponsor(call, token, who),124 }125}126127mod erc721 {128 use super::*;129130 pub fn call_sponsor<T>(131 call: ERC721Call<T>,132 collection: CollectionHandle<T>,133 _who: &T::CrossAccountId,134 ) -> Option<()>135 where136 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,137 {138 use ERC721Call::*;139140 match call {141 142 ERC165Call(_, _)143 | BalanceOf { .. }144 | OwnerOf { .. }145 | GetApproved { .. }146 | IsApprovedForAll { .. } => None,147148 149 SafeTransferFromWithData { .. }150 | SafeTransferFrom { .. }151 | SetApprovalForAll { .. } => None,152153 TransferFrom { token_id, from, .. } => {154 let token_id = TokenId::try_from(token_id).ok()?;155 let from = T::CrossAccountId::from_eth(from);156 withdraw_transfer::<T>(&collection, &from, &token_id)157 }158159 160 Approve { .. } => None,161 }162 }163164 pub fn enumerable_call_sponsor<T>(165 call: ERC721EnumerableCall<T>,166 _collection: CollectionHandle<T>,167 _who: &T::CrossAccountId,168 ) -> Option<()>169 where170 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,171 {172 use ERC721EnumerableCall::*;173174 match call {175 176 ERC165Call(_, _) | TokenByIndex { .. } | TokenOfOwnerByIndex { .. } | TotalSupply => {177 None178 }179 }180 }181182 pub fn burnable_call_sponsor<T>(183 call: ERC721BurnableCall<T>,184 _collection: CollectionHandle<T>,185 _who: &T::CrossAccountId,186 ) -> Option<()>187 where188 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,189 {190 use ERC721BurnableCall::*;191192 match call {193 194 ERC165Call(_, _) => None,195196 197 Burn { .. } => None,198 }199 }200201 pub fn metadata_call_sponsor<T>(202 call: ERC721MetadataCall<T>,203 _collection: CollectionHandle<T>,204 _who: &T::CrossAccountId,205 ) -> Option<()>206 where207 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,208 {209 use ERC721MetadataCall::*;210211 match call {212 213 ERC165Call(_, _) | NameProxy | SymbolProxy | TokenUri { .. } => None,214 }215 }216217 pub fn unique_extensions_call_sponsor<T>(218 call: ERC721UniqueExtensionsCall<T>,219 collection: CollectionHandle<T>,220 who: &T::CrossAccountId,221 ) -> Option<()>222 where223 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,224 {225 use ERC721UniqueExtensionsCall::*;226227 match call {228 229 ERC165Call(_, _)230 | Name231 | Symbol232 | Description233 | CrossOwnerOf { .. }234 | OwnerOfCross { .. }235 | BalanceOfCross { .. }236 | Properties { .. }237 | NextTokenId238 | TokenContractAddress { .. }239 | CollectionHelperAddress => None,240241 242 BurnFrom { .. }243 | BurnFromCross { .. }244 | MintBulk { .. }245 | MintBulkCross { .. }246 | MintBulkWithTokenUri { .. } => None,247248 MintCross { .. } => withdraw_create_item::<T>(249 &collection,250 who,251 &CreateItemData::NFT(CreateNftData::default()),252 ),253254 TransferCross { token_id, .. }255 | TransferFromCross { token_id, .. }256 | Transfer { token_id, .. } => {257 let token_id = TokenId::try_from(token_id).ok()?;258 withdraw_transfer::<T>(&collection, who, &token_id)259 }260 }261 }262263 pub fn unique_mintable_call_sponsor<T>(264 call: ERC721UniqueMintableCall<T>,265 collection: CollectionHandle<T>,266 who: &T::CrossAccountId,267 ) -> Option<()>268 where269 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,270 {271 use ERC721UniqueMintableCall::*;272273 match call {274 275 ERC165Call(_, _) => None,276277 278 Mint { .. }279 | MintCheckId { .. }280 | MintWithTokenUri { .. }281 | MintWithTokenUriCheckId { .. } => withdraw_create_item::<T>(282 &collection,283 who,284 &CreateItemData::NFT(CreateNftData::default()),285 ),286 }287 }288}289290291292293294mod erc20 {295 use super::*;296297 pub fn call_sponsor<T>(298 call: ERC20Call<T>,299 token: RefungibleTokenHandle<T>,300 who: &T::CrossAccountId,301 ) -> Option<()>302 where303 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,304 {305 use ERC20Call::*;306307 match call {308 309 ERC165Call(_, _)310 | Name311 | Symbol312 | TotalSupply313 | Decimals314 | BalanceOf { .. }315 | Allowance { .. } => None,316317 Transfer { .. } => {318 let RefungibleTokenHandle(handle, token_id) = token;319 withdraw_transfer::<T>(&handle, who, &token_id)320 }321 TransferFrom { from, .. } => {322 let RefungibleTokenHandle(handle, token_id) = token;323 let from = T::CrossAccountId::from_eth(from);324 withdraw_transfer::<T>(&handle, &from, &token_id)325 }326 Approve { .. } => {327 let RefungibleTokenHandle(handle, token_id) = token;328 withdraw_approve::<T>(&handle, who.as_sub(), &token_id)329 }330 }331 }332333 pub fn unique_extensions_call_sponsor<T>(334 call: ERC20UniqueExtensionsCall<T>,335 token: RefungibleTokenHandle<T>,336 who: &T::CrossAccountId,337 ) -> Option<()>338 where339 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,340 {341 use ERC20UniqueExtensionsCall::*;342343 match call {344 345 ERC165Call(_, _) => None,346347 348 AllowanceCross { .. }349 | BalanceOfCross { .. }350 | BurnFrom { .. }351 | BurnFromCross { .. }352 | Repartition { .. } => None,353354 TransferCross { .. } | TransferFromCross { .. } => {355 let RefungibleTokenHandle(handle, token_id) = token;356 withdraw_transfer::<T>(&handle, who, &token_id)357 }358359 ApproveCross { .. } => {360 let RefungibleTokenHandle(handle, token_id) = token;361 withdraw_approve::<T>(&handle, who.as_sub(), &token_id)362 }363 }364 }365}366367mod erc1633 {368 use super::*;369370 pub fn call_sponsor<T>(371 call: ERC1633Call<T>,372 _token: RefungibleTokenHandle<T>,373 _who: &T::CrossAccountId,374 ) -> Option<()>375 where376 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,377 {378 use ERC1633Call::*;379380 match call {381 382 ERC165Call(_, _) | ParentToken | ParentTokenId => None,383 }384 }385}