@kamino-finance/klend-sdk 5.11.3-beta.1 → 5.11.3
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.
- package/dist/classes/action.d.ts +23 -23
- package/dist/classes/action.d.ts.map +1 -1
- package/dist/classes/action.js +122 -195
- package/dist/classes/action.js.map +1 -1
- package/dist/classes/index.d.ts +1 -0
- package/dist/classes/index.d.ts.map +1 -1
- package/dist/classes/index.js +1 -0
- package/dist/classes/index.js.map +1 -1
- package/dist/classes/manager.d.ts +6 -1
- package/dist/classes/manager.d.ts.map +1 -1
- package/dist/classes/manager.js +16 -1
- package/dist/classes/manager.js.map +1 -1
- package/dist/classes/market.d.ts +3 -3
- package/dist/classes/market.d.ts.map +1 -1
- package/dist/classes/market.js +30 -16
- package/dist/classes/market.js.map +1 -1
- package/dist/classes/obligation.d.ts +2 -0
- package/dist/classes/obligation.d.ts.map +1 -1
- package/dist/classes/obligation.js +5 -0
- package/dist/classes/obligation.js.map +1 -1
- package/dist/lending_operations/repay_with_collateral_operations.d.ts +4 -4
- package/dist/lending_operations/repay_with_collateral_operations.d.ts.map +1 -1
- package/dist/lending_operations/repay_with_collateral_operations.js +10 -8
- package/dist/lending_operations/repay_with_collateral_operations.js.map +1 -1
- package/dist/lending_operations/swap_collateral_operations.d.ts +2 -2
- package/dist/lending_operations/swap_collateral_operations.d.ts.map +1 -1
- package/dist/lending_operations/swap_collateral_operations.js +11 -6
- package/dist/lending_operations/swap_collateral_operations.js.map +1 -1
- package/dist/leverage/calcs.d.ts +5 -10
- package/dist/leverage/calcs.d.ts.map +1 -1
- package/dist/leverage/calcs.js +6 -13
- package/dist/leverage/calcs.js.map +1 -1
- package/dist/leverage/operations.d.ts +9 -7
- package/dist/leverage/operations.d.ts.map +1 -1
- package/dist/leverage/operations.js +78 -72
- package/dist/leverage/operations.js.map +1 -1
- package/dist/leverage/types.d.ts +4 -4
- package/dist/leverage/types.d.ts.map +1 -1
- package/dist/utils/ObligationType.d.ts +1 -1
- package/dist/utils/ObligationType.d.ts.map +1 -1
- package/dist/utils/managerTypes.d.ts.map +1 -1
- package/dist/utils/managerTypes.js +7 -52
- package/dist/utils/managerTypes.js.map +1 -1
- package/dist/utils/oracle.d.ts +3 -3
- package/dist/utils/oracle.d.ts.map +1 -1
- package/dist/utils/oracle.js +4 -3
- package/dist/utils/oracle.js.map +1 -1
- package/package.json +2 -2
- package/src/classes/action.ts +143 -211
- package/src/classes/index.ts +1 -0
- package/src/classes/manager.ts +32 -1
- package/src/classes/market.ts +34 -25
- package/src/classes/obligation.ts +6 -0
- package/src/client.ts +8 -3
- package/src/lending_operations/repay_with_collateral_operations.ts +15 -11
- package/src/lending_operations/swap_collateral_operations.ts +19 -7
- package/src/leverage/calcs.ts +2 -18
- package/src/leverage/operations.ts +114 -72
- package/src/leverage/types.ts +4 -4
- package/src/utils/ObligationType.ts +1 -1
- package/src/utils/managerTypes.ts +10 -52
- package/src/utils/oracle.ts +7 -6
|
@@ -6,6 +6,8 @@ import {
|
|
|
6
6
|
KaminoObligation,
|
|
7
7
|
KaminoReserve,
|
|
8
8
|
lamportsToNumberDecimal as fromLamports,
|
|
9
|
+
getTokenIdsForScopeRefresh,
|
|
10
|
+
isKaminoObligation,
|
|
9
11
|
} from '../classes';
|
|
10
12
|
import { getFlashLoanInstructions } from './instructions';
|
|
11
13
|
|
|
@@ -15,7 +17,9 @@ import {
|
|
|
15
17
|
MultiplyObligation,
|
|
16
18
|
ObligationType,
|
|
17
19
|
ObligationTypeTag,
|
|
20
|
+
PublicKeySet,
|
|
18
21
|
SOL_DECIMALS,
|
|
22
|
+
ScopePriceRefreshConfig,
|
|
19
23
|
U64_MAX,
|
|
20
24
|
createAtasIdempotent,
|
|
21
25
|
getAssociatedTokenAddress,
|
|
@@ -80,7 +84,7 @@ export async function getDepositWithLeverageSwapInputs<QuoteResponse>({
|
|
|
80
84
|
selectedTokenMint,
|
|
81
85
|
kamino,
|
|
82
86
|
obligationTypeTagOverride,
|
|
83
|
-
|
|
87
|
+
scopeRefreshConfig,
|
|
84
88
|
budgetAndPriorityFeeIxs,
|
|
85
89
|
quoteBufferBps,
|
|
86
90
|
priceAinB,
|
|
@@ -142,7 +146,7 @@ export async function getDepositWithLeverageSwapInputs<QuoteResponse>({
|
|
|
142
146
|
referrer,
|
|
143
147
|
currentSlot,
|
|
144
148
|
depositTokenIsSol,
|
|
145
|
-
|
|
149
|
+
scopeRefreshConfig,
|
|
146
150
|
calcs,
|
|
147
151
|
budgetAndPriorityFeeIxs,
|
|
148
152
|
{
|
|
@@ -309,7 +313,7 @@ export async function getDepositWithLeverageIxns<QuoteResponse>({
|
|
|
309
313
|
selectedTokenMint,
|
|
310
314
|
kamino,
|
|
311
315
|
obligationTypeTagOverride,
|
|
312
|
-
|
|
316
|
+
scopeRefreshConfig,
|
|
313
317
|
budgetAndPriorityFeeIxs,
|
|
314
318
|
quoteBufferBps,
|
|
315
319
|
priceAinB,
|
|
@@ -334,7 +338,7 @@ export async function getDepositWithLeverageIxns<QuoteResponse>({
|
|
|
334
338
|
selectedTokenMint,
|
|
335
339
|
kamino,
|
|
336
340
|
obligationTypeTagOverride,
|
|
337
|
-
|
|
341
|
+
scopeRefreshConfig,
|
|
338
342
|
budgetAndPriorityFeeIxs,
|
|
339
343
|
quoteBufferBps,
|
|
340
344
|
priceAinB,
|
|
@@ -386,7 +390,7 @@ export async function getDepositWithLeverageIxns<QuoteResponse>({
|
|
|
386
390
|
referrer,
|
|
387
391
|
currentSlot,
|
|
388
392
|
depositTokenIsSol,
|
|
389
|
-
|
|
393
|
+
scopeRefreshConfig,
|
|
390
394
|
initialInputs.calcs,
|
|
391
395
|
budgetAndPriorityFeeIxs,
|
|
392
396
|
{
|
|
@@ -417,7 +421,7 @@ async function buildDepositWithLeverageIxns(
|
|
|
417
421
|
referrer: PublicKey,
|
|
418
422
|
currentSlot: number,
|
|
419
423
|
depositTokenIsSol: boolean,
|
|
420
|
-
|
|
424
|
+
scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
|
|
421
425
|
calcs: DepositLeverageCalcsResult,
|
|
422
426
|
budgetAndPriorityFeeIxs: TransactionInstruction[] | undefined,
|
|
423
427
|
swapQuoteIxs: SwapIxs,
|
|
@@ -442,7 +446,7 @@ async function buildDepositWithLeverageIxns(
|
|
|
442
446
|
debtReserve.getLiquidityTokenProgram()
|
|
443
447
|
);
|
|
444
448
|
|
|
445
|
-
// 1. Create atas & budget
|
|
449
|
+
// 1. Create atas & budget ixns
|
|
446
450
|
let mintsToCreateAtas: Array<{ mint: PublicKey; tokenProgram: PublicKey }>;
|
|
447
451
|
if (collIsKtoken) {
|
|
448
452
|
const secondTokenAta = strategy!.strategy.tokenAMint.equals(debtTokenMint)
|
|
@@ -503,10 +507,13 @@ async function buildDepositWithLeverageIxns(
|
|
|
503
507
|
);
|
|
504
508
|
}
|
|
505
509
|
|
|
510
|
+
const scopeRefreshIxn = await getScopeRefreshIx(market, collReserve, debtReserve, obligation, scopeRefreshConfig);
|
|
511
|
+
|
|
506
512
|
// 2. Flash borrow & repay the collateral amount needed for given leverage
|
|
507
513
|
// if user deposits coll, then we borrow the diff, else we borrow the entire amount
|
|
508
514
|
const { flashBorrowIxn, flashRepayIxn } = getFlashLoanInstructions({
|
|
509
|
-
borrowIxnIndex:
|
|
515
|
+
borrowIxnIndex:
|
|
516
|
+
budgetIxns.length + atasAndCreateIxns.length + fillWsolAtaIxns.length + (scopeRefreshIxn.length > 0 ? 1 : 0),
|
|
510
517
|
walletPublicKey: owner,
|
|
511
518
|
lendingMarketAuthority: market.getLendingMarketAuthority(),
|
|
512
519
|
lendingMarketAddress: market.getAddress(),
|
|
@@ -523,7 +530,6 @@ async function buildDepositWithLeverageIxns(
|
|
|
523
530
|
});
|
|
524
531
|
|
|
525
532
|
// 3. Deposit initial tokens + borrowed tokens into reserve
|
|
526
|
-
const scopeRefresh = scopeFeed ? { includeScopeRefresh: true, scopeFeed: scopeFeed } : undefined;
|
|
527
533
|
const kaminoDepositAndBorrowAction = await KaminoAction.buildDepositAndBorrowTxns(
|
|
528
534
|
market,
|
|
529
535
|
toLamports(!collIsKtoken ? calcs.collTokenToDeposit : calcs.collTokenToDeposit, collReserve.stats.decimals)
|
|
@@ -537,14 +543,14 @@ async function buildDepositWithLeverageIxns(
|
|
|
537
543
|
owner,
|
|
538
544
|
obligation!,
|
|
539
545
|
useV2Ixs,
|
|
546
|
+
undefined,
|
|
540
547
|
0,
|
|
541
548
|
false,
|
|
542
549
|
elevationGroupOverride === 0 ? false : true, // emode
|
|
543
550
|
false, // to be checked and created in a setup tx in the UI
|
|
544
551
|
false, // to be checked and created in a setup tx in the UI
|
|
545
552
|
referrer,
|
|
546
|
-
currentSlot
|
|
547
|
-
scopeRefresh
|
|
553
|
+
currentSlot
|
|
548
554
|
);
|
|
549
555
|
|
|
550
556
|
// 4. Swap
|
|
@@ -553,18 +559,18 @@ async function buildDepositWithLeverageIxns(
|
|
|
553
559
|
|
|
554
560
|
if (!collIsKtoken) {
|
|
555
561
|
return [
|
|
562
|
+
...scopeRefreshIxn,
|
|
556
563
|
...budgetIxns,
|
|
557
564
|
...atasAndCreateIxns.map((x) => x.createAtaIx),
|
|
558
565
|
...fillWsolAtaIxns,
|
|
559
566
|
...[flashBorrowIxn],
|
|
560
|
-
...kaminoDepositAndBorrowAction
|
|
561
|
-
...KaminoAction.actionToLendingIxs(kaminoDepositAndBorrowAction),
|
|
562
|
-
...kaminoDepositAndBorrowAction.cleanupIxs,
|
|
567
|
+
...KaminoAction.actionToIxs(kaminoDepositAndBorrowAction),
|
|
563
568
|
...swapInstructions,
|
|
564
569
|
...[flashRepayIxn],
|
|
565
570
|
];
|
|
566
571
|
} else {
|
|
567
572
|
return [
|
|
573
|
+
...scopeRefreshIxn,
|
|
568
574
|
...budgetIxns,
|
|
569
575
|
...atasAndCreateIxns.map((x) => x.createAtaIx),
|
|
570
576
|
...fillWsolAtaIxns,
|
|
@@ -595,7 +601,7 @@ export async function getWithdrawWithLeverageSwapInputs<QuoteResponse>({
|
|
|
595
601
|
selectedTokenMint,
|
|
596
602
|
budgetAndPriorityFeeIxs,
|
|
597
603
|
kamino,
|
|
598
|
-
|
|
604
|
+
scopeRefreshConfig,
|
|
599
605
|
quoteBufferBps,
|
|
600
606
|
isKtoken,
|
|
601
607
|
quoter,
|
|
@@ -641,7 +647,7 @@ export async function getWithdrawWithLeverageSwapInputs<QuoteResponse>({
|
|
|
641
647
|
currentSlot,
|
|
642
648
|
isClosingPosition,
|
|
643
649
|
depositTokenIsSol,
|
|
644
|
-
|
|
650
|
+
scopeRefreshConfig,
|
|
645
651
|
calcs,
|
|
646
652
|
budgetAndPriorityFeeIxs,
|
|
647
653
|
{
|
|
@@ -729,7 +735,7 @@ export async function getWithdrawWithLeverageIxns<QuoteResponse>({
|
|
|
729
735
|
selectedTokenMint,
|
|
730
736
|
budgetAndPriorityFeeIxs,
|
|
731
737
|
kamino,
|
|
732
|
-
|
|
738
|
+
scopeRefreshConfig,
|
|
733
739
|
quoteBufferBps,
|
|
734
740
|
isKtoken,
|
|
735
741
|
quoter,
|
|
@@ -758,7 +764,7 @@ export async function getWithdrawWithLeverageIxns<QuoteResponse>({
|
|
|
758
764
|
selectedTokenMint,
|
|
759
765
|
budgetAndPriorityFeeIxs,
|
|
760
766
|
kamino,
|
|
761
|
-
|
|
767
|
+
scopeRefreshConfig,
|
|
762
768
|
quoteBufferBps,
|
|
763
769
|
isKtoken,
|
|
764
770
|
quoter,
|
|
@@ -804,7 +810,7 @@ export async function getWithdrawWithLeverageIxns<QuoteResponse>({
|
|
|
804
810
|
currentSlot,
|
|
805
811
|
isClosingPosition,
|
|
806
812
|
depositTokenIsSol,
|
|
807
|
-
|
|
813
|
+
scopeRefreshConfig,
|
|
808
814
|
initialInputs.calcs,
|
|
809
815
|
budgetAndPriorityFeeIxs,
|
|
810
816
|
{
|
|
@@ -836,7 +842,7 @@ export async function buildWithdrawWithLeverageIxns(
|
|
|
836
842
|
currentSlot: number,
|
|
837
843
|
isClosingPosition: boolean,
|
|
838
844
|
depositTokenIsSol: boolean,
|
|
839
|
-
|
|
845
|
+
scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
|
|
840
846
|
calcs: WithdrawLeverageCalcsResult,
|
|
841
847
|
budgetAndPriorityFeeIxs: TransactionInstruction[] | undefined,
|
|
842
848
|
swapQuoteIxs: SwapIxs,
|
|
@@ -910,7 +916,7 @@ export async function buildWithdrawWithLeverageIxns(
|
|
|
910
916
|
|
|
911
917
|
const budgetIxns = budgetAndPriorityFeeIxs || getComputeBudgetAndPriorityFeeIxns(3000000);
|
|
912
918
|
|
|
913
|
-
// TODO:
|
|
919
|
+
// TODO: Mihai/Marius check if we can improve this logic and not convert any SOL
|
|
914
920
|
// This is here so that we have enough wsol to repay in case the kAB swapped to sol after estimates is not enough
|
|
915
921
|
const fillWsolAtaIxns: TransactionInstruction[] = [];
|
|
916
922
|
if (debtTokenMint.equals(NATIVE_MINT)) {
|
|
@@ -925,11 +931,14 @@ export async function buildWithdrawWithLeverageIxns(
|
|
|
925
931
|
);
|
|
926
932
|
}
|
|
927
933
|
|
|
934
|
+
const scopeRefreshIxn = await getScopeRefreshIx(market, collReserve, debtReserve, obligation, scopeRefreshConfig);
|
|
935
|
+
|
|
928
936
|
// 2. Prepare the flash borrow and flash repay amounts and ixns
|
|
929
937
|
// We borrow exactly how much we need to repay
|
|
930
938
|
// and repay that + flash amount fee
|
|
931
939
|
const { flashBorrowIxn, flashRepayIxn } = getFlashLoanInstructions({
|
|
932
|
-
borrowIxnIndex:
|
|
940
|
+
borrowIxnIndex:
|
|
941
|
+
budgetIxns.length + atasAndCreateIxns.length + fillWsolAtaIxns.length + (scopeRefreshIxn.length > 0 ? 1 : 0),
|
|
933
942
|
walletPublicKey: owner,
|
|
934
943
|
lendingMarketAuthority: market.getLendingMarketAuthority(),
|
|
935
944
|
lendingMarketAddress: market.getAddress(),
|
|
@@ -942,7 +951,7 @@ export async function buildWithdrawWithLeverageIxns(
|
|
|
942
951
|
programId: market.programId,
|
|
943
952
|
});
|
|
944
953
|
|
|
945
|
-
//
|
|
954
|
+
// 3. Repay borrowed tokens and Withdraw tokens from reserve that will be swapped to repay flash loan
|
|
946
955
|
const repayAndWithdrawAction = await KaminoAction.buildRepayAndWithdrawTxns(
|
|
947
956
|
market,
|
|
948
957
|
isClosingPosition ? U64_MAX : toLamports(calcs.repayAmount, debtReserve!.stats.decimals).floor().toString(),
|
|
@@ -955,25 +964,24 @@ export async function buildWithdrawWithLeverageIxns(
|
|
|
955
964
|
currentSlot,
|
|
956
965
|
obligation,
|
|
957
966
|
useV2Ixs,
|
|
967
|
+
undefined,
|
|
958
968
|
0,
|
|
959
969
|
false,
|
|
960
970
|
false, // to be checked and created in a setup tx in the UI (won't be the case for withdraw anyway as this would be created in deposit)
|
|
961
971
|
false, // to be checked and created in a setup tx in the UI (won't be the case for withdraw anyway as this would be created in deposit)
|
|
962
972
|
isClosingPosition,
|
|
963
|
-
referrer
|
|
964
|
-
{ includeScopeRefresh: true, scopeFeed: scopeFeed! }
|
|
973
|
+
referrer
|
|
965
974
|
);
|
|
966
975
|
|
|
967
976
|
const swapInstructions = removeBudgetAndAtaIxns(swapQuoteIxs.swapIxs, []);
|
|
968
977
|
|
|
969
978
|
return [
|
|
979
|
+
...scopeRefreshIxn,
|
|
970
980
|
...budgetIxns,
|
|
971
981
|
...atasAndCreateIxns.map((x) => x.createAtaIx),
|
|
972
982
|
...fillWsolAtaIxns,
|
|
973
983
|
...[flashBorrowIxn],
|
|
974
|
-
...repayAndWithdrawAction
|
|
975
|
-
...KaminoAction.actionToLendingIxs(repayAndWithdrawAction),
|
|
976
|
-
...repayAndWithdrawAction.cleanupIxs,
|
|
984
|
+
...KaminoAction.actionToIxs(repayAndWithdrawAction),
|
|
977
985
|
...swapInstructions,
|
|
978
986
|
...[flashRepayIxn],
|
|
979
987
|
...closeWsolAtaIxns,
|
|
@@ -996,7 +1004,7 @@ export async function getAdjustLeverageSwapInputs<QuoteResponse>({
|
|
|
996
1004
|
slippagePct,
|
|
997
1005
|
budgetAndPriorityFeeIxs,
|
|
998
1006
|
kamino,
|
|
999
|
-
|
|
1007
|
+
scopeRefreshConfig,
|
|
1000
1008
|
quoteBufferBps,
|
|
1001
1009
|
isKtoken,
|
|
1002
1010
|
quoter,
|
|
@@ -1016,13 +1024,10 @@ export async function getAdjustLeverageSwapInputs<QuoteResponse>({
|
|
|
1016
1024
|
const currentLeverage = obligation.refreshedStats.leverage;
|
|
1017
1025
|
const isDepositViaLeverage = targetLeverage.gte(new Decimal(currentLeverage));
|
|
1018
1026
|
let flashLoanFee;
|
|
1019
|
-
let borrowFee;
|
|
1020
1027
|
if (isDepositViaLeverage) {
|
|
1021
1028
|
flashLoanFee = collReserve.getFlashLoanFee() || new Decimal(0);
|
|
1022
|
-
borrowFee = collReserve.getBorrowFee() || new Decimal(0);
|
|
1023
1029
|
} else {
|
|
1024
1030
|
flashLoanFee = debtReserve.getFlashLoanFee() || new Decimal(0);
|
|
1025
|
-
borrowFee = debtReserve.getBorrowFee() || new Decimal(0);
|
|
1026
1031
|
}
|
|
1027
1032
|
|
|
1028
1033
|
const { adjustDepositPosition, adjustBorrowPosition } = calcAdjustAmounts({
|
|
@@ -1031,7 +1036,6 @@ export async function getAdjustLeverageSwapInputs<QuoteResponse>({
|
|
|
1031
1036
|
targetLeverage: targetLeverage,
|
|
1032
1037
|
priceCollToDebt: priceCollToDebt,
|
|
1033
1038
|
flashLoanFee: new Decimal(flashLoanFee),
|
|
1034
|
-
borrowFee,
|
|
1035
1039
|
});
|
|
1036
1040
|
|
|
1037
1041
|
const isDeposit = adjustDepositPosition.gte(0) && adjustBorrowPosition.gte(0);
|
|
@@ -1063,7 +1067,7 @@ export async function getAdjustLeverageSwapInputs<QuoteResponse>({
|
|
|
1063
1067
|
currentSlot,
|
|
1064
1068
|
calcs,
|
|
1065
1069
|
strategy,
|
|
1066
|
-
|
|
1070
|
+
scopeRefreshConfig,
|
|
1067
1071
|
collIsKtoken,
|
|
1068
1072
|
{
|
|
1069
1073
|
preActionIxs: [],
|
|
@@ -1099,7 +1103,6 @@ export async function getAdjustLeverageSwapInputs<QuoteResponse>({
|
|
|
1099
1103
|
targetLeverage: targetLeverage,
|
|
1100
1104
|
priceCollToDebt: new Decimal(1).div(swapQuote.priceAInB),
|
|
1101
1105
|
flashLoanFee: new Decimal(flashLoanFee),
|
|
1102
|
-
borrowFee,
|
|
1103
1106
|
});
|
|
1104
1107
|
|
|
1105
1108
|
const calcsQuotePrice = await adjustDepositLeverageCalcs(
|
|
@@ -1168,7 +1171,7 @@ export async function getAdjustLeverageSwapInputs<QuoteResponse>({
|
|
|
1168
1171
|
currentSlot,
|
|
1169
1172
|
calcs,
|
|
1170
1173
|
strategy,
|
|
1171
|
-
|
|
1174
|
+
scopeRefreshConfig,
|
|
1172
1175
|
collIsKtoken,
|
|
1173
1176
|
{
|
|
1174
1177
|
preActionIxs: [],
|
|
@@ -1204,7 +1207,6 @@ export async function getAdjustLeverageSwapInputs<QuoteResponse>({
|
|
|
1204
1207
|
targetLeverage: targetLeverage,
|
|
1205
1208
|
priceCollToDebt: swapQuote.priceAInB,
|
|
1206
1209
|
flashLoanFee: new Decimal(flashLoanFee),
|
|
1207
|
-
borrowFee,
|
|
1208
1210
|
});
|
|
1209
1211
|
|
|
1210
1212
|
const calcsQuotePrice = adjustWithdrawLeverageCalcs(
|
|
@@ -1257,7 +1259,7 @@ export async function getAdjustLeverageIxns<QuoteResponse>({
|
|
|
1257
1259
|
slippagePct,
|
|
1258
1260
|
budgetAndPriorityFeeIxs,
|
|
1259
1261
|
kamino,
|
|
1260
|
-
|
|
1262
|
+
scopeRefreshConfig,
|
|
1261
1263
|
quoteBufferBps,
|
|
1262
1264
|
priceAinB,
|
|
1263
1265
|
isKtoken,
|
|
@@ -1281,7 +1283,7 @@ export async function getAdjustLeverageIxns<QuoteResponse>({
|
|
|
1281
1283
|
slippagePct,
|
|
1282
1284
|
budgetAndPriorityFeeIxs,
|
|
1283
1285
|
kamino,
|
|
1284
|
-
|
|
1286
|
+
scopeRefreshConfig,
|
|
1285
1287
|
quoteBufferBps,
|
|
1286
1288
|
priceAinB,
|
|
1287
1289
|
isKtoken,
|
|
@@ -1327,7 +1329,7 @@ export async function getAdjustLeverageIxns<QuoteResponse>({
|
|
|
1327
1329
|
currentSlot,
|
|
1328
1330
|
initialInputs.calcs,
|
|
1329
1331
|
initialInputs.strategy,
|
|
1330
|
-
|
|
1332
|
+
scopeRefreshConfig,
|
|
1331
1333
|
initialInputs.collIsKtoken,
|
|
1332
1334
|
{
|
|
1333
1335
|
preActionIxs: [],
|
|
@@ -1374,7 +1376,7 @@ export async function getAdjustLeverageIxns<QuoteResponse>({
|
|
|
1374
1376
|
currentSlot,
|
|
1375
1377
|
initialInputs.calcs,
|
|
1376
1378
|
initialInputs.strategy,
|
|
1377
|
-
|
|
1379
|
+
scopeRefreshConfig,
|
|
1378
1380
|
initialInputs.collIsKtoken,
|
|
1379
1381
|
{
|
|
1380
1382
|
preActionIxs: [],
|
|
@@ -1407,7 +1409,7 @@ async function buildIncreaseLeverageIxns(
|
|
|
1407
1409
|
currentSlot: number,
|
|
1408
1410
|
calcs: AdjustLeverageCalcsResult,
|
|
1409
1411
|
strategy: StrategyWithAddress | undefined,
|
|
1410
|
-
|
|
1412
|
+
scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
|
|
1411
1413
|
collIsKtoken: boolean,
|
|
1412
1414
|
swapQuoteIxs: SwapIxs,
|
|
1413
1415
|
budgetAndPriorityFeeIxns: TransactionInstruction[] | undefined,
|
|
@@ -1479,9 +1481,17 @@ async function buildIncreaseLeverageIxns(
|
|
|
1479
1481
|
|
|
1480
1482
|
const atasAndCreateIxns = createAtasIdempotent(owner, mintsToCreateAtas);
|
|
1481
1483
|
|
|
1484
|
+
const scopeRefreshIxn = await getScopeRefreshIx(
|
|
1485
|
+
kaminoMarket,
|
|
1486
|
+
collReserve!,
|
|
1487
|
+
debtReserve!,
|
|
1488
|
+
obligation,
|
|
1489
|
+
scopeRefreshConfig
|
|
1490
|
+
);
|
|
1491
|
+
|
|
1482
1492
|
// 2. Create borrow flash loan instruction
|
|
1483
1493
|
const { flashBorrowIxn, flashRepayIxn } = getFlashLoanInstructions({
|
|
1484
|
-
borrowIxnIndex: budgetIxns.length + atasAndCreateIxns.length, // TODO: how about user metadata ixns
|
|
1494
|
+
borrowIxnIndex: budgetIxns.length + atasAndCreateIxns.length + (scopeRefreshIxn.length > 0 ? 1 : 0), // TODO: how about user metadata ixns
|
|
1485
1495
|
walletPublicKey: owner,
|
|
1486
1496
|
lendingMarketAuthority: kaminoMarket.getLendingMarketAuthority(),
|
|
1487
1497
|
lendingMarketAddress: kaminoMarket.getAddress(),
|
|
@@ -1504,14 +1514,14 @@ async function buildIncreaseLeverageIxns(
|
|
|
1504
1514
|
owner,
|
|
1505
1515
|
obligation,
|
|
1506
1516
|
useV2Ixs,
|
|
1517
|
+
undefined,
|
|
1507
1518
|
0,
|
|
1508
1519
|
false,
|
|
1509
1520
|
false,
|
|
1510
1521
|
false, // 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)
|
|
1511
1522
|
false, // 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)
|
|
1512
1523
|
referrer,
|
|
1513
|
-
currentSlot
|
|
1514
|
-
{ includeScopeRefresh: true, scopeFeed: scopeFeed! }
|
|
1524
|
+
currentSlot
|
|
1515
1525
|
);
|
|
1516
1526
|
|
|
1517
1527
|
// 4. Borrow tokens in borrow token reserve that will be swapped to repay flash loan
|
|
@@ -1522,43 +1532,37 @@ async function buildIncreaseLeverageIxns(
|
|
|
1522
1532
|
owner,
|
|
1523
1533
|
obligation,
|
|
1524
1534
|
useV2Ixs,
|
|
1535
|
+
undefined,
|
|
1525
1536
|
0,
|
|
1526
1537
|
false,
|
|
1527
1538
|
false,
|
|
1528
1539
|
false, // 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)
|
|
1529
1540
|
false, // 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)
|
|
1530
1541
|
referrer,
|
|
1531
|
-
currentSlot
|
|
1532
|
-
{ includeScopeRefresh: true, scopeFeed: scopeFeed! }
|
|
1542
|
+
currentSlot
|
|
1533
1543
|
);
|
|
1534
1544
|
|
|
1535
1545
|
const swapInstructions = removeBudgetAndAtaIxns(swapQuoteIxs.swapIxs, []);
|
|
1536
1546
|
|
|
1537
1547
|
const ixs = !collIsKtoken
|
|
1538
1548
|
? [
|
|
1549
|
+
...scopeRefreshIxn,
|
|
1539
1550
|
...budgetIxns,
|
|
1540
1551
|
...atasAndCreateIxns.map((x) => x.createAtaIx),
|
|
1541
1552
|
...[flashBorrowIxn],
|
|
1542
|
-
...depositAction
|
|
1543
|
-
...
|
|
1544
|
-
...depositAction.cleanupIxs,
|
|
1545
|
-
...borrowAction.setupIxs,
|
|
1546
|
-
...borrowAction.lendingIxs,
|
|
1547
|
-
...borrowAction.cleanupIxs,
|
|
1553
|
+
...KaminoAction.actionToIxs(depositAction),
|
|
1554
|
+
...KaminoAction.actionToIxs(borrowAction),
|
|
1548
1555
|
...swapInstructions,
|
|
1549
1556
|
...[flashRepayIxn],
|
|
1550
1557
|
]
|
|
1551
1558
|
: [
|
|
1559
|
+
...scopeRefreshIxn,
|
|
1552
1560
|
...budgetIxns,
|
|
1553
1561
|
...atasAndCreateIxns.map((x) => x.createAtaIx),
|
|
1554
1562
|
...[flashBorrowIxn],
|
|
1555
1563
|
...swapInstructions,
|
|
1556
|
-
...depositAction
|
|
1557
|
-
...
|
|
1558
|
-
...depositAction.cleanupIxs,
|
|
1559
|
-
...borrowAction.setupIxs,
|
|
1560
|
-
...borrowAction.lendingIxs,
|
|
1561
|
-
...borrowAction.cleanupIxs,
|
|
1564
|
+
...KaminoAction.actionToIxs(depositAction),
|
|
1565
|
+
...KaminoAction.actionToIxs(borrowAction),
|
|
1562
1566
|
...[flashRepayIxn],
|
|
1563
1567
|
];
|
|
1564
1568
|
|
|
@@ -1578,7 +1582,7 @@ async function buildDecreaseLeverageIxns(
|
|
|
1578
1582
|
currentSlot: number,
|
|
1579
1583
|
calcs: AdjustLeverageCalcsResult,
|
|
1580
1584
|
strategy: StrategyWithAddress | undefined,
|
|
1581
|
-
|
|
1585
|
+
scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
|
|
1582
1586
|
collIsKtoken: boolean,
|
|
1583
1587
|
swapQuoteIxs: SwapIxs,
|
|
1584
1588
|
budgetAndPriorityFeeIxns: TransactionInstruction[] | undefined,
|
|
@@ -1659,9 +1663,18 @@ async function buildDecreaseLeverageIxns(
|
|
|
1659
1663
|
);
|
|
1660
1664
|
}
|
|
1661
1665
|
|
|
1666
|
+
const scopeRefreshIxn = await getScopeRefreshIx(
|
|
1667
|
+
kaminoMarket,
|
|
1668
|
+
collReserve!,
|
|
1669
|
+
debtReserve!,
|
|
1670
|
+
obligation,
|
|
1671
|
+
scopeRefreshConfig
|
|
1672
|
+
);
|
|
1673
|
+
|
|
1662
1674
|
// 3. Flash borrow & repay amount to repay (debt)
|
|
1663
1675
|
const { flashBorrowIxn, flashRepayIxn } = getFlashLoanInstructions({
|
|
1664
|
-
borrowIxnIndex:
|
|
1676
|
+
borrowIxnIndex:
|
|
1677
|
+
budgetIxns.length + atasAndCreateIxns.length + fillWsolAtaIxns.length + (scopeRefreshIxn.length > 0 ? 1 : 0),
|
|
1665
1678
|
walletPublicKey: owner,
|
|
1666
1679
|
lendingMarketAuthority: kaminoMarket.getLendingMarketAuthority(),
|
|
1667
1680
|
lendingMarketAddress: kaminoMarket.getAddress(),
|
|
@@ -1675,7 +1688,6 @@ async function buildDecreaseLeverageIxns(
|
|
|
1675
1688
|
});
|
|
1676
1689
|
|
|
1677
1690
|
// 4. Actually do the repay of the flash borrowed amounts
|
|
1678
|
-
const scopeRefresh = scopeFeed ? { includeScopeRefresh: true, scopeFeed: scopeFeed } : undefined;
|
|
1679
1691
|
const repayAction = await KaminoAction.buildRepayTxns(
|
|
1680
1692
|
kaminoMarket,
|
|
1681
1693
|
toLamports(Decimal.abs(calcs.adjustBorrowPosition), debtReserve!.stats.decimals).floor().toString(),
|
|
@@ -1683,6 +1695,7 @@ async function buildDecreaseLeverageIxns(
|
|
|
1683
1695
|
owner,
|
|
1684
1696
|
obligation,
|
|
1685
1697
|
useV2Ixs,
|
|
1698
|
+
undefined,
|
|
1686
1699
|
currentSlot,
|
|
1687
1700
|
undefined,
|
|
1688
1701
|
0,
|
|
@@ -1690,8 +1703,7 @@ async function buildDecreaseLeverageIxns(
|
|
|
1690
1703
|
false,
|
|
1691
1704
|
false, // 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)
|
|
1692
1705
|
false, // 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)
|
|
1693
|
-
referrer
|
|
1694
|
-
scopeRefresh
|
|
1706
|
+
referrer
|
|
1695
1707
|
);
|
|
1696
1708
|
|
|
1697
1709
|
// 6. Withdraw collateral (a little bit more to be able to pay for the slippage on swap)
|
|
@@ -1702,29 +1714,26 @@ async function buildDecreaseLeverageIxns(
|
|
|
1702
1714
|
owner,
|
|
1703
1715
|
obligation,
|
|
1704
1716
|
useV2Ixs,
|
|
1717
|
+
undefined,
|
|
1705
1718
|
0,
|
|
1706
1719
|
false,
|
|
1707
1720
|
false,
|
|
1708
1721
|
false, // 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)
|
|
1709
1722
|
false, // 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)
|
|
1710
1723
|
referrer,
|
|
1711
|
-
currentSlot
|
|
1712
|
-
{ includeScopeRefresh: true, scopeFeed: scopeFeed! }
|
|
1724
|
+
currentSlot
|
|
1713
1725
|
);
|
|
1714
1726
|
|
|
1715
1727
|
const swapInstructions = removeBudgetAndAtaIxns(swapQuoteIxs.swapIxs, []);
|
|
1716
1728
|
|
|
1717
1729
|
const ixns = [
|
|
1730
|
+
...scopeRefreshIxn,
|
|
1718
1731
|
...budgetIxns,
|
|
1719
1732
|
...atasAndCreateIxns.map((x) => x.createAtaIx),
|
|
1720
1733
|
...fillWsolAtaIxns,
|
|
1721
1734
|
...[flashBorrowIxn],
|
|
1722
|
-
...repayAction
|
|
1723
|
-
...
|
|
1724
|
-
...repayAction.cleanupIxs,
|
|
1725
|
-
...withdrawAction.setupIxs,
|
|
1726
|
-
...withdrawAction.lendingIxs,
|
|
1727
|
-
...withdrawAction.cleanupIxs,
|
|
1735
|
+
...KaminoAction.actionToIxs(repayAction),
|
|
1736
|
+
...KaminoAction.actionToIxs(withdrawAction),
|
|
1728
1737
|
...swapInstructions,
|
|
1729
1738
|
...[flashRepayIxn],
|
|
1730
1739
|
...closeWsolAtaIxns,
|
|
@@ -1732,3 +1741,36 @@ async function buildDecreaseLeverageIxns(
|
|
|
1732
1741
|
|
|
1733
1742
|
return ixns;
|
|
1734
1743
|
}
|
|
1744
|
+
|
|
1745
|
+
export const getScopeRefreshIx = async (
|
|
1746
|
+
market: KaminoMarket,
|
|
1747
|
+
collReserve: KaminoReserve,
|
|
1748
|
+
debtReserve: KaminoReserve,
|
|
1749
|
+
obligation: KaminoObligation | ObligationType | undefined,
|
|
1750
|
+
scopeRefreshConfig: ScopePriceRefreshConfig | undefined
|
|
1751
|
+
): Promise<TransactionInstruction[]> => {
|
|
1752
|
+
const allReserves =
|
|
1753
|
+
obligation && isKaminoObligation(obligation)
|
|
1754
|
+
? new PublicKeySet<PublicKey>([
|
|
1755
|
+
...obligation.getDeposits().map((x) => x.reserveAddress),
|
|
1756
|
+
...obligation.getBorrows().map((x) => x.reserveAddress),
|
|
1757
|
+
collReserve.address,
|
|
1758
|
+
debtReserve.address,
|
|
1759
|
+
]).toArray()
|
|
1760
|
+
: new PublicKeySet<PublicKey>([collReserve.address, debtReserve.address]).toArray();
|
|
1761
|
+
const tokenIds = getTokenIdsForScopeRefresh(market, allReserves);
|
|
1762
|
+
|
|
1763
|
+
const scopeRefreshIxns: TransactionInstruction[] = [];
|
|
1764
|
+
if (tokenIds.length > 0 && scopeRefreshConfig) {
|
|
1765
|
+
scopeRefreshIxns.push(
|
|
1766
|
+
await scopeRefreshConfig.scope.refreshPriceListIx(
|
|
1767
|
+
{
|
|
1768
|
+
feed: scopeRefreshConfig.scopeFeed,
|
|
1769
|
+
},
|
|
1770
|
+
tokenIds
|
|
1771
|
+
)
|
|
1772
|
+
);
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
return scopeRefreshIxns;
|
|
1776
|
+
};
|
package/src/leverage/types.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { AddressLookupTableAccount, PublicKey, TransactionInstruction } from '@s
|
|
|
2
2
|
import Decimal from 'decimal.js';
|
|
3
3
|
import { KaminoMarket, KaminoObligation } from '../classes';
|
|
4
4
|
import { InstructionsWithLookupTables, Kamino, StrategyWithAddress } from '@kamino-finance/kliquidity-sdk';
|
|
5
|
-
import { ObligationType, ObligationTypeTag } from '../utils';
|
|
5
|
+
import { ObligationType, ObligationTypeTag, ScopePriceRefreshConfig } from '../utils';
|
|
6
6
|
|
|
7
7
|
export type SwapQuoteProvider<QuoteResponse> = (
|
|
8
8
|
inputs: SwapInputs,
|
|
@@ -82,7 +82,7 @@ export interface DepositWithLeverageSwapInputsProps<QuoteResponse> {
|
|
|
82
82
|
selectedTokenMint: PublicKey;
|
|
83
83
|
budgetAndPriorityFeeIxs?: TransactionInstruction[];
|
|
84
84
|
kamino: Kamino | undefined;
|
|
85
|
-
|
|
85
|
+
scopeRefreshConfig?: ScopePriceRefreshConfig;
|
|
86
86
|
quoteBufferBps: Decimal;
|
|
87
87
|
priceAinB: PriceAinBProvider;
|
|
88
88
|
isKtoken: IsKtokenProvider;
|
|
@@ -143,7 +143,7 @@ export interface WithdrawWithLeverageSwapInputsProps<QuoteResponse> {
|
|
|
143
143
|
selectedTokenMint: PublicKey;
|
|
144
144
|
budgetAndPriorityFeeIxs?: TransactionInstruction[];
|
|
145
145
|
kamino: Kamino | undefined;
|
|
146
|
-
|
|
146
|
+
scopeRefreshConfig?: ScopePriceRefreshConfig;
|
|
147
147
|
quoteBufferBps: Decimal;
|
|
148
148
|
isKtoken: IsKtokenProvider;
|
|
149
149
|
quoter: SwapQuoteProvider<QuoteResponse>;
|
|
@@ -196,7 +196,7 @@ export interface AdjustLeverageSwapInputsProps<QuoteResponse> {
|
|
|
196
196
|
slippagePct: Decimal;
|
|
197
197
|
budgetAndPriorityFeeIxs?: TransactionInstruction[];
|
|
198
198
|
kamino: Kamino | undefined;
|
|
199
|
-
|
|
199
|
+
scopeRefreshConfig?: ScopePriceRefreshConfig;
|
|
200
200
|
quoteBufferBps: Decimal;
|
|
201
201
|
priceAinB: PriceAinBProvider;
|
|
202
202
|
isKtoken: IsKtokenProvider;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PublicKey } from '@solana/web3.js';
|
|
2
2
|
import { KaminoMarket, KaminoObligation } from '../classes';
|
|
3
3
|
|
|
4
|
-
export type ObligationType = VanillaObligation | MultiplyObligation | LendingObligation;
|
|
4
|
+
export type ObligationType = VanillaObligation | MultiplyObligation | LendingObligation | LeverageObligation;
|
|
5
5
|
|
|
6
6
|
export enum ObligationTypeTag {
|
|
7
7
|
Vanilla = 0,
|
|
@@ -397,59 +397,17 @@ export function getReserveOracleConfigs(priceFeed: PriceFeed | null): {
|
|
|
397
397
|
};
|
|
398
398
|
}
|
|
399
399
|
|
|
400
|
+
const ORACLE_TYPE_MAP = Object.fromEntries(
|
|
401
|
+
Object.values(OracleType)
|
|
402
|
+
// Filter for oracle types that have a discriminator property
|
|
403
|
+
// This ensures we only include actual oracle implementations in the mapping
|
|
404
|
+
// Pyth is used as a type assertion here but actually any oracle type with a discriminator will pass
|
|
405
|
+
.filter((T): T is typeof OracleType.Pyth => 'discriminator' in T)
|
|
406
|
+
.map((T) => [T.discriminator, T.name])
|
|
407
|
+
);
|
|
408
|
+
|
|
400
409
|
export function parseOracleType(type: number): string {
|
|
401
|
-
|
|
402
|
-
case new OracleType.Pyth().discriminator:
|
|
403
|
-
return 'Pyth';
|
|
404
|
-
case new OracleType.SwitchboardV2().discriminator:
|
|
405
|
-
return 'SwitchboardV2';
|
|
406
|
-
case new OracleType.CToken().discriminator:
|
|
407
|
-
return 'CToken';
|
|
408
|
-
case new OracleType.KToken().discriminator:
|
|
409
|
-
return 'KToken';
|
|
410
|
-
case new OracleType.SplStake().discriminator:
|
|
411
|
-
return 'SplStake';
|
|
412
|
-
case new OracleType.PythEMA().discriminator:
|
|
413
|
-
return 'PythEMA';
|
|
414
|
-
case new OracleType.DeprecatedPlaceholder1().discriminator:
|
|
415
|
-
return 'DeprecatedPlaceholder1';
|
|
416
|
-
case new OracleType.DeprecatedPlaceholder2().discriminator:
|
|
417
|
-
return 'DeprecatedPlaceholder2';
|
|
418
|
-
case new OracleType.MsolStake().discriminator:
|
|
419
|
-
return 'MsolStake';
|
|
420
|
-
case new OracleType.KTokenToTokenA().discriminator:
|
|
421
|
-
return 'KTokenToTokenA';
|
|
422
|
-
case new OracleType.KTokenToTokenB().discriminator:
|
|
423
|
-
return 'KTokenToTokenB';
|
|
424
|
-
case new OracleType.JupiterLpFetch().discriminator:
|
|
425
|
-
return 'JupiterLpFetch';
|
|
426
|
-
case new OracleType.ScopeTwap().discriminator:
|
|
427
|
-
return 'ScopeTwap';
|
|
428
|
-
case new OracleType.OrcaWhirlpoolAtoB().discriminator:
|
|
429
|
-
return 'OrcaWhirlpoolAtoB';
|
|
430
|
-
case new OracleType.OrcaWhirlpoolBtoA().discriminator:
|
|
431
|
-
return 'OrcaWhirlpoolBtoA';
|
|
432
|
-
case new OracleType.RaydiumAmmV3AtoB().discriminator:
|
|
433
|
-
return 'RaydiumAmmV3AtoB';
|
|
434
|
-
case new OracleType.RaydiumAmmV3BtoA().discriminator:
|
|
435
|
-
return 'RaydiumAmmV3BtoA';
|
|
436
|
-
case new OracleType.JupiterLpCompute().discriminator:
|
|
437
|
-
return 'JupiterLpCompute';
|
|
438
|
-
case new OracleType.MeteoraDlmmAtoB().discriminator:
|
|
439
|
-
return 'MeteoraDlmmAtoB';
|
|
440
|
-
case new OracleType.MeteoraDlmmBtoA().discriminator:
|
|
441
|
-
return 'MeteoraDlmmBtoA';
|
|
442
|
-
case new OracleType.JupiterLpScope().discriminator:
|
|
443
|
-
return 'JupiterLpScope';
|
|
444
|
-
case new OracleType.PythPullBased().discriminator:
|
|
445
|
-
return 'PythPullBased';
|
|
446
|
-
case new OracleType.PythPullBasedEMA().discriminator:
|
|
447
|
-
return 'PythPullBasedEMA';
|
|
448
|
-
case new OracleType.FixedPrice().discriminator:
|
|
449
|
-
return 'FixedPrice';
|
|
450
|
-
default:
|
|
451
|
-
return 'Unknown';
|
|
452
|
-
}
|
|
410
|
+
return ORACLE_TYPE_MAP[type] || 'Unknown';
|
|
453
411
|
}
|
|
454
412
|
|
|
455
413
|
export type MarketWithAddress = {
|