sablier_thread_program/instructions/
thread_create.rs1use anchor_lang::{
2 prelude::*,
3 system_program::{transfer, Transfer},
4};
5use sablier_utils::thread::{SerializableInstruction, Trigger};
6
7use crate::{constants::*, state::*};
8
9#[derive(Accounts)]
11#[instruction(amount: u64, id: Vec<u8>, domain: Option<Vec<u8>>, instructions: Vec<SerializableInstruction>, trigger: Trigger)]
12pub struct ThreadCreate<'info> {
13 pub authority: Signer<'info>,
15
16 #[account(mut)]
18 pub payer: Signer<'info>,
19
20 pub system_program: Program<'info, System>,
22
23 #[account(
25 init,
26 seeds = [
27 SEED_THREAD,
28 authority.key().as_ref(),
29 id.as_slice(),
30 domain.as_ref().unwrap_or(&Vec::new()).as_slice()
31 ],
32 bump,
33 payer = payer,
34 space = Thread::min_space(&instructions)?
35 )]
36 pub thread: Account<'info, Thread>,
37}
38
39pub fn handler(
40 ctx: Context<ThreadCreate>,
41 amount: u64,
42 id: Vec<u8>,
43 domain: Option<Vec<u8>>,
44 instructions: Vec<SerializableInstruction>,
45 trigger: Trigger,
46) -> Result<()> {
47 let authority = &ctx.accounts.authority;
49 let payer = &ctx.accounts.payer;
50 let system_program = &ctx.accounts.system_program;
51 let thread = &mut ctx.accounts.thread;
52
53 let bump = ctx.bumps.thread;
55 thread.authority = authority.key();
56 thread.bump = bump;
57 thread.created_at = Clock::get()?.into();
58 thread.exec_context = None;
59 thread.fee = THREAD_MINIMUM_FEE;
60 thread.id = id;
61 thread.domain = domain;
62 thread.instructions = instructions;
63 thread.next_instruction = None;
64 thread.paused = false;
65 thread.rate_limit = u64::MAX;
66 thread.trigger = trigger;
67
68 transfer(
70 CpiContext::new(
71 system_program.to_account_info(),
72 Transfer {
73 from: payer.to_account_info(),
74 to: thread.to_account_info(),
75 },
76 ),
77 amount,
78 )?;
79
80 Ok(())
81}