#![cfg_attr(not(feature = "std"), no_std)]
use astar_primitives::evm::{EvmAddress, UnifiedAddressMapper};
use core::marker::PhantomData;
use sp_runtime::DispatchError;
use frame_support::DefaultNoBound;
use pallet_contracts::chain_extension::{
ChainExtension, Environment, Ext, InitState, Result as DispatchResult, RetVal,
};
use pallet_unified_accounts::WeightInfo;
use parity_scale_codec::Encode;
pub use unified_accounts_chain_extension_types::Command::{self, *};
type UAWeight<T> = <T as pallet_unified_accounts::Config>::WeightInfo;
#[derive(DefaultNoBound)]
pub struct UnifiedAccountsExtension<T, UA>(PhantomData<(T, UA)>);
impl<T, UA> ChainExtension<T> for UnifiedAccountsExtension<T, UA>
where
T: pallet_contracts::Config + pallet_unified_accounts::Config,
UA: UnifiedAddressMapper<T::AccountId>,
{
fn call<E>(&mut self, env: Environment<E, InitState>) -> DispatchResult<RetVal>
where
E: Ext<T = T>,
{
let mut env = env.buf_in_buf_out();
match env.func_id().try_into().map_err(|_| {
DispatchError::Other("Unsupported func id in Unified Accounts Chain Extension")
})? {
GetEvmAddress => {
let account_id: T::AccountId = env.read_as()?;
env.charge_weight(UAWeight::<T>::to_h160())?;
UA::to_h160(&account_id).using_encoded(|r| env.write(r, false, None))?;
}
GetEvmAddressOrDefault => {
let account_id: T::AccountId = env.read_as()?;
env.charge_weight(UAWeight::<T>::to_h160_or_default())?;
UA::to_h160_or_default(&account_id).using_encoded(|r| env.write(r, false, None))?;
}
GetNativeAddress => {
let evm_address: EvmAddress = env.read_as()?;
env.charge_weight(UAWeight::<T>::to_account_id())?;
UA::to_account_id(&evm_address).using_encoded(|r| env.write(r, false, None))?;
}
GetNativeAddressOrDefault => {
let evm_address: EvmAddress = env.read_as()?;
env.charge_weight(UAWeight::<T>::to_account_id_or_default())?;
UA::to_account_id_or_default(&evm_address)
.using_encoded(|r| env.write(r, false, None))?;
}
};
Ok(RetVal::Converging(0))
}
}