use std::mem::size_of;
use anchor_lang::{
prelude::*,
solana_program::system_program,
system_program::{transfer, Transfer}
};
use clockwork_utils::thread::{Trigger, SerializableInstruction};
use crate::state::*;
const MINIMUM_FEE: u64 = 1000;
#[derive(Accounts)]
#[instruction(amount: u64, id: Vec<u8>, instructions: Vec<SerializableInstruction>, trigger: Trigger)]
pub struct ThreadCreate<'info> {
#[account()]
pub authority: Signer<'info>,
#[account(mut)]
pub payer: Signer<'info>,
#[account(address = system_program::ID)]
pub system_program: Program<'info, System>,
#[account(
init,
seeds = [
SEED_THREAD,
authority.key().as_ref(),
id.as_slice(),
],
bump,
payer= payer,
space = vec![
8,
size_of::<Thread>(),
id.len(),
instructions.try_to_vec()?.len(),
trigger.try_to_vec()?.len()
].iter().sum()
)]
pub thread: Account<'info, Thread>,
}
pub fn handler(ctx: Context<ThreadCreate>, amount: u64, id: Vec<u8>, instructions: Vec<SerializableInstruction>, trigger: Trigger) -> Result<()> {
let authority = &ctx.accounts.authority;
let payer = &ctx.accounts.payer;
let system_program = &ctx.accounts.system_program;
let thread = &mut ctx.accounts.thread;
let bump = *ctx.bumps.get("thread").unwrap();
thread.authority = authority.key();
thread.bump = bump;
thread.created_at = Clock::get().unwrap().into();
thread.exec_context = None;
thread.fee = MINIMUM_FEE;
thread.id = id;
thread.instructions = instructions;
thread.name = String::new();
thread.next_instruction = None;
thread.paused = false;
thread.rate_limit = u64::MAX;
thread.trigger = trigger;
transfer(
CpiContext::new(
system_program.to_account_info(),
Transfer {
from: payer.to_account_info(),
to: thread.to_account_info(),
},
),
amount
)?;
Ok(())
}