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, PYTH_BTC_USD_PRICE_FEED_ACCOUNT, USDC_MAINNET_MINT,
},
instruction::{AdminInstantSettlement, AdminPayout, Deposit, Initialize},
state::Treasury,
};
#[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),
AccountMeta::new_readonly(PYTH_BTC_USD_PRICE_FEED_ACCOUNT, false),
],
data: Initialize {}.to_bytes(),
}
}
pub fn deposit(user: Pubkey, amount: u64, token_program: Pubkey) -> Instruction {
let user_ata = associated_usdc_ata(user, &token_program);
let treasury_ata = treasury_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_ata, false),
AccountMeta::new_readonly(USDC_MAINNET_MINT, false),
AccountMeta::new_readonly(token_program, false),
],
data: Deposit {
amount: amount.to_le_bytes(),
}
.to_bytes(),
}
}
pub fn settle_period(authority: Pubkey, series_id: u16, period: u64) -> Instruction {
Instruction {
program_id: crate::ID,
accounts: vec![
AccountMeta::new(authority, true),
AccountMeta::new(Treasury::pda().0, false),
AccountMeta::new_readonly(PYTH_BTC_USD_PRICE_FEED_ACCOUNT, false),
],
data: AdminInstantSettlement {
series_id: series_id.to_le_bytes(),
_pad_ix: [0; 6],
period: period.to_le_bytes(),
}
.to_bytes(),
}
}
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(),
}
}
pub fn settle_period_default_executor(series_id: u16, period: u64) -> Instruction {
settle_period(EXECUTOR_ADDRESS, series_id, period)
}