@kamino-finance/klend-sdk 4.0.2 → 5.0.0

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 (67) hide show
  1. package/README.md +2 -2
  2. package/dist/classes/action.d.ts +3 -1
  3. package/dist/classes/action.d.ts.map +1 -1
  4. package/dist/classes/action.js +62 -61
  5. package/dist/classes/action.js.map +1 -1
  6. package/dist/classes/obligation.d.ts +9 -0
  7. package/dist/classes/obligation.d.ts.map +1 -1
  8. package/dist/classes/obligation.js +8 -0
  9. package/dist/classes/obligation.js.map +1 -1
  10. package/dist/classes/reserve.d.ts +3 -1
  11. package/dist/classes/reserve.d.ts.map +1 -1
  12. package/dist/classes/reserve.js +32 -0
  13. package/dist/classes/reserve.js.map +1 -1
  14. package/dist/classes/shared.d.ts +8 -0
  15. package/dist/classes/shared.d.ts.map +1 -1
  16. package/dist/classes/shared.js +6 -1
  17. package/dist/classes/shared.js.map +1 -1
  18. package/dist/classes/vault.d.ts.map +1 -1
  19. package/dist/classes/vault.js +19 -5
  20. package/dist/classes/vault.js.map +1 -1
  21. package/dist/lending_operations/repay_with_collateral_calcs.d.ts +18 -1
  22. package/dist/lending_operations/repay_with_collateral_calcs.d.ts.map +1 -1
  23. package/dist/lending_operations/repay_with_collateral_calcs.js +62 -0
  24. package/dist/lending_operations/repay_with_collateral_calcs.js.map +1 -1
  25. package/dist/lending_operations/repay_with_collateral_operations.d.ts +27 -43
  26. package/dist/lending_operations/repay_with_collateral_operations.d.ts.map +1 -1
  27. package/dist/lending_operations/repay_with_collateral_operations.js +99 -152
  28. package/dist/lending_operations/repay_with_collateral_operations.js.map +1 -1
  29. package/dist/leverage/operations.d.ts +14 -3
  30. package/dist/leverage/operations.d.ts.map +1 -1
  31. package/dist/leverage/operations.js +184 -128
  32. package/dist/leverage/operations.js.map +1 -1
  33. package/dist/utils/ata.d.ts +12 -3
  34. package/dist/utils/ata.d.ts.map +1 -1
  35. package/dist/utils/ata.js +26 -39
  36. package/dist/utils/ata.js.map +1 -1
  37. package/dist/utils/index.d.ts +0 -2
  38. package/dist/utils/index.d.ts.map +1 -1
  39. package/dist/utils/index.js +0 -2
  40. package/dist/utils/index.js.map +1 -1
  41. package/dist/utils/instruction.d.ts +1 -0
  42. package/dist/utils/instruction.d.ts.map +1 -1
  43. package/dist/utils/instruction.js +18 -0
  44. package/dist/utils/instruction.js.map +1 -1
  45. package/package.json +3 -3
  46. package/src/classes/action.ts +92 -98
  47. package/src/classes/obligation.ts +15 -6
  48. package/src/classes/reserve.ts +48 -1
  49. package/src/classes/shared.ts +10 -0
  50. package/src/classes/vault.ts +23 -19
  51. package/src/lending_operations/repay_with_collateral_calcs.ts +98 -1
  52. package/src/lending_operations/repay_with_collateral_operations.ts +233 -253
  53. package/src/leverage/operations.ts +227 -140
  54. package/src/utils/ata.ts +33 -56
  55. package/src/utils/index.ts +0 -2
  56. package/src/utils/instruction.ts +22 -0
  57. package/dist/utils/layout.d.ts +0 -14
  58. package/dist/utils/layout.d.ts.map +0 -1
  59. package/dist/utils/layout.js +0 -123
  60. package/dist/utils/layout.js.map +0 -1
  61. package/dist/utils/syncNative.d.ts +0 -11
  62. package/dist/utils/syncNative.d.ts.map +0 -1
  63. package/dist/utils/syncNative.js +0 -45
  64. package/dist/utils/syncNative.js.map +0 -1
  65. package/src/global.d.ts +0 -1
  66. package/src/utils/layout.ts +0 -118
  67. package/src/utils/syncNative.ts +0 -22
@@ -1,4 +1,10 @@
1
- import { Connection, LAMPORTS_PER_SOL, PublicKey, TransactionInstruction } from '@solana/web3.js';
1
+ import {
2
+ AddressLookupTableAccount,
3
+ Connection,
4
+ LAMPORTS_PER_SOL,
5
+ PublicKey,
6
+ TransactionInstruction,
7
+ } from '@solana/web3.js';
2
8
  import Decimal from 'decimal.js';
3
9
  import { KaminoAction, KaminoMarket, KaminoObligation, lamportsToNumberDecimal as fromLamports } from '../classes';
4
10
  import { getFlashLoanInstructions } from './instructions';
@@ -17,6 +23,7 @@ import {
17
23
  getComputeBudgetAndPriorityFeeIxns,
18
24
  getDepositWsolIxns,
19
25
  removeBudgetAndAtaIxns,
26
+ uniqueAccounts,
20
27
  } from '../utils';
21
28
  import { calcAdjustAmounts, calcWithdrawAmounts, simulateMintKToken, toJson } from './calcs';
22
29
  import { TOKEN_PROGRAM_ID, createCloseAccountInstruction } from '@solana/spl-token';
@@ -30,18 +37,40 @@ import { getExpectedTokenBalanceAfterBorrow, getKtokenToTokenSwapper, getTokenTo
30
37
 
31
38
  export type SwapIxnsProvider = (
32
39
  amountInLamports: number,
33
- amountInMint: PublicKey,
34
- amountOutMint: PublicKey,
40
+ inputMint: PublicKey,
41
+ outputMint: PublicKey,
35
42
  slippagePct: number,
36
43
  amountDebtAtaBalance?: Decimal
37
44
  ) => Promise<[TransactionInstruction[], PublicKey[]]>;
38
45
 
46
+ export type SwapQuoteProvider<QuoteResponse> = (
47
+ inputs: SwapInputs,
48
+ klendAccounts: Array<PublicKey>
49
+ ) => Promise<SwapQuote<QuoteResponse>>;
50
+
51
+ export type SwapQuoteIxsProvider<QuoteResponse> = (
52
+ inputs: SwapInputs,
53
+ klendAccounts: Array<PublicKey>,
54
+ quote: SwapQuote<QuoteResponse>
55
+ ) => Promise<SwapQuoteIxs>;
56
+
57
+ export type SwapQuote<QuoteResponse> = {
58
+ priceAInB: Decimal;
59
+ quoteResponse?: QuoteResponse;
60
+ };
61
+
62
+ export type SwapQuoteIxs = {
63
+ preActionIxs: TransactionInstruction[];
64
+ swapIxs: TransactionInstruction[];
65
+ lookupTables: AddressLookupTableAccount[];
66
+ };
67
+
39
68
  export type PriceAinBProvider = (mintA: PublicKey, mintB: PublicKey) => Promise<Decimal>;
40
69
 
41
70
  export type IsKtokenProvider = (token: PublicKey | string) => Promise<boolean>;
42
71
 
43
72
  export type SwapInputs = {
44
- inputAmountLamports: number;
73
+ inputAmountLamports: Decimal;
45
74
  inputMint: PublicKey;
46
75
  outputMint: PublicKey;
47
76
  };
@@ -265,9 +294,10 @@ export const getDepositWithLeverageSwapInputs = (props: {
265
294
 
266
295
  return {
267
296
  swapInputs: {
268
- inputAmountLamports: toLamports(calcs.swapDebtTokenIn, debtReserve!.state.liquidity.mintDecimals.toNumber())
269
- .ceil()
270
- .toNumber(),
297
+ inputAmountLamports: toLamports(
298
+ calcs.swapDebtTokenIn,
299
+ debtReserve!.state.liquidity.mintDecimals.toNumber()
300
+ ).ceil(),
271
301
  inputMint: debtTokenMint,
272
302
  outputMint: collTokenMint,
273
303
  },
@@ -386,8 +416,7 @@ export const getDepositWithLeverageIxns = async (props: {
386
416
  );
387
417
 
388
418
  // 1. Create atas & budget txns
389
- let mintsToCreateAtas: PublicKey[] = [];
390
- let mintsToCreateAtasTokenPrograms: PublicKey[] = [];
419
+ let mintsToCreateAtas: Array<{ mint: PublicKey; tokenProgram: PublicKey }>;
391
420
  if (collIsKtoken) {
392
421
  const secondTokenAta = strategy!.strategy.tokenAMint.equals(debtTokenMint)
393
422
  ? strategy!.strategy.tokenBMint
@@ -399,28 +428,46 @@ export const getDepositWithLeverageIxns = async (props: {
399
428
  : strategy!.strategy.tokenATokenProgram.equals(PublicKey.default)
400
429
  ? TOKEN_PROGRAM_ID
401
430
  : strategy!.strategy.tokenATokenProgram;
402
- mintsToCreateAtas = [collTokenMint, debtTokenMint, collReserve!.getCTokenMint(), secondTokenAta];
403
- mintsToCreateAtasTokenPrograms = [
404
- collReserve!.getLiquidityTokenProgram(),
405
- debtReserve!.getLiquidityTokenProgram(),
406
- TOKEN_PROGRAM_ID,
407
- secondTokenTokenProgarm,
431
+ mintsToCreateAtas = [
432
+ {
433
+ mint: collTokenMint,
434
+ tokenProgram: collReserve!.getLiquidityTokenProgram(),
435
+ },
436
+ {
437
+ mint: debtTokenMint,
438
+ tokenProgram: debtReserve!.getLiquidityTokenProgram(),
439
+ },
440
+ {
441
+ mint: collReserve!.getCTokenMint(),
442
+ tokenProgram: TOKEN_PROGRAM_ID,
443
+ },
444
+ {
445
+ mint: secondTokenAta,
446
+ tokenProgram: secondTokenTokenProgarm,
447
+ },
408
448
  ];
409
449
  } else {
410
- mintsToCreateAtas = [collTokenMint, debtTokenMint, collReserve!.getCTokenMint()];
411
- mintsToCreateAtasTokenPrograms = [
412
- collReserve!.getLiquidityTokenProgram(),
413
- debtReserve!.getLiquidityTokenProgram(),
414
- TOKEN_PROGRAM_ID,
450
+ mintsToCreateAtas = [
451
+ {
452
+ mint: collTokenMint,
453
+ tokenProgram: collReserve!.getLiquidityTokenProgram(),
454
+ },
455
+ {
456
+ mint: debtTokenMint,
457
+ tokenProgram: debtReserve!.getLiquidityTokenProgram(),
458
+ },
459
+ {
460
+ mint: collReserve!.getCTokenMint(),
461
+ tokenProgram: TOKEN_PROGRAM_ID,
462
+ },
415
463
  ];
416
464
  }
417
465
 
418
466
  const budgetIxns = budgetAndPriorityFeeIxns || getComputeBudgetAndPriorityFeeIxns(3000000);
419
467
  const {
420
468
  atas: [collTokenAta, debtTokenAta],
421
- createAtasIxns,
422
- closeAtasIxns,
423
- } = await getAtasWithCreateIxnsIfMissing(connection, user, mintsToCreateAtas, mintsToCreateAtasTokenPrograms);
469
+ createAtaIxs,
470
+ } = await getAtasWithCreateIxnsIfMissing(connection, user, mintsToCreateAtas);
424
471
 
425
472
  // TODO: this needs to work the other way around also
426
473
  // TODO: marius test this with shorting leverage and with leverage looping
@@ -438,7 +485,7 @@ export const getDepositWithLeverageIxns = async (props: {
438
485
  // 1. Flash borrow & repay the collateral amount needed for given leverage
439
486
  // if user deposits coll, then we borrow the diff, else we borrow the entire amount
440
487
  const { flashBorrowIxn, flashRepayIxn } = getFlashLoanInstructions({
441
- borrowIxnIndex: budgetIxns.length + createAtasIxns.length + fillWsolAtaIxns.length,
488
+ borrowIxnIndex: budgetIxns.length + createAtaIxs.length + fillWsolAtaIxns.length,
442
489
  walletPublicKey: user,
443
490
  lendingMarketAuthority: kaminoMarket.getLendingMarketAuthority(),
444
491
  lendingMarketAddress: kaminoMarket.getAddress(),
@@ -504,7 +551,7 @@ export const getDepositWithLeverageIxns = async (props: {
504
551
 
505
552
  const ixns = [
506
553
  ...budgetIxns,
507
- ...createAtasIxns,
554
+ ...createAtaIxs,
508
555
  ...fillWsolAtaIxns,
509
556
  ...[flashBorrowIxn],
510
557
  ...kaminoDepositAndBorrowAction.setupIxs,
@@ -513,7 +560,6 @@ export const getDepositWithLeverageIxns = async (props: {
513
560
  ...[kaminoDepositAndBorrowAction.lendingIxs[1]],
514
561
  ...kaminoDepositAndBorrowAction.cleanupIxs,
515
562
  ...[flashRepayIxn],
516
- ...closeAtasIxns,
517
563
  ];
518
564
 
519
565
  const uniqueAccounts = new PublicKeySet<PublicKey>([]);
@@ -529,7 +575,11 @@ export const getDepositWithLeverageIxns = async (props: {
529
575
  return {
530
576
  ixns: [],
531
577
  lookupTablesAddresses: [],
532
- swapInputs: { inputAmountLamports: 0, inputMint: PublicKey.default, outputMint: PublicKey.default },
578
+ swapInputs: {
579
+ inputAmountLamports: new Decimal('0'),
580
+ inputMint: PublicKey.default,
581
+ outputMint: PublicKey.default,
582
+ },
533
583
  totalKlendAccounts: totalKlendAccounts,
534
584
  };
535
585
  }
@@ -567,15 +617,13 @@ export const getDepositWithLeverageIxns = async (props: {
567
617
  inputAmountLamports: toLamports(
568
618
  !collIsKtoken ? calcs.swapDebtTokenIn : calcsKtoken!.singleSidedDeposit,
569
619
  debtReserve!.stats.decimals
570
- )
571
- .ceil()
572
- .toNumber(),
620
+ ).ceil(),
573
621
  inputMint: debtTokenMint,
574
622
  outputMint: collTokenMint,
575
623
  };
576
624
 
577
625
  const [swapIxns, lookupTablesAddresses] = await depositSwapper(
578
- swapInputs.inputAmountLamports,
626
+ swapInputs.inputAmountLamports.toNumber(),
579
627
  swapInputs.inputMint,
580
628
  swapInputs.outputMint,
581
629
  slippagePct.toNumber(),
@@ -596,7 +644,7 @@ export const getDepositWithLeverageIxns = async (props: {
596
644
  return {
597
645
  ixns: [
598
646
  ...budgetIxns,
599
- ...createAtasIxns,
647
+ ...createAtaIxs,
600
648
  ...fillWsolAtaIxns,
601
649
  ...[flashBorrowIxn],
602
650
  ...kaminoDepositAndBorrowAction.setupIxs,
@@ -606,7 +654,6 @@ export const getDepositWithLeverageIxns = async (props: {
606
654
  ...kaminoDepositAndBorrowAction.cleanupIxs,
607
655
  ...swapInstructions,
608
656
  ...[flashRepayIxn],
609
- ...closeAtasIxns,
610
657
  ],
611
658
  lookupTablesAddresses,
612
659
  swapInputs,
@@ -616,7 +663,7 @@ export const getDepositWithLeverageIxns = async (props: {
616
663
  return {
617
664
  ixns: [
618
665
  ...budgetIxns,
619
- ...createAtasIxns,
666
+ ...createAtaIxs,
620
667
  ...fillWsolAtaIxns,
621
668
  ...[flashBorrowIxn],
622
669
  ...swapInstructions,
@@ -626,7 +673,6 @@ export const getDepositWithLeverageIxns = async (props: {
626
673
  ...[kaminoDepositAndBorrowAction.lendingIxs[1]],
627
674
  ...kaminoDepositAndBorrowAction.cleanupIxs,
628
675
  ...[flashRepayIxn],
629
- ...closeAtasIxns,
630
676
  ],
631
677
  lookupTablesAddresses,
632
678
  swapInputs,
@@ -700,9 +746,7 @@ export const getWithdrawWithLeverageSwapInputs = (props: {
700
746
 
701
747
  return {
702
748
  swapInputs: {
703
- inputAmountLamports: toLamports(collTokenSwapIn, collReserve!.state.liquidity.mintDecimals.toNumber())
704
- .ceil()
705
- .toNumber(),
749
+ inputAmountLamports: toLamports(collTokenSwapIn, collReserve!.state.liquidity.mintDecimals.toNumber()).ceil(),
706
750
  inputMint: collTokenMint,
707
751
  outputMint: debtTokenMint,
708
752
  },
@@ -838,47 +882,63 @@ export const getWithdrawWithLeverageIxns = async (props: {
838
882
 
839
883
  console.log('Expecting to swap', collTokenSwapIn.toString(), 'coll for', debtTokenExpectedSwapOut.toString(), 'debt');
840
884
  // 1. Create atas & budget txns & user metadata
841
- let mintsToCreateAtas: PublicKey[] = [];
842
- let mintsToCreateAtasTokenPrograms: PublicKey[] = [];
885
+ let mintsToCreateAtas: Array<{ mint: PublicKey; tokenProgram: PublicKey }>;
843
886
  if (collIsKtoken) {
844
887
  const secondTokenAta = strategy!.strategy.tokenAMint.equals(debtTokenMint)
845
888
  ? strategy!.strategy.tokenBMint
846
889
  : strategy!.strategy.tokenAMint;
847
- const secondTokenTokenProgarm = strategy?.strategy.tokenAMint.equals(debtTokenMint)
890
+ const secondTokenTokenProgram = strategy?.strategy.tokenAMint.equals(debtTokenMint)
848
891
  ? strategy!.strategy.tokenBTokenProgram.equals(PublicKey.default)
849
892
  ? TOKEN_PROGRAM_ID
850
893
  : strategy!.strategy.tokenBTokenProgram
851
894
  : strategy!.strategy.tokenATokenProgram.equals(PublicKey.default)
852
895
  ? TOKEN_PROGRAM_ID
853
896
  : strategy!.strategy.tokenATokenProgram;
854
- mintsToCreateAtas = [collTokenMint, debtTokenMint, collReserve!.getCTokenMint(), secondTokenAta];
855
- mintsToCreateAtasTokenPrograms = [
856
- collReserve!.getLiquidityTokenProgram(),
857
- debtReserve!.getLiquidityTokenProgram(),
858
- TOKEN_PROGRAM_ID,
859
- secondTokenTokenProgarm,
897
+ mintsToCreateAtas = [
898
+ {
899
+ mint: collTokenMint,
900
+ tokenProgram: collReserve!.getLiquidityTokenProgram(),
901
+ },
902
+ {
903
+ mint: debtTokenMint,
904
+ tokenProgram: debtReserve!.getLiquidityTokenProgram(),
905
+ },
906
+ {
907
+ mint: collReserve!.getCTokenMint(),
908
+ tokenProgram: TOKEN_PROGRAM_ID,
909
+ },
910
+ {
911
+ mint: secondTokenAta,
912
+ tokenProgram: secondTokenTokenProgram,
913
+ },
860
914
  ];
861
915
  } else {
862
- mintsToCreateAtas = [collTokenMint, debtTokenMint, collReserve!.getCTokenMint()];
863
- mintsToCreateAtasTokenPrograms = [
864
- collReserve!.getLiquidityTokenProgram(),
865
- debtReserve!.getLiquidityTokenProgram(),
866
- TOKEN_PROGRAM_ID,
916
+ mintsToCreateAtas = [
917
+ {
918
+ mint: collTokenMint,
919
+ tokenProgram: collReserve!.getLiquidityTokenProgram(),
920
+ },
921
+ {
922
+ mint: debtTokenMint,
923
+ tokenProgram: debtReserve!.getLiquidityTokenProgram(),
924
+ },
925
+ {
926
+ mint: collReserve!.getCTokenMint(),
927
+ tokenProgram: TOKEN_PROGRAM_ID,
928
+ },
867
929
  ];
868
930
  }
869
931
 
870
932
  const {
871
933
  atas: [, debtTokenAta],
872
- createAtasIxns,
873
- closeAtasIxns,
874
- } = await getAtasWithCreateIxnsIfMissing(connection, user, mintsToCreateAtas, mintsToCreateAtasTokenPrograms);
934
+ createAtaIxs,
935
+ } = await getAtasWithCreateIxnsIfMissing(connection, user, mintsToCreateAtas);
875
936
 
876
937
  const closeWsolAtaIxns: TransactionInstruction[] = [];
877
938
  if (depositTokenIsSol || debtTokenMint.equals(WRAPPED_SOL_MINT)) {
878
939
  const wsolAta = getAssociatedTokenAddress(WRAPPED_SOL_MINT, user, false);
879
940
  closeWsolAtaIxns.push(createCloseAccountInstruction(wsolAta, user, user, [], TOKEN_PROGRAM_ID));
880
941
  }
881
- closeAtasIxns.push(...closeWsolAtaIxns);
882
942
 
883
943
  const budgetIxns = budgetAndPriorityFeeIxns || getComputeBudgetAndPriorityFeeIxns(3000000);
884
944
 
@@ -898,7 +958,7 @@ export const getWithdrawWithLeverageIxns = async (props: {
898
958
  // and repay that + flash amount fee
899
959
 
900
960
  const { flashBorrowIxn, flashRepayIxn } = getFlashLoanInstructions({
901
- borrowIxnIndex: budgetIxns.length + createAtasIxns.length + fillWsolAtaIxns.length,
961
+ borrowIxnIndex: budgetIxns.length + createAtaIxs.length + fillWsolAtaIxns.length,
902
962
  walletPublicKey: user,
903
963
  lendingMarketAuthority: kaminoMarket.getLendingMarketAuthority(),
904
964
  lendingMarketAddress: kaminoMarket.getAddress(),
@@ -931,7 +991,7 @@ export const getWithdrawWithLeverageIxns = async (props: {
931
991
 
932
992
  const klendIxns = [
933
993
  ...budgetIxns,
934
- ...createAtasIxns,
994
+ ...createAtaIxs,
935
995
  ...fillWsolAtaIxns,
936
996
  ...[flashBorrowIxn],
937
997
  ...repayAndWithdrawAction.setupIxs,
@@ -940,23 +1000,22 @@ export const getWithdrawWithLeverageIxns = async (props: {
940
1000
  ...[repayAndWithdrawAction.lendingIxs[1]],
941
1001
  ...repayAndWithdrawAction.cleanupIxs,
942
1002
  ...[flashRepayIxn],
943
- ...closeAtasIxns,
1003
+ ...closeWsolAtaIxns,
944
1004
  ];
945
1005
 
946
- const uniqueAccounts = new PublicKeySet<PublicKey>([]);
947
- klendIxns.forEach((ixn) => {
948
- ixn.keys.forEach((key) => {
949
- uniqueAccounts.add(key.pubkey);
950
- });
951
- });
952
- const totalKlendAccounts = uniqueAccounts.toArray().length;
1006
+ const uniqueAccs = uniqueAccounts(klendIxns);
1007
+ const totalKlendAccounts = uniqueAccs.length;
953
1008
 
954
1009
  // return early to avoid extra swapper calls
955
1010
  if (getTotalKlendAccountsOnly) {
956
1011
  return {
957
1012
  ixns: [],
958
1013
  lookupTablesAddresses: [],
959
- swapInputs: { inputAmountLamports: 0, inputMint: PublicKey.default, outputMint: PublicKey.default },
1014
+ swapInputs: {
1015
+ inputAmountLamports: new Decimal('0'),
1016
+ inputMint: PublicKey.default,
1017
+ outputMint: PublicKey.default,
1018
+ },
960
1019
  totalKlendAccounts: totalKlendAccounts,
961
1020
  };
962
1021
  }
@@ -973,13 +1032,13 @@ export const getWithdrawWithLeverageIxns = async (props: {
973
1032
  }
974
1033
 
975
1034
  const swapInputs: SwapInputs = {
976
- inputAmountLamports: toLamports(collTokenSwapIn, collReserve!.stats.decimals).ceil().toNumber(),
1035
+ inputAmountLamports: toLamports(collTokenSwapIn, collReserve!.stats.decimals).ceil(),
977
1036
  inputMint: collTokenMint,
978
1037
  outputMint: debtTokenMint,
979
1038
  };
980
1039
 
981
1040
  const [swapIxns, lookupTablesAddresses] = await withdrawSwapper(
982
- swapInputs.inputAmountLamports,
1041
+ swapInputs.inputAmountLamports.toNumber(),
983
1042
  swapInputs.inputMint,
984
1043
  swapInputs.outputMint,
985
1044
  slippagePct
@@ -999,7 +1058,7 @@ export const getWithdrawWithLeverageIxns = async (props: {
999
1058
 
1000
1059
  const ixns = [
1001
1060
  ...budgetIxns,
1002
- ...createAtasIxns,
1061
+ ...createAtaIxs,
1003
1062
  ...fillWsolAtaIxns,
1004
1063
  ...[flashBorrowIxn],
1005
1064
  ...repayAndWithdrawAction.setupIxs,
@@ -1009,7 +1068,7 @@ export const getWithdrawWithLeverageIxns = async (props: {
1009
1068
  ...repayAndWithdrawAction.cleanupIxs,
1010
1069
  ...swapInstructions,
1011
1070
  ...[flashRepayIxn],
1012
- ...closeAtasIxns,
1071
+ ...closeWsolAtaIxns,
1013
1072
  ];
1014
1073
 
1015
1074
  // Send ixns and lookup tables
@@ -1066,9 +1125,7 @@ export const getAdjustLeverageSwapInputs = (props: {
1066
1125
 
1067
1126
  return {
1068
1127
  swapInputs: {
1069
- inputAmountLamports: toLamports(borrowAmount, debtReserve!.state.liquidity.mintDecimals.toNumber())
1070
- .ceil()
1071
- .toNumber(),
1128
+ inputAmountLamports: toLamports(borrowAmount, debtReserve!.state.liquidity.mintDecimals.toNumber()).ceil(),
1072
1129
  inputMint: debtTokenMint,
1073
1130
  outputMint: collTokenMint,
1074
1131
  },
@@ -1083,9 +1140,7 @@ export const getAdjustLeverageSwapInputs = (props: {
1083
1140
  inputAmountLamports: toLamports(
1084
1141
  withdrawAmountWithSlippageAndFlashLoanFee,
1085
1142
  collReserve!.state.liquidity.mintDecimals.toNumber()
1086
- )
1087
- .ceil()
1088
- .toNumber(),
1143
+ ).ceil(),
1089
1144
  inputMint: collTokenMint,
1090
1145
  outputMint: debtTokenMint,
1091
1146
  },
@@ -1157,7 +1212,7 @@ export const getAdjustLeverageIxns = async (props: {
1157
1212
  const currentLeverage = userObligation!.refreshedStats.leverage;
1158
1213
  const isDepositViaLeverage = targetLeverage.gte(new Decimal(currentLeverage));
1159
1214
 
1160
- let flashLoanFee = new Decimal(0);
1215
+ let flashLoanFee;
1161
1216
  if (isDepositViaLeverage) {
1162
1217
  flashLoanFee = collReserve!.getFlashLoanFee() || new Decimal(0);
1163
1218
  } else {
@@ -1310,8 +1365,7 @@ export const getIncreaseLeverageIxns = async (props: {
1310
1365
 
1311
1366
  // 1. Create atas & budget txns
1312
1367
  const budgetIxns = budgetAndPriorityFeeIxns || getComputeBudgetAndPriorityFeeIxns(3000000);
1313
- let mintsToCreateAtas: PublicKey[] = [];
1314
- let mintsToCreateAtasTokenPrograms: PublicKey[] = [];
1368
+ let mintsToCreateAtas: Array<{ mint: PublicKey; tokenProgram: PublicKey }>;
1315
1369
  if (collIsKtoken) {
1316
1370
  const secondTokenAta = strategy!.strategy.tokenAMint.equals(debtTokenMint)
1317
1371
  ? strategy!.strategy.tokenBMint
@@ -1323,27 +1377,45 @@ export const getIncreaseLeverageIxns = async (props: {
1323
1377
  : strategy!.strategy.tokenATokenProgram.equals(PublicKey.default)
1324
1378
  ? TOKEN_PROGRAM_ID
1325
1379
  : strategy!.strategy.tokenATokenProgram;
1326
- mintsToCreateAtas = [collTokenMint, debtTokenMint, collReserve!.getCTokenMint(), secondTokenAta];
1327
- mintsToCreateAtasTokenPrograms = [
1328
- collReserve!.getLiquidityTokenProgram(),
1329
- debtReserve!.getLiquidityTokenProgram(),
1330
- TOKEN_PROGRAM_ID,
1331
- secondTokenTokenProgarm,
1380
+ mintsToCreateAtas = [
1381
+ {
1382
+ mint: collTokenMint,
1383
+ tokenProgram: collReserve!.getLiquidityTokenProgram(),
1384
+ },
1385
+ {
1386
+ mint: debtTokenMint,
1387
+ tokenProgram: debtReserve!.getLiquidityTokenProgram(),
1388
+ },
1389
+ {
1390
+ mint: collReserve!.getCTokenMint(),
1391
+ tokenProgram: TOKEN_PROGRAM_ID,
1392
+ },
1393
+ {
1394
+ mint: secondTokenAta,
1395
+ tokenProgram: secondTokenTokenProgarm,
1396
+ },
1332
1397
  ];
1333
1398
  } else {
1334
- mintsToCreateAtas = [collTokenMint, debtTokenMint, collReserve!.getCTokenMint()];
1335
- mintsToCreateAtasTokenPrograms = [
1336
- collReserve!.getLiquidityTokenProgram(),
1337
- debtReserve!.getLiquidityTokenProgram(),
1338
- TOKEN_PROGRAM_ID,
1399
+ mintsToCreateAtas = [
1400
+ {
1401
+ mint: collTokenMint,
1402
+ tokenProgram: collReserve!.getLiquidityTokenProgram(),
1403
+ },
1404
+ {
1405
+ mint: debtTokenMint,
1406
+ tokenProgram: debtReserve!.getLiquidityTokenProgram(),
1407
+ },
1408
+ {
1409
+ mint: collReserve!.getCTokenMint(),
1410
+ tokenProgram: TOKEN_PROGRAM_ID,
1411
+ },
1339
1412
  ];
1340
1413
  }
1341
1414
 
1342
1415
  const {
1343
1416
  atas: [collTokenAta, debtTokenAta],
1344
- createAtasIxns,
1345
- closeAtasIxns,
1346
- } = await getAtasWithCreateIxnsIfMissing(connection, user, mintsToCreateAtas, mintsToCreateAtasTokenPrograms);
1417
+ createAtaIxs,
1418
+ } = await getAtasWithCreateIxnsIfMissing(connection, user, mintsToCreateAtas);
1347
1419
 
1348
1420
  // 2. Create borrow flash loan instruction
1349
1421
 
@@ -1355,7 +1427,7 @@ export const getIncreaseLeverageIxns = async (props: {
1355
1427
  // .toDecimalPlaces(debtReserve?.state.liquidity.mintDecimals.toNumber());
1356
1428
 
1357
1429
  const { flashBorrowIxn, flashRepayIxn } = getFlashLoanInstructions({
1358
- borrowIxnIndex: budgetIxns.length + createAtasIxns.length, // TODO: how about user metadata ixns
1430
+ borrowIxnIndex: budgetIxns.length + createAtaIxs.length, // TODO: how about user metadata ixns
1359
1431
  walletPublicKey: user,
1360
1432
  lendingMarketAuthority: kaminoMarket.getLendingMarketAuthority(),
1361
1433
  lendingMarketAddress: kaminoMarket.getAddress(),
@@ -1423,7 +1495,7 @@ export const getIncreaseLeverageIxns = async (props: {
1423
1495
 
1424
1496
  const klendIxns = [
1425
1497
  ...budgetIxns,
1426
- ...createAtasIxns,
1498
+ ...createAtaIxs,
1427
1499
  ...[flashBorrowIxn],
1428
1500
  ...depositAction.setupIxs,
1429
1501
  ...depositAction.lendingIxs,
@@ -1432,7 +1504,6 @@ export const getIncreaseLeverageIxns = async (props: {
1432
1504
  ...borrowAction.lendingIxs,
1433
1505
  ...borrowAction.cleanupIxs,
1434
1506
  ...[flashRepayIxn],
1435
- ...closeAtasIxns,
1436
1507
  ];
1437
1508
 
1438
1509
  const uniqueAccounts = new PublicKeySet<PublicKey>([]);
@@ -1448,7 +1519,11 @@ export const getIncreaseLeverageIxns = async (props: {
1448
1519
  return {
1449
1520
  ixns: [],
1450
1521
  lookupTablesAddresses: [],
1451
- swapInputs: { inputAmountLamports: 0, inputMint: PublicKey.default, outputMint: PublicKey.default },
1522
+ swapInputs: {
1523
+ inputAmountLamports: new Decimal('0'),
1524
+ inputMint: PublicKey.default,
1525
+ outputMint: PublicKey.default,
1526
+ },
1452
1527
  totalKlendAccounts: totalKlendAccounts,
1453
1528
  };
1454
1529
  }
@@ -1474,15 +1549,16 @@ export const getIncreaseLeverageIxns = async (props: {
1474
1549
  }
1475
1550
 
1476
1551
  const swapInputs: SwapInputs = {
1477
- inputAmountLamports: toLamports(!collIsKtoken ? borrowAmount : amountToFashBorrowDebt, debtReserve!.stats.decimals)
1478
- .ceil()
1479
- .toNumber(),
1552
+ inputAmountLamports: toLamports(
1553
+ !collIsKtoken ? borrowAmount : amountToFashBorrowDebt,
1554
+ debtReserve!.stats.decimals
1555
+ ).ceil(),
1480
1556
  inputMint: debtTokenMint,
1481
1557
  outputMint: collTokenMint,
1482
1558
  };
1483
1559
 
1484
1560
  const [swapIxns, lookupTablesAddresses] = await depositSwapper(
1485
- swapInputs.inputAmountLamports,
1561
+ swapInputs.inputAmountLamports.toNumber(),
1486
1562
  swapInputs.inputMint,
1487
1563
  swapInputs.outputMint,
1488
1564
  slippagePct,
@@ -1494,7 +1570,7 @@ export const getIncreaseLeverageIxns = async (props: {
1494
1570
  const ixns = !collIsKtoken
1495
1571
  ? [
1496
1572
  ...budgetIxns,
1497
- ...createAtasIxns,
1573
+ ...createAtaIxs,
1498
1574
  ...[flashBorrowIxn],
1499
1575
  ...depositAction.setupIxs,
1500
1576
  ...depositAction.lendingIxs,
@@ -1504,11 +1580,10 @@ export const getIncreaseLeverageIxns = async (props: {
1504
1580
  ...borrowAction.cleanupIxs,
1505
1581
  ...swapInstructions,
1506
1582
  ...[flashRepayIxn],
1507
- ...closeAtasIxns,
1508
1583
  ]
1509
1584
  : [
1510
1585
  ...budgetIxns,
1511
- ...createAtasIxns,
1586
+ ...createAtaIxs,
1512
1587
  ...[flashBorrowIxn],
1513
1588
  ...swapInstructions,
1514
1589
  ...depositAction.setupIxs,
@@ -1518,7 +1593,6 @@ export const getIncreaseLeverageIxns = async (props: {
1518
1593
  ...borrowAction.lendingIxs,
1519
1594
  ...borrowAction.cleanupIxs,
1520
1595
  ...[flashRepayIxn],
1521
- ...closeAtasIxns,
1522
1596
  ];
1523
1597
 
1524
1598
  ixns.forEach((ixn, i) => {
@@ -1599,8 +1673,7 @@ export const getDecreaseLeverageIxns = async (props: {
1599
1673
 
1600
1674
  // 1. Create atas & budget txns
1601
1675
  const budgetIxns = budgetAndPriorityFeeIxns || getComputeBudgetAndPriorityFeeIxns(3000000);
1602
- let mintsToCreateAtas: PublicKey[] = [];
1603
- let mintsToCreateAtasTokenPrograms: PublicKey[] = [];
1676
+ let mintsToCreateAtas: Array<{ mint: PublicKey; tokenProgram: PublicKey }>;
1604
1677
  if (collIsKtoken) {
1605
1678
  const secondTokenAta = strategy!.strategy.tokenAMint.equals(debtTokenMint)
1606
1679
  ? strategy!.strategy.tokenBMint
@@ -1612,26 +1685,44 @@ export const getDecreaseLeverageIxns = async (props: {
1612
1685
  : strategy!.strategy.tokenATokenProgram.equals(PublicKey.default)
1613
1686
  ? TOKEN_PROGRAM_ID
1614
1687
  : strategy!.strategy.tokenATokenProgram;
1615
- mintsToCreateAtas = [collTokenMint, debtTokenMint, collReserve!.getCTokenMint(), secondTokenAta];
1616
- mintsToCreateAtasTokenPrograms = [
1617
- collReserve!.getLiquidityTokenProgram(),
1618
- debtReserve!.getLiquidityTokenProgram(),
1619
- TOKEN_PROGRAM_ID,
1620
- secondTokenTokenProgarm,
1688
+ mintsToCreateAtas = [
1689
+ {
1690
+ mint: collTokenMint,
1691
+ tokenProgram: collReserve!.getLiquidityTokenProgram(),
1692
+ },
1693
+ {
1694
+ mint: debtTokenMint,
1695
+ tokenProgram: debtReserve!.getLiquidityTokenProgram(),
1696
+ },
1697
+ {
1698
+ mint: collReserve!.getCTokenMint(),
1699
+ tokenProgram: TOKEN_PROGRAM_ID,
1700
+ },
1701
+ {
1702
+ mint: secondTokenAta,
1703
+ tokenProgram: secondTokenTokenProgarm,
1704
+ },
1621
1705
  ];
1622
1706
  } else {
1623
- mintsToCreateAtas = [collTokenMint, debtTokenMint, collReserve!.getCTokenMint()];
1624
- mintsToCreateAtasTokenPrograms = [
1625
- collReserve!.getLiquidityTokenProgram(),
1626
- debtReserve!.getLiquidityTokenProgram(),
1627
- TOKEN_PROGRAM_ID,
1707
+ mintsToCreateAtas = [
1708
+ {
1709
+ mint: collTokenMint,
1710
+ tokenProgram: collReserve!.getLiquidityTokenProgram(),
1711
+ },
1712
+ {
1713
+ mint: debtTokenMint,
1714
+ tokenProgram: debtReserve!.getLiquidityTokenProgram(),
1715
+ },
1716
+ {
1717
+ mint: collReserve!.getCTokenMint(),
1718
+ tokenProgram: TOKEN_PROGRAM_ID,
1719
+ },
1628
1720
  ];
1629
1721
  }
1630
1722
  const {
1631
1723
  atas: [, debtTokenAta],
1632
- createAtasIxns,
1633
- closeAtasIxns,
1634
- } = await getAtasWithCreateIxnsIfMissing(connection, user, mintsToCreateAtas, mintsToCreateAtasTokenPrograms);
1724
+ createAtaIxs,
1725
+ } = await getAtasWithCreateIxnsIfMissing(connection, user, mintsToCreateAtas);
1635
1726
 
1636
1727
  // TODO: Mihai/Marius check if we can improve this logic and not convert any SOL
1637
1728
  // This is here so that we have enough wsol to repay in case the kAB swapped to sol after estimates is not enough
@@ -1640,7 +1731,6 @@ export const getDecreaseLeverageIxns = async (props: {
1640
1731
  const wsolAta = await getAssociatedTokenAddress(WRAPPED_SOL_MINT, user, false);
1641
1732
  closeWsolAtaIxns.push(createCloseAccountInstruction(wsolAta, user, user, [], TOKEN_PROGRAM_ID));
1642
1733
  }
1643
- closeAtasIxns.push(...closeWsolAtaIxns);
1644
1734
 
1645
1735
  const fillWsolAtaIxns: TransactionInstruction[] = [];
1646
1736
  if (debtTokenMint.equals(WRAPPED_SOL_MINT)) {
@@ -1653,7 +1743,7 @@ export const getDecreaseLeverageIxns = async (props: {
1653
1743
 
1654
1744
  // 3. Flash borrow & repay amount to repay (debt)
1655
1745
  const { flashBorrowIxn, flashRepayIxn } = getFlashLoanInstructions({
1656
- borrowIxnIndex: budgetIxns.length + createAtasIxns.length + fillWsolAtaIxns.length,
1746
+ borrowIxnIndex: budgetIxns.length + createAtaIxs.length + fillWsolAtaIxns.length,
1657
1747
  walletPublicKey: user,
1658
1748
  lendingMarketAuthority: kaminoMarket.getLendingMarketAuthority(),
1659
1749
  lendingMarketAddress: kaminoMarket.getAddress(),
@@ -1717,7 +1807,7 @@ export const getDecreaseLeverageIxns = async (props: {
1717
1807
 
1718
1808
  const klendIxns = [
1719
1809
  ...budgetIxns,
1720
- ...createAtasIxns,
1810
+ ...createAtaIxs,
1721
1811
  ...fillWsolAtaIxns,
1722
1812
  ...[flashBorrowIxn],
1723
1813
  ...repayAction.setupIxs,
@@ -1727,23 +1817,22 @@ export const getDecreaseLeverageIxns = async (props: {
1727
1817
  ...withdrawAction.lendingIxs,
1728
1818
  ...withdrawAction.cleanupIxs,
1729
1819
  ...[flashRepayIxn],
1730
- ...closeAtasIxns,
1820
+ ...closeWsolAtaIxns,
1731
1821
  ];
1732
1822
 
1733
- const uniqueAccounts = new PublicKeySet<PublicKey>([]);
1734
- klendIxns.forEach((ixn) => {
1735
- ixn.keys.forEach((key) => {
1736
- uniqueAccounts.add(key.pubkey);
1737
- });
1738
- });
1739
- const totalKlendAccounts = uniqueAccounts.toArray().length;
1823
+ const uniqueAccs = uniqueAccounts(klendIxns);
1824
+ const totalKlendAccounts = uniqueAccs.length;
1740
1825
 
1741
1826
  // return early to avoid extra swapper calls
1742
1827
  if (getTotalKlendAccountsOnly) {
1743
1828
  return {
1744
1829
  ixns: [],
1745
1830
  lookupTablesAddresses: [],
1746
- swapInputs: { inputAmountLamports: 0, inputMint: PublicKey.default, outputMint: PublicKey.default },
1831
+ swapInputs: {
1832
+ inputAmountLamports: new Decimal('0'),
1833
+ inputMint: PublicKey.default,
1834
+ outputMint: PublicKey.default,
1835
+ },
1747
1836
  totalKlendAccounts: totalKlendAccounts,
1748
1837
  };
1749
1838
  }
@@ -1760,16 +1849,14 @@ export const getDecreaseLeverageIxns = async (props: {
1760
1849
  }
1761
1850
 
1762
1851
  const swapInputs: SwapInputs = {
1763
- inputAmountLamports: toLamports(withdrawAmountWithSlippageAndFlashLoanFee, collReserve!.stats.decimals)
1764
- .ceil()
1765
- .toNumber(),
1852
+ inputAmountLamports: toLamports(withdrawAmountWithSlippageAndFlashLoanFee, collReserve!.stats.decimals).ceil(),
1766
1853
  inputMint: collTokenMint,
1767
1854
  outputMint: debtTokenMint,
1768
1855
  };
1769
1856
 
1770
1857
  // 5. Get swap ixns
1771
1858
  const [swapIxns, lookupTablesAddresses] = await withdrawSwapper(
1772
- swapInputs.inputAmountLamports,
1859
+ swapInputs.inputAmountLamports.toNumber(),
1773
1860
  swapInputs.inputMint,
1774
1861
  swapInputs.outputMint,
1775
1862
  slippagePct
@@ -1779,7 +1866,7 @@ export const getDecreaseLeverageIxns = async (props: {
1779
1866
 
1780
1867
  const ixns = [
1781
1868
  ...budgetIxns,
1782
- ...createAtasIxns,
1869
+ ...createAtaIxs,
1783
1870
  ...fillWsolAtaIxns,
1784
1871
  ...[flashBorrowIxn],
1785
1872
  ...repayAction.setupIxs,
@@ -1790,7 +1877,7 @@ export const getDecreaseLeverageIxns = async (props: {
1790
1877
  ...withdrawAction.cleanupIxs,
1791
1878
  ...swapInstructions,
1792
1879
  ...[flashRepayIxn],
1793
- ...closeAtasIxns,
1880
+ ...closeWsolAtaIxns,
1794
1881
  ];
1795
1882
 
1796
1883
  ixns.forEach((ixn, i) => {