use crate::state::{Metadata};
use crate::{ CreateMetadataInput, MetadataEvent, MetadataEventType, assert_pda_derivation::assert_pda_derivation};
use anchor_lang::prelude::*;
use crate::{errors::ErrorCode};
use spl_token_2022::ID as TOKEN_2022_PROGRAM_ID;
use anchor_spl::token_interface::Mint;
pub mod migrator_lite {
use super::*;
declare_id!("migr1m1An7f3X75nKuuUn9mm3844miK62ZohpqRfQHp");
}
#[derive(Accounts)]
#[instruction(metadata_input: CreateMetadataInput)]
pub struct CreateMetadata<'info> {
#[account(mut)]
pub payer: Signer<'info>,
#[account(init, seeds = [b"metadata", mint.key().as_ref()],
bump, payer = payer, space = Metadata::BASE_SIZE + metadata_input.get_size())]
pub metadata: Box<Account<'info, Metadata>>,
#[account(
constraint = mint.owner.eq(&TOKEN_2022_PROGRAM_ID)
)]
pub mint: UncheckedAccount<'info>,
pub authority: Signer<'info>,
pub system_program: Program<'info, System>,
pub invoked_migrator_program: Option<UncheckedAccount<'info>>
}
pub fn handler(ctx: Context<CreateMetadata>, metadata_input: CreateMetadataInput) -> Result<()> {
let metadata = &mut ctx.accounts.metadata;
let mint = &mut ctx.accounts.mint;
let authority = &ctx.accounts.authority;
let invoked_migrator_program = &ctx.accounts.invoked_migrator_program;
assert_is_valid_signer(&authority.key(), &mint.key(), invoked_migrator_program)?;
metadata.mint = ctx.accounts.mint.key();
metadata.is_mutable = true;
metadata.symbol = metadata_input.symbol.clone();
metadata.name = metadata_input.name.clone();
metadata.creator = authority.key();
metadata.asset = metadata_input.asset;
metadata.update_authority = metadata_input.update_authority;
metadata.extension = metadata_input.extension;
metadata.group = None;
msg!(
"metadata created for mint with pubkey {}",
ctx.accounts.mint.key()
);
emit!(MetadataEvent {
id: metadata.key(),
mint: ctx.accounts.mint.key(),
event_type: MetadataEventType::Create
});
Ok(())
}
fn assert_is_valid_signer<'info> (signer: &Pubkey, mint: &Pubkey, invoked_migrator_program: &Option<UncheckedAccount<'info>>) -> Result<()> {
match invoked_migrator_program {
Some(x) => {
if x.key() != migrator_lite::ID {
return err!(ErrorCode::InvalidSignedProgram);
}
let seeds = [
b"metadata_signer",
mint.as_ref()
];
msg!("{} {}", x.key(), signer.key());
assert_pda_derivation(&x.key(), signer, &seeds)?;
},
None => {
}
}
return Ok(())
}