pinocchio_token/instructions/
initialize_multisig.rs1use core::{mem::MaybeUninit, slice};
2
3use solana_account_view::AccountView;
4use solana_instruction_view::{cpi::invoke_with_bounds, InstructionAccount, InstructionView};
5use solana_program_error::{ProgramError, ProgramResult};
6
7pub const MAX_MULTISIG_SIGNERS: usize = 11;
9
10pub struct InitializeMultisig<'a, 'b>
17where
18 'a: 'b,
19{
20 pub multisig: &'a AccountView,
22 pub rent_sysvar: &'a AccountView,
24 pub signers: &'b [&'a AccountView],
26 pub m: u8,
29}
30
31impl InitializeMultisig<'_, '_> {
32 #[inline(always)]
33 pub fn invoke(&self) -> ProgramResult {
34 let &Self {
35 multisig,
36 rent_sysvar,
37 signers,
38 m,
39 } = self;
40
41 if signers.len() > MAX_MULTISIG_SIGNERS {
42 return Err(ProgramError::InvalidArgument);
43 }
44
45 let num_accounts = 2 + signers.len();
46
47 const UNINIT_INSTRUCTION_ACCOUNT: MaybeUninit<InstructionAccount> =
49 MaybeUninit::<InstructionAccount>::uninit();
50 let mut instruction_accounts = [UNINIT_INSTRUCTION_ACCOUNT; 2 + MAX_MULTISIG_SIGNERS];
51
52 unsafe {
53 instruction_accounts
57 .get_unchecked_mut(0)
58 .write(InstructionAccount::writable(multisig.address()));
59 instruction_accounts
60 .get_unchecked_mut(1)
61 .write(InstructionAccount::readonly(rent_sysvar.address()));
62 }
63
64 for (instruction_account, signer) in
65 instruction_accounts[2..].iter_mut().zip(signers.iter())
66 {
67 instruction_account.write(InstructionAccount::readonly(signer.address()));
68 }
69
70 let data = &[2, m];
74
75 let instruction = InstructionView {
76 program_id: &crate::ID,
77 accounts: unsafe {
78 slice::from_raw_parts(instruction_accounts.as_ptr() as _, num_accounts)
79 },
80 data,
81 };
82
83 const UNINIT_VIEW: MaybeUninit<&AccountView> = MaybeUninit::uninit();
85 let mut acc_views = [UNINIT_VIEW; 2 + MAX_MULTISIG_SIGNERS];
86
87 unsafe {
88 acc_views.get_unchecked_mut(0).write(multisig);
92 acc_views.get_unchecked_mut(1).write(rent_sysvar);
93 }
94
95 for (account_view, signer) in acc_views[2..].iter_mut().zip(signers.iter()) {
97 account_view.write(signer);
98 }
99
100 invoke_with_bounds::<{ 2 + MAX_MULTISIG_SIGNERS }>(&instruction, unsafe {
101 slice::from_raw_parts(acc_views.as_ptr() as _, num_accounts)
102 })
103 }
104}