use solana_program::pubkey::Pubkey;
use spl_associated_token_account::{
get_associated_token_address, get_associated_token_address_with_program_id,
};
use steel::*;
use crate::{
consts::{EXECUTOR_ADDRESS, FEE_COLLECTOR, USDC_MAINNET_MINT},
instruction::{AdminPayout, AdminRouteFees, BuyTicket, Initialize, PlaceBet},
state::{Treasury, User},
};
#[inline(always)]
pub fn program_id() -> Pubkey {
crate::ID
}
pub fn treasury_usdc_ata() -> Pubkey {
get_associated_token_address(&Treasury::pda().0, &USDC_MAINNET_MINT)
}
pub fn treasury_usdc_ata_with_token_program(token_program: &Pubkey) -> Pubkey {
get_associated_token_address_with_program_id(
&Treasury::pda().0,
&USDC_MAINNET_MINT,
token_program,
)
}
pub fn associated_usdc_ata(owner: Pubkey, token_program: &Pubkey) -> Pubkey {
get_associated_token_address_with_program_id(&owner, &USDC_MAINNET_MINT, token_program)
}
pub fn usdc_ata(owner: Pubkey) -> Pubkey {
get_associated_token_address(&owner, &USDC_MAINNET_MINT)
}
pub fn fee_collector_usdc_ata_with_token_program(token_program: &Pubkey) -> Pubkey {
get_associated_token_address_with_program_id(&FEE_COLLECTOR, &USDC_MAINNET_MINT, token_program)
}
pub fn initialize(payer: Pubkey, token_program: Pubkey) -> Instruction {
let treasury_address = Treasury::pda().0;
let treasury_ata = treasury_usdc_ata_with_token_program(&token_program);
Instruction {
program_id: crate::ID,
accounts: vec![
AccountMeta::new(payer, true),
AccountMeta::new(treasury_address, false),
AccountMeta::new_readonly(USDC_MAINNET_MINT, false),
AccountMeta::new(treasury_ata, false),
AccountMeta::new_readonly(system_program::ID, false),
AccountMeta::new_readonly(token_program, false),
AccountMeta::new_readonly(spl_associated_token_account::ID, false),
],
data: Initialize {}.to_bytes(),
}
}
pub fn buy_ticket(user: Pubkey, amount: u64, token_program: Pubkey) -> Instruction {
let user_ata = associated_usdc_ata(user, &token_program);
let treasury_address = Treasury::pda().0;
let treasury_ata = treasury_usdc_ata_with_token_program(&token_program);
let user_pda = User::pda(&user).0;
let fee_collector_ata = fee_collector_usdc_ata_with_token_program(&token_program);
Instruction {
program_id: crate::ID,
accounts: vec![
AccountMeta::new(user, true),
AccountMeta::new(user_ata, false),
AccountMeta::new(treasury_address, false),
AccountMeta::new(treasury_ata, false),
AccountMeta::new(user_pda, false),
AccountMeta::new(fee_collector_ata, false),
AccountMeta::new_readonly(USDC_MAINNET_MINT, false),
AccountMeta::new_readonly(token_program, false),
AccountMeta::new_readonly(system_program::ID, false),
],
data: BuyTicket {
amount: amount.to_le_bytes(),
}
.to_bytes(),
}
}
pub fn place_bet(user: Pubkey, side: u8, series_id: u16, period: u64) -> Instruction {
let user_pda = User::pda(&user).0;
Instruction {
program_id: crate::ID,
accounts: vec![
AccountMeta::new(user, true),
AccountMeta::new(user_pda, false),
],
data: PlaceBet {
side,
_pad: [0; 1],
series_id: series_id.to_le_bytes(),
_pad2: [0; 4],
period: period.to_le_bytes(),
}
.to_bytes(),
}
}
pub fn route_fees(executor: Pubkey, amount: u64, token_program: Pubkey) -> Instruction {
let treasury_address = Treasury::pda().0;
let treasury_ata = treasury_usdc_ata_with_token_program(&token_program);
let executor_ata = associated_usdc_ata(executor, &token_program);
let fee_collector_ata = fee_collector_usdc_ata_with_token_program(&token_program);
Instruction {
program_id: crate::ID,
accounts: vec![
AccountMeta::new(executor, true),
AccountMeta::new(executor_ata, false),
AccountMeta::new(treasury_address, false),
AccountMeta::new(treasury_ata, false),
AccountMeta::new(fee_collector_ata, false),
AccountMeta::new_readonly(USDC_MAINNET_MINT, false),
AccountMeta::new_readonly(token_program, false),
],
data: AdminRouteFees {
amount: amount.to_le_bytes(),
}
.to_bytes(),
}
}
pub fn route_fees_default_executor(amount: u64, token_program: Pubkey) -> Instruction {
route_fees(EXECUTOR_ADDRESS, amount, token_program)
}
pub fn payout(
executor: Pubkey,
recipient_ata: Pubkey,
amount: u64,
series_id: u16,
period: u64,
token_program: Pubkey,
) -> Instruction {
let treasury_address = Treasury::pda().0;
let treasury_ata = treasury_usdc_ata_with_token_program(&token_program);
Instruction {
program_id: crate::ID,
accounts: vec![
AccountMeta::new(executor, true),
AccountMeta::new(treasury_address, false),
AccountMeta::new(treasury_ata, false),
AccountMeta::new(recipient_ata, false),
AccountMeta::new_readonly(USDC_MAINNET_MINT, false),
AccountMeta::new_readonly(token_program, false),
],
data: AdminPayout {
amount: amount.to_le_bytes(),
series_id: series_id.to_le_bytes(),
_pad_ix: [0; 6],
period: period.to_le_bytes(),
}
.to_bytes(),
}
}