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 CallbackError {
#[msg("Invalid callback transaction")]
InvalidCallbackTx,
}
};
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_CALLBACK_COMPUTATION_DISCRIMINATOR: [u8; 8] =
[11, 224, 42, 236, 0, 154, 74, 163];
const LIGHTHOUSE_PROGRAM_ID: Pubkey = ::anchor_lang::solana_program::pubkey::Pubkey::from_str_const(
"L2TExMFKdjpN9kozasaurPirfHy9P8sbXoAN1qA3S95",
);
let curr_ix_index = ::anchor_lang::solana_program::sysvar::instructions::load_current_index_checked(instructions_sysvar)?;
require!(curr_ix_index != 0, CallbackError::InvalidCallbackTx);
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,
CallbackError::InvalidCallbackTx,
);
require!(
prev_ix.data[0..8] == ARCIUM_CALLBACK_COMPUTATION_DISCRIMINATOR,
CallbackError::InvalidCallbackTx
);
let mut check_index = (curr_ix_index as usize) + 1;
let mut lighthouse_count = 0;
while let Ok(ix) = ::anchor_lang::solana_program::sysvar::instructions::load_instruction_at_checked(
check_index,
instructions_sysvar,
) {
require!(
ix.program_id == LIGHTHOUSE_PROGRAM_ID,
CallbackError::InvalidCallbackTx
);
lighthouse_count += 1;
require!(
lighthouse_count <= 2,
CallbackError::InvalidCallbackTx
);
check_index += 1;
}
Ok(())
}
};
quote! {
#errors
#signer_account_struct
#validate_callback_ixs
#[program]
#input
}
.into()
}