squads_multisig_program/instructions/
batch_create.rs1use anchor_lang::prelude::*;
2
3use crate::errors::*;
4use crate::state::*;
5
6#[derive(AnchorSerialize, AnchorDeserialize)]
7pub struct BatchCreateArgs {
8 pub vault_index: u8,
10 pub memo: Option<String>,
11}
12
13#[derive(Accounts)]
14pub struct BatchCreate<'info> {
15 #[account(
16 mut,
17 seeds = [SEED_PREFIX, SEED_MULTISIG, multisig.create_key.as_ref()],
18 bump = multisig.bump,
19 )]
20 pub multisig: Account<'info, Multisig>,
21
22 #[account(
23 init,
24 payer = rent_payer,
25 space = 8 + Batch::INIT_SPACE,
26 seeds = [
27 SEED_PREFIX,
28 multisig.key().as_ref(),
29 SEED_TRANSACTION,
30 &multisig.transaction_index.checked_add(1).unwrap().to_le_bytes(),
31 ],
32 bump
33 )]
34 pub batch: Account<'info, Batch>,
35
36 pub creator: Signer<'info>,
38
39 #[account(mut)]
41 pub rent_payer: Signer<'info>,
42
43 pub system_program: Program<'info, System>,
44}
45
46impl BatchCreate<'_> {
47 fn validate(&self) -> Result<()> {
48 let Self {
49 multisig, creator, ..
50 } = self;
51
52 require!(
54 multisig.is_member(creator.key()).is_some(),
55 MultisigError::NotAMember
56 );
57 require!(
58 multisig.member_has_permission(creator.key(), Permission::Initiate),
59 MultisigError::Unauthorized
60 );
61
62 Ok(())
63 }
64
65 #[access_control(ctx.accounts.validate())]
67 pub fn batch_create(ctx: Context<Self>, args: BatchCreateArgs) -> Result<()> {
68 let multisig = &mut ctx.accounts.multisig;
69 let creator = &mut ctx.accounts.creator;
70 let batch = &mut ctx.accounts.batch;
71
72 let multisig_key = multisig.key();
73
74 let index = multisig.transaction_index.checked_add(1).expect("overflow");
76
77 let vault_seeds = &[
78 SEED_PREFIX,
79 multisig_key.as_ref(),
80 SEED_VAULT,
81 &args.vault_index.to_le_bytes(),
82 ];
83 let (_, vault_bump) = Pubkey::find_program_address(vault_seeds, ctx.program_id);
84
85 batch.multisig = multisig_key;
86 batch.creator = creator.key();
87 batch.index = index;
88 batch.bump = ctx.bumps.batch;
89 batch.vault_index = args.vault_index;
90 batch.vault_bump = vault_bump;
91 batch.size = 0;
92 batch.executed_transaction_index = 0;
93
94 batch.invariant()?;
95
96 multisig.transaction_index = index;
98
99 multisig.invariant()?;
100
101 msg!("batch index: {}", index);
103
104 Ok(())
105 }
106}