use std::str::FromStr;
use crate::errors::ErrorCode;
use crate::state::MintManager;
use crate::state::TokenManager;
use crate::state::MINT_MANAGER_SEED;
use anchor_spl::token::Mint;
use anchor_spl::token::ThawAccount;
use anchor_spl::token::Token;
use anchor_spl::token::TokenAccount;
use anchor_spl::token::{self};
use cardinal_creator_standard::instructions::init_mint_manager;
use solana_program::program::invoke_signed;
use anchor_lang::prelude::*;
use anchor_lang::AccountsClose;
#[derive(Accounts)]
pub struct MigrateCtx<'info> {
current_mint_manager: Box<Account<'info, MintManager>>,
#[account(mut)]
mint_manager: UncheckedAccount<'info>,
#[account(mut, constraint = token_manager.mint == mint.key() @ ErrorCode::InvalidMint )]
mint: Box<Account<'info, Mint>>,
mint_metadata: UncheckedAccount<'info>,
ruleset: UncheckedAccount<'info>,
#[account(mut)]
token_manager: Box<Account<'info, TokenManager>>,
#[account(mut)]
holder_token_account: Box<Account<'info, TokenAccount>>,
token_authority: UncheckedAccount<'info>,
authority: UncheckedAccount<'info>,
#[account(mut)]
payer: Signer<'info>,
rent: Sysvar<'info, Rent>,
token_program: Program<'info, Token>,
system_program: Program<'info, System>,
#[account(address = cardinal_creator_standard::id())]
cardinal_creator_standard: UncheckedAccount<'info>,
}
pub fn handler(ctx: Context<MigrateCtx>) -> Result<()> {
if ctx.accounts.payer.key() != Pubkey::from_str("gmdS6fDgVbeCCYwwvTPJRKM9bFbAgSZh6MTDUT2DcgV").unwrap() {
return Err(error!(ErrorCode::InvalidMigrateAuthority));
}
if ctx.accounts.holder_token_account.delegate.is_some() {
return Err(error!(ErrorCode::CannotMigrateDelegatedToken));
}
let mint_manager_key = ctx.accounts.mint.key();
let current_mint_manager_seeds = &[MINT_MANAGER_SEED.as_bytes(), mint_manager_key.as_ref(), &[ctx.accounts.current_mint_manager.bump]];
let current_mint_manager_signer = &[¤t_mint_manager_seeds[..]];
let cpi_accounts = ThawAccount {
account: ctx.accounts.holder_token_account.to_account_info(),
mint: ctx.accounts.mint.to_account_info(),
authority: ctx.accounts.current_mint_manager.to_account_info(),
};
let cpi_program = ctx.accounts.token_program.to_account_info();
let cpi_context = CpiContext::new(cpi_program, cpi_accounts).with_signer(current_mint_manager_signer);
token::thaw_account(cpi_context)?;
invoke_signed(
&init_mint_manager(
ctx.accounts.cardinal_creator_standard.key(),
ctx.accounts.mint_manager.key(),
ctx.accounts.mint.key(),
ctx.accounts.mint_metadata.key(),
ctx.accounts.ruleset.key(),
ctx.accounts.holder_token_account.key(),
ctx.accounts.token_authority.key(),
ctx.accounts.authority.key(),
ctx.accounts.payer.key(),
)?,
&[
ctx.accounts.mint_manager.to_account_info(),
ctx.accounts.mint.to_account_info(),
ctx.accounts.mint_metadata.to_account_info(),
ctx.accounts.ruleset.to_account_info(),
ctx.accounts.holder_token_account.to_account_info(),
ctx.accounts.token_authority.to_account_info(),
ctx.accounts.authority.to_account_info(),
ctx.accounts.payer.to_account_info(),
ctx.accounts.rent.to_account_info(),
ctx.accounts.token_program.to_account_info(),
ctx.accounts.system_program.to_account_info(),
ctx.accounts.cardinal_creator_standard.to_account_info(),
],
current_mint_manager_signer,
)?;
ctx.accounts.token_manager.close(ctx.accounts.payer.to_account_info())?;
Ok(())
}