This TokenAccountAndBalance struct is to track token accounts and balance change. This is for tracking how much token is increased or decreased.
Loading remaining accounts
pub fn load_remaining_accounts<'info>(
remaining_accounts: &[AccountInfo<'info>],
index_array: Vec<usize>,
) -> Vec<AccountMeta> {
let mut accounts: Vec<AccountMeta> = vec![];
for index in index_array.iter() {
if remaining_accounts[*index].is_writable {
accounts.push(AccountMeta::new(
remaining_accounts[*index].key(),
remaining_accounts[*index].is_signer,
))
} else {
accounts.push(AccountMeta::new_readonly(
remaining_accounts[*index].key(),
remaining_accounts[*index].is_signer,
))
}
}
return accounts;
}
This function is to load the remaining_accounts into a Vec<AccountMeta> The index_array is a array of index for looking up the remaining_accounts to build the account meta.
The OutputWrapper is for wrapping up the result after the CPI call. The Gataway program takes 32 byte long return data, dummy here is for adding 0 in the ends to fill the rest.
Main Logic
{
...
let mut stake_data = sighash("global", "stake").to_vec();
stake_data.append(&mut input_struct.amount.to_le_bytes().to_vec());
stake_data.append(&mut input_struct.lock_for_months.to_le_bytes().to_vec());
stake_data.push(0); // default False cuz it's deprecated
let stake_accounts = load_remaining_accounts(
ctx.remaining_accounts,
vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
);
let mut stake_token_account_and_balance =
load_token_account_and_balance(ctx.remaining_accounts, 5); // Save the token balance before the invocation
let stake_ix = Instruction {
program_id: ctx.accounts.base_program_id.key(),
accounts: stake_accounts,
data: stake_data,
};
invoke(&stake_ix, ctx.remaining_accounts)?;
// Wrap Output
let output_struct = StakeOutputWrapper {
token_in_amount: stake_token_account_and_balance.get_balance_change(),
..Default::default()
};
let mut output: Vec<u8> = Vec::new();
output_struct.serialize(&mut output).unwrap();
// Return Result
anchor_lang::solana_program::program::set_return_data(&output);
msg!("Output: {:?}", output_struct);
Ok(())
}
After loading the inputs, is to build the instruction data and accounts for CPI call.
After calling the base program using invoke, the output is serialized and returned to Gateway program.