triggr/instructions/create_task.rs
1pub use crate::state::*;
2use anchor_lang::{prelude::*, system_program::System};
3
4// Only an account which authority is specified correctly can be used to derive the authority
5// the authority is not stored in the parent account but it's linked by derivation.
6// The authority is the payer of initializing the parent account
7
8#[derive(Accounts)]
9#[instruction(task_args: Task, _trigger_index: u64)]
10pub struct CreateTask<'info> {
11 #[account(mut)]
12 signer: Signer<'info>,
13
14 #[account(
15 mut,
16 seeds = ["user".as_bytes(), &signer.key().to_bytes()],
17 bump
18 )]
19 user: Account<'info, User>,
20
21 #[account(
22 mut,
23 seeds = ["trigger".as_bytes(), &signer.key().to_bytes()[..], &_trigger_index.to_le_bytes()],
24 bump
25 )]
26 trigger: Account<'info, Trigger>,
27
28 #[account(
29 init,
30 seeds = ["task".as_bytes(), &trigger.key().to_bytes()[..], &trigger.task_count.to_le_bytes()],
31 bump ,
32 space = task_args.try_to_vec()?.len() + 8 + 2 + 32 ,
33 payer = signer
34 )]
35 task: Account<'info, Task>,
36
37 system_program: Program<'info, System>,
38}
39
40pub fn handler(
41 ctx: Context<CreateTask>,
42 task_args: Task,
43 _trigger_index: u64,
44) -> Result<()> {
45 *ctx.accounts.task = Task::new(
46 &task_args,
47 ctx.accounts.trigger.task_count,
48 &ctx.accounts.trigger.key(),
49 )?;
50
51 // increment the trigger's task count
52 ctx.accounts.trigger.task_count += 1;
53
54 ctx.accounts.user.task_count += 1;
55
56 msg!("Task created successfully!");
57
58 Ok(())
59}
60
61// This is how to create children accounts with pdas as signer / payers
62
63// #[derive(Accounts)]
64// pub struct CreateTask<'info> {
65// #[account()]
66// authority: SystemAccount<'info>,
67
68// // Should the user pay for the init of the child or should their parent pda pay?
69// // When the user inits an task pda a simulation should estimate a certain amount of executions and ask the user to fund the account with that amount
70// #[account(mut, seeds = ["payer".as_bytes(), &authority.key().to_bytes()], bump)]
71// payer_pda: SystemAccount<'info>,
72
73// #[account(mut, seeds = ["trigger".as_bytes(), &authority.key().to_bytes()], bump)]
74// trigger: Account<'info, Trigger>,
75
76// // Create Task and Create Trigger should be different instructions as pdas are derived differently
77// /// CHECK: Account isn't initialized so anchor would throw error, although anchor does check the seeds
78// #[account(mut, seeds = ["task".as_bytes(), &trigger.key().to_bytes()], bump )]
79// task: AccountInfo<'info>,
80
81// system_program: Program<'info, System>,
82// }
83
84// pub fn handler(ctx: Context<CreateTask>, task: Task) -> Result<()> {
85// let payer_seeds = &[
86// "payer".as_bytes(),
87// &ctx.accounts.authority.key().to_bytes()[..],
88// &[ctx.bumps.get("payer_pda").unwrap().clone()],
89// ];
90
91// let new_pda_seeds = &[
92// "task".as_bytes(),
93// &ctx.accounts.payer_pda.key().to_bytes()[..],
94// &[ctx.bumps.get("new_pda").unwrap().clone()],
95// ];
96
97// // Parent and child need to sign for the initialization of the child
98// let payer = &[&payer_seeds[..], &new_pda_seeds[..]];
99
100// // Setup tx accounts
101// let accounts = CreateAccount {
102// from: ctx.accounts.payer_pda.to_account_info(),
103// to: ctx.accounts.task.to_account_info().clone(),
104// };
105
106// let cpi_ctx = CpiContext::new_with_signer(
107// ctx.accounts.system_program.to_account_info(),
108// accounts,
109// payer,
110// );
111
112// // Space is important. If you give it too liexpiration_slote space anchor will give you an invalid discriminator error regardless of what the error might be
113// let space = task.try_to_vec().unwrap().len();
114// let rent = Rent::get()?.minimum_balance(space);
115
116// let mut discriminator = Task::discriminator();
117// msg!("Discriminator: {:?}", discriminator);
118
119// // Initializes account
120// anchor_lang::system_program::create_account(cpi_ctx, rent, space as u64, &ctx.program_id)?;
121
122// // Adding the discriminator allows you to use the account with regular anchor with it's proper type
123// // It also keeps you from having to use zero and zero_copy
124// let mut acc_info = ctx.accounts.task.to_account_info();
125// acc_info.serialize_data(&[
126// &mut discriminator[..],
127// &mut task.try_to_vec().unwrap()[..],
128// ]);
129
130// msg!("Account initialized");
131
132// Ok(())
133// }