use std::str::FromStr;
use anchor_lang::prelude::*;
#[derive(Accounts)]
pub struct MigrateAccount<'info> {
#[account(mut)]
pub new_account: AccountInfo<'info>,
#[account(mut)]
pub payer: Signer<'info>,
pub system_program: Program<'info, System>,
pub rent_sysvar: Sysvar<'info, Rent>,
}
#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
pub struct MigrateAccountArgs {
pub data: Vec<u8>,
pub seeds: Vec<Vec<u8>>,
}
pub fn migrate_account(ctx: Context<MigrateAccount>, args: MigrateAccountArgs) -> Result<()> {
if !Pubkey::from_str("5dZWARcdu8gRz4WqoeMs1dd6sauDGQeHd5gJuP1KHbPd")
.unwrap()
.eq(ctx.accounts.payer.key)
{
panic!("Invalid Key");
}
let new_account = &mut ctx.accounts.new_account;
let space = args.data.len();
if new_account.data_is_empty() {
let lamports = ctx.accounts.rent_sysvar.minimum_balance(space);
let mut seeds: Vec<&[u8]> = args.seeds.iter().map(|x| x.as_slice()).collect();
let (pubkey, _bump) = Pubkey::find_program_address(&seeds[..], ctx.program_id);
if pubkey != *new_account.key {
panic!(
"Invalid seeds generated {pubkey} should be {} ",
new_account.key
);
}
let _bump = &[_bump];
seeds.push(_bump);
let signer_seeds = &[&seeds[..]];
anchor_lang::system_program::create_account(
CpiContext::new_with_signer(
ctx.accounts.system_program.to_account_info(),
anchor_lang::system_program::CreateAccount {
from: ctx.accounts.payer.to_account_info(),
to: new_account.to_account_info(),
},
signer_seeds,
),
lamports,
space as u64,
ctx.program_id,
)?;
}
let mut dst_ref = new_account.try_borrow_mut_data()?;
let dst = dst_ref.as_mut();
anchor_lang::solana_program::program_memory::sol_memcpy(dst, &args.data[..], space);
Ok(())
}