1
// Copyright 2019-2025 PureStake Inc.
2
// This file is part of Moonbeam.
3

            
4
// Moonbeam is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8

            
9
// Moonbeam is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13

            
14
// You should have received a copy of the GNU General Public License
15
// along with Moonbeam.  If not, see <http://www.gnu.org/licenses/>.
16

            
17
//! Precompile to xcm transactor runtime methods via the EVM
18

            
19
use crate::functions::{CurrencyIdOf, GetDataLimit, TransactorOf, XcmTransactorWrapper};
20
use fp_evm::PrecompileHandle;
21
use frame_support::dispatch::{GetDispatchInfo, PostDispatchInfo};
22
use pallet_evm::AddressMapping;
23
use precompile_utils::prelude::*;
24
use sp_core::{H160, U256};
25
use sp_runtime::traits::Dispatchable;
26
use sp_std::{convert::TryFrom, marker::PhantomData};
27
use xcm::latest::Location;
28
use xcm_primitives::AccountIdToCurrencyId;
29

            
30
/// A precompile to wrap the functionality from xcm transactor
31
pub struct XcmTransactorPrecompileV1<Runtime>(PhantomData<Runtime>);
32

            
33
222
#[precompile_utils::precompile]
34
impl<Runtime> XcmTransactorPrecompileV1<Runtime>
35
where
36
	Runtime: pallet_xcm_transactor::Config + pallet_evm::Config + frame_system::Config,
37
	Runtime::RuntimeCall: Dispatchable<PostInfo = PostDispatchInfo> + GetDispatchInfo,
38
	Runtime::RuntimeCall: From<pallet_xcm_transactor::Call<Runtime>>,
39
	<Runtime::RuntimeCall as Dispatchable>::RuntimeOrigin: From<Option<Runtime::AccountId>>,
40
	TransactorOf<Runtime>: TryFrom<u8>,
41
	Runtime::AccountId: Into<H160>,
42
	Runtime: AccountIdToCurrencyId<Runtime::AccountId, CurrencyIdOf<Runtime>>,
43
	<Runtime as pallet_evm::Config>::AddressMapping: AddressMapping<Runtime::AccountId>,
44
{
45
	#[precompile::public("indexToAccount(uint16)")]
46
	#[precompile::public("index_to_account(uint16)")]
47
	#[precompile::view]
48
2
	fn index_to_account(handle: &mut impl PrecompileHandle, index: u16) -> EvmResult<Address> {
49
2
		XcmTransactorWrapper::<Runtime>::account_index(handle, index)
50
2
	}
51

            
52
	#[precompile::public("transactInfo((uint8,bytes[]))")]
53
	#[precompile::public("transact_info((uint8,bytes[]))")]
54
	#[precompile::view]
55
2
	fn transact_info(
56
2
		handle: &mut impl PrecompileHandle,
57
2
		location: Location,
58
2
	) -> EvmResult<(u64, U256, u64)> {
59
2
		XcmTransactorWrapper::<Runtime>::transact_info(handle, location)
60
2
	}
61

            
62
	#[precompile::public("transactInfoWithSigned((uint8,bytes[]))")]
63
	#[precompile::public("transact_info_with_signed((uint8,bytes[]))")]
64
	#[precompile::view]
65
2
	fn transact_info_with_signed(
66
2
		handle: &mut impl PrecompileHandle,
67
2
		location: Location,
68
2
	) -> EvmResult<(u64, u64, u64)> {
69
2
		XcmTransactorWrapper::<Runtime>::transact_info_with_signed(handle, location)
70
2
	}
71

            
72
	#[precompile::public("feePerSecond((uint8,bytes[]))")]
73
	#[precompile::public("fee_per_second((uint8,bytes[]))")]
74
	#[precompile::view]
75
2
	fn fee_per_second(handle: &mut impl PrecompileHandle, location: Location) -> EvmResult<U256> {
76
2
		XcmTransactorWrapper::<Runtime>::fee_per_second(handle, location)
77
2
	}
78

            
79
	#[precompile::public(
80
		"transactThroughDerivativeMultilocation(\
81
		uint8,\
82
		uint16,\
83
		(uint8,bytes[]),\
84
		uint64,\
85
		bytes)"
86
	)]
87
	#[precompile::public(
88
		"transact_through_derivative_multilocation(\
89
		uint8,\
90
		uint16,\
91
		(uint8,bytes[]),\
92
		uint64,\
93
		bytes)"
94
	)]
95
1
	fn transact_through_derivative_multilocation(
96
1
		handle: &mut impl PrecompileHandle,
97
1
		transactor: u8,
98
1
		index: u16,
99
1
		fee_asset: Location,
100
1
		weight: u64,
101
1
		inner_call: BoundedBytes<GetDataLimit>,
102
1
	) -> EvmResult {
103
1
		XcmTransactorWrapper::<Runtime>::transact_through_derivative_multilocation(
104
1
			handle, transactor, index, fee_asset, weight, inner_call,
105
1
		)
106
1
	}
107

            
108
	#[precompile::public("transactThroughDerivative(uint8,uint16,address,uint64,bytes)")]
109
	#[precompile::public("transact_through_derivative(uint8,uint16,address,uint64,bytes)")]
110
1
	fn transact_through_derivative(
111
1
		handle: &mut impl PrecompileHandle,
112
1
		transactor: u8,
113
1
		index: u16,
114
1
		currency_id: Address,
115
1
		weight: u64,
116
1
		inner_call: BoundedBytes<GetDataLimit>,
117
1
	) -> EvmResult {
118
1
		XcmTransactorWrapper::<Runtime>::transact_through_derivative(
119
1
			handle,
120
1
			transactor,
121
1
			index,
122
1
			currency_id,
123
1
			weight,
124
1
			inner_call,
125
1
		)
126
1
	}
127

            
128
	#[precompile::public(
129
		"transactThroughSignedMultilocation(\
130
		(uint8,bytes[]),\
131
		(uint8,bytes[]),\
132
		uint64,\
133
		bytes)"
134
	)]
135
	#[precompile::public(
136
		"transact_through_signed_multilocation(\
137
		(uint8,bytes[]),\
138
		(uint8,bytes[]),\
139
		uint64,\
140
		bytes)"
141
	)]
142
2
	fn transact_through_signed_multilocation(
143
2
		handle: &mut impl PrecompileHandle,
144
2
		dest: Location,
145
2
		fee_asset: Location,
146
2
		weight: u64,
147
2
		call: BoundedBytes<GetDataLimit>,
148
2
	) -> EvmResult {
149
2
		XcmTransactorWrapper::<Runtime>::transact_through_signed_multilocation(
150
2
			handle, dest, fee_asset, weight, call,
151
2
		)
152
2
	}
153

            
154
	#[precompile::public("transactThroughSigned((uint8,bytes[]),address,uint64,bytes)")]
155
	#[precompile::public("transact_through_signed((uint8,bytes[]),address,uint64,bytes)")]
156
1
	fn transact_through_signed(
157
1
		handle: &mut impl PrecompileHandle,
158
1
		dest: Location,
159
1
		fee_asset: Address,
160
1
		weight: u64,
161
1
		call: BoundedBytes<GetDataLimit>,
162
1
	) -> EvmResult {
163
1
		XcmTransactorWrapper::<Runtime>::transact_through_signed(
164
1
			handle, dest, fee_asset, weight, call,
165
1
		)
166
1
	}
167

            
168
	#[precompile::public("encodeUtilityAsDerivative(uint8,uint16,bytes)")]
169
	#[precompile::public("encode_utility_as_derivative(uint8,uint16,bytes)")]
170
	#[precompile::view]
171
	fn encode_utility_as_derivative(
172
		handle: &mut impl PrecompileHandle,
173
		transactor: u8,
174
		index: u16,
175
		inner_call: BoundedBytes<GetDataLimit>,
176
	) -> EvmResult<UnboundedBytes> {
177
		XcmTransactorWrapper::<Runtime>::encode_utility_as_derivative(
178
			handle, transactor, index, inner_call,
179
		)
180
	}
181
}