@kamino-finance/klend-sdk 6.0.5-beta.2 → 6.0.5-beta.20

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 (62) 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 +32 -16
  4. package/dist/classes/action.js.map +1 -1
  5. package/dist/classes/manager.d.ts +29 -18
  6. package/dist/classes/manager.d.ts.map +1 -1
  7. package/dist/classes/manager.js +66 -49
  8. package/dist/classes/manager.js.map +1 -1
  9. package/dist/classes/market.d.ts +12 -11
  10. package/dist/classes/market.d.ts.map +1 -1
  11. package/dist/classes/market.js +77 -37
  12. package/dist/classes/market.js.map +1 -1
  13. package/dist/classes/vault.d.ts +5 -3
  14. package/dist/classes/vault.d.ts.map +1 -1
  15. package/dist/classes/vault.js +8 -6
  16. package/dist/classes/vault.js.map +1 -1
  17. package/dist/client_kamino_manager.d.ts.map +1 -1
  18. package/dist/client_kamino_manager.js +30 -22
  19. package/dist/client_kamino_manager.js.map +1 -1
  20. package/dist/lending_operations/repay_with_collateral_operations.d.ts.map +1 -1
  21. package/dist/lending_operations/repay_with_collateral_operations.js +36 -32
  22. package/dist/lending_operations/repay_with_collateral_operations.js.map +1 -1
  23. package/dist/lending_operations/swap_collateral_operations.d.ts.map +1 -1
  24. package/dist/lending_operations/swap_collateral_operations.js +4 -4
  25. package/dist/lending_operations/swap_collateral_operations.js.map +1 -1
  26. package/dist/leverage/operations.d.ts +4 -3
  27. package/dist/leverage/operations.d.ts.map +1 -1
  28. package/dist/leverage/operations.js +186 -154
  29. package/dist/leverage/operations.js.map +1 -1
  30. package/dist/leverage/types.d.ts +1 -0
  31. package/dist/leverage/types.d.ts.map +1 -1
  32. package/dist/utils/managerTypes.d.ts +1 -2
  33. package/dist/utils/managerTypes.d.ts.map +1 -1
  34. package/dist/utils/managerTypes.js +9 -9
  35. package/dist/utils/managerTypes.js.map +1 -1
  36. package/dist/utils/obligations.d.ts +5 -0
  37. package/dist/utils/obligations.d.ts.map +1 -0
  38. package/dist/utils/obligations.js +53 -0
  39. package/dist/utils/obligations.js.map +1 -0
  40. package/dist/utils/oracle.d.ts +3 -3
  41. package/dist/utils/oracle.d.ts.map +1 -1
  42. package/dist/utils/oracle.js +2 -2
  43. package/dist/utils/oracle.js.map +1 -1
  44. package/dist/utils/pubkey.d.ts +1 -0
  45. package/dist/utils/pubkey.d.ts.map +1 -1
  46. package/dist/utils/pubkey.js +10 -0
  47. package/dist/utils/pubkey.js.map +1 -1
  48. package/package.json +3 -3
  49. package/src/classes/action.ts +32 -20
  50. package/src/classes/manager.ts +87 -53
  51. package/src/classes/market.ts +132 -52
  52. package/src/classes/vault.ts +17 -6
  53. package/src/client.ts +4 -4
  54. package/src/client_kamino_manager.ts +40 -35
  55. package/src/lending_operations/repay_with_collateral_operations.ts +76 -72
  56. package/src/lending_operations/swap_collateral_operations.ts +13 -11
  57. package/src/leverage/operations.ts +362 -328
  58. package/src/leverage/types.ts +1 -0
  59. package/src/utils/managerTypes.ts +1 -2
  60. package/src/utils/obligations.ts +69 -0
  61. package/src/utils/oracle.ts +5 -4
  62. package/src/utils/pubkey.ts +9 -0
@@ -71,6 +71,8 @@ import {
71
71
  FlashLoanInfo,
72
72
  } from './types';
73
73
 
74
+ export const WITHDRAW_SLOT_OFFSET = 150; // Offset for the withdraw slot to ensure it is after the deposit slot
75
+
74
76
  export async function getDepositWithLeverageSwapInputs<QuoteResponse>({
75
77
  owner,
76
78
  kaminoMarket,
@@ -131,32 +133,36 @@ export async function getDepositWithLeverageSwapInputs<QuoteResponse>({
131
133
  const obligationType = checkObligationType(obligationTypeTagOverride, collTokenMint, debtTokenMint, kaminoMarket);
132
134
 
133
135
  // Build the repay & withdraw collateral tx to get the number of accounts
134
- const klendIxs: LeverageIxsOutput = await buildDepositWithLeverageIxs(
135
- kaminoMarket,
136
- debtReserve,
137
- collReserve,
138
- owner,
139
- obligation ? obligation : obligationType,
140
- referrer,
141
- currentSlot,
142
- depositTokenIsSol,
143
- scopeRefreshConfig,
144
- calcs,
145
- budgetAndPriorityFeeIxs,
146
- {
147
- preActionIxs: [],
148
- swapIxs: [],
149
- lookupTables: [],
150
- quote: {
151
- priceAInB: new Decimal(0), // not used
152
- quoteResponse: undefined,
153
- },
154
- },
155
- strategy,
156
- collIsKtoken,
157
- useV2Ixs,
158
- elevationGroupOverride
159
- );
136
+ const klendIxs: LeverageIxsOutput = (
137
+ await buildDepositWithLeverageIxs(
138
+ kaminoMarket,
139
+ debtReserve,
140
+ collReserve,
141
+ owner,
142
+ obligation ? obligation : obligationType,
143
+ referrer,
144
+ currentSlot,
145
+ depositTokenIsSol,
146
+ scopeRefreshConfig,
147
+ calcs,
148
+ budgetAndPriorityFeeIxs,
149
+ [
150
+ {
151
+ preActionIxs: [],
152
+ swapIxs: [],
153
+ lookupTables: [],
154
+ quote: {
155
+ priceAInB: new Decimal(0), // not used
156
+ quoteResponse: undefined,
157
+ },
158
+ },
159
+ ],
160
+ strategy,
161
+ collIsKtoken,
162
+ useV2Ixs,
163
+ elevationGroupOverride
164
+ )
165
+ )[0];
160
166
 
161
167
  const uniqueKlendAccounts = uniqueAccountsWithProgramIds(klendIxs.instructions);
162
168
 
@@ -378,42 +384,42 @@ export async function getDepositWithLeverageIxs<QuoteResponse>({
378
384
  const solTokenReserve = kaminoMarket.getReserveByMint(NATIVE_MINT);
379
385
  const depositTokenIsSol = !solTokenReserve ? false : selectedTokenMint.equals(solTokenReserve!.getLiquidityMint());
380
386
 
381
- return Promise.all(
382
- swapsArray.map(async (swap) => {
383
- const ixs: LeverageIxsOutput = await buildDepositWithLeverageIxs(
384
- kaminoMarket,
385
- debtReserve!,
386
- collReserve!,
387
- owner,
388
- initialInputs.obligation,
389
- referrer,
390
- currentSlot,
391
- depositTokenIsSol,
392
- scopeRefreshConfig,
393
- initialInputs.calcs,
394
- budgetAndPriorityFeeIxs,
395
- {
396
- preActionIxs: [],
397
- swapIxs: swap.swapIxs,
398
- lookupTables: swap.lookupTables,
399
- quote: swap.quote,
400
- },
401
- initialInputs.strategy,
402
- initialInputs.collIsKtoken,
403
- useV2Ixs,
404
- elevationGroupOverride
405
- );
406
-
387
+ const depositWithLeverageIxs = await buildDepositWithLeverageIxs(
388
+ kaminoMarket,
389
+ debtReserve!,
390
+ collReserve!,
391
+ owner,
392
+ initialInputs.obligation,
393
+ referrer,
394
+ currentSlot,
395
+ depositTokenIsSol,
396
+ scopeRefreshConfig,
397
+ initialInputs.calcs,
398
+ budgetAndPriorityFeeIxs,
399
+ swapsArray.map((swap) => {
407
400
  return {
408
- ixs: ixs.instructions,
409
- flashLoanInfo: ixs.flashLoanInfo,
401
+ preActionIxs: [],
402
+ swapIxs: swap.swapIxs,
410
403
  lookupTables: swap.lookupTables,
411
- swapInputs,
412
- initialInputs,
413
- quote: swap.quote.quoteResponse,
404
+ quote: swap.quote,
414
405
  };
415
- })
406
+ }),
407
+ initialInputs.strategy,
408
+ initialInputs.collIsKtoken,
409
+ useV2Ixs,
410
+ elevationGroupOverride
416
411
  );
412
+
413
+ return depositWithLeverageIxs.map((depositWithLeverageIxs, index) => {
414
+ return {
415
+ ixs: depositWithLeverageIxs.instructions,
416
+ flashLoanInfo: depositWithLeverageIxs.flashLoanInfo,
417
+ lookupTables: swapsArray[index].lookupTables,
418
+ swapInputs,
419
+ initialInputs,
420
+ quote: swapsArray[index].quote.quoteResponse,
421
+ };
422
+ });
417
423
  }
418
424
 
419
425
  async function buildDepositWithLeverageIxs<QuoteResponse>(
@@ -428,12 +434,12 @@ async function buildDepositWithLeverageIxs<QuoteResponse>(
428
434
  scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
429
435
  calcs: DepositLeverageCalcsResult,
430
436
  budgetAndPriorityFeeIxs: TransactionInstruction[] | undefined,
431
- swapQuoteIxs: SwapIxs<QuoteResponse>,
437
+ swapQuoteIxsArray: SwapIxs<QuoteResponse>[],
432
438
  strategy: StrategyWithAddress | undefined,
433
439
  collIsKtoken: boolean,
434
440
  useV2Ixs: boolean,
435
441
  elevationGroupOverride?: number
436
- ): Promise<LeverageIxsOutput> {
442
+ ): Promise<LeverageIxsOutput[]> {
437
443
  const collTokenMint = collReserve.getLiquidityMint();
438
444
  const debtTokenMint = debtReserve.getLiquidityMint();
439
445
  const collTokenAta = getAssociatedTokenAddressSync(
@@ -519,29 +525,31 @@ async function buildDepositWithLeverageIxs<QuoteResponse>(
519
525
  currentSlot
520
526
  );
521
527
 
522
- // 4. Swap
523
- const { swapIxs } = swapQuoteIxs;
524
- const swapInstructions = removeBudgetIxs(swapIxs);
525
- const flashBorrowReserve = !collIsKtoken ? collReserve : debtReserve;
526
- const flashLoanInfo = {
527
- flashBorrowReserve: flashBorrowReserve.address,
528
- flashLoanFee: flashBorrowReserve.getFlashLoanFee(),
529
- };
528
+ return swapQuoteIxsArray.map((swapQuoteIxs) => {
529
+ // 4. Swap
530
+ const { swapIxs } = swapQuoteIxs;
531
+ const swapInstructions = removeBudgetIxs(swapIxs);
532
+ const flashBorrowReserve = !collIsKtoken ? collReserve : debtReserve;
533
+ const flashLoanInfo = {
534
+ flashBorrowReserve: flashBorrowReserve.address,
535
+ flashLoanFee: flashBorrowReserve.getFlashLoanFee(),
536
+ };
530
537
 
531
- return {
532
- flashLoanInfo,
533
- instructions: [
534
- ...scopeRefreshIx,
535
- ...budgetIxs,
536
- ...createAtasIxs,
537
- ...fillWsolAtaIxs,
538
- ...[flashBorrowIx],
539
- ...(collIsKtoken ? swapInstructions : []),
540
- ...KaminoAction.actionToIxs(kaminoDepositAndBorrowAction),
541
- ...(collIsKtoken ? [] : swapInstructions),
542
- ...[flashRepayIx],
543
- ],
544
- };
538
+ return {
539
+ flashLoanInfo,
540
+ instructions: [
541
+ ...scopeRefreshIx,
542
+ ...budgetIxs,
543
+ ...createAtasIxs,
544
+ ...fillWsolAtaIxs,
545
+ ...[flashBorrowIx],
546
+ ...(collIsKtoken ? swapInstructions : []),
547
+ ...KaminoAction.actionToIxs(kaminoDepositAndBorrowAction),
548
+ ...(collIsKtoken ? [] : swapInstructions),
549
+ ...[flashRepayIx],
550
+ ],
551
+ };
552
+ });
545
553
  }
546
554
 
547
555
  export async function getWithdrawWithLeverageSwapInputs<QuoteResponse>({
@@ -597,32 +605,36 @@ export async function getWithdrawWithLeverageSwapInputs<QuoteResponse>({
597
605
  slippagePct
598
606
  );
599
607
 
600
- const klendIxs = await buildWithdrawWithLeverageIxs(
601
- kaminoMarket,
602
- debtReserve!,
603
- collReserve!,
604
- owner,
605
- obligation,
606
- referrer,
607
- currentSlot,
608
- isClosingPosition,
609
- inputTokenIsSol,
610
- scopeRefreshConfig,
611
- calcs,
612
- budgetAndPriorityFeeIxs,
613
- {
614
- preActionIxs: [],
615
- swapIxs: [],
616
- lookupTables: [],
617
- quote: {
618
- priceAInB: new Decimal(0), // not used
619
- quoteResponse: undefined,
620
- },
621
- },
622
- strategy,
623
- collIsKtoken,
624
- useV2Ixs
625
- );
608
+ const klendIxs = (
609
+ await buildWithdrawWithLeverageIxs(
610
+ kaminoMarket,
611
+ debtReserve!,
612
+ collReserve!,
613
+ owner,
614
+ obligation,
615
+ referrer,
616
+ currentSlot,
617
+ isClosingPosition,
618
+ inputTokenIsSol,
619
+ scopeRefreshConfig,
620
+ calcs,
621
+ budgetAndPriorityFeeIxs,
622
+ [
623
+ {
624
+ preActionIxs: [],
625
+ swapIxs: [],
626
+ lookupTables: [],
627
+ quote: {
628
+ priceAInB: new Decimal(0), // not used
629
+ quoteResponse: undefined,
630
+ },
631
+ },
632
+ ],
633
+ strategy,
634
+ collIsKtoken,
635
+ useV2Ixs
636
+ )
637
+ )[0];
626
638
 
627
639
  const uniqueKlendAccounts = uniqueAccountsWithProgramIds(klendIxs.instructions);
628
640
 
@@ -756,43 +768,43 @@ export async function getWithdrawWithLeverageIxs<QuoteResponse>({
756
768
  }
757
769
  }
758
770
 
759
- return Promise.all(
760
- swapsArray.map(async (swap) => {
761
- const ixs: LeverageIxsOutput = await buildWithdrawWithLeverageIxs<QuoteResponse>(
762
- kaminoMarket,
763
- debtReserve!,
764
- collReserve!,
765
- owner,
766
- obligation,
767
- referrer,
768
- currentSlot,
769
- isClosingPosition,
770
- inputTokenIsSol,
771
- scopeRefreshConfig,
772
- initialInputs.calcs,
773
- budgetAndPriorityFeeIxs,
774
- {
775
- preActionIxs: [],
776
- swapIxs: swap.swapIxs,
777
- lookupTables: swap.lookupTables,
778
- quote: swap.quote,
779
- },
780
- initialInputs.strategy,
781
- initialInputs.collIsKtoken,
782
- useV2Ixs
783
- );
784
-
785
- // Send ixs and lookup tables
771
+ const withdrawWithLeverageIxs = await buildWithdrawWithLeverageIxs<QuoteResponse>(
772
+ kaminoMarket,
773
+ debtReserve!,
774
+ collReserve!,
775
+ owner,
776
+ obligation,
777
+ referrer,
778
+ currentSlot,
779
+ isClosingPosition,
780
+ inputTokenIsSol,
781
+ scopeRefreshConfig,
782
+ initialInputs.calcs,
783
+ budgetAndPriorityFeeIxs,
784
+ swapsArray.map((swap) => {
786
785
  return {
787
- ixs: ixs.instructions,
788
- flashLoanInfo: ixs.flashLoanInfo,
786
+ preActionIxs: [],
787
+ swapIxs: swap.swapIxs,
789
788
  lookupTables: swap.lookupTables,
790
- swapInputs,
791
- initialInputs: initialInputs,
792
- quote: swap.quote.quoteResponse,
789
+ quote: swap.quote,
793
790
  };
794
- })
791
+ }),
792
+ initialInputs.strategy,
793
+ initialInputs.collIsKtoken,
794
+ useV2Ixs
795
795
  );
796
+
797
+ // Send ixs and lookup tables
798
+ return withdrawWithLeverageIxs.map((ixs, index) => {
799
+ return {
800
+ ixs: ixs.instructions,
801
+ flashLoanInfo: ixs.flashLoanInfo,
802
+ lookupTables: swapsArray[index].lookupTables,
803
+ swapInputs,
804
+ initialInputs: initialInputs,
805
+ quote: swapsArray[index].quote.quoteResponse,
806
+ };
807
+ });
796
808
  }
797
809
 
798
810
  export async function buildWithdrawWithLeverageIxs<QuoteResponse>(
@@ -808,11 +820,11 @@ export async function buildWithdrawWithLeverageIxs<QuoteResponse>(
808
820
  scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
809
821
  calcs: WithdrawLeverageCalcsResult,
810
822
  budgetAndPriorityFeeIxs: TransactionInstruction[] | undefined,
811
- swapQuoteIxs: SwapIxs<QuoteResponse>,
823
+ swapQuoteIxsArray: SwapIxs<QuoteResponse>[],
812
824
  strategy: StrategyWithAddress | undefined,
813
825
  collIsKtoken: boolean,
814
826
  useV2Ixs: boolean
815
- ): Promise<LeverageIxsOutput> {
827
+ ): Promise<LeverageIxsOutput[]> {
816
828
  const collTokenMint = collReserve.getLiquidityMint();
817
829
  const debtTokenMint = debtReserve.getLiquidityMint();
818
830
  const debtTokenAta = getAssociatedTokenAddressSync(
@@ -897,25 +909,27 @@ export async function buildWithdrawWithLeverageIxs<QuoteResponse>(
897
909
  referrer
898
910
  );
899
911
 
900
- const swapInstructions = removeBudgetIxs(swapQuoteIxs.swapIxs);
912
+ return swapQuoteIxsArray.map((swapQuoteIxs) => {
913
+ const swapInstructions = removeBudgetIxs(swapQuoteIxs.swapIxs);
901
914
 
902
- return {
903
- flashLoanInfo: {
904
- flashLoanFee: debtReserve.getFlashLoanFee(),
905
- flashBorrowReserve: debtReserve.address,
906
- },
907
- instructions: [
908
- ...scopeRefreshIx,
909
- ...budgetIxs,
910
- ...createAtasIxs,
911
- ...fillWsolAtaIxs,
912
- ...[flashBorrowIx],
913
- ...KaminoAction.actionToIxs(repayAndWithdrawAction),
914
- ...swapInstructions,
915
- ...[flashRepayIx],
916
- ...closeWsolAtaIxs,
917
- ],
918
- };
915
+ return {
916
+ flashLoanInfo: {
917
+ flashLoanFee: debtReserve.getFlashLoanFee(),
918
+ flashBorrowReserve: debtReserve.address,
919
+ },
920
+ instructions: [
921
+ ...scopeRefreshIx,
922
+ ...budgetIxs,
923
+ ...createAtasIxs,
924
+ ...fillWsolAtaIxs,
925
+ ...[flashBorrowIx],
926
+ ...KaminoAction.actionToIxs(repayAndWithdrawAction),
927
+ ...swapInstructions,
928
+ ...[flashRepayIx],
929
+ ...closeWsolAtaIxs,
930
+ ],
931
+ };
932
+ });
919
933
  }
920
934
 
921
935
  export async function getAdjustLeverageSwapInputs<QuoteResponse>({
@@ -939,6 +953,7 @@ export async function getAdjustLeverageSwapInputs<QuoteResponse>({
939
953
  isKtoken,
940
954
  quoter,
941
955
  useV2Ixs,
956
+ withdrawSlotOffset,
942
957
  }: AdjustLeverageSwapInputsProps<QuoteResponse>): Promise<{
943
958
  swapInputs: SwapInputs;
944
959
  flashLoanInfo: FlashLoanInfo;
@@ -988,30 +1003,34 @@ export async function getAdjustLeverageSwapInputs<QuoteResponse>({
988
1003
  );
989
1004
 
990
1005
  // Build the repay & withdraw collateral tx to get the number of accounts
991
- const klendIxs: LeverageIxsOutput = await buildIncreaseLeverageIxs(
992
- owner,
993
- kaminoMarket,
994
- collTokenMint,
995
- debtTokenMint,
996
- obligation,
997
- referrer,
998
- currentSlot,
999
- calcs,
1000
- strategy,
1001
- scopeRefreshConfig,
1002
- collIsKtoken,
1003
- {
1004
- preActionIxs: [],
1005
- swapIxs: [],
1006
- lookupTables: [],
1007
- quote: {
1008
- priceAInB: new Decimal(0), // not used
1009
- quoteResponse: undefined,
1010
- },
1011
- },
1012
- budgetAndPriorityFeeIxs,
1013
- useV2Ixs
1014
- );
1006
+ const klendIxs: LeverageIxsOutput = (
1007
+ await buildIncreaseLeverageIxs(
1008
+ owner,
1009
+ kaminoMarket,
1010
+ collTokenMint,
1011
+ debtTokenMint,
1012
+ obligation,
1013
+ referrer,
1014
+ currentSlot,
1015
+ calcs,
1016
+ strategy,
1017
+ scopeRefreshConfig,
1018
+ collIsKtoken,
1019
+ [
1020
+ {
1021
+ preActionIxs: [],
1022
+ swapIxs: [],
1023
+ lookupTables: [],
1024
+ quote: {
1025
+ priceAInB: new Decimal(0), // not used
1026
+ quoteResponse: undefined,
1027
+ },
1028
+ },
1029
+ ],
1030
+ budgetAndPriorityFeeIxs,
1031
+ useV2Ixs
1032
+ )
1033
+ )[0];
1015
1034
 
1016
1035
  const uniqueKlendAccounts = uniqueAccountsWithProgramIds(klendIxs.instructions);
1017
1036
 
@@ -1097,30 +1116,35 @@ export async function getAdjustLeverageSwapInputs<QuoteResponse>({
1097
1116
  } else {
1098
1117
  const calcs = adjustWithdrawLeverageCalcs(adjustDepositPosition, adjustBorrowPosition, flashLoanFee, slippagePct);
1099
1118
 
1100
- const klendIxs: LeverageIxsOutput = await buildDecreaseLeverageIxs(
1101
- owner,
1102
- kaminoMarket,
1103
- collTokenMint,
1104
- debtTokenMint,
1105
- obligation,
1106
- referrer,
1107
- currentSlot,
1108
- calcs,
1109
- strategy,
1110
- scopeRefreshConfig,
1111
- collIsKtoken,
1112
- {
1113
- preActionIxs: [],
1114
- swapIxs: [],
1115
- lookupTables: [],
1116
- quote: {
1117
- priceAInB: new Decimal(0), // not used
1118
- quoteResponse: undefined,
1119
- },
1120
- },
1121
- budgetAndPriorityFeeIxs,
1122
- useV2Ixs
1123
- );
1119
+ const klendIxs: LeverageIxsOutput = (
1120
+ await buildDecreaseLeverageIxs(
1121
+ owner,
1122
+ kaminoMarket,
1123
+ collTokenMint,
1124
+ debtTokenMint,
1125
+ obligation,
1126
+ referrer,
1127
+ currentSlot,
1128
+ calcs,
1129
+ strategy,
1130
+ scopeRefreshConfig,
1131
+ collIsKtoken,
1132
+ [
1133
+ {
1134
+ preActionIxs: [],
1135
+ swapIxs: [],
1136
+ lookupTables: [],
1137
+ quote: {
1138
+ priceAInB: new Decimal(0), // not used
1139
+ quoteResponse: undefined,
1140
+ },
1141
+ },
1142
+ ],
1143
+ budgetAndPriorityFeeIxs,
1144
+ useV2Ixs,
1145
+ withdrawSlotOffset
1146
+ )
1147
+ )[0];
1124
1148
 
1125
1149
  const uniqueKlendAccounts = uniqueAccountsWithProgramIds(klendIxs.instructions);
1126
1150
 
@@ -1207,6 +1231,7 @@ export async function getAdjustLeverageIxs<QuoteResponse>({
1207
1231
  quoter,
1208
1232
  swapper,
1209
1233
  useV2Ixs,
1234
+ withdrawSlotOffset,
1210
1235
  }: AdjustLeverageProps<QuoteResponse>): Promise<Array<AdjustLeverageIxsResponse<QuoteResponse>>> {
1211
1236
  const { swapInputs, initialInputs } = await getAdjustLeverageSwapInputs({
1212
1237
  owner,
@@ -1255,39 +1280,39 @@ export async function getAdjustLeverageIxs<QuoteResponse>({
1255
1280
 
1256
1281
  const swapsArray = await depositSwapper(swapInputs, initialInputs.klendAccounts, initialInputs.swapQuote);
1257
1282
 
1258
- return Promise.all(
1259
- swapsArray.map(async (swap) => {
1260
- const ixs: LeverageIxsOutput = await buildIncreaseLeverageIxs(
1261
- owner,
1262
- kaminoMarket,
1263
- collTokenMint,
1264
- debtTokenMint,
1265
- obligation,
1266
- referrer,
1267
- currentSlot,
1268
- initialInputs.calcs,
1269
- initialInputs.strategy,
1270
- scopeRefreshConfig,
1271
- initialInputs.collIsKtoken,
1272
- {
1273
- preActionIxs: [],
1274
- swapIxs: swap.swapIxs,
1275
- lookupTables: swap.lookupTables,
1276
- quote: swap.quote,
1277
- },
1278
- budgetAndPriorityFeeIxs,
1279
- useV2Ixs
1280
- );
1283
+ const increaseLeverageIxs = await buildIncreaseLeverageIxs(
1284
+ owner,
1285
+ kaminoMarket,
1286
+ collTokenMint,
1287
+ debtTokenMint,
1288
+ obligation,
1289
+ referrer,
1290
+ currentSlot,
1291
+ initialInputs.calcs,
1292
+ initialInputs.strategy,
1293
+ scopeRefreshConfig,
1294
+ initialInputs.collIsKtoken,
1295
+ swapsArray.map((swap) => {
1281
1296
  return {
1282
- ixs: ixs.instructions,
1283
- flashLoanInfo: ixs.flashLoanInfo,
1297
+ preActionIxs: [],
1298
+ swapIxs: swap.swapIxs,
1284
1299
  lookupTables: swap.lookupTables,
1285
- swapInputs,
1286
- initialInputs,
1287
- quote: swap.quote.quoteResponse,
1300
+ quote: swap.quote,
1288
1301
  };
1289
- })
1302
+ }),
1303
+ budgetAndPriorityFeeIxs,
1304
+ useV2Ixs
1290
1305
  );
1306
+ return increaseLeverageIxs.map((ixs, index) => {
1307
+ return {
1308
+ ixs: ixs.instructions,
1309
+ flashLoanInfo: ixs.flashLoanInfo,
1310
+ lookupTables: swapsArray[index].lookupTables,
1311
+ swapInputs,
1312
+ initialInputs,
1313
+ quote: swapsArray[index].quote.quoteResponse,
1314
+ };
1315
+ });
1291
1316
  } else {
1292
1317
  console.log('Decreasing leverage');
1293
1318
 
@@ -1305,40 +1330,41 @@ export async function getAdjustLeverageIxs<QuoteResponse>({
1305
1330
  // 5. Get swap ixs
1306
1331
  const swapsArray = await withdrawSwapper(swapInputs, initialInputs.klendAccounts, initialInputs.swapQuote);
1307
1332
 
1308
- return Promise.all(
1309
- swapsArray.map(async (swap) => {
1310
- const ixs: LeverageIxsOutput = await buildDecreaseLeverageIxs(
1311
- owner,
1312
- kaminoMarket,
1313
- collTokenMint,
1314
- debtTokenMint,
1315
- obligation,
1316
- referrer,
1317
- currentSlot,
1318
- initialInputs.calcs,
1319
- initialInputs.strategy,
1320
- scopeRefreshConfig,
1321
- initialInputs.collIsKtoken,
1322
- {
1323
- preActionIxs: [],
1324
- swapIxs: swap.swapIxs,
1325
- lookupTables: swap.lookupTables,
1326
- quote: swap.quote,
1327
- },
1328
- budgetAndPriorityFeeIxs,
1329
- useV2Ixs
1330
- );
1331
-
1333
+ const decreaseLeverageIxs = await buildDecreaseLeverageIxs(
1334
+ owner,
1335
+ kaminoMarket,
1336
+ collTokenMint,
1337
+ debtTokenMint,
1338
+ obligation,
1339
+ referrer,
1340
+ currentSlot,
1341
+ initialInputs.calcs,
1342
+ initialInputs.strategy,
1343
+ scopeRefreshConfig,
1344
+ initialInputs.collIsKtoken,
1345
+ swapsArray.map((swap) => {
1332
1346
  return {
1333
- ixs: ixs.instructions,
1334
- flashLoanInfo: ixs.flashLoanInfo,
1347
+ preActionIxs: [],
1348
+ swapIxs: swap.swapIxs,
1335
1349
  lookupTables: swap.lookupTables,
1336
- swapInputs,
1337
- initialInputs,
1338
- quote: swap.quote.quoteResponse,
1350
+ quote: swap.quote,
1339
1351
  };
1340
- })
1352
+ }),
1353
+ budgetAndPriorityFeeIxs,
1354
+ useV2Ixs,
1355
+ withdrawSlotOffset
1341
1356
  );
1357
+
1358
+ return decreaseLeverageIxs.map((ixs, index) => {
1359
+ return {
1360
+ ixs: ixs.instructions,
1361
+ flashLoanInfo: ixs.flashLoanInfo,
1362
+ lookupTables: swapsArray[index].lookupTables,
1363
+ swapInputs,
1364
+ initialInputs,
1365
+ quote: swapsArray[index].quote.quoteResponse,
1366
+ };
1367
+ });
1342
1368
  }
1343
1369
  }
1344
1370
 
@@ -1357,10 +1383,10 @@ async function buildIncreaseLeverageIxs<QuoteResponse>(
1357
1383
  strategy: StrategyWithAddress | undefined,
1358
1384
  scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
1359
1385
  collIsKtoken: boolean,
1360
- swapQuoteIxs: SwapIxs<QuoteResponse>,
1386
+ swapQuoteIxsArray: SwapIxs<QuoteResponse>[],
1361
1387
  budgetAndPriorityFeeIxs: TransactionInstruction[] | undefined,
1362
1388
  useV2Ixs: boolean
1363
- ): Promise<LeverageIxsOutput> {
1389
+ ): Promise<LeverageIxsOutput[]> {
1364
1390
  const collReserve = kaminoMarket.getExistingReserveByMint(collTokenMint);
1365
1391
  const debtReserve = kaminoMarket.getExistingReserveByMint(debtTokenMint);
1366
1392
  const debtTokenAta = getAssociatedTokenAddressSync(
@@ -1442,30 +1468,32 @@ async function buildIncreaseLeverageIxs<QuoteResponse>(
1442
1468
  currentSlot
1443
1469
  );
1444
1470
 
1445
- const swapInstructions = removeBudgetIxs(swapQuoteIxs.swapIxs);
1446
-
1447
- const ixs = [
1448
- ...scopeRefreshIx,
1449
- ...budgetIxs,
1450
- ...createAtasIxs,
1451
- ...[flashBorrowIx],
1452
- ...(collIsKtoken ? swapInstructions : []),
1453
- ...KaminoAction.actionToIxs(depositAction),
1454
- ...KaminoAction.actionToIxs(borrowAction),
1455
- ...(collIsKtoken ? [] : swapInstructions),
1456
- ...[flashRepayIx],
1457
- ];
1471
+ return swapQuoteIxsArray.map((swapQuoteIxs) => {
1472
+ const swapInstructions = removeBudgetIxs(swapQuoteIxs.swapIxs);
1458
1473
 
1459
- const flashBorrowReserve = !collIsKtoken ? collReserve! : debtReserve!;
1460
- const res: LeverageIxsOutput = {
1461
- flashLoanInfo: {
1462
- flashBorrowReserve: flashBorrowReserve.address,
1463
- flashLoanFee: flashBorrowReserve.getFlashLoanFee(),
1464
- },
1465
- instructions: ixs,
1466
- };
1474
+ const ixs = [
1475
+ ...scopeRefreshIx,
1476
+ ...budgetIxs,
1477
+ ...createAtasIxs,
1478
+ ...[flashBorrowIx],
1479
+ ...(collIsKtoken ? swapInstructions : []),
1480
+ ...KaminoAction.actionToIxs(depositAction),
1481
+ ...KaminoAction.actionToIxs(borrowAction),
1482
+ ...(collIsKtoken ? [] : swapInstructions),
1483
+ ...[flashRepayIx],
1484
+ ];
1485
+
1486
+ const flashBorrowReserve = !collIsKtoken ? collReserve! : debtReserve!;
1487
+ const res: LeverageIxsOutput = {
1488
+ flashLoanInfo: {
1489
+ flashBorrowReserve: flashBorrowReserve.address,
1490
+ flashLoanFee: flashBorrowReserve.getFlashLoanFee(),
1491
+ },
1492
+ instructions: ixs,
1493
+ };
1467
1494
 
1468
- return res;
1495
+ return res;
1496
+ });
1469
1497
  }
1470
1498
 
1471
1499
  /**
@@ -1483,10 +1511,11 @@ async function buildDecreaseLeverageIxs<QuoteResponse>(
1483
1511
  strategy: StrategyWithAddress | undefined,
1484
1512
  scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
1485
1513
  collIsKtoken: boolean,
1486
- swapQuoteIxs: SwapIxs<QuoteResponse>,
1514
+ swapQuoteIxsArray: SwapIxs<QuoteResponse>[],
1487
1515
  budgetAndPriorityFeeIxs: TransactionInstruction[] | undefined,
1488
- useV2Ixs: boolean
1489
- ): Promise<LeverageIxsOutput> {
1516
+ useV2Ixs: boolean,
1517
+ withdrawSlotOffset: number = WITHDRAW_SLOT_OFFSET
1518
+ ): Promise<LeverageIxsOutput[]> {
1490
1519
  const collReserve = kaminoMarket.getExistingReserveByMint(collTokenMint);
1491
1520
  const debtReserve = kaminoMarket.getExistingReserveByMint(debtTokenMint);
1492
1521
  const debtTokenAta = getAssociatedTokenAddressSync(
@@ -1561,6 +1590,7 @@ async function buildDecreaseLeverageIxs<QuoteResponse>(
1561
1590
  referrer
1562
1591
  );
1563
1592
 
1593
+ const withdrawSlot = currentSlot - withdrawSlotOffset;
1564
1594
  // 6. Withdraw collateral (a little bit more to be able to pay for the slippage on swap)
1565
1595
  const withdrawAction = await KaminoAction.buildWithdrawTxns(
1566
1596
  kaminoMarket,
@@ -1575,33 +1605,35 @@ async function buildDecreaseLeverageIxs<QuoteResponse>(
1575
1605
  false,
1576
1606
  { skipInitialization: true, skipLutCreation: true }, // to be checked and create in a setup tx in the UI (won't be the case for adjust anyway as this would be created in deposit)
1577
1607
  referrer,
1578
- currentSlot
1608
+ withdrawSlot
1579
1609
  );
1580
1610
 
1581
- const swapInstructions = removeBudgetIxs(swapQuoteIxs.swapIxs);
1582
-
1583
- const ixs = [
1584
- ...scopeRefreshIx,
1585
- ...budgetIxs,
1586
- ...createAtasIxs,
1587
- ...fillWsolAtaIxs,
1588
- ...[flashBorrowIx],
1589
- ...KaminoAction.actionToIxs(repayAction),
1590
- ...KaminoAction.actionToIxs(withdrawAction),
1591
- ...swapInstructions,
1592
- ...[flashRepayIx],
1593
- ...closeWsolAtaIxs,
1594
- ];
1611
+ return swapQuoteIxsArray.map((swapQuoteIxs) => {
1612
+ const swapInstructions = removeBudgetIxs(swapQuoteIxs.swapIxs);
1595
1613
 
1596
- const res: LeverageIxsOutput = {
1597
- flashLoanInfo: {
1598
- flashBorrowReserve: debtReserve!.address,
1599
- flashLoanFee: debtReserve!.getFlashLoanFee(),
1600
- },
1601
- instructions: ixs,
1602
- };
1614
+ const ixs = [
1615
+ ...scopeRefreshIx,
1616
+ ...budgetIxs,
1617
+ ...createAtasIxs,
1618
+ ...fillWsolAtaIxs,
1619
+ ...[flashBorrowIx],
1620
+ ...KaminoAction.actionToIxs(repayAction),
1621
+ ...KaminoAction.actionToIxs(withdrawAction),
1622
+ ...swapInstructions,
1623
+ ...[flashRepayIx],
1624
+ ...closeWsolAtaIxs,
1625
+ ];
1603
1626
 
1604
- return res;
1627
+ const res: LeverageIxsOutput = {
1628
+ flashLoanInfo: {
1629
+ flashBorrowReserve: debtReserve!.address,
1630
+ flashLoanFee: debtReserve!.getFlashLoanFee(),
1631
+ },
1632
+ instructions: ixs,
1633
+ };
1634
+
1635
+ return res;
1636
+ });
1605
1637
  }
1606
1638
 
1607
1639
  export const getSetupIxs = async (
@@ -1661,18 +1693,20 @@ export const getScopeRefreshIx = async (
1661
1693
  debtReserve.address,
1662
1694
  ]).toArray()
1663
1695
  : new PublicKeySet<PublicKey>([collReserve.address, debtReserve.address]).toArray();
1664
- const tokenIds = getTokenIdsForScopeRefresh(market, allReserves);
1665
1696
 
1666
1697
  const scopeRefreshIxs: TransactionInstruction[] = [];
1667
- if (tokenIds.length > 0 && scopeRefreshConfig) {
1668
- scopeRefreshIxs.push(
1669
- await scopeRefreshConfig.scope.refreshPriceListIx(
1670
- {
1671
- feed: scopeRefreshConfig.scopeFeed,
1672
- },
1673
- tokenIds
1674
- )
1675
- );
1698
+ const scopeTokensMap = getTokenIdsForScopeRefresh(market, allReserves);
1699
+
1700
+ if (scopeTokensMap.size > 0 && scopeRefreshConfig) {
1701
+ for (const [configPubkey, config] of scopeRefreshConfig.scopeConfigurations) {
1702
+ const tokenIds = scopeTokensMap.get(config.oraclePrices);
1703
+ if (tokenIds && tokenIds.length > 0) {
1704
+ const refreshIx = await scopeRefreshConfig.scope.refreshPriceListIx({ config: configPubkey }, tokenIds);
1705
+ if (refreshIx) {
1706
+ scopeRefreshIxs.push(refreshIx);
1707
+ }
1708
+ }
1709
+ }
1676
1710
  }
1677
1711
 
1678
1712
  return scopeRefreshIxs;