gpl_core/instructions/
user.rs

1use anchor_lang::prelude::*;
2
3use crate::constants::*;
4use crate::events::{UserAuthorityChanged, UserDeleted, UserNew};
5use crate::state::User;
6
7// Initialize a new user account
8#[derive(Accounts)]
9#[instruction(random_hash: [u8;32])]
10pub struct CreateUser<'info> {
11    // The account that will be initialized as a user
12    #[account(
13        init,
14        seeds = [
15            USER_PREFIX_SEED.as_bytes(),
16            random_hash.as_ref(),
17        ],
18        bump,
19        payer = authority,
20        space = User::LEN
21    )]
22    pub user: Account<'info, User>,
23    // The authority of the user
24    #[account(mut)]
25    pub authority: Signer<'info>,
26    // The system program
27    pub system_program: Program<'info, System>,
28}
29
30// Handler to create a new user account
31pub fn create_user_handler(ctx: Context<CreateUser>, random_hash: [u8; 32]) -> Result<()> {
32    let user = &mut ctx.accounts.user;
33    user.random_hash = random_hash;
34    user.authority = *ctx.accounts.authority.key;
35
36    // emit new user event
37    emit!(UserNew {
38        user: *user.to_account_info().key,
39        random_hash: random_hash,
40        authority: *ctx.accounts.authority.key,
41        timestamp: Clock::get()?.unix_timestamp,
42    });
43
44    Ok(())
45}
46
47// Update a user account with new authority
48#[derive(Accounts)]
49pub struct UpdateUser<'info> {
50    // The user account to update
51    #[account(
52        mut,
53        seeds = [
54            USER_PREFIX_SEED.as_bytes(),
55            user.random_hash.as_ref(),
56        ],
57        bump,
58        has_one = authority,
59    )]
60    pub user: Account<'info, User>,
61
62    // The new authority of the user
63    pub new_authority: SystemAccount<'info>,
64    // The authority of the user
65    pub authority: Signer<'info>,
66    pub system_program: Program<'info, System>,
67}
68
69// Handler to update a user account with new authority
70pub fn update_user_handler(ctx: Context<UpdateUser>) -> Result<()> {
71    let user = &mut ctx.accounts.user;
72    user.authority = *ctx.accounts.new_authority.key;
73    // Emit user authority changed event
74    emit!(UserAuthorityChanged {
75        user: *user.to_account_info().key,
76        old_authority: *ctx.accounts.authority.key,
77        new_authority: *ctx.accounts.new_authority.key,
78        timestamp: Clock::get()?.unix_timestamp,
79    });
80    Ok(())
81}
82
83// Delete a user account
84#[derive(Accounts)]
85pub struct DeleteUser<'info> {
86    // The user account to close
87    #[account(
88        mut,
89        seeds = [
90            USER_PREFIX_SEED.as_bytes(),
91            user.random_hash.as_ref(),
92        ],
93        bump,
94        has_one = authority,
95        close = authority
96    )]
97    pub user: Account<'info, User>,
98
99    // The authority of the user
100    #[account(mut)]
101    pub authority: Signer<'info>,
102    pub system_program: Program<'info, System>,
103}
104
105// Handler to close a user account
106pub fn delete_user_handler(ctx: Context<DeleteUser>) -> Result<()> {
107    // Emit user deleted event
108    emit!(UserDeleted {
109        user: *ctx.accounts.user.to_account_info().key,
110        authority: *ctx.accounts.authority.key,
111        timestamp: Clock::get()?.unix_timestamp,
112    });
113    Ok(())
114}