klend_interface/helpers/
borrow.rs1use solana_instruction::Instruction;
2use solana_pubkey::Pubkey;
3
4use super::{
5 common::{
6 build_deposit_reserves_remaining, build_refresh_all_obligation_reserves,
7 build_refresh_obligation, build_refresh_reserve,
8 },
9 info::{FarmsAccounts, ObligationInfo, ReserveInfo},
10};
11use crate::{
12 instructions::borrow::{
13 borrow_obligation_liquidity_v2, rollover_fixed_term_borrow as rollover_ix,
14 BorrowObligationLiquidityV2Accounts, RolloverFixedTermBorrowAccounts,
15 },
16 pda::{self, ReservePdas},
17 KLEND_PROGRAM_ID,
18};
19
20pub fn borrow(
28 owner: Pubkey,
29 borrow_reserve: &ReserveInfo,
30 obligation: &ObligationInfo,
31 obligation_reserves: &[ReserveInfo],
32 user_destination_liquidity: Pubkey,
33 liquidity_amount: u64,
34 farms: Option<&FarmsAccounts>,
35) -> Vec<Instruction> {
36 let pdas = ReservePdas::derive(&KLEND_PROGRAM_ID, &borrow_reserve.address);
37 let (lma, _) = pda::lending_market_authority(&KLEND_PROGRAM_ID, &borrow_reserve.lending_market);
38
39 let referrer_token_state = obligation.referrer.map(|referrer| {
40 pda::referrer_token_state(&KLEND_PROGRAM_ID, &referrer, &borrow_reserve.address).0
41 });
42
43 let remaining = build_deposit_reserves_remaining(obligation);
44
45 let mut ixs = build_refresh_all_obligation_reserves(
46 obligation,
47 obligation_reserves,
48 &[borrow_reserve.address],
49 );
50 ixs.push(build_refresh_reserve(borrow_reserve));
51 ixs.push(build_refresh_obligation(
52 &borrow_reserve.lending_market,
53 obligation,
54 ));
55 ixs.push(borrow_obligation_liquidity_v2(
56 BorrowObligationLiquidityV2Accounts {
57 owner,
58 obligation: obligation.address,
59 lending_market: borrow_reserve.lending_market,
60 lending_market_authority: lma,
61 borrow_reserve: borrow_reserve.address,
62 borrow_reserve_liquidity_mint: borrow_reserve.liquidity_mint,
63 reserve_source_liquidity: pdas.liquidity_supply_vault,
64 borrow_reserve_liquidity_fee_receiver: pdas.fee_vault,
65 user_destination_liquidity,
66 referrer_token_state,
67 token_program: borrow_reserve.liquidity_token_program,
68 obligation_farm_user_state: farms.map(|f| f.obligation_farm_user_state),
69 reserve_farm_state: farms.map(|f| f.reserve_farm_state),
70 },
71 liquidity_amount,
72 remaining,
73 ));
74
75 ixs
76}
77
78pub fn rollover_fixed_term_borrow(
86 payer: Pubkey,
87 obligation: &ObligationInfo,
88 obligation_reserves: &[ReserveInfo],
89 source_reserve: &ReserveInfo,
90 target_reserve: &ReserveInfo,
91 source_farms: Option<&FarmsAccounts>,
92 target_farms: Option<&FarmsAccounts>,
93) -> Vec<Instruction> {
94 let (lma, _) = pda::lending_market_authority(&KLEND_PROGRAM_ID, &source_reserve.lending_market);
95 let source_pdas = ReservePdas::derive(&KLEND_PROGRAM_ID, &source_reserve.address);
96 let target_pdas = ReservePdas::derive(&KLEND_PROGRAM_ID, &target_reserve.address);
97
98 let mut already_refreshed = vec![source_reserve.address];
99 let same_reserve = source_reserve.address == target_reserve.address;
100 if !same_reserve {
101 already_refreshed.push(target_reserve.address);
102 }
103
104 let mut ixs =
105 build_refresh_all_obligation_reserves(obligation, obligation_reserves, &already_refreshed);
106 ixs.push(build_refresh_reserve(source_reserve));
107 if !same_reserve {
108 ixs.push(build_refresh_reserve(target_reserve));
109 }
110 ixs.push(build_refresh_obligation(
111 &source_reserve.lending_market,
112 obligation,
113 ));
114
115 ixs.push(rollover_ix(RolloverFixedTermBorrowAccounts {
116 payer,
117 obligation: obligation.address,
118 lending_market: source_reserve.lending_market,
119 lending_market_authority: lma,
120 source_borrow_reserve: source_reserve.address,
121 target_borrow_reserve: target_reserve.address,
122 liquidity_mint: source_reserve.liquidity_mint,
123 source_borrow_reserve_liquidity: source_pdas.liquidity_supply_vault,
124 target_borrow_reserve_liquidity: target_pdas.liquidity_supply_vault,
125 token_program: source_reserve.liquidity_token_program,
126 source_obligation_farm_user_state: source_farms.map(|f| f.obligation_farm_user_state),
127 source_reserve_farm_state: source_farms.map(|f| f.reserve_farm_state),
128 target_obligation_farm_user_state: target_farms.map(|f| f.obligation_farm_user_state),
129 target_reserve_farm_state: target_farms.map(|f| f.reserve_farm_state),
130 }));
131
132 ixs
133}