jup-lend-sdk 0.1.3

SDK for Jupiter lending protocol
Documentation
use std::rc::Rc;

use crate::programs::oracle::ID;
use crate::programs::{oracle, oracle::types::Sources};

use anchor_client::solana_sdk::message::Message;
use anchor_client::solana_sdk::transaction::Transaction;
use anchor_client::{
    solana_client::rpc_config::RpcSimulateTransactionConfig,
    solana_sdk::{commitment_config::CommitmentConfig, signer::Signer},
    Client, Cluster,
};
use anchor_lang::prelude::{AccountMeta, Pubkey};
pub const ORACLE_PROGRAM_ID: Pubkey = ID;

#[derive(Debug, Clone)]
pub struct OraclePriceLiquidate {
    pub price: u128,
    pub sources: Vec<Sources>,
}

#[derive(Debug, Clone)]
pub struct OraclePriceLiquidateParams {
    pub oracle: Pubkey,
    pub cluster: Cluster,
}

#[derive(Debug, Clone)]
struct Keypair;

impl Keypair {
    fn new() -> Self {
        Keypair
    }
}

impl Signer for Keypair {
    fn pubkey(&self) -> Pubkey {
        Pubkey::from_str_const("HEyJLdMfZhhQ7FHCtjD5DWDFNFQhaeAVAsHeWqoY6dSD")
    }

    fn try_pubkey(&self) -> Result<Pubkey, anchor_client::solana_sdk::signer::SignerError> {
        Ok(self.pubkey())
    }

    fn try_sign_message(
        &self,
        _message: &[u8],
    ) -> Result<
        anchor_client::solana_sdk::signature::Signature,
        anchor_client::solana_sdk::signer::SignerError,
    > {
        Ok(anchor_client::solana_sdk::signature::Signature::default())
    }

    fn is_interactive(&self) -> bool {
        true
    }
}

pub fn get_oracle_price_liquidate(
    params: OraclePriceLiquidateParams,
) -> anyhow::Result<OraclePriceLiquidate> {
    let payer = Keypair::new();
    let provider = Client::new_with_options(
        params.cluster.clone(),
        Rc::new(payer.clone()),
        CommitmentConfig::confirmed(),
    );
    let program = provider.program(ORACLE_PROGRAM_ID)?;
    let oracle: oracle::accounts::Oracle = program.account(params.oracle)?;

    let mut remaining_accounts = vec![];

    for source in &oracle.sources {
        remaining_accounts.push(AccountMeta::new_readonly(source.source, false));
    }

    let mut price = 0;

    let instructions = program
        .request()
        .accounts(oracle::client::accounts::GetExchangeRateLiquidate {
            oracle: params.oracle,
        })
        .accounts(remaining_accounts)
        .args(oracle::client::args::GetExchangeRateLiquidate {
            _nonce: oracle.nonce,
        })
        .instructions()?;

    let message = Message::new(&instructions, Some(&payer.pubkey()));
    let transaction = Transaction::new_unsigned(message);

    let simulation = program.rpc().simulate_transaction_with_config(
        &transaction,
        RpcSimulateTransactionConfig {
            replace_recent_blockhash: true,
            sig_verify: false,
            ..Default::default()
        },
    )?;

    if let Some(data) = &simulation.value.return_data {
        let raw_bytes = base64::decode(&data.data.0)?;
        price = u128::from_le_bytes(raw_bytes.try_into().unwrap());
    }

    Ok(OraclePriceLiquidate {
        price,
        sources: oracle.sources,
    })
}