12345678910111213141516171819use crate::{Config, sponsorship::*};20use evm_coder::{Call, abi::AbiReader};21use pallet_common::{CollectionHandle, eth::map_eth_to_id};22use sp_core::H160;23use sp_std::prelude::*;24use up_sponsorship::SponsorshipHandler;25use core::marker::PhantomData;26use core::convert::TryInto;27use up_data_structs::{TokenId, CreateItemData, CreateNftData};28use up_evm_mapping::EvmBackwardsAddressMapping;29use pallet_common::account::CrossAccountId;3031use pallet_nonfungible::erc::{32 UniqueNFTCall, ERC721UniqueExtensionsCall, ERC721MintableCall, ERC721Call,33};34use pallet_fungible::erc::{UniqueFungibleCall, ERC20Call};3536pub struct UniqueEthSponsorshipHandler<T: Config>(PhantomData<*const T>);37impl<T: Config> SponsorshipHandler<H160, (H160, Vec<u8>)> for UniqueEthSponsorshipHandler<T> {38 fn get_sponsor(who: &H160, call: &(H160, Vec<u8>)) -> Option<H160> {39 let collection_id = map_eth_to_id(&call.0)?;40 let collection = <CollectionHandle<T>>::new(collection_id)?;41 let sponsor = collection.sponsorship.sponsor()?.clone();42 let sponsor =43 <T as pallet_common::Config>::EvmBackwardsAddressMapping::from_account_id(sponsor);44 let who = T::CrossAccountId::from_eth(*who);45 let (method_id, mut reader) = AbiReader::new_call(&call.1).ok()?;46 match &collection.mode {47 crate::CollectionMode::NFT => {48 let call = <UniqueNFTCall<T>>::parse(method_id, &mut reader).ok()??;49 match call {50 UniqueNFTCall::ERC721UniqueExtensions(51 ERC721UniqueExtensionsCall::Transfer { token_id, .. },52 ) => {53 let token_id: TokenId = token_id.try_into().ok()?;54 withdraw_transfer::<T>(&collection, &who, &token_id).map(|()| sponsor)55 }56 UniqueNFTCall::ERC721Mintable(57 ERC721MintableCall::Mint { token_id, .. }58 | ERC721MintableCall::MintWithTokenUri { token_id, .. },59 ) => {60 let _token_id: TokenId = token_id.try_into().ok()?;61 withdraw_create_item::<T>(62 &collection,63 &who,64 &CreateItemData::NFT(CreateNftData::default()),65 )66 .map(|()| sponsor)67 }68 UniqueNFTCall::ERC721(ERC721Call::TransferFrom { token_id, from, .. }) => {69 let token_id: TokenId = token_id.try_into().ok()?;70 let from = T::CrossAccountId::from_eth(from);71 withdraw_transfer::<T>(&collection, &from, &token_id).map(|()| sponsor)72 }73 UniqueNFTCall::ERC721(ERC721Call::Approve { token_id, .. }) => {74 let token_id: TokenId = token_id.try_into().ok()?;75 withdraw_approve::<T>(&collection, who.as_sub(), &token_id)76 .map(|()| sponsor)77 }78 _ => None,79 }80 }81 crate::CollectionMode::Fungible(_) => {82 let call = <UniqueFungibleCall<T>>::parse(method_id, &mut reader).ok()??;83 #[allow(clippy::single_match)]84 match call {85 UniqueFungibleCall::ERC20(ERC20Call::Transfer { .. }) => {86 withdraw_transfer::<T>(&collection, &who, &TokenId::default())87 .map(|()| sponsor)88 }89 UniqueFungibleCall::ERC20(ERC20Call::TransferFrom { from, .. }) => {90 let from = T::CrossAccountId::from_eth(from);91 withdraw_transfer::<T>(&collection, &from, &TokenId::default())92 .map(|()| sponsor)93 }94 UniqueFungibleCall::ERC20(ERC20Call::Approve { .. }) => {95 withdraw_approve::<T>(&collection, who.as_sub(), &TokenId::default())96 .map(|()| sponsor)97 }98 _ => None,99 }100 }101 _ => None,102 }103 }104}