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