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
pub const TEST_RELAY_INDICES: RelayChainIndices = RelayChainIndices {
76
	staking: 1u8,
77
	utility: 0u8,
78
	hrmp: 2u8,
79
	bond: 0u8,
80
	bond_extra: 1u8,
81
	unbond: 2u8,
82
	withdraw_unbonded: 3u8,
83
	validate: 4u8,
84
	nominate: 5u8,
85
	chill: 6u8,
86
	set_payee: 7u8,
87
	set_controller: 8u8,
88
	rebond: 19u8,
89
	as_derivative: 0u8,
90
	init_open_channel: 0u8,
91
	accept_open_channel: 1u8,
92
	close_channel: 2u8,
93
	cancel_open_request: 6u8,
94
};
95

            
96
pub struct TestEncoder;
97

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

            
103
1
			AvailableStakeCalls::BondExtra(a) => RelayCall::Stake(StakeCall::BondExtra(a)).encode(),
104

            
105
1
			AvailableStakeCalls::Unbond(a) => RelayCall::Stake(StakeCall::Unbond(a)).encode(),
106

            
107
1
			AvailableStakeCalls::WithdrawUnbonded(a) => {
108
1
				RelayCall::Stake(StakeCall::WithdrawUnbonded(a)).encode()
109
			}
110

            
111
1
			AvailableStakeCalls::Validate(a) => RelayCall::Stake(StakeCall::Validate(a)).encode(),
112

            
113
1
			AvailableStakeCalls::Chill => RelayCall::Stake(StakeCall::Chill).encode(),
114

            
115
1
			AvailableStakeCalls::SetPayee(a) => {
116
1
				RelayCall::Stake(StakeCall::SetPayee(a.into())).encode()
117
			}
118

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

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

            
127
1
			AvailableStakeCalls::Nominate(a) => {
128
1
				let nominated: Vec<<AccountIdLookup<AccountId32, ()> as StaticLookup>::Source> =
129
2
					a.iter().map(|add| (*add).clone().into()).collect();
130
1

            
131
1
				RelayCall::Stake(StakeCall::Nominate(nominated)).encode()
132
			}
133
		}
134
10
	}
135
}
136

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