triggr-program 0.1.1

Created with Anchor
Documentation
pub use crate::state::*;
use anchor_lang::{prelude::*, system_program::System};

// 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

#[derive(Accounts)]
#[instruction(task_args: Task, _trigger_index: u64)]
pub struct CreateTask<'info> {
    #[account(mut)]
    signer: Signer<'info>,

    #[account(
        mut,
        seeds = ["user".as_bytes(), &signer.key().to_bytes()], 
        bump
        )]
    user: Account<'info, User>,

    #[account(
        mut,
        seeds = ["trigger".as_bytes(), &signer.key().to_bytes()[..], &_trigger_index.to_le_bytes()], 
        bump 
    )]
    trigger: Account<'info, Trigger>,

    #[account(
        init,
        seeds = ["task".as_bytes(), &trigger.key().to_bytes()[..], &trigger.task_count.to_le_bytes()], 
        bump , 
        space = task_args.try_to_vec()?.len() + 8 + 2 + 32 , 
        payer = signer
    )]
    task: Account<'info, Task>,

    system_program: Program<'info, System>,
}

pub fn handler(
    ctx: Context<CreateTask>,
    task_args: Task,
    _trigger_index: u64,
) -> Result<()> {
    *ctx.accounts.task = Task::new(
        &task_args,
        ctx.accounts.trigger.task_count,
        &ctx.accounts.trigger.key(),
    )?;

    // increment the trigger's task count
    ctx.accounts.trigger.task_count += 1;

    ctx.accounts.user.task_count += 1;

    msg!("Task created successfully!");

    Ok(())
}

// 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(())
// }