@kamino-finance/klend-sdk 7.0.7 → 7.0.9

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 (36) hide show
  1. package/dist/classes/action.d.ts +1 -1
  2. package/dist/classes/action.d.ts.map +1 -1
  3. package/dist/classes/action.js +15 -15
  4. package/dist/classes/action.js.map +1 -1
  5. package/dist/classes/obligation.js +7 -6
  6. package/dist/classes/obligation.js.map +1 -1
  7. package/dist/classes/vault.d.ts.map +1 -1
  8. package/dist/classes/vault.js +0 -1
  9. package/dist/classes/vault.js.map +1 -1
  10. package/dist/lending_operations/repay_with_collateral_operations.d.ts.map +1 -1
  11. package/dist/lending_operations/repay_with_collateral_operations.js +36 -32
  12. package/dist/lending_operations/repay_with_collateral_operations.js.map +1 -1
  13. package/dist/lending_operations/swap_collateral_operations.d.ts.map +1 -1
  14. package/dist/lending_operations/swap_collateral_operations.js +6 -6
  15. package/dist/lending_operations/swap_collateral_operations.js.map +1 -1
  16. package/dist/leverage/operations.d.ts +4 -3
  17. package/dist/leverage/operations.d.ts.map +1 -1
  18. package/dist/leverage/operations.js +175 -149
  19. package/dist/leverage/operations.js.map +1 -1
  20. package/dist/leverage/types.d.ts +1 -0
  21. package/dist/leverage/types.d.ts.map +1 -1
  22. package/dist/manager/client_kamino_manager.js +5 -4
  23. package/dist/manager/client_kamino_manager.js.map +1 -1
  24. package/dist/utils/farmUtils.d.ts.map +1 -1
  25. package/dist/utils/farmUtils.js +1 -4
  26. package/dist/utils/farmUtils.js.map +1 -1
  27. package/package.json +1 -1
  28. package/src/classes/action.ts +15 -15
  29. package/src/classes/obligation.ts +9 -9
  30. package/src/classes/vault.ts +0 -1
  31. package/src/lending_operations/repay_with_collateral_operations.ts +78 -74
  32. package/src/lending_operations/swap_collateral_operations.ts +15 -13
  33. package/src/leverage/operations.ts +350 -318
  34. package/src/leverage/types.ts +1 -0
  35. package/src/manager/client_kamino_manager.ts +5 -4
  36. package/src/utils/farmUtils.ts +1 -4
@@ -330,7 +330,7 @@ export class KaminoAction {
330
330
  );
331
331
 
332
332
  if (extraComputeBudget > 0) {
333
- axn.addComputeBudgetIxn(extraComputeBudget);
333
+ axn.addComputeBudgetIx(extraComputeBudget);
334
334
  }
335
335
 
336
336
  await axn.addRefreshObligation(payer);
@@ -363,7 +363,7 @@ export class KaminoAction {
363
363
  );
364
364
 
365
365
  if (extraComputeBudget > 0) {
366
- axn.addComputeBudgetIxn(extraComputeBudget);
366
+ axn.addComputeBudgetIx(extraComputeBudget);
367
367
  }
368
368
 
369
369
  await axn.addRefreshObligation(owner);
@@ -404,7 +404,7 @@ export class KaminoAction {
404
404
  const addInitObligationForFarm = true;
405
405
 
406
406
  if (extraComputeBudget > 0) {
407
- axn.addComputeBudgetIxn(extraComputeBudget);
407
+ axn.addComputeBudgetIx(extraComputeBudget);
408
408
  }
409
409
 
410
410
  await axn.addSupportIxs(
@@ -467,7 +467,7 @@ export class KaminoAction {
467
467
  );
468
468
  const addInitObligationForFarm = true;
469
469
  if (extraComputeBudget > 0) {
470
- axn.addComputeBudgetIxn(extraComputeBudget);
470
+ axn.addComputeBudgetIx(extraComputeBudget);
471
471
  }
472
472
 
473
473
  if (isSome(axn.referrer)) {
@@ -529,7 +529,7 @@ export class KaminoAction {
529
529
  const addInitObligationForFarm = true;
530
530
 
531
531
  if (extraComputeBudget > 0) {
532
- axn.addComputeBudgetIxn(extraComputeBudget);
532
+ axn.addComputeBudgetIx(extraComputeBudget);
533
533
  }
534
534
 
535
535
  await axn.addSupportIxs(
@@ -572,7 +572,7 @@ export class KaminoAction {
572
572
  const addInitObligationForFarm = true;
573
573
 
574
574
  if (extraComputeBudget > 0) {
575
- axn.addComputeBudgetIxn(extraComputeBudget);
575
+ axn.addComputeBudgetIx(extraComputeBudget);
576
576
  }
577
577
 
578
578
  await axn.addSupportIxs(
@@ -620,7 +620,7 @@ export class KaminoAction {
620
620
  const addInitObligationForFarm = true;
621
621
 
622
622
  if (extraComputeBudget > 0) {
623
- axn.addComputeBudgetIxn(extraComputeBudget);
623
+ axn.addComputeBudgetIx(extraComputeBudget);
624
624
  }
625
625
 
626
626
  await axn.addSupportIxs(
@@ -679,7 +679,7 @@ export class KaminoAction {
679
679
  const twoTokenAction = true;
680
680
 
681
681
  if (extraComputeBudget > 0) {
682
- axn.addComputeBudgetIxn(extraComputeBudget);
682
+ axn.addComputeBudgetIx(extraComputeBudget);
683
683
  }
684
684
 
685
685
  if (isSome(axn.referrer)) {
@@ -776,7 +776,7 @@ export class KaminoAction {
776
776
  const addInitObligationForFarm = true;
777
777
  const twoTokenAction = true;
778
778
  if (extraComputeBudget > 0) {
779
- axn.addComputeBudgetIxn(extraComputeBudget);
779
+ axn.addComputeBudgetIx(extraComputeBudget);
780
780
  }
781
781
 
782
782
  await axn.addSupportIxs(
@@ -830,7 +830,7 @@ export class KaminoAction {
830
830
  const addInitObligationForFarm = true;
831
831
  const twoTokenAction = true;
832
832
  if (extraComputeBudget > 0) {
833
- axn.addComputeBudgetIxn(extraComputeBudget);
833
+ axn.addComputeBudgetIx(extraComputeBudget);
834
834
  }
835
835
 
836
836
  await axn.addSupportIxs(
@@ -886,7 +886,7 @@ export class KaminoAction {
886
886
  const addInitObligationForFarmForWithdraw = false;
887
887
  const twoTokenAction = true;
888
888
  if (extraComputeBudget > 0) {
889
- axn.addComputeBudgetIxn(extraComputeBudget);
889
+ axn.addComputeBudgetIx(extraComputeBudget);
890
890
  }
891
891
 
892
892
  await axn.addSupportIxs(
@@ -975,7 +975,7 @@ export class KaminoAction {
975
975
  const addInitObligationForFarm = true;
976
976
 
977
977
  if (extraComputeBudget > 0) {
978
- axn.addComputeBudgetIxn(extraComputeBudget);
978
+ axn.addComputeBudgetIx(extraComputeBudget);
979
979
  }
980
980
 
981
981
  axn.depositReserves.push(...(obligationCustomizations?.addedDepositReserves || []));
@@ -1054,7 +1054,7 @@ export class KaminoAction {
1054
1054
  const addInitObligationForFarm = true;
1055
1055
 
1056
1056
  if (extraComputeBudget > 0) {
1057
- axn.addComputeBudgetIxn(extraComputeBudget);
1057
+ axn.addComputeBudgetIx(extraComputeBudget);
1058
1058
  }
1059
1059
 
1060
1060
  await axn.addSupportIxs(
@@ -1114,7 +1114,7 @@ export class KaminoAction {
1114
1114
  const addInitObligationForFarm = true;
1115
1115
 
1116
1116
  if (extraComputeBudget > 0) {
1117
- axn.addComputeBudgetIxn(extraComputeBudget);
1117
+ axn.addComputeBudgetIx(extraComputeBudget);
1118
1118
  }
1119
1119
 
1120
1120
  await axn.addSupportIxs(
@@ -3082,7 +3082,7 @@ export class KaminoAction {
3082
3082
  this.lendingIxsLabels.push(`WithdrawReferrerFeesIx[${this.owner.toString()}]`);
3083
3083
  }
3084
3084
 
3085
- private addComputeBudgetIxn(units: number) {
3085
+ private addComputeBudgetIx(units: number) {
3086
3086
  this.computeBudgetIxs.push(buildComputeBudgetIx(units));
3087
3087
  this.computeBudgetIxsLabels.push(`AddComputeBudget[${units}]`);
3088
3088
  }
@@ -1399,6 +1399,13 @@ export class KaminoObligation {
1399
1399
  throw new Error('Reserve not found');
1400
1400
  }
1401
1401
 
1402
+ const reserveAvailableLiquidity = depositReserve.getLiquidityAvailableAmount();
1403
+ const withdrawalCapRemained = depositReserve
1404
+ .getDepositWithdrawalCapCapacity()
1405
+ .sub(depositReserve.getDepositWithdrawalCapCurrent(slot));
1406
+
1407
+ const reserveWithdrawalLimit = Decimal.min(withdrawalCapRemained, reserveAvailableLiquidity);
1408
+
1402
1409
  const userDepositPosition = this.getDepositByReserve(depositReserve.address);
1403
1410
 
1404
1411
  if (!userDepositPosition) {
@@ -1408,7 +1415,7 @@ export class KaminoObligation {
1408
1415
  const userDepositPositionAmount = userDepositPosition.amount;
1409
1416
 
1410
1417
  if (this.refreshedStats.userTotalBorrowBorrowFactorAdjusted.equals(new Decimal(0))) {
1411
- return new Decimal(userDepositPositionAmount);
1418
+ return Decimal.max(0, Decimal.min(userDepositPositionAmount, reserveWithdrawalLimit));
1412
1419
  }
1413
1420
 
1414
1421
  const { maxLtv: reserveMaxLtv } = KaminoObligation.getLtvForReserve(
@@ -1436,15 +1443,8 @@ export class KaminoObligation {
1436
1443
  const maxWithdrawAmount = maxWithdrawValue
1437
1444
  .div(depositReserve.getOracleMarketPrice())
1438
1445
  .mul(depositReserve.getMintFactor());
1439
- const reserveAvailableLiquidity = depositReserve.getLiquidityAvailableAmount();
1440
1446
 
1441
- const withdrawalCapRemained = depositReserve
1442
- .getDepositWithdrawalCapCapacity()
1443
- .sub(depositReserve.getDepositWithdrawalCapCurrent(slot));
1444
- return Decimal.max(
1445
- 0,
1446
- Decimal.min(userDepositPositionAmount, maxWithdrawAmount, reserveAvailableLiquidity, withdrawalCapRemained)
1447
- );
1447
+ return Decimal.max(0, Decimal.min(userDepositPositionAmount, maxWithdrawAmount, reserveWithdrawalLimit));
1448
1448
  }
1449
1449
 
1450
1450
  getObligationLiquidityByReserve(reserveAddress: Address): ObligationLiquidity {
@@ -1545,7 +1545,6 @@ export class KaminoVaultClient {
1545
1545
  vaultReservesMap?: Map<Address, KaminoReserve>,
1546
1546
  createAtaIfNeeded: boolean = true
1547
1547
  ): Promise<IInstruction[]> {
1548
- console.log('create invest ix for reserve', reserve.address);
1549
1548
  const vaultState = await vault.getState(this.getConnection());
1550
1549
  const cTokenVault = await getCTokenVaultPda(vault.address, reserve.address, this._kaminoVaultProgramId);
1551
1550
  const [lendingMarketAuth] = await lendingMarketAuthPda(reserve.state.lendingMarket, this._kaminoLendProgramId);
@@ -120,27 +120,31 @@ export async function getRepayWithCollSwapInputs<QuoteResponse>({
120
120
  const inputAmountLamports = Decimal.min(maxWithdrawableCollLamports, maxCollNeededFromOracle);
121
121
 
122
122
  // Build the repay & withdraw collateral tx to get the number of accounts
123
- const klendIxs: LeverageIxsOutput = await buildRepayWithCollateralIxs(
124
- kaminoMarket,
125
- debtReserve,
126
- collReserve,
127
- owner,
128
- obligation,
129
- referrer,
130
- currentSlot,
131
- budgetAndPriorityFeeIxs,
132
- scopeRefreshConfig,
133
- {
134
- preActionIxs: [],
135
- swapIxs: [],
136
- lookupTables: [],
137
- quote: {} as SwapQuote<QuoteResponse>,
138
- },
139
- isClosingPosition,
140
- repayAmountLamports,
141
- inputAmountLamports,
142
- useV2Ixs
143
- );
123
+ const klendIxs: LeverageIxsOutput = (
124
+ await buildRepayWithCollateralIxs(
125
+ kaminoMarket,
126
+ debtReserve,
127
+ collReserve,
128
+ owner,
129
+ obligation,
130
+ referrer,
131
+ currentSlot,
132
+ budgetAndPriorityFeeIxs,
133
+ scopeRefreshConfig,
134
+ [
135
+ {
136
+ preActionIxs: [],
137
+ swapIxs: [],
138
+ lookupTables: [],
139
+ quote: {} as SwapQuote<QuoteResponse>,
140
+ },
141
+ ],
142
+ isClosingPosition,
143
+ repayAmountLamports,
144
+ inputAmountLamports,
145
+ useV2Ixs
146
+ )
147
+ )[0];
144
148
  const uniqueKlendAccounts = uniqueAccountsWithProgramIds(klendIxs.instructions);
145
149
 
146
150
  const swapQuoteInputs: SwapInputs = {
@@ -244,35 +248,33 @@ export async function getRepayWithCollIxs<QuoteResponse>({
244
248
 
245
249
  const swapResponses = await swapper(swapInputs, initialInputs.klendAccounts, swapQuote);
246
250
 
247
- return Promise.all(
248
- swapResponses.map(async (swapResponse) => {
249
- const ixs: LeverageIxsOutput = await buildRepayWithCollateralIxs(
250
- kaminoMarket,
251
- debtReserve,
252
- collReserve,
253
- owner,
254
- obligation,
255
- referrer,
256
- currentSlot,
257
- budgetAndPriorityFeeIxs,
258
- scopeRefreshConfig,
259
- swapResponse,
260
- isClosingPosition,
261
- debtRepayAmountLamports,
262
- swapInputs.inputAmountLamports,
263
- useV2Ixs
264
- );
265
-
266
- return {
267
- ixs: ixs.instructions,
268
- lookupTables: swapResponse.lookupTables,
269
- swapInputs,
270
- flashLoanInfo: ixs.flashLoanInfo,
271
- initialInputs,
272
- quote: swapResponse.quote.quoteResponse,
273
- };
274
- })
251
+ const repayWithCollateralIxs = await buildRepayWithCollateralIxs(
252
+ kaminoMarket,
253
+ debtReserve,
254
+ collReserve,
255
+ owner,
256
+ obligation,
257
+ referrer,
258
+ currentSlot,
259
+ budgetAndPriorityFeeIxs,
260
+ scopeRefreshConfig,
261
+ swapResponses,
262
+ isClosingPosition,
263
+ debtRepayAmountLamports,
264
+ swapInputs.inputAmountLamports,
265
+ useV2Ixs
275
266
  );
267
+
268
+ return repayWithCollateralIxs.map((ixs, index) => {
269
+ return {
270
+ ixs: ixs.instructions,
271
+ lookupTables: swapResponses[index].lookupTables,
272
+ swapInputs,
273
+ flashLoanInfo: ixs.flashLoanInfo,
274
+ initialInputs,
275
+ quote: swapResponses[index].quote.quoteResponse,
276
+ };
277
+ });
276
278
  }
277
279
 
278
280
  async function buildRepayWithCollateralIxs<QuoteResponse>(
@@ -285,12 +287,12 @@ async function buildRepayWithCollateralIxs<QuoteResponse>(
285
287
  currentSlot: Slot,
286
288
  budgetAndPriorityFeeIxs: IInstruction[] | undefined,
287
289
  scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
288
- swapQuoteIxs: SwapIxs<QuoteResponse>,
290
+ swapQuoteIxsArray: SwapIxs<QuoteResponse>[],
289
291
  isClosingPosition: boolean,
290
292
  debtRepayAmountLamports: Decimal,
291
293
  collWithdrawLamports: Decimal,
292
294
  useV2Ixs: boolean
293
- ): Promise<LeverageIxsOutput> {
295
+ ): Promise<LeverageIxsOutput[]> {
294
296
  // 1. Create atas & budget txns
295
297
  const budgetIxs = budgetAndPriorityFeeIxs || getComputeBudgetAndPriorityFeeIxs(1_400_000);
296
298
 
@@ -369,29 +371,31 @@ async function buildRepayWithCollateralIxs<QuoteResponse>(
369
371
  }
370
372
 
371
373
  // 4. Swap collateral to debt to repay flash loan
372
- const { preActionIxs, swapIxs } = swapQuoteIxs;
373
- const swapInstructions = removeBudgetIxs(swapIxs);
374
-
375
- const ixs = [
376
- ...scopeRefreshIx,
377
- ...budgetIxs,
378
- ...atasAndIxs.map((x) => x.createAtaIx),
379
- flashBorrowIx,
380
- ...preActionIxs,
381
- ...KaminoAction.actionToIxs(repayAndWithdrawAction),
382
- ...swapInstructions,
383
- flashRepayIx,
384
- ];
385
-
386
- const res: LeverageIxsOutput = {
387
- flashLoanInfo: {
388
- flashBorrowReserve: debtReserve.address,
389
- flashLoanFee: debtReserve.getFlashLoanFee(),
390
- },
391
- instructions: ixs,
392
- };
393
-
394
- return res;
374
+ return swapQuoteIxsArray.map((swapQuoteIxs) => {
375
+ const { preActionIxs, swapIxs } = swapQuoteIxs;
376
+ const swapInstructions = removeBudgetIxs(swapIxs);
377
+
378
+ const ixs = [
379
+ ...scopeRefreshIx,
380
+ ...budgetIxs,
381
+ ...atasAndIxs.map((x) => x.createAtaIx),
382
+ flashBorrowIx,
383
+ ...preActionIxs,
384
+ ...KaminoAction.actionToIxs(repayAndWithdrawAction),
385
+ ...swapInstructions,
386
+ flashRepayIx,
387
+ ];
388
+
389
+ const res: LeverageIxsOutput = {
390
+ flashLoanInfo: {
391
+ flashBorrowReserve: debtReserve.address,
392
+ flashLoanFee: debtReserve.getFlashLoanFee(),
393
+ },
394
+ instructions: ixs,
395
+ };
396
+
397
+ return res;
398
+ });
395
399
  }
396
400
 
397
401
  export const getMaxWithdrawLtvCheck = (
@@ -164,7 +164,16 @@ export async function getSwapCollIxs<QuoteResponse>(
164
164
  // - To construct 1. (i.e. flash-borrow), we need to know the target collateral swap-out from 4.
165
165
 
166
166
  // Construct the Klend's own ixs with a fake swap-out (only to learn the klend accounts used):
167
- const fakeKlendIxs = await getKlendIxs(args, FAKE_TARGET_COLL_SWAP_OUT_AMOUNT, context);
167
+
168
+ const scopeRefreshIx = await getScopeRefreshIx(
169
+ context.market,
170
+ context.sourceCollReserve,
171
+ context.targetCollReserve,
172
+ context.obligation,
173
+ context.scopeRefreshConfig
174
+ );
175
+
176
+ const fakeKlendIxs = await getKlendIxs(args, FAKE_TARGET_COLL_SWAP_OUT_AMOUNT, context, scopeRefreshIx);
168
177
  const klendAccounts = uniqueAccountsWithProgramIds(listIxs(fakeKlendIxs));
169
178
 
170
179
  // Construct the external swap ixs (and learn the actual swap-out amount):
@@ -179,7 +188,7 @@ export async function getSwapCollIxs<QuoteResponse>(
179
188
  checkResultingObligationValid(args, externalSwapIxs.swapOutAmount, context);
180
189
 
181
190
  // Construct the Klend's own ixs with an actual swap-out amount:
182
- const klendIxs = await getKlendIxs(args, externalSwapIxs.swapOutAmount, context);
191
+ const klendIxs = await getKlendIxs(args, externalSwapIxs.swapOutAmount, context, scopeRefreshIx);
183
192
 
184
193
  return {
185
194
  ixs: listIxs(klendIxs, externalSwapIxs.ixs),
@@ -275,21 +284,14 @@ type SwapCollKlendIxs = {
275
284
  async function getKlendIxs(
276
285
  args: SwapCollArgs,
277
286
  targetCollSwapOutAmount: Decimal,
278
- context: SwapCollContext<any>
287
+ context: SwapCollContext<any>,
288
+ scopeRefreshIx: IInstruction[]
279
289
  ): Promise<SwapCollKlendIxs> {
280
290
  const { ataCreationIxs, targetCollAta } = await getAtaCreationIxs(context);
281
291
  const setupIxs = [...context.budgetAndPriorityFeeIxs, ...ataCreationIxs];
282
292
 
283
- const scopeRefreshIxn = await getScopeRefreshIx(
284
- context.market,
285
- context.sourceCollReserve,
286
- context.targetCollReserve,
287
- context.obligation,
288
- context.scopeRefreshConfig
289
- );
290
-
291
- if (scopeRefreshIxn) {
292
- setupIxs.unshift(...scopeRefreshIxn);
293
+ if (scopeRefreshIx) {
294
+ setupIxs.unshift(...scopeRefreshIx);
293
295
  }
294
296
 
295
297
  const targetCollFlashBorrowedAmount = calculateTargetCollFlashBorrowedAmount(targetCollSwapOutAmount, context);