miclockwork_thread_program/instructions/
thread_create.rs

1use std::mem::size_of;
2
3use anchor_lang::{
4    prelude::*,
5    solana_program::system_program,
6    system_program::{transfer, Transfer}
7};
8use miclockwork_utils::thread::{Trigger, SerializableInstruction};
9
10use crate::state::*;
11
12/// The minimum exec fee that may be set on a thread.
13const MINIMUM_FEE: u64 = 1000;
14
15/// Accounts required by the `thread_create` instruction.
16#[derive(Accounts)]
17#[instruction(amount: u64, id: Vec<u8>, instructions: Vec<SerializableInstruction>,  trigger: Trigger)]
18pub struct ThreadCreate<'info> {
19    /// The authority (owner) of the thread.
20    #[account()]
21    pub authority: Signer<'info>,
22
23    /// The payer for account initializations. 
24    #[account(mut)]
25    pub payer: Signer<'info>,
26
27    /// The Solana system program.
28    #[account(address = system_program::ID)]
29    pub system_program: Program<'info, System>,
30
31    /// The thread to be created.
32    #[account(
33        init,
34        seeds = [
35            SEED_THREAD,
36            authority.key().as_ref(),
37            id.as_slice(),
38        ],
39        bump,
40        payer= payer,
41        space = vec![
42            8, 
43            size_of::<Thread>(), 
44            id.len(),
45            instructions.try_to_vec()?.len(),  
46            trigger.try_to_vec()?.len(),
47            NEXT_INSTRUCTION_SIZE,
48        ].iter().sum()
49    )]
50    pub thread: Account<'info, Thread>,
51}
52
53pub fn handler(ctx: Context<ThreadCreate>, amount: u64, id: Vec<u8>, instructions: Vec<SerializableInstruction>, trigger: Trigger) -> Result<()> {
54    // Get accounts
55    let authority = &ctx.accounts.authority;
56    let payer = &ctx.accounts.payer;
57    let system_program = &ctx.accounts.system_program;
58    let thread = &mut ctx.accounts.thread;
59
60    // Initialize the thread
61    let bump = *ctx.bumps.get("thread").unwrap();
62    thread.authority = authority.key();
63    thread.bump = bump;
64    thread.created_at = Clock::get().unwrap().into();
65    thread.exec_context = None;
66    thread.fee = MINIMUM_FEE;
67    thread.id = id;
68    thread.instructions = instructions;
69    thread.name = String::new();
70    thread.next_instruction = None;
71    thread.paused = false;
72    thread.rate_limit = u64::MAX;
73    thread.trigger = trigger;
74
75    // Transfer SOL from payer to the thread.
76    transfer(
77        CpiContext::new(
78            system_program.to_account_info(),
79            Transfer {
80                from: payer.to_account_info(),
81                to: thread.to_account_info(),
82            },
83        ),
84        amount
85    )?;
86
87    Ok(())
88}