1#![doc = include_str!("../README.md")]
2#![allow(unexpected_cfgs)]
3
4use solana_account_info::AccountInfo;
5use solana_instruction::Instruction;
6use solana_program_entrypoint::ProgramResult;
7
8mod stable_instruction_borrowed;
9
10pub fn invoke(instruction: &Instruction, account_infos: &[AccountInfo]) -> ProgramResult {
11 invoke_signed(instruction, account_infos, &[])
12}
13
14pub fn invoke_unchecked(instruction: &Instruction, account_infos: &[AccountInfo]) -> ProgramResult {
15 invoke_signed_unchecked(instruction, account_infos, &[])
16}
17
18pub fn invoke_signed(
19 instruction: &Instruction,
20 account_infos: &[AccountInfo],
21 signers_seeds: &[&[&[u8]]],
22) -> ProgramResult {
23 for account_meta in instruction.accounts.iter() {
25 for account_info in account_infos.iter() {
26 if account_meta.pubkey == *account_info.key {
27 if account_meta.is_writable {
28 let _ = account_info.try_borrow_mut_lamports()?;
29 let _ = account_info.try_borrow_mut_data()?;
30 } else {
31 let _ = account_info.try_borrow_lamports()?;
32 let _ = account_info.try_borrow_data()?;
33 }
34 break;
35 }
36 }
37 }
38
39 invoke_signed_unchecked(instruction, account_infos, signers_seeds)
40}
41
42#[cfg(target_os = "solana")]
43use solana_define_syscall::definitions::sol_invoke_signed_rust;
44
45#[cfg(not(target_os = "solana"))]
46unsafe fn sol_invoke_signed_rust(_: *const u8, _: *const u8, _: u64, _: *const u8, _: u64) -> u64 {
47 unimplemented!("only supported with `target_os = \"solana\"")
48}
49
50pub fn invoke_signed_unchecked(
51 instruction: &Instruction,
52 account_infos: &[AccountInfo],
53 signers_seeds: &[&[&[u8]]],
54) -> ProgramResult {
55 use stable_instruction_borrowed::StableInstructionBorrowed;
56 let stable = StableInstructionBorrowed::new(instruction);
57 let instruction_addr = stable.instruction_addr();
58
59 let result = unsafe {
60 sol_invoke_signed_rust(
61 instruction_addr,
62 account_infos as *const _ as *const u8,
63 account_infos.len() as u64,
64 signers_seeds as *const _ as *const u8,
65 signers_seeds.len() as u64,
66 )
67 };
68
69 match result {
70 solana_program_entrypoint::SUCCESS => Ok(()),
71 _ => Err(result.into()),
72 }
73}