pub mod custom;
use std::ops::Deref;
use anchor_lang::prelude::*;
use crate::{
states::{Chainlink, Oracle, PriceValidator, Store, TokenMapHeader, TokenMapLoader},
utils::internal,
};
pub use self::custom::*;
#[derive(Accounts)]
pub struct InitializeOracle<'info> {
pub payer: Signer<'info>,
pub authority: UncheckedAccount<'info>,
pub store: AccountLoader<'info, Store>,
#[account(zero)]
pub oracle: AccountLoader<'info, Oracle>,
pub system_program: Program<'info, System>,
}
pub(crate) fn initialize_oracle(ctx: Context<InitializeOracle>) -> Result<()> {
ctx.accounts
.oracle
.load_init()?
.init(ctx.accounts.store.key(), ctx.accounts.authority.key());
Ok(())
}
#[derive(Accounts)]
pub struct ClearAllPrices<'info> {
pub authority: Signer<'info>,
pub store: AccountLoader<'info, Store>,
#[account(
mut,
has_one = store,
has_one = authority,
)]
pub oracle: AccountLoader<'info, Oracle>,
}
pub(crate) fn unchecked_clear_all_prices(ctx: Context<ClearAllPrices>) -> Result<()> {
ctx.accounts.oracle.load_mut()?.clear_all_prices();
Ok(())
}
impl<'info> internal::Authentication<'info> for ClearAllPrices<'info> {
fn authority(&self) -> &Signer<'info> {
&self.authority
}
fn store(&self) -> &AccountLoader<'info, Store> {
&self.store
}
}
#[derive(Accounts)]
pub struct SetPricesFromPriceFeed<'info> {
pub authority: Signer<'info>,
#[account(has_one = token_map)]
pub store: AccountLoader<'info, Store>,
#[account(
mut,
has_one = store,
has_one = authority,
)]
pub oracle: AccountLoader<'info, Oracle>,
#[account(has_one = store)]
pub token_map: AccountLoader<'info, TokenMapHeader>,
pub chainlink_program: Option<Program<'info, Chainlink>>,
}
pub(crate) fn unchecked_set_prices_from_price_feed<'info>(
ctx: Context<'_, '_, 'info, 'info, SetPricesFromPriceFeed<'info>>,
tokens: Vec<Pubkey>,
) -> Result<()> {
let validator = PriceValidator::try_from(ctx.accounts.store.load()?.deref())?;
let token_map = ctx.accounts.token_map.load_token_map()?;
ctx.accounts
.oracle
.load_mut()?
.set_prices_from_remaining_accounts(
validator,
&token_map,
&tokens,
ctx.remaining_accounts,
ctx.accounts.chainlink_program.as_ref(),
)
}
impl<'info> internal::Authentication<'info> for SetPricesFromPriceFeed<'info> {
fn authority(&self) -> &Signer<'info> {
&self.authority
}
fn store(&self) -> &AccountLoader<'info, Store> {
&self.store
}
}