locked_voter/instructions/
approve_program_lock_privilege.rs

1use crate::*;
2
3/// Accounts for [locked_voter::approve_program_lock_privilege].
4#[derive(Accounts)]
5pub struct ApproveProgramLockPrivilege<'info> {
6    /// The [Locker].
7    pub locker: Account<'info, Locker>,
8    /// [LockerWhitelistEntry].
9    #[account(
10        init,
11        seeds = [
12            b"LockerWhitelistEntry".as_ref(),
13            locker.key().to_bytes().as_ref(),
14            executable_id.key().to_bytes().as_ref(),
15            whitelisted_owner.key().to_bytes().as_ref()
16        ],
17        bump,
18        payer = payer,
19        space = 8 + LockerWhitelistEntry::LEN
20    )]
21    pub whitelist_entry: Account<'info, LockerWhitelistEntry>,
22
23    /// Governor for the [Locker].
24    pub governor: Account<'info, Governor>,
25
26    /// Smart wallet on the [Governor].
27    pub smart_wallet: Signer<'info>,
28
29    /// CHECK: ProgramId of the program to whitelist.
30    #[account(executable)]
31    pub executable_id: AccountInfo<'info>,
32
33    /// CHECK: Owner whitelisted. If set to [anchor_lang::solana_program::system_program::ID], then the program is whitelisted for all accounts.
34    pub whitelisted_owner: AccountInfo<'info>,
35
36    /// Payer of the initialization.
37    #[account(mut)]
38    pub payer: Signer<'info>,
39
40    /// System program.
41    pub system_program: Program<'info, System>,
42}
43
44impl<'info> ApproveProgramLockPrivilege<'info> {
45    /// Creates a new [LockerWhitelistEntry].
46    pub fn approve_program_lock_privilege(&mut self, bump: u8) -> Result<()> {
47        let whitelist_entry = &mut self.whitelist_entry;
48        whitelist_entry.bump = bump;
49        whitelist_entry.locker = self.locker.key();
50        whitelist_entry.program_id = self.executable_id.key();
51        whitelist_entry.owner = self.whitelisted_owner.key();
52
53        emit!(ApproveLockPrivilegeEvent {
54            locker: whitelist_entry.locker,
55            program_id: whitelist_entry.program_id,
56            owner: whitelist_entry.owner,
57            timestamp: Clock::get()?.unix_timestamp
58        });
59
60        Ok(())
61    }
62}
63
64impl<'info> Validate<'info> for ApproveProgramLockPrivilege<'info> {
65    fn validate(&self) -> Result<()> {
66        assert_keys_eq!(self.governor.smart_wallet, self.smart_wallet);
67        invariant!(
68            self.executable_id.executable,
69            "program_id must be an executable"
70        );
71
72        Ok(())
73    }
74}
75
76#[event]
77/// Event called in [locked_voter::approve_program_lock_privilege].
78pub struct ApproveLockPrivilegeEvent {
79    /// The [Locker].
80    #[index]
81    pub locker: Pubkey,
82    /// ProgramId approved to make CPI calls to [locked_voter::lock].
83    pub program_id: Pubkey,
84    /// Owner of the [Escrow].
85    pub owner: Pubkey,
86    /// Timestamp of the event.
87    pub timestamp: i64,
88}