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 | MintBulkWithTokenUri { .. } => None,246247 MintCross { .. } => withdraw_create_item::<T>(248 &collection,249 who,250 &CreateItemData::NFT(CreateNftData::default()),251 ),252253 TransferCross { token_id, .. }254 | TransferFromCross { token_id, .. }255 | Transfer { token_id, .. } => {256 let token_id = TokenId::try_from(token_id).ok()?;257 withdraw_transfer::<T>(&collection, who, &token_id)258 }259 }260 }261262 pub fn unique_mintable_call_sponsor<T>(263 call: ERC721UniqueMintableCall<T>,264 collection: CollectionHandle<T>,265 who: &T::CrossAccountId,266 ) -> Option<()>267 where268 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,269 {270 use ERC721UniqueMintableCall::*;271272 match call {273 274 ERC165Call(_, _) => None,275276 277 Mint { .. }278 | MintCheckId { .. }279 | MintWithTokenUri { .. }280 | MintWithTokenUriCheckId { .. } => withdraw_create_item::<T>(281 &collection,282 who,283 &CreateItemData::NFT(CreateNftData::default()),284 ),285 }286 }287}288289290291292293mod erc20 {294 use super::*;295296 pub fn call_sponsor<T>(297 call: ERC20Call<T>,298 token: RefungibleTokenHandle<T>,299 who: &T::CrossAccountId,300 ) -> Option<()>301 where302 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,303 {304 use ERC20Call::*;305306 match call {307 308 ERC165Call(_, _)309 | Name310 | Symbol311 | TotalSupply312 | Decimals313 | BalanceOf { .. }314 | Allowance { .. } => None,315316 Transfer { .. } => {317 let RefungibleTokenHandle(handle, token_id) = token;318 withdraw_transfer::<T>(&handle, who, &token_id)319 }320 TransferFrom { from, .. } => {321 let RefungibleTokenHandle(handle, token_id) = token;322 let from = T::CrossAccountId::from_eth(from);323 withdraw_transfer::<T>(&handle, &from, &token_id)324 }325 Approve { .. } => {326 let RefungibleTokenHandle(handle, token_id) = token;327 withdraw_approve::<T>(&handle, who.as_sub(), &token_id)328 }329 }330 }331332 pub fn unique_extensions_call_sponsor<T>(333 call: ERC20UniqueExtensionsCall<T>,334 token: RefungibleTokenHandle<T>,335 who: &T::CrossAccountId,336 ) -> Option<()>337 where338 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,339 {340 use ERC20UniqueExtensionsCall::*;341342 match call {343 344 ERC165Call(_, _) => None,345346 347 AllowanceCross { .. }348 | BalanceOfCross { .. }349 | BurnFrom { .. }350 | BurnFromCross { .. }351 | Repartition { .. } => None,352353 TransferCross { .. } | TransferFromCross { .. } => {354 let RefungibleTokenHandle(handle, token_id) = token;355 withdraw_transfer::<T>(&handle, who, &token_id)356 }357358 ApproveCross { .. } => {359 let RefungibleTokenHandle(handle, token_id) = token;360 withdraw_approve::<T>(&handle, who.as_sub(), &token_id)361 }362 }363 }364}365366mod erc1633 {367 use super::*;368369 pub fn call_sponsor<T>(370 call: ERC1633Call<T>,371 _token: RefungibleTokenHandle<T>,372 _who: &T::CrossAccountId,373 ) -> Option<()>374 where375 T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,376 {377 use ERC1633Call::*;378379 match call {380 381 ERC165Call(_, _) | ParentToken | ParentTokenId => None,382 }383 }384}