gmsol_timelock/states/
executor.rs

1use anchor_lang::{prelude::*, solana_program::pubkey::PubkeyError};
2use gmsol_store::{
3    states::{Seed, MAX_ROLE_NAME_LEN},
4    utils::fixed_str::{bytes_to_fixed_str, fixed_str_to_bytes},
5};
6
7/// Executor.
8#[account(zero_copy)]
9pub struct Executor {
10    version: u8,
11    pub(crate) bump: u8,
12    pub(crate) wallet_bump: u8,
13    padding: [u8; 13],
14    pub(crate) store: Pubkey,
15    role_name: [u8; MAX_ROLE_NAME_LEN],
16    reserved: [u8; 256],
17}
18
19impl Executor {
20    /// Wallet Seed.
21    pub const WALLET_SEED: &'static [u8] = b"wallet";
22
23    /// Get role name.
24    pub fn role_name(&self) -> Result<&str> {
25        bytes_to_fixed_str(&self.role_name)
26    }
27
28    pub(crate) fn try_init(
29        &mut self,
30        bump: u8,
31        wallet_bump: u8,
32        store: Pubkey,
33        role_name: &str,
34    ) -> Result<()> {
35        let role_name = fixed_str_to_bytes(role_name)?;
36        self.bump = bump;
37        self.wallet_bump = wallet_bump;
38        self.store = store;
39        self.role_name = role_name;
40        Ok(())
41    }
42}
43
44impl Seed for Executor {
45    const SEED: &'static [u8] = b"timelock_executor";
46}
47
48impl gmsol_utils::InitSpace for Executor {
49    const INIT_SPACE: usize = std::mem::size_of::<Self>();
50}
51
52/// Executor Wallet Signer.
53pub struct ExecutorWalletSigner {
54    executor: Pubkey,
55    bump_bytes: [u8; 1],
56}
57
58impl ExecutorWalletSigner {
59    pub(crate) fn new(executor: Pubkey, bump: u8) -> Self {
60        Self {
61            executor,
62            bump_bytes: [bump],
63        }
64    }
65
66    pub(crate) fn as_seeds(&self) -> [&[u8]; 3] {
67        [
68            Executor::WALLET_SEED,
69            self.executor.as_ref(),
70            &self.bump_bytes,
71        ]
72    }
73}
74
75/// Find executor wallet PDA.
76pub fn find_executor_wallet_pda(executor: &Pubkey, timelock_program_id: &Pubkey) -> (Pubkey, u8) {
77    Pubkey::find_program_address(
78        &[Executor::WALLET_SEED, executor.as_ref()],
79        timelock_program_id,
80    )
81}
82
83/// Create executor wallet PDA.
84pub fn create_executor_wallet_pda(
85    executor: &Pubkey,
86    wallet_bump: u8,
87    timelock_program_id: &Pubkey,
88) -> std::result::Result<Pubkey, PubkeyError> {
89    Pubkey::create_program_address(
90        &[Executor::WALLET_SEED, executor.as_ref(), &[wallet_bump]],
91        timelock_program_id,
92    )
93}