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
use crate::AvailableStakeCalls;
18
use crate::StakeEncodeCall;
19
use cumulus_primitives_core::{relay_chain::HrmpChannelId, ParaId};
20
use parity_scale_codec::{Decode, Encode};
21
use sp_runtime::traits::{AccountIdLookup, StaticLookup};
22
use sp_runtime::AccountId32;
23
use sp_std::vec::Vec;
24

            
25
#[derive(Encode, Decode)]
26
pub enum RelayCall {
27
	#[codec(index = 1u8)]
28
	Stake(StakeCall),
29
	#[codec(index = 2u8)]
30
	Hrmp(HrmpCall),
31
}
32

            
33
#[derive(Encode, Decode)]
34
pub enum StakeCall {
35
	#[codec(index = 0u16)]
36
	// the index should match the position of the dispatchable in the target pallet
37
	Bond(
38
		#[codec(compact)] cumulus_primitives_core::relay_chain::Balance,
39
		pallet_staking::RewardDestination<AccountId32>,
40
	),
41
	#[codec(index = 1u16)]
42
	BondExtra(#[codec(compact)] cumulus_primitives_core::relay_chain::Balance),
43
	#[codec(index = 2u16)]
44
	Unbond(#[codec(compact)] cumulus_primitives_core::relay_chain::Balance),
45
	#[codec(index = 3u16)]
46
	WithdrawUnbonded(u32),
47
	#[codec(index = 4u16)]
48
	Validate(pallet_staking::ValidatorPrefs),
49
	#[codec(index = 5u16)]
50
	Nominate(Vec<<AccountIdLookup<AccountId32, ()> as StaticLookup>::Source>),
51
	#[codec(index = 6u16)]
52
	Chill,
53
	#[codec(index = 7u16)]
54
	SetPayee(pallet_staking::RewardDestination<AccountId32>),
55
	#[codec(index = 8u16)]
56
	SetController,
57
	#[codec(index = 19u16)]
58
	Rebond(#[codec(compact)] cumulus_primitives_core::relay_chain::Balance),
59
}
60

            
61
// HRMP call encoding, needed for xcm transactor pallet
62
#[derive(Encode, Decode)]
63
pub enum HrmpCall {
64
	#[codec(index = 0u8)]
65
	InitOpenChannel(ParaId, u32, u32),
66
	#[codec(index = 1u8)]
67
	AcceptOpenChannel(ParaId),
68
	#[codec(index = 2u8)]
69
	CloseChannel(HrmpChannelId),
70
	#[codec(index = 6u8)]
71
	CancelOpenChannel(HrmpChannelId, u32),
72
}
73

            
74
use pallet_xcm_transactor::relay_indices::*;
75
use xcm_primitives::XcmTransact;
76
pub const TEST_RELAY_INDICES: RelayChainIndices = RelayChainIndices {
77
	staking: 1u8,
78
	utility: 0u8,
79
	hrmp: 2u8,
80
	bond: 0u8,
81
	bond_extra: 1u8,
82
	unbond: 2u8,
83
	withdraw_unbonded: 3u8,
84
	validate: 4u8,
85
	nominate: 5u8,
86
	chill: 6u8,
87
	set_payee: 7u8,
88
	set_controller: 8u8,
89
	rebond: 19u8,
90
	as_derivative: 0u8,
91
	init_open_channel: 0u8,
92
	accept_open_channel: 1u8,
93
	close_channel: 2u8,
94
	cancel_open_request: 6u8,
95
};
96

            
97
pub struct TestEncoder;
98

            
99
impl StakeEncodeCall for TestEncoder {
100
10
	fn encode_call<Transactor: XcmTransact>(
101
10
		_transactor: Transactor,
102
10
		call: AvailableStakeCalls,
103
10
	) -> Vec<u8> {
104
10
		match call {
105
1
			AvailableStakeCalls::Bond(b, c) => RelayCall::Stake(StakeCall::Bond(b, c)).encode(),
106

            
107
1
			AvailableStakeCalls::BondExtra(a) => RelayCall::Stake(StakeCall::BondExtra(a)).encode(),
108

            
109
1
			AvailableStakeCalls::Unbond(a) => RelayCall::Stake(StakeCall::Unbond(a)).encode(),
110

            
111
1
			AvailableStakeCalls::WithdrawUnbonded(a) => {
112
1
				RelayCall::Stake(StakeCall::WithdrawUnbonded(a)).encode()
113
			}
114

            
115
1
			AvailableStakeCalls::Validate(a) => RelayCall::Stake(StakeCall::Validate(a)).encode(),
116

            
117
1
			AvailableStakeCalls::Chill => RelayCall::Stake(StakeCall::Chill).encode(),
118

            
119
1
			AvailableStakeCalls::SetPayee(a) => {
120
1
				RelayCall::Stake(StakeCall::SetPayee(a.into())).encode()
121
			}
122

            
123
			AvailableStakeCalls::SetController => {
124
1
				RelayCall::Stake(StakeCall::SetController).encode()
125
			}
126

            
127
1
			AvailableStakeCalls::Rebond(a) => {
128
1
				RelayCall::Stake(StakeCall::Rebond(a.into())).encode()
129
			}
130

            
131
1
			AvailableStakeCalls::Nominate(a) => {
132
1
				let nominated: Vec<<AccountIdLookup<AccountId32, ()> as StaticLookup>::Source> =
133
2
					a.iter().map(|add| (*add).clone().into()).collect();
134
1

            
135
1
				RelayCall::Stake(StakeCall::Nominate(nominated)).encode()
136
			}
137
		}
138
10
	}
139
}
140

            
141
impl xcm_primitives::HrmpEncodeCall for TestEncoder {
142
	fn hrmp_encode_call(
143
		call: xcm_primitives::HrmpAvailableCalls,
144
	) -> Result<Vec<u8>, xcm::latest::Error> {
145
		match call {
146
			xcm_primitives::HrmpAvailableCalls::InitOpenChannel(a, b, c) => Ok(RelayCall::Hrmp(
147
				HrmpCall::InitOpenChannel(a.clone(), b.clone(), c.clone()),
148
			)
149
			.encode()),
150
			xcm_primitives::HrmpAvailableCalls::AcceptOpenChannel(a) => {
151
				Ok(RelayCall::Hrmp(HrmpCall::AcceptOpenChannel(a.clone())).encode())
152
			}
153
			xcm_primitives::HrmpAvailableCalls::CloseChannel(a) => {
154
				Ok(RelayCall::Hrmp(HrmpCall::CloseChannel(a.clone())).encode())
155
			}
156
			xcm_primitives::HrmpAvailableCalls::CancelOpenRequest(a, b) => {
157
				Ok(RelayCall::Hrmp(HrmpCall::CancelOpenChannel(a.clone(), b.clone())).encode())
158
			}
159
		}
160
	}
161
}