cardinal-time-invalidator 4.4.0

Program for a invalidating token managers based on time
Documentation
use crate::errors::ErrorCode;
use crate::state::*;
use anchor_lang::prelude::*;
use cardinal_token_manager::state::TokenManager;
use cardinal_token_manager::state::TokenManagerState;

#[derive(AnchorSerialize, AnchorDeserialize)]
pub struct UpdateMaxExpirationIx {
    pub new_max_expiration: i64,
}

#[derive(Accounts)]
pub struct UpdateMaxExpirationCtx<'info> {
    #[account(constraint = token_manager.state != TokenManagerState::Invalidated as u8 && time_invalidator.token_manager == token_manager.key() @ ErrorCode::InvalidTokenManager)]
    token_manager: Box<Account<'info, TokenManager>>,

    #[account(mut)]
    time_invalidator: Box<Account<'info, TimeInvalidator>>,

    #[account(mut, constraint = issuer.key() == token_manager.issuer @ ErrorCode::InvalidIssuer)]
    issuer: Signer<'info>,
}

pub fn handler(ctx: Context<UpdateMaxExpirationCtx>, ix: UpdateMaxExpirationIx) -> Result<()> {
    let time_invalidator = &mut ctx.accounts.time_invalidator;
    let token_manager = &ctx.accounts.token_manager;

    if token_manager.state == TokenManagerState::Claimed as u8 {
        if let Some(expiration) = time_invalidator.expiration {
            if ix.new_max_expiration < expiration {
                return Err(error!(ErrorCode::InvalidNewMaxExpiration));
            }
        }

        if let Some(max_expiration) = time_invalidator.max_expiration {
            if ix.new_max_expiration < max_expiration && time_invalidator.expiration.is_none() {
                return Err(error!(ErrorCode::InvalidNewMaxExpiration));
            }
        }

        if time_invalidator.max_expiration.is_none()
            && time_invalidator.duration_seconds.is_some()
            && ix.new_max_expiration < token_manager.state_changed_at.checked_add(time_invalidator.duration_seconds.unwrap()).expect("Add error")
        {
            return Err(error!(ErrorCode::InvalidNewMaxExpiration));
        }
    }
    time_invalidator.max_expiration = Some(ix.new_max_expiration);

    Ok(())
}