gmsol_callback/instructions/
action_stats.rs

1use anchor_lang::prelude::*;
2
3use crate::states::{ActionStats, ACTION_STATS_SEED};
4
5/// Create [`ActionStats`] account idempotently.
6#[derive(Accounts)]
7#[instruction(action_kind: u8)]
8pub struct CreateActionStatsIdempotent<'info> {
9    /// Payer.
10    #[account(mut)]
11    pub payer: Signer<'info>,
12    /// The [`ActionStats`] account.
13    #[account(
14        init_if_needed,
15        payer = payer,
16        space = 8 + ActionStats::INIT_SPACE,
17        seeds = [
18            ACTION_STATS_SEED,
19            owner.key.as_ref(),
20            &[action_kind],
21        ],
22        bump
23    )]
24    pub action_stats: Account<'info, ActionStats>,
25    /// The owner of the action account.
26    /// CHECK: This account is unchecked because only its address is used.
27    pub owner: UncheckedAccount<'info>,
28    /// The system program.
29    pub system_program: Program<'info, System>,
30}
31
32impl CreateActionStatsIdempotent<'_> {
33    pub(crate) fn invoke(ctx: Context<Self>, action_kind: u8) -> Result<()> {
34        let action_stats = &mut ctx.accounts.action_stats;
35        if !action_stats.initialized {
36            action_stats.initialized = true;
37            action_stats.bump = ctx.bumps.action_stats;
38            action_stats.action_kind = action_kind;
39            action_stats.owner = ctx.accounts.owner.key();
40        }
41        Ok(())
42    }
43}