use {
solana_farm_sdk::program::account,
solana_program::{
account_info::AccountInfo,
entrypoint::ProgramResult,
hash::Hasher,
instruction::{AccountMeta, Instruction},
msg,
program::invoke,
program_error::ProgramError,
pubkey::Pubkey,
system_program,
},
};
pub fn user_init(accounts: &[AccountInfo]) -> ProgramResult {
msg!("Processing AmmInstruction::UserInit");
#[allow(clippy::deprecated_cfg_attr)]
#[cfg_attr(rustfmt, rustfmt_skip)]
if let [
funding_account,
user_account,
farm_program_id,
lp_token_mint,
_spl_token_id,
_system_program,
miner,
miner_vault,
quarry,
rewarder
] = accounts
{
if &quarry_mine::id() != farm_program_id.key {
return Err(ProgramError::IncorrectProgramId);
}
if account::exists(miner)? {
return Err(ProgramError::AccountAlreadyInitialized);
}
let (miner_derived, bump) = Pubkey::find_program_address(
&[
b"Miner",
&quarry.key.to_bytes(),
&user_account.key.to_bytes(),
],
&quarry_mine::id(),
);
if &miner_derived != miner.key {
msg!("Error: Invalid Miner address");
return Err(ProgramError::InvalidSeeds);
}
let mut hasher = Hasher::default();
hasher.hash(b"global:create_miner");
let mut data = hasher.result().as_ref()[..8].to_vec();
data.push(bump);
let saber_accounts = vec![
AccountMeta::new(*funding_account.key, true),
AccountMeta::new(*miner.key, false),
AccountMeta::new(*quarry.key, false),
AccountMeta::new(*rewarder.key, false),
AccountMeta::new_readonly(system_program::id(), false),
AccountMeta::new_readonly(*funding_account.key, true),
AccountMeta::new(*lp_token_mint.key, false),
AccountMeta::new(*miner_vault.key, false),
AccountMeta::new_readonly(spl_token::id(), false),
];
let instruction = Instruction {
program_id: quarry_mine::id(),
accounts: saber_accounts,
data,
};
invoke(&instruction, accounts)?;
} else {
return Err(ProgramError::NotEnoughAccountKeys);
}
msg!("AmmInstruction::UserInit complete");
Ok(())
}