@kamino-finance/klend-sdk 5.11.5-beta.0 → 5.11.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/classes/action.d.ts +2 -12
  2. package/dist/classes/action.d.ts.map +1 -1
  3. package/dist/classes/action.js +30 -228
  4. package/dist/classes/action.js.map +1 -1
  5. package/dist/classes/lut_utils.d.ts +29 -0
  6. package/dist/classes/lut_utils.d.ts.map +1 -0
  7. package/dist/classes/lut_utils.js +62 -0
  8. package/dist/classes/lut_utils.js.map +1 -0
  9. package/dist/classes/manager.d.ts.map +1 -1
  10. package/dist/classes/manager.js +0 -1
  11. package/dist/classes/manager.js.map +1 -1
  12. package/dist/classes/obligation.d.ts +1 -1
  13. package/dist/classes/obligation.d.ts.map +1 -1
  14. package/dist/classes/obligation.js +1 -1
  15. package/dist/classes/obligation.js.map +1 -1
  16. package/dist/classes/types.d.ts.map +1 -1
  17. package/dist/classes/vault.js +6 -6
  18. package/dist/classes/vault.js.map +1 -1
  19. package/dist/lending_operations/repay_with_collateral_calcs.d.ts.map +1 -1
  20. package/dist/lending_operations/repay_with_collateral_calcs.js +5 -9
  21. package/dist/lending_operations/repay_with_collateral_calcs.js.map +1 -1
  22. package/dist/lending_operations/repay_with_collateral_operations.d.ts +0 -5
  23. package/dist/lending_operations/repay_with_collateral_operations.d.ts.map +1 -1
  24. package/dist/lending_operations/repay_with_collateral_operations.js +1 -26
  25. package/dist/lending_operations/repay_with_collateral_operations.js.map +1 -1
  26. package/dist/utils/lookupTable.d.ts +0 -27
  27. package/dist/utils/lookupTable.d.ts.map +1 -1
  28. package/dist/utils/lookupTable.js +0 -58
  29. package/dist/utils/lookupTable.js.map +1 -1
  30. package/dist/utils/seeds.d.ts +1 -11
  31. package/dist/utils/seeds.d.ts.map +1 -1
  32. package/dist/utils/seeds.js +3 -13
  33. package/dist/utils/seeds.js.map +1 -1
  34. package/dist/utils/userMetadata.d.ts.map +1 -1
  35. package/dist/utils/userMetadata.js +7 -8
  36. package/dist/utils/userMetadata.js.map +1 -1
  37. package/package.json +1 -1
  38. package/src/classes/action.ts +50 -361
  39. package/src/classes/lut_utils.ts +63 -0
  40. package/src/classes/manager.ts +0 -3
  41. package/src/classes/obligation.ts +1 -1
  42. package/src/classes/types.ts +1 -1
  43. package/src/classes/vault.ts +1 -1
  44. package/src/lending_operations/repay_with_collateral_calcs.ts +5 -14
  45. package/src/lending_operations/repay_with_collateral_operations.ts +20 -63
  46. package/src/utils/lookupTable.ts +0 -62
  47. package/src/utils/seeds.ts +4 -14
  48. package/src/utils/userMetadata.ts +15 -16
@@ -50,7 +50,6 @@ import {
50
50
  ReserveWithAddress,
51
51
  sameLengthArrayEquals,
52
52
  ScopeOracleConfig,
53
- sleep,
54
53
  updateEntireReserveConfigIx,
55
54
  updateLendingMarket,
56
55
  UpdateLendingMarketAccounts,
@@ -594,8 +593,6 @@ export class KaminoManager {
594
593
  }
595
594
  );
596
595
 
597
- await sleep(500);
598
-
599
596
  const markets = await Promise.all(
600
597
  lendingMarketsAccounts.map((account) =>
601
598
  KaminoMarket.load(this._connection, account.pubkey, this.recentSlotDurationMs, this._kaminoLendProgramId)
@@ -267,7 +267,7 @@ export class KaminoObligation {
267
267
  /**
268
268
  * @returns total borrow power of the obligation, relative to max LTV of each asset's reserve
269
269
  */
270
- getMaxAllowedBorrowValue(): Decimal {
270
+ getAllowedBorrowValue(): Decimal {
271
271
  return new Fraction(this.state.allowedBorrowValueSf).toDecimal();
272
272
  }
273
273
 
@@ -58,4 +58,4 @@ export type ReserveAllocationOverview = {
58
58
  export type APYs = {
59
59
  grossAPY: Decimal;
60
60
  netAPY: Decimal;
61
- }
61
+ };
@@ -82,7 +82,7 @@ import {
82
82
  import { batchFetch, collToLamportsDecimal, ZERO } from '@kamino-finance/kliquidity-sdk';
83
83
  import { FullBPSDecimal } from '@kamino-finance/kliquidity-sdk/dist/utils/CreationParameters';
84
84
  import { FarmState } from '@kamino-finance/farms-sdk/dist';
85
- import { getAccountsInLUT, initLookupTableIx } from '../utils/lookupTable';
85
+ import { getAccountsInLUT, initLookupTableIx } from './lut_utils';
86
86
  import {
87
87
  getFarmStakeIxs,
88
88
  getFarmUnstakeAndWithdrawIxs,
@@ -2,7 +2,6 @@ import Decimal from 'decimal.js';
2
2
  import { KaminoMarket, KaminoObligation, KaminoReserve, numberToLamportsDecimal } from '../classes';
3
3
  import { PublicKey } from '@solana/web3.js';
4
4
  import { lamportsToDecimal } from '../classes/utils';
5
- import { MaxWithdrawLtvCheck, getMaxWithdrawLtvCheck } from './repay_with_collateral_operations';
6
5
 
7
6
  export function calcRepayAmountWithSlippage(
8
7
  kaminoMarket: KaminoMarket,
@@ -103,7 +102,6 @@ export function calcMaxWithdrawCollateral(
103
102
  .filter((p) => !p.reserveAddress.equals(borrow.reserveAddress))
104
103
  .reduce((acc, b) => acc.add(b.marketValueRefreshed), new Decimal('0'));
105
104
  }
106
- const maxWithdrawLtvCheck = getMaxWithdrawLtvCheck(obligation);
107
105
 
108
106
  let remainingDepositsValueWithLtv = new Decimal('0');
109
107
  if (obligation.getDeposits().length > 1) {
@@ -111,13 +109,8 @@ export function calcMaxWithdrawCollateral(
111
109
  .getDeposits()
112
110
  .filter((p) => !p.reserveAddress.equals(deposit.reserveAddress))
113
111
  .reduce((acc, d) => {
114
- const { maxLtv, liquidationLtv } = obligation.getLtvForReserve(
115
- market,
116
- market.getReserveByAddress(d.reserveAddress)!
117
- );
118
- const maxWithdrawLtv =
119
- maxWithdrawLtvCheck === MaxWithdrawLtvCheck.LIQUIDATION_THRESHOLD ? liquidationLtv : maxLtv;
120
- return acc.add(d.marketValueRefreshed.mul(maxWithdrawLtv));
112
+ const { maxLtv } = obligation.getLtvForReserve(market, market.getReserveByAddress(d.reserveAddress)!);
113
+ return acc.add(d.marketValueRefreshed.mul(maxLtv));
121
114
  }, new Decimal('0'));
122
115
  }
123
116
 
@@ -130,18 +123,16 @@ export function calcMaxWithdrawCollateral(
130
123
  repayingAllDebt: repayAmountLamports.gte(borrow.amount),
131
124
  };
132
125
  } else {
133
- const { maxLtv: collMaxLtv, liquidationLtv: collLiquidationLtv } = obligation.getLtvForReserve(
126
+ const { maxLtv: collMaxLtv } = obligation.getLtvForReserve(
134
127
  market,
135
128
  market.getReserveByAddress(depositReserve.address)!
136
129
  );
137
- const maxWithdrawLtv =
138
- maxWithdrawLtvCheck === MaxWithdrawLtvCheck.LIQUIDATION_THRESHOLD ? collLiquidationLtv : collMaxLtv;
139
130
  const numerator = deposit.marketValueRefreshed
140
- .mul(maxWithdrawLtv)
131
+ .mul(collMaxLtv)
141
132
  .add(remainingDepositsValueWithLtv)
142
133
  .sub(remainingBorrowsValue);
143
134
 
144
- const denominator = depositReserve.getOracleMarketPrice().mul(maxWithdrawLtv);
135
+ const denominator = depositReserve.getOracleMarketPrice().mul(collMaxLtv);
145
136
  const maxCollWithdrawAmount = numerator.div(denominator);
146
137
  const withdrawableCollLamports = maxCollWithdrawAmount.mul(depositReserve.getMintFactor()).floor();
147
138
 
@@ -57,11 +57,6 @@ interface RepayWithCollSwapInputsProps<QuoteResponse> {
57
57
  quoter: SwapQuoteProvider<QuoteResponse>;
58
58
  }
59
59
 
60
- export enum MaxWithdrawLtvCheck {
61
- MAX_LTV,
62
- LIQUIDATION_THRESHOLD,
63
- }
64
-
65
60
  export async function getRepayWithCollSwapInputs<QuoteResponse>({
66
61
  collTokenMint,
67
62
  currentSlot,
@@ -218,17 +213,8 @@ export async function getRepayWithCollIxs<QuoteResponse>({
218
213
  const { debtRepayAmountLamports, flashRepayAmountLamports, maxCollateralWithdrawLamports, swapQuote } = initialInputs;
219
214
  const { inputAmountLamports: collSwapInLamports } = swapInputs;
220
215
 
221
- const collReserve = kaminoMarket.getReserveByMint(collTokenMint);
222
-
223
- if (!collReserve) {
224
- throw new Error(`Collateral reserve with mint ${collTokenMint} not found in market ${kaminoMarket.getAddress()}`);
225
- }
226
-
227
- const debtReserve = kaminoMarket.getReserveByMint(debtTokenMint);
228
-
229
- if (!debtReserve) {
230
- throw new Error(`Debt reserve with mint ${debtTokenMint} not found in market ${kaminoMarket.getAddress()}`);
231
- }
216
+ const collReserve = kaminoMarket.getReserveByMint(collTokenMint)!;
217
+ const debtReserve = kaminoMarket.getReserveByMint(debtTokenMint)!;
232
218
 
233
219
  // the client should use these values to prevent this input, but the tx may succeed, so we don't want to fail
234
220
  // there is also a chance that the tx will consume debt token from the user's ata which they would not expect
@@ -320,48 +306,25 @@ async function buildRepayWithCollateralIxs(
320
306
 
321
307
  const requestElevationGroup = !isClosingPosition && obligation.state.elevationGroup !== 0;
322
308
 
323
- const maxWithdrawLtvCheck = getMaxWithdrawLtvCheck(obligation);
324
-
325
309
  // 3. Repay using the flash borrowed funds & withdraw collateral to swap and pay the flash loan
326
- let repayAndWithdrawAction;
327
- if (maxWithdrawLtvCheck === MaxWithdrawLtvCheck.MAX_LTV) {
328
- repayAndWithdrawAction = await KaminoAction.buildRepayAndWithdrawTxns(
329
- market,
330
- isClosingPosition ? U64_MAX : debtRepayAmountLamports.toString(),
331
- debtReserve.getLiquidityMint(),
332
- isClosingPosition ? U64_MAX : collWithdrawLamports.toString(),
333
- collReserve.getLiquidityMint(),
334
- obligation.state.owner,
335
- currentSlot,
336
- obligation,
337
- useV2Ixs,
338
- undefined,
339
- 0,
340
- false,
341
- requestElevationGroup,
342
- undefined,
343
- undefined,
344
- referrer
345
- );
346
- } else {
347
- repayAndWithdrawAction = await KaminoAction.buildRepayAndWithdrawV2Txns(
348
- market,
349
- isClosingPosition ? U64_MAX : debtRepayAmountLamports.toString(),
350
- debtReserve.getLiquidityMint(),
351
- isClosingPosition ? U64_MAX : collWithdrawLamports.toString(),
352
- collReserve.getLiquidityMint(),
353
- obligation.state.owner,
354
- currentSlot,
355
- obligation,
356
- undefined,
357
- 0,
358
- false,
359
- requestElevationGroup,
360
- undefined,
361
- undefined,
362
- referrer
363
- );
364
- }
310
+ const repayAndWithdrawAction = await KaminoAction.buildRepayAndWithdrawTxns(
311
+ market,
312
+ isClosingPosition ? U64_MAX : debtRepayAmountLamports.toString(),
313
+ debtReserve.getLiquidityMint(),
314
+ isClosingPosition ? U64_MAX : collWithdrawLamports.toString(),
315
+ collReserve.getLiquidityMint(),
316
+ obligation.state.owner,
317
+ currentSlot,
318
+ obligation,
319
+ useV2Ixs,
320
+ undefined,
321
+ 0,
322
+ false,
323
+ requestElevationGroup,
324
+ undefined,
325
+ undefined,
326
+ referrer
327
+ );
365
328
 
366
329
  // 4. Swap collateral to debt to repay flash loan
367
330
  const { preActionIxs, swapIxs } = swapQuoteIxs;
@@ -378,9 +341,3 @@ async function buildRepayWithCollateralIxs(
378
341
  flashRepayIxn,
379
342
  ];
380
343
  }
381
-
382
- export const getMaxWithdrawLtvCheck = (obligation: KaminoObligation) => {
383
- return obligation.refreshedStats.userTotalBorrowBorrowFactorAdjusted.gte(obligation.refreshedStats.borrowLimit)
384
- ? MaxWithdrawLtvCheck.LIQUIDATION_THRESHOLD
385
- : MaxWithdrawLtvCheck.MAX_LTV;
386
- };
@@ -53,65 +53,3 @@ export const extendLookupTableIxs = (
53
53
 
54
54
  return extendLookupIxs;
55
55
  };
56
-
57
- /**
58
- * This method retuns an instruction that creates a lookup table, alongside the pubkey of the lookup table
59
- * @param payer - the owner of the lookup table
60
- * @param slot - the current slot
61
- * @returns - the instruction to create the lookup table and its address
62
- */
63
- export function initLookupTableIx(payer: PublicKey, slot: number): [TransactionInstruction, PublicKey] {
64
- const [ixn, address] = AddressLookupTableProgram.createLookupTable({
65
- authority: payer,
66
- payer,
67
- recentSlot: slot,
68
- });
69
-
70
- return [ixn, address];
71
- }
72
-
73
- /**
74
- * This method retuns an instruction that deactivates a lookup table, which is needed to close it
75
- * @param payer - the owner of the lookup table
76
- * @param lookupTable - the lookup table to deactivate
77
- * @returns - the instruction to deactivate the lookup table
78
- */
79
- export function deactivateLookupTableIx(payer: PublicKey, lookupTable: PublicKey): TransactionInstruction {
80
- const ixn = AddressLookupTableProgram.deactivateLookupTable({
81
- authority: payer,
82
- lookupTable: lookupTable,
83
- });
84
-
85
- return ixn;
86
- }
87
-
88
- /**
89
- * This method returns an instruction that closes a lookup table. That lookup table needs to be disabled at least 500 blocks before closing it.
90
- * @param payer - the owner of the lookup table
91
- * @param lookupTable - the lookup table to close
92
- * @returns - the instruction to close the lookup table
93
- */
94
- /// this require the LUT to be deactivated at least 500 blocks before
95
- export function closeLookupTableIx(payer: PublicKey, lookupTable: PublicKey): TransactionInstruction {
96
- const ixn = AddressLookupTableProgram.closeLookupTable({
97
- authority: payer,
98
- recipient: payer,
99
- lookupTable: lookupTable,
100
- });
101
-
102
- return ixn;
103
- }
104
-
105
- /**
106
- * Returns the accounts in a lookup table
107
- * @param lookupTable - lookup table to get the accounts from
108
- * @returns - an array of accounts in the lookup table
109
- */
110
- export async function getAccountsInLUT(connection: Connection, lookupTable: PublicKey): Promise<PublicKey[]> {
111
- const lutState = await connection.getAddressLookupTable(lookupTable);
112
- if (!lutState || !lutState.value) {
113
- throw new Error(`Lookup table ${lookupTable} not found`);
114
- }
115
-
116
- return lutState.value.state.addresses;
117
- }
@@ -38,10 +38,6 @@ export const BASE_SEED_REFERRER_STATE = 'ref_state';
38
38
  * Short url seed
39
39
  */
40
40
  export const BASE_SEED_SHORT_URL = 'short_url';
41
- /**
42
- * Farm user state seed
43
- */
44
- export const BASE_SEED_USER_STATE = 'user';
45
41
 
46
42
  /**
47
43
  * User farm state seed
@@ -192,15 +188,9 @@ export function shortUrlPda(shortUrl: string, programId: PublicKey = PROGRAM_ID)
192
188
  return PublicKey.findProgramAddressSync([Buffer.from(BASE_SEED_SHORT_URL), Buffer.from(shortUrl)], programId);
193
189
  }
194
190
 
195
- /**
196
- * Returns the PDA for the obligation farm state
197
- * @param farm
198
- * @param obligation
199
- * @returns pda
200
- */
201
- export function obligationFarmStatePda(farm: PublicKey, obligation: PublicKey) {
191
+ export function obligationFarmStatePda(obligation: PublicKey, farm: PublicKey, programId: PublicKey = farmsId) {
202
192
  return PublicKey.findProgramAddressSync(
203
- [Buffer.from(BASE_SEED_USER_STATE), farm.toBytes(), obligation.toBytes()],
204
- farmsId
205
- )[0];
193
+ [Buffer.from(BASE_SEED_FARM_USER_STATE), farm.toBuffer(), obligation.toBuffer()],
194
+ programId
195
+ );
206
196
  }
@@ -6,7 +6,6 @@ import {
6
6
  Connection,
7
7
  GetProgramAccountsFilter,
8
8
  } from '@solana/web3.js';
9
- import { NATIVE_MINT } from '@solana/spl-token';
10
9
  import { KaminoMarket, KaminoObligation } from '../classes';
11
10
  import {
12
11
  LeverageObligation,
@@ -259,7 +258,7 @@ function getMultiplyObligationAndObligationFarmStateAddresses(
259
258
  const collMintString = collMint.toString();
260
259
  const debtMintString = debtMint.toString();
261
260
  if (collReserve && debtReserve) {
262
- const multiplyObligation = new MultiplyObligation(collMint, NATIVE_MINT, kaminoMarket.programId);
261
+ const multiplyObligation = new MultiplyObligation(collMint, debtMint, kaminoMarket.programId);
263
262
  obligationPdas.push({
264
263
  address: multiplyObligation.toPda(kaminoMarket.getAddress(), user),
265
264
  log: 'multiply obligation coll: ' + collMintString + ' debt: ' + debtMintString,
@@ -267,18 +266,18 @@ function getMultiplyObligationAndObligationFarmStateAddresses(
267
266
  if (!collReserve.state.farmCollateral.equals(PublicKey.default)) {
268
267
  farmUserStates.push({
269
268
  address: obligationFarmStatePda(
270
- collReserve.state.farmCollateral!,
271
- multiplyObligation.toPda(kaminoMarket.getAddress(), user)
272
- ),
269
+ multiplyObligation.toPda(kaminoMarket.getAddress(), user),
270
+ collReserve.state.farmCollateral!
271
+ )[0],
273
272
  log: 'collReserve farmState for multiply obligation coll: ' + collMintString + ' debt: ' + debtMintString,
274
273
  });
275
274
  }
276
275
  if (!debtReserve.state.farmDebt.equals(PublicKey.default)) {
277
276
  farmUserStates.push({
278
277
  address: obligationFarmStatePda(
279
- debtReserve.state.farmDebt!,
280
- multiplyObligation.toPda(kaminoMarket.getAddress(), user)
281
- ),
278
+ multiplyObligation.toPda(kaminoMarket.getAddress(), user),
279
+ debtReserve.state.farmDebt!
280
+ )[0],
282
281
  log: 'debtReserve farmState for multiply obligation coll: ' + collMintString + ' debt: ' + debtMintString,
283
282
  });
284
283
  }
@@ -310,18 +309,18 @@ function getLeverageObligationAndObligationFarmStateAddresses(
310
309
  if (!collReserve.state.farmCollateral.equals(PublicKey.default)) {
311
310
  farmUserStates.push({
312
311
  address: obligationFarmStatePda(
313
- collReserve.state.farmCollateral!,
314
- leverageObligation.toPda(kaminoMarket.getAddress(), user)
315
- ),
312
+ leverageObligation.toPda(kaminoMarket.getAddress(), user),
313
+ collReserve.state.farmCollateral!
314
+ )[0],
316
315
  log: 'collReserve farmState for leverage obligation coll: ' + collMintString + ' debt: ' + debtMintString,
317
316
  });
318
317
  }
319
318
  if (!debtReserve.state.farmDebt.equals(PublicKey.default)) {
320
319
  farmUserStates.push({
321
320
  address: obligationFarmStatePda(
322
- debtReserve.state.farmDebt!,
323
- leverageObligation.toPda(kaminoMarket.getAddress(), user)
324
- ),
321
+ leverageObligation.toPda(kaminoMarket.getAddress(), user),
322
+ debtReserve.state.farmDebt!
323
+ )[0],
325
324
  log: 'debtReserve farmState for leverage obligation coll: ' + collMintString + ' debt: ' + debtMintString,
326
325
  });
327
326
  }
@@ -342,7 +341,7 @@ function getRepayWithCollObligationFarmStateAddresses(
342
341
  const borrowReserve = kaminoMarket.getReserveByMint(borrow.mintAddress)!;
343
342
  if (!borrowReserve.state.farmDebt.equals(PublicKey.default)) {
344
343
  farmUserStates.push({
345
- address: obligationFarmStatePda(borrowReserve.state.farmDebt!, obligation.obligationAddress),
344
+ address: obligationFarmStatePda(obligation.obligationAddress, borrowReserve.state.farmDebt!)[0],
346
345
  log: 'debtReserve farmState for vanilla obligation: ' + obligationString,
347
346
  });
348
347
  }
@@ -352,7 +351,7 @@ function getRepayWithCollObligationFarmStateAddresses(
352
351
  const depositReserve = kaminoMarket.getReserveByMint(deposit.mintAddress)!;
353
352
  if (!depositReserve.state.farmCollateral.equals(PublicKey.default)) {
354
353
  farmUserStates.push({
355
- address: obligationFarmStatePda(depositReserve.state.farmCollateral!, obligation.obligationAddress),
354
+ address: obligationFarmStatePda(obligation.obligationAddress, depositReserve.state.farmCollateral!)[0],
356
355
  log: 'collReserve farmState for vanilla obligation' + obligationString,
357
356
  });
358
357
  }