use anchor_lang::{InstructionData, ToAccountMetas};
use solana_program::{instruction::Instruction, pubkey::Pubkey};
use crate::constants::{
INSTRUCTIONS_SYSVAR_ID, KAMINO_FARMS_PROGRAM_ID, KAMINO_LENDING_PROGRAM_ID, SYSTEM_PROGRAM_ID,
};
pub struct DepositKaminoParams {
pub owner: Pubkey,
pub payer: Pubkey,
pub liquidity_mint: Pubkey,
pub liquidity_token_program: Pubkey,
pub kamino_market: Pubkey,
pub kamino_reserve: Pubkey,
pub deposit_address_spl: Option<Pubkey>,
}
pub fn deposit_kamino(params: &DepositKaminoParams) -> Instruction {
let vault = pyra_accounts::get_vault(¶ms.owner);
let vault_liquidity_ata = pyra_accounts::get_associated_token_address(
&vault,
¶ms.liquidity_mint,
¶ms.liquidity_token_program,
);
let deposit_address = pyra_accounts::get_deposit_address(¶ms.owner);
let kamino_obligation =
pyra_accounts::get_kamino_obligation(¶ms.owner, ¶ms.kamino_market);
let kamino_market_authority =
pyra_accounts::get_kamino_lending_market_authority(¶ms.kamino_market);
let kamino_reserve_liquidity_supply =
pyra_accounts::get_kamino_reserve_liquidity_supply(¶ms.kamino_reserve);
let kamino_reserve_collateral_mint =
pyra_accounts::get_kamino_reserve_collateral_mint(¶ms.kamino_reserve);
let kamino_reserve_collateral_supply =
pyra_accounts::get_kamino_reserve_collateral_supply(¶ms.kamino_reserve);
let accounts = crate::pyra_program::client::accounts::DepositKamino {
vault,
vault_liquidity_ata,
deposit_address,
deposit_address_spl: params.deposit_address_spl,
liquidity_mint: params.liquidity_mint,
payer: params.payer,
liquidity_token_program: params.liquidity_token_program,
associated_token_program: pyra_accounts::ASSOCIATED_TOKEN_PROGRAM_ID,
kamino_program: KAMINO_LENDING_PROGRAM_ID,
kamino_obligation,
kamino_market: params.kamino_market,
kamino_market_authority,
kamino_reserve: params.kamino_reserve,
kamino_reserve_liquidity_supply,
kamino_reserve_collateral_mint,
kamino_reserve_collateral_supply,
collateral_token_program: pyra_tokens::TOKEN_PROGRAM_ID,
instructions_sysvar_account: INSTRUCTIONS_SYSVAR_ID,
kamino_farms_program: KAMINO_FARMS_PROGRAM_ID,
system_program: SYSTEM_PROGRAM_ID,
}
.to_account_metas(None);
let data = crate::pyra_program::client::args::DepositKamino {}.data();
Instruction {
program_id: pyra_accounts::PYRA_PROGRAM_ID,
accounts,
data,
}
}
#[cfg(test)]
#[allow(clippy::allow_attributes, clippy::allow_attributes_without_reason, clippy::unwrap_used, reason = "test code")]
mod tests {
use super::*;
use solana_pubkey::pubkey;
#[test]
fn test_deposit_kamino_instruction() {
let owner = pubkey!("d4A2prbA2whesmvHaL88BH6Ewn5N4bTSjm4GiKy2eSi");
let payer = pubkey!("7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF");
let market = pubkey!("Gnt27xtC473ZT2Mw5u8wZ68Z3gULkSTb5DuxJy7eJotD");
let reserve = pubkey!("AdtRGGhmqvom3Fk5H2LTnGMfcXmUQdhSz8aPJGfhFqHj");
let mint = pubkey!("DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5");
let token_program = pubkey!("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
let ix = deposit_kamino(&DepositKaminoParams {
owner,
payer,
liquidity_mint: mint,
liquidity_token_program: token_program,
kamino_market: market,
kamino_reserve: reserve,
deposit_address_spl: None,
});
assert_eq!(ix.program_id, pyra_accounts::PYRA_PROGRAM_ID);
assert_eq!(ix.accounts.len(), 20);
assert_eq!(ix.accounts[0].pubkey, pyra_accounts::get_vault(&owner));
assert!(ix.accounts[0].is_writable);
assert!(!ix.data.is_empty());
}
#[test]
fn test_deposit_kamino_with_deposit_address_spl() {
let owner = pubkey!("d4A2prbA2whesmvHaL88BH6Ewn5N4bTSjm4GiKy2eSi");
let payer = pubkey!("7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF");
let market = pubkey!("Gnt27xtC473ZT2Mw5u8wZ68Z3gULkSTb5DuxJy7eJotD");
let reserve = pubkey!("AdtRGGhmqvom3Fk5H2LTnGMfcXmUQdhSz8aPJGfhFqHj");
let mint = pubkey!("DUcTi3rDyS5QEmZ4BNRBejtArmDCWaPYGfN44vBJXKL5");
let token_program = pubkey!("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
let deposit_spl = pubkey!("3NJYftD5sjVfxFkKFgU7bbtBBhBsBYAg1CEhJkJ4iY3H");
let ix = deposit_kamino(&DepositKaminoParams {
owner,
payer,
liquidity_mint: mint,
liquidity_token_program: token_program,
kamino_market: market,
kamino_reserve: reserve,
deposit_address_spl: Some(deposit_spl),
});
assert_eq!(ix.program_id, pyra_accounts::PYRA_PROGRAM_ID);
assert!(!ix.data.is_empty());
}
}