use proc_macro::TokenStream;
use quote::quote;
use syn::Item;
pub fn arcium_program_macro(input: &mut Item) -> TokenStream {
let errors = quote! {
#[error_code]
pub enum FinalizeError {
#[msg("Invalid finalize transaction")]
InvalidFinalizeTx,
#[msg("Invalid account")]
InvalidAccount,
}
};
let signer_account_struct = quote! {
#[::anchor_lang::prelude::account]
pub struct SignerAccount {
bump: u8,
}
};
let validate_callback_ixs = quote! {
fn validate_callback_ixs(instructions_sysvar: &AccountInfo, arcium_program: &Pubkey) -> Result<()> {
const ARCIUM_FINALIZE_COMPUTATION_DISCRIMINATOR: [u8; 8] =
[43, 29, 152, 92, 241, 179, 193, 210];
const ARCIUM_CALLBACK_COMPUTATION_DISCRIMINATOR: [u8; 8] =
[11, 224, 42, 236, 0, 154, 74, 163];
let curr_ix_index = ::anchor_lang::solana_program::sysvar::instructions::load_current_index_checked(instructions_sysvar)?;
require!(curr_ix_index != 0, FinalizeError::InvalidFinalizeTx);
let prev_ix = ::anchor_lang::solana_program::sysvar::instructions::load_instruction_at_checked((curr_ix_index as usize) - 1, instructions_sysvar)?;
require!(
prev_ix.program_id == *arcium_program,
FinalizeError::InvalidFinalizeTx,
);
require!(
prev_ix.data[0..8] == ARCIUM_FINALIZE_COMPUTATION_DISCRIMINATOR || prev_ix.data[0..8] == ARCIUM_CALLBACK_COMPUTATION_DISCRIMINATOR,
FinalizeError::InvalidFinalizeTx
);
require!(
::anchor_lang::solana_program::sysvar::instructions::load_instruction_at_checked((curr_ix_index as usize) + 1, instructions_sysvar)
.is_err_and(|e| { e == ProgramError::InvalidArgument }),
FinalizeError::InvalidFinalizeTx
);
Ok(())
}
};
quote! {
#errors
#signer_account_struct
#validate_callback_ixs
#[program]
#input
}
.into()
}