1pub mod sponsoring;23use fp_evm::PrecompileResult;4use pallet_common::{5 CollectionById,6 erc::CommonEvmHandler,7 eth::{map_eth_to_id, map_eth_to_token_id},8};9use pallet_fungible::FungibleHandle;10use pallet_nonfungible::NonfungibleHandle;11use pallet_refungible::{RefungibleHandle, erc::RefungibleTokenHandle};12use sp_std::borrow::ToOwned;13use sp_std::vec::Vec;14use sp_core::{H160, U256};15use crate::{CollectionMode, Config, dispatch::Dispatched};16use pallet_common::CollectionHandle;1718pub struct NftErcSupport<T: Config>(core::marker::PhantomData<T>);1920impl<T: Config> pallet_evm::OnMethodCall<T> for NftErcSupport<T> {21 fn is_reserved(target: &H160) -> bool {22 map_eth_to_id(target).is_some()23 }24 fn is_used(target: &H160) -> bool {25 map_eth_to_id(target)26 .map(<CollectionById<T>>::contains_key)27 .unwrap_or(false)28 }29 fn get_code(target: &H160) -> Option<Vec<u8>> {30 if let Some(collection_id) = map_eth_to_id(target) {31 let collection = <CollectionById<T>>::get(collection_id)?;32 Some(33 match collection.mode {34 CollectionMode::NFT => <NonfungibleHandle<T>>::CODE,35 CollectionMode::Fungible(_) => <FungibleHandle<T>>::CODE,36 CollectionMode::ReFungible => <RefungibleHandle<T>>::CODE,37 }38 .to_owned(),39 )40 } else if let Some((collection_id, _token_id)) = map_eth_to_token_id(target) {41 let collection = <CollectionById<T>>::get(collection_id)?;42 if collection.mode != CollectionMode::ReFungible {43 return None;44 }45 46 Some(<RefungibleTokenHandle<T>>::CODE.to_owned())47 } else {48 None49 }50 }51 fn call(52 source: &H160,53 target: &H160,54 gas_limit: u64,55 input: &[u8],56 value: U256,57 ) -> Option<PrecompileResult> {58 if let Some(collection_id) = map_eth_to_id(target) {59 let collection = <CollectionHandle<T>>::new_with_gas_limit(collection_id, gas_limit)?;60 let dispatched = Dispatched::dispatch(collection);6162 match dispatched {63 Dispatched::Fungible(h) => h.call(source, input, value),64 Dispatched::Nonfungible(h) => h.call(source, input, value),65 Dispatched::Refungible(h) => h.call(source, input, value),66 }67 } else if let Some((collection_id, token_id)) = map_eth_to_token_id(target) {68 let collection = <CollectionHandle<T>>::new_with_gas_limit(collection_id, gas_limit)?;69 if collection.mode != CollectionMode::ReFungible {70 return None;71 }7273 let handle = RefungibleHandle::cast(collection);74 75 RefungibleTokenHandle(handle, token_id).call(source, input, value)76 } else {77 None78 }79 }80}