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
//! A companion pallet to pallet-proxy
18
//!
19
//! This pallet allows you to specify proxy accounts that will exist from genesis. This
20
//! functionality could be moved upstream into pallet proxy eventually, but for now there are fewer
21
//! obstacles to including it here.
22

            
23
#![cfg_attr(not(feature = "std"), no_std)]
24

            
25
#[cfg(test)]
26
mod mock;
27
#[cfg(test)]
28
mod tests;
29

            
30
use frame_support::pallet;
31
pub use pallet::*;
32

            
33
80
#[pallet]
34
pub mod pallet {
35
	use frame_support::pallet_prelude::*;
36
	use sp_runtime::traits::BlockNumberProvider;
37
	use sp_std::vec::Vec;
38

            
39
	type BlockNumberFor<T> =
40
		<<T as Config>::BlockNumberProvider as BlockNumberProvider>::BlockNumber;
41

            
42
	/// Pallet for configuring proxy at genesis
43
121
	#[pallet::pallet]
44
	#[pallet::without_storage_info]
45
	pub struct Pallet<T>(PhantomData<T>);
46

            
47
	/// This pallet requires
48
	/// 1. pallet-proxy to be installed
49
	/// 2. it's ProxyType and BlockNumberProvider to be serializable when built to std.
50
	#[pallet::config]
51
	pub trait Config:
52
		frame_system::Config
53
		+ pallet_proxy::Config<
54
			ProxyType = <Self as Config>::ProxyType,
55
			BlockNumberProvider = <Self as Config>::BlockNumberProvider,
56
		>
57
	{
58
		/// This MUST be the same as in pallet_proxy or it won't compile
59
		type ProxyType: MaybeSerializeDeserialize + Clone;
60

            
61
		type BlockNumberProvider: BlockNumberProvider<
62
			BlockNumber: MaybeSerializeDeserialize + Clone,
63
		>;
64
	}
65

            
66
	#[pallet::genesis_config]
67
	pub struct GenesisConfig<T: Config> {
68
		pub proxies: Vec<(
69
			T::AccountId,
70
			T::AccountId,
71
			<T as Config>::ProxyType,
72
			BlockNumberFor<T>,
73
		)>,
74
	}
75

            
76
	impl<T: Config> Default for GenesisConfig<T> {
77
6
		fn default() -> Self {
78
6
			Self {
79
6
				proxies: Vec::new(),
80
6
			}
81
6
		}
82
	}
83

            
84
3
	#[pallet::genesis_build]
85
	impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
86
7
		fn build(&self) {
87
9
			for (delegator, delegatee, proxy_type, delay) in &self.proxies {
88
2
				pallet_proxy::Pallet::<T>::add_proxy_delegate(
89
2
					delegator,
90
2
					delegatee.clone(),
91
2
					proxy_type.clone(),
92
2
					*delay,
93
2
				)
94
2
				.expect("Genesis proxy could not be added");
95
2
			}
96
7
		}
97
	}
98
}