pallet_chain_extension_unified_accounts/
lib.rs

1// This file is part of Astar.
2
3// Copyright (C) Stake Technologies Pte.Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later
5
6// Astar is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// Astar is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with Astar. If not, see <http://www.gnu.org/licenses/>.
18
19#![cfg_attr(not(feature = "std"), no_std)]
20
21use astar_primitives::evm::{EvmAddress, UnifiedAddressMapper};
22use core::marker::PhantomData;
23use sp_runtime::DispatchError;
24
25use frame_support::DefaultNoBound;
26use pallet_contracts::chain_extension::{
27    ChainExtension, Environment, Ext, InitState, Result as DispatchResult, RetVal,
28};
29use pallet_unified_accounts::WeightInfo;
30use parity_scale_codec::Encode;
31pub use unified_accounts_chain_extension_types::Command::{self, *};
32
33type UAWeight<T> = <T as pallet_unified_accounts::Config>::WeightInfo;
34
35#[derive(DefaultNoBound)]
36pub struct UnifiedAccountsExtension<T, UA>(PhantomData<(T, UA)>);
37
38impl<T, UA> ChainExtension<T> for UnifiedAccountsExtension<T, UA>
39where
40    T: pallet_contracts::Config + pallet_unified_accounts::Config,
41    UA: UnifiedAddressMapper<T::AccountId>,
42{
43    fn call<E>(&mut self, env: Environment<E, InitState>) -> DispatchResult<RetVal>
44    where
45        E: Ext<T = T>,
46    {
47        let mut env = env.buf_in_buf_out();
48        match env.func_id().try_into().map_err(|_| {
49            DispatchError::Other("Unsupported func id in Unified Accounts Chain Extension")
50        })? {
51            GetEvmAddress => {
52                let account_id: T::AccountId = env.read_as()?;
53                // charge weight
54                env.charge_weight(UAWeight::<T>::to_h160())?;
55                // write to buffer
56                UA::to_h160(&account_id).using_encoded(|r| env.write(r, false, None))?;
57            }
58            GetEvmAddressOrDefault => {
59                let account_id: T::AccountId = env.read_as()?;
60                // charge weight
61                env.charge_weight(UAWeight::<T>::to_h160_or_default())?;
62
63                // write to buffer
64                UA::to_h160_or_default(&account_id).using_encoded(|r| env.write(r, false, None))?;
65            }
66            GetNativeAddress => {
67                let evm_address: EvmAddress = env.read_as()?;
68                // charge weight
69                env.charge_weight(UAWeight::<T>::to_account_id())?;
70                // write to buffer
71                UA::to_account_id(&evm_address).using_encoded(|r| env.write(r, false, None))?;
72            }
73            GetNativeAddressOrDefault => {
74                let evm_address: EvmAddress = env.read_as()?;
75                // charge weight
76                env.charge_weight(UAWeight::<T>::to_account_id_or_default())?;
77
78                // write to buffer
79                UA::to_account_id_or_default(&evm_address)
80                    .using_encoded(|r| env.write(r, false, None))?;
81            }
82        };
83        Ok(RetVal::Converging(0))
84    }
85}