@kamino-finance/klend-sdk 5.11.2-beta.0 → 5.11.3-beta.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 (73) hide show
  1. package/dist/classes/action.d.ts +25 -35
  2. package/dist/classes/action.d.ts.map +1 -1
  3. package/dist/classes/action.js +92 -388
  4. package/dist/classes/action.js.map +1 -1
  5. package/dist/classes/lut_utils.d.ts +29 -0
  6. package/dist/classes/lut_utils.d.ts.map +1 -0
  7. package/dist/classes/lut_utils.js +62 -0
  8. package/dist/classes/lut_utils.js.map +1 -0
  9. package/dist/classes/manager.d.ts +1 -1
  10. package/dist/classes/manager.js +1 -1
  11. package/dist/classes/market.d.ts +3 -3
  12. package/dist/classes/market.d.ts.map +1 -1
  13. package/dist/classes/market.js +30 -16
  14. package/dist/classes/market.js.map +1 -1
  15. package/dist/classes/obligation.d.ts +3 -1
  16. package/dist/classes/obligation.d.ts.map +1 -1
  17. package/dist/classes/obligation.js +6 -1
  18. package/dist/classes/obligation.js.map +1 -1
  19. package/dist/classes/vault.js +6 -6
  20. package/dist/classes/vault.js.map +1 -1
  21. package/dist/lending_operations/repay_with_collateral_calcs.d.ts.map +1 -1
  22. package/dist/lending_operations/repay_with_collateral_calcs.js +5 -9
  23. package/dist/lending_operations/repay_with_collateral_calcs.js.map +1 -1
  24. package/dist/lending_operations/repay_with_collateral_operations.d.ts +4 -9
  25. package/dist/lending_operations/repay_with_collateral_operations.d.ts.map +1 -1
  26. package/dist/lending_operations/repay_with_collateral_operations.js +10 -33
  27. package/dist/lending_operations/repay_with_collateral_operations.js.map +1 -1
  28. package/dist/lending_operations/swap_collateral_operations.d.ts +2 -2
  29. package/dist/lending_operations/swap_collateral_operations.d.ts.map +1 -1
  30. package/dist/lending_operations/swap_collateral_operations.js +11 -6
  31. package/dist/lending_operations/swap_collateral_operations.js.map +1 -1
  32. package/dist/leverage/operations.d.ts +9 -7
  33. package/dist/leverage/operations.d.ts.map +1 -1
  34. package/dist/leverage/operations.js +78 -66
  35. package/dist/leverage/operations.js.map +1 -1
  36. package/dist/leverage/types.d.ts +4 -4
  37. package/dist/leverage/types.d.ts.map +1 -1
  38. package/dist/utils/ObligationType.d.ts +1 -1
  39. package/dist/utils/ObligationType.d.ts.map +1 -1
  40. package/dist/utils/lookupTable.d.ts +0 -27
  41. package/dist/utils/lookupTable.d.ts.map +1 -1
  42. package/dist/utils/lookupTable.js +0 -58
  43. package/dist/utils/lookupTable.js.map +1 -1
  44. package/dist/utils/managerTypes.d.ts.map +1 -1
  45. package/dist/utils/managerTypes.js +7 -52
  46. package/dist/utils/managerTypes.js.map +1 -1
  47. package/dist/utils/oracle.d.ts +3 -3
  48. package/dist/utils/oracle.d.ts.map +1 -1
  49. package/dist/utils/seeds.d.ts +1 -11
  50. package/dist/utils/seeds.d.ts.map +1 -1
  51. package/dist/utils/seeds.js +3 -13
  52. package/dist/utils/seeds.js.map +1 -1
  53. package/dist/utils/userMetadata.js +6 -6
  54. package/dist/utils/userMetadata.js.map +1 -1
  55. package/package.json +2 -2
  56. package/src/classes/action.ts +116 -532
  57. package/src/classes/lut_utils.ts +63 -0
  58. package/src/classes/manager.ts +1 -1
  59. package/src/classes/market.ts +34 -25
  60. package/src/classes/obligation.ts +7 -1
  61. package/src/classes/vault.ts +1 -1
  62. package/src/client.ts +8 -3
  63. package/src/lending_operations/repay_with_collateral_calcs.ts +5 -14
  64. package/src/lending_operations/repay_with_collateral_operations.ts +33 -72
  65. package/src/lending_operations/swap_collateral_operations.ts +19 -7
  66. package/src/leverage/operations.ts +114 -66
  67. package/src/leverage/types.ts +4 -4
  68. package/src/utils/ObligationType.ts +1 -1
  69. package/src/utils/lookupTable.ts +0 -62
  70. package/src/utils/managerTypes.ts +10 -52
  71. package/src/utils/oracle.ts +2 -2
  72. package/src/utils/seeds.ts +4 -14
  73. package/src/utils/userMetadata.ts +14 -14
@@ -21,7 +21,6 @@ import BN from 'bn.js';
21
21
  import Decimal from 'decimal.js';
22
22
  import {
23
23
  borrowObligationLiquidity,
24
- depositAndWithdraw,
25
24
  borrowObligationLiquidityV2,
26
25
  depositObligationCollateral,
27
26
  depositObligationCollateralV2,
@@ -42,7 +41,6 @@ import {
42
41
  RefreshObligationFarmsForReserveAccounts,
43
42
  RefreshObligationFarmsForReserveArgs,
44
43
  refreshReserve,
45
- repayAndWithdrawAndRedeem,
46
44
  repayObligationLiquidity,
47
45
  repayObligationLiquidityV2,
48
46
  requestElevationGroup,
@@ -63,11 +61,11 @@ import {
63
61
  isNotNullPubkey,
64
62
  PublicKeySet,
65
63
  getAssociatedTokenAddress,
66
- ScopeRefresh,
64
+ ScopePriceRefreshConfig,
67
65
  createAtasIdempotent,
68
66
  obligationFarmStatePda,
69
67
  } from '../utils';
70
- import { KaminoMarket } from './market';
68
+ import { getTokenIdsForScopeRefresh, KaminoMarket } from './market';
71
69
  import { KaminoObligation } from './obligation';
72
70
  import { KaminoReserve } from './reserve';
73
71
  import { ReserveFarmKind } from '../idl_codegen/types';
@@ -75,7 +73,7 @@ import { farmsId } from '@kamino-finance/farms-sdk';
75
73
  import { Reserve } from '../idl_codegen/accounts';
76
74
  import { VanillaObligation } from '../utils/ObligationType';
77
75
  import { PROGRAM_ID } from '../lib';
78
- import { U16_MAX } from '@kamino-finance/scope-sdk';
76
+ import { Scope } from '@kamino-finance/scope-sdk';
79
77
 
80
78
  const SOL_PADDING_FOR_INTEREST = new BN('1000000');
81
79
 
@@ -92,9 +90,7 @@ export type ActionType =
92
90
  | 'repayAndWithdraw'
93
91
  | 'refreshObligation'
94
92
  | 'requestElevationGroup'
95
- | 'withdrawReferrerFees'
96
- | 'repayAndWithdrawV2'
97
- | 'depositAndWithdraw';
93
+ | 'withdrawReferrerFees';
98
94
 
99
95
  export type AuxiliaryIx = 'setup' | 'inBetween' | 'cleanup';
100
96
 
@@ -415,6 +411,7 @@ export class KaminoAction {
415
411
  owner: PublicKey,
416
412
  obligation: KaminoObligation | ObligationType,
417
413
  useV2Ixs: boolean,
414
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
418
415
  extraComputeBudget: number = 1_000_000, // if > 0 then adds the ixn
419
416
  includeAtaIxns: boolean = true, // if true it includes create and close wsol and token atas,
420
417
  requestElevationGroup: boolean = false, // to be requested *before* the deposit
@@ -422,7 +419,6 @@ export class KaminoAction {
422
419
  createLookupTable: boolean = true,
423
420
  referrer: PublicKey = PublicKey.default,
424
421
  currentSlot: number = 0,
425
- scopeRefresh: ScopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' },
426
422
  overrideElevationGroupRequest: number | undefined = undefined // if set, when an elevationgroup request is made, it will use this value
427
423
  ) {
428
424
  const axn = await KaminoAction.initialize(
@@ -441,16 +437,6 @@ export class KaminoAction {
441
437
  axn.addComputeBudgetIxn(extraComputeBudget);
442
438
  }
443
439
 
444
- const allReserves = new PublicKeySet<PublicKey>([
445
- ...axn.depositReserves,
446
- ...axn.borrowReserves,
447
- axn.reserve.address,
448
- ]).toArray();
449
- const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
450
-
451
- if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
452
- await axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
453
- }
454
440
  await axn.addSupportIxs(
455
441
  'deposit',
456
442
  includeAtaIxns,
@@ -458,6 +444,7 @@ export class KaminoAction {
458
444
  includeUserMetadata,
459
445
  addInitObligationForFarm,
460
446
  useV2Ixs,
447
+ scopeRefreshConfig,
461
448
  createLookupTable,
462
449
  undefined,
463
450
  overrideElevationGroupRequest
@@ -472,36 +459,10 @@ export class KaminoAction {
472
459
  return axn;
473
460
  }
474
461
 
475
- getTokenIdsForScopeRefresh(kaminoMarket: KaminoMarket, reserves: PublicKey[]): number[] {
476
- const tokenIds: number[] = [];
477
-
478
- for (const reserveAddress of reserves) {
479
- const reserve = kaminoMarket.getReserveByAddress(reserveAddress);
480
- if (!reserve) {
481
- throw new Error(`Reserve not found for reserve ${reserveAddress.toBase58()}`);
482
- }
483
-
484
- if (!reserve.state.config.tokenInfo.scopeConfiguration.priceFeed.equals(PublicKey.default)) {
485
- reserve.state.config.tokenInfo.scopeConfiguration.priceChain.map((x) => {
486
- if (x !== U16_MAX) {
487
- tokenIds.push(x);
488
- }
489
- });
490
- reserve.state.config.tokenInfo.scopeConfiguration.twapChain.map((x) => {
491
- if (x !== U16_MAX) {
492
- tokenIds.push(x);
493
- }
494
- });
495
- }
496
- }
497
-
498
- return tokenIds;
499
- }
500
-
501
- async addScopeRefreshIxs(tokens: number[], feed: string = 'hubble') {
502
- this.preTxnIxsLabels.unshift(`refreshScopePrices`);
503
- this.preTxnIxs.unshift(
504
- await this.kaminoMarket.scope.refreshPriceListIx(
462
+ async addScopeRefreshIxs(scope: Scope, tokens: number[], feed: string = 'hubble') {
463
+ this.setupIxsLabels.unshift(`refreshScopePrices`);
464
+ this.setupIxs.unshift(
465
+ await scope.refreshPriceListIx(
505
466
  {
506
467
  feed: feed,
507
468
  },
@@ -517,6 +478,7 @@ export class KaminoAction {
517
478
  owner: PublicKey,
518
479
  obligation: KaminoObligation | ObligationType,
519
480
  useV2Ixs: boolean,
481
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
520
482
  extraComputeBudget: number = 1_000_000, // if > 0 then adds the ixn
521
483
  includeAtaIxns: boolean = true, // if true it includes create and close wsol and token atas,
522
484
  requestElevationGroup: boolean = false,
@@ -524,7 +486,6 @@ export class KaminoAction {
524
486
  createLookupTable: boolean = true,
525
487
  referrer: PublicKey = PublicKey.default,
526
488
  currentSlot: number = 0,
527
- scopeRefresh: ScopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' },
528
489
  overrideElevationGroupRequest: number | undefined = undefined // if set, when an elevationgroup request is made, it will use this value
529
490
  ) {
530
491
  const axn = await KaminoAction.initialize(
@@ -542,17 +503,6 @@ export class KaminoAction {
542
503
  axn.addComputeBudgetIxn(extraComputeBudget);
543
504
  }
544
505
 
545
- const allReserves = new PublicKeySet<PublicKey>([
546
- ...axn.depositReserves,
547
- ...axn.borrowReserves,
548
- axn.reserve.address,
549
- ]).toArray();
550
- const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
551
-
552
- if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
553
- await axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
554
- }
555
-
556
506
  await axn.addSupportIxs(
557
507
  'borrow',
558
508
  includeAtaIxns,
@@ -560,6 +510,7 @@ export class KaminoAction {
560
510
  includeUserMetadata,
561
511
  addInitObligationForFarm,
562
512
  useV2Ixs,
513
+ scopeRefreshConfig,
563
514
  createLookupTable,
564
515
  undefined,
565
516
  overrideElevationGroupRequest
@@ -580,12 +531,12 @@ export class KaminoAction {
580
531
  mint: PublicKey,
581
532
  owner: PublicKey,
582
533
  obligation: KaminoObligation | ObligationType,
534
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
583
535
  extraComputeBudget: number = 1_000_000, // if > 0 then adds the ixn
584
536
  includeAtaIxns: boolean = true, // if true it includes create and close wsol and token atas
585
537
  requestElevationGroup: boolean = false,
586
538
  referrer: PublicKey = PublicKey.default,
587
- currentSlot: number = 0,
588
- scopeRefresh: ScopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }
539
+ currentSlot: number = 0
589
540
  ) {
590
541
  const axn = await KaminoAction.initialize(
591
542
  'mint',
@@ -603,17 +554,6 @@ export class KaminoAction {
603
554
  axn.addComputeBudgetIxn(extraComputeBudget);
604
555
  }
605
556
 
606
- const allReserves = new PublicKeySet<PublicKey>([
607
- ...axn.depositReserves,
608
- ...axn.borrowReserves,
609
- axn.reserve.address,
610
- ]).toArray();
611
- const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
612
-
613
- if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
614
- await axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
615
- }
616
-
617
557
  await axn.addSupportIxs(
618
558
  'mint',
619
559
  includeAtaIxns,
@@ -621,6 +561,7 @@ export class KaminoAction {
621
561
  false,
622
562
  addInitObligationForFarm,
623
563
  false,
564
+ scopeRefreshConfig,
624
565
  false
625
566
  );
626
567
  axn.addDepositReserveLiquidityIx();
@@ -634,12 +575,12 @@ export class KaminoAction {
634
575
  mint: PublicKey,
635
576
  owner: PublicKey,
636
577
  obligation: KaminoObligation | ObligationType,
578
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
637
579
  extraComputeBudget: number = 1_000_000, // if > 0 then adds the ixn
638
580
  includeAtaIxns: boolean = true, // if true it includes create and close wsol and token atas
639
581
  requestElevationGroup: boolean = false,
640
582
  referrer: PublicKey = PublicKey.default,
641
- currentSlot: number = 0,
642
- scopeRefresh: ScopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }
583
+ currentSlot: number = 0
643
584
  ) {
644
585
  const axn = await KaminoAction.initialize(
645
586
  'redeem',
@@ -657,17 +598,6 @@ export class KaminoAction {
657
598
  axn.addComputeBudgetIxn(extraComputeBudget);
658
599
  }
659
600
 
660
- const allReserves = new PublicKeySet<PublicKey>([
661
- ...axn.depositReserves,
662
- ...axn.borrowReserves,
663
- axn.reserve.address,
664
- ]).toArray();
665
- const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
666
-
667
- if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
668
- await axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
669
- }
670
-
671
601
  await axn.addSupportIxs(
672
602
  'redeem',
673
603
  includeAtaIxns,
@@ -675,6 +605,7 @@ export class KaminoAction {
675
605
  false,
676
606
  addInitObligationForFarm,
677
607
  false,
608
+ scopeRefreshConfig,
678
609
  false
679
610
  );
680
611
  axn.addRedeemReserveCollateralIx();
@@ -689,14 +620,14 @@ export class KaminoAction {
689
620
  owner: PublicKey,
690
621
  obligation: KaminoObligation | ObligationType,
691
622
  useV2Ixs: boolean,
623
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
692
624
  extraComputeBudget: number = 1_000_000, // if > 0 then adds the ixn
693
625
  includeAtaIxns: boolean = true, // if true it includes create and close wsol and token atas
694
626
  requestElevationGroup: boolean = false,
695
627
  includeUserMetadata: boolean = true, // if true it includes user metadata
696
628
  createLookupTable: boolean = true,
697
629
  referrer: PublicKey = PublicKey.default,
698
- currentSlot: number = 0,
699
- scopeRefresh: ScopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }
630
+ currentSlot: number = 0
700
631
  ) {
701
632
  const axn = await KaminoAction.initialize(
702
633
  'depositCollateral',
@@ -714,17 +645,6 @@ export class KaminoAction {
714
645
  axn.addComputeBudgetIxn(extraComputeBudget);
715
646
  }
716
647
 
717
- const allReserves = new PublicKeySet<PublicKey>([
718
- ...axn.depositReserves,
719
- ...axn.borrowReserves,
720
- axn.reserve.address,
721
- ]).toArray();
722
- const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
723
-
724
- if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
725
- await axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
726
- }
727
-
728
648
  await axn.addSupportIxs(
729
649
  'depositCollateral',
730
650
  includeAtaIxns,
@@ -732,6 +652,7 @@ export class KaminoAction {
732
652
  includeUserMetadata,
733
653
  addInitObligationForFarm,
734
654
  useV2Ixs,
655
+ scopeRefreshConfig,
735
656
  createLookupTable
736
657
  );
737
658
  if (useV2Ixs) {
@@ -752,14 +673,14 @@ export class KaminoAction {
752
673
  payer: PublicKey,
753
674
  obligation: KaminoObligation | ObligationType,
754
675
  useV2Ixs: boolean,
676
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
755
677
  extraComputeBudget: number = 1_000_000, // if > 0 then adds the ixn
756
678
  includeAtaIxns: boolean = true, // if true it includes create and close wsol and token atas,
757
679
  requestElevationGroup: boolean = false,
758
680
  includeUserMetadata: boolean = true, // if true it includes user metadata,
759
681
  createLookupTable: boolean = true,
760
682
  referrer: PublicKey = PublicKey.default,
761
- currentSlot: number = 0,
762
- scopeRefresh: ScopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }
683
+ currentSlot: number = 0
763
684
  ) {
764
685
  const axn = await KaminoAction.initializeMultiTokenAction(
765
686
  kaminoMarket,
@@ -782,18 +703,6 @@ export class KaminoAction {
782
703
  axn.addComputeBudgetIxn(extraComputeBudget);
783
704
  }
784
705
 
785
- const allReserves = new PublicKeySet<PublicKey>([
786
- ...axn.depositReserves,
787
- ...axn.borrowReserves,
788
- axn.reserve.address,
789
- axn.outflowReserve!.address,
790
- ]).toArray();
791
- const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
792
-
793
- if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
794
- await axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
795
- }
796
-
797
706
  await axn.addSupportIxs(
798
707
  'deposit',
799
708
  includeAtaIxns,
@@ -801,6 +710,7 @@ export class KaminoAction {
801
710
  includeUserMetadata,
802
711
  addInitObligationForFarmForDeposit,
803
712
  useV2Ixs,
713
+ undefined,
804
714
  createLookupTable,
805
715
  twoTokenAction
806
716
  );
@@ -818,132 +728,20 @@ export class KaminoAction {
818
728
  useV2Ixs
819
729
  );
820
730
  axn.addRefreshFarmsCleanupTxnIxsToCleanupIxs();
821
- return axn;
822
- }
823
-
824
- static async buildDepositAndWithdrawV2Txns(
825
- kaminoMarket: KaminoMarket,
826
- depositAmount: string | BN,
827
- depositMint: PublicKey,
828
- withdrawAmount: string | BN,
829
- withdrawMint: PublicKey,
830
- payer: PublicKey,
831
- currentSlot: number,
832
- obligation: KaminoObligation | ObligationType,
833
- extraComputeBudget: number = 1_000_000, // if > 0 then adds the ixn
834
- includeAtaIxns: boolean = true, // if true it includes create and close wsol and token atas,
835
- requestElevationGroup: boolean = false,
836
- includeUserMetadata: boolean = true, // if true it includes user metadata,
837
- referrer: PublicKey = PublicKey.default,
838
- scopeRefresh: ScopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }
839
- ) {
840
- const axn = await KaminoAction.initializeMultiTokenAction(
841
- kaminoMarket,
842
- 'depositAndWithdraw',
843
- depositAmount,
844
- depositMint,
845
- withdrawMint,
846
- payer,
847
- payer,
848
- obligation,
849
- withdrawAmount,
850
- referrer,
851
- currentSlot
852
- );
853
- const addInitObligationForFarm = true;
854
- const twoTokenAction = true;
855
- if (extraComputeBudget > 0) {
856
- axn.addComputeBudgetIxn(extraComputeBudget);
857
- }
858
731
 
732
+ // Create the scope refresh ixn in here to ensure it's the first ixn in the txn
859
733
  const allReserves = new PublicKeySet<PublicKey>([
860
734
  ...axn.depositReserves,
861
735
  ...axn.borrowReserves,
862
736
  axn.reserve.address,
863
- axn.outflowReserve!.address,
737
+ ...(axn.outflowReserve ? [axn.outflowReserve.address] : []),
738
+ ...(axn.preLoadedDepositReservesSameTx ? axn.preLoadedDepositReservesSameTx : []),
864
739
  ]).toArray();
865
- const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
740
+ const tokenIds = getTokenIdsForScopeRefresh(axn.kaminoMarket, allReserves);
866
741
 
867
- if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
868
- await axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
742
+ if (tokenIds.length > 0 && scopeRefreshConfig) {
743
+ await axn.addScopeRefreshIxs(scopeRefreshConfig.scope, tokenIds, scopeRefreshConfig.scopeFeed);
869
744
  }
870
-
871
- await axn.addSupportIxs(
872
- 'depositAndWithdraw',
873
- includeAtaIxns,
874
- requestElevationGroup,
875
- includeUserMetadata,
876
- addInitObligationForFarm,
877
- true,
878
- twoTokenAction
879
- );
880
- const withdrawCollateralAmount = axn.getWithdrawCollateralAmount(axn.outflowReserve!, axn.outflowAmount!);
881
- axn.addDepositAndWithdrawV2Ixs(withdrawCollateralAmount);
882
-
883
- return axn;
884
- }
885
-
886
- static async buildRepayAndWithdrawV2Txns(
887
- kaminoMarket: KaminoMarket,
888
- repayAmount: string | BN,
889
- repayMint: PublicKey,
890
- withdrawAmount: string | BN,
891
- withdrawMint: PublicKey,
892
- payer: PublicKey,
893
- currentSlot: number,
894
- obligation: KaminoObligation | ObligationType,
895
- extraComputeBudget: number = 1_000_000, // if > 0 then adds the ixn
896
- includeAtaIxns: boolean = true, // if true it includes create and close wsol and token atas,
897
- requestElevationGroup: boolean = false,
898
- includeUserMetadata: boolean = true, // if true it includes user metadata,
899
- createLookupTable: boolean = true,
900
- referrer: PublicKey = PublicKey.default,
901
- scopeRefresh: ScopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }
902
- ) {
903
- const axn = await KaminoAction.initializeMultiTokenAction(
904
- kaminoMarket,
905
- 'repayAndWithdrawV2',
906
- repayAmount,
907
- repayMint,
908
- withdrawMint,
909
- payer,
910
- payer,
911
- obligation,
912
- withdrawAmount,
913
- referrer,
914
- currentSlot
915
- );
916
- const addInitObligationForFarm = true;
917
- const twoTokenAction = true;
918
- if (extraComputeBudget > 0) {
919
- axn.addComputeBudgetIxn(extraComputeBudget);
920
- }
921
-
922
- const allReserves = new PublicKeySet<PublicKey>([
923
- ...axn.depositReserves,
924
- ...axn.borrowReserves,
925
- axn.reserve.address,
926
- axn.outflowReserve!.address,
927
- ]).toArray();
928
- const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
929
-
930
- if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
931
- await axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
932
- }
933
-
934
- await axn.addSupportIxs(
935
- 'repayAndWithdrawV2',
936
- includeAtaIxns,
937
- requestElevationGroup,
938
- includeUserMetadata,
939
- addInitObligationForFarm,
940
- true,
941
- createLookupTable,
942
- twoTokenAction
943
- );
944
- const withdrawCollateralAmount = axn.getWithdrawCollateralAmount(axn.outflowReserve!, axn.outflowAmount!);
945
- axn.addRepayAndWithdrawV2Ixs(withdrawCollateralAmount);
946
-
947
745
  return axn;
948
746
  }
949
747
 
@@ -957,13 +755,13 @@ export class KaminoAction {
957
755
  currentSlot: number,
958
756
  obligation: KaminoObligation | ObligationType,
959
757
  useV2Ixs: boolean,
758
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
960
759
  extraComputeBudget: number = 1_000_000, // if > 0 then adds the ixn
961
760
  includeAtaIxns: boolean = true, // if true it includes create and close wsol and token atas,
962
761
  requestElevationGroup: boolean = false,
963
762
  includeUserMetadata: boolean = true, // if true it includes user metadata,
964
763
  createLookupTable: boolean = true,
965
- referrer: PublicKey = PublicKey.default,
966
- scopeRefresh: ScopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }
764
+ referrer: PublicKey = PublicKey.default
967
765
  ) {
968
766
  const axn = await KaminoAction.initializeMultiTokenAction(
969
767
  kaminoMarket,
@@ -985,18 +783,6 @@ export class KaminoAction {
985
783
  axn.addComputeBudgetIxn(extraComputeBudget);
986
784
  }
987
785
 
988
- const allReserves = new PublicKeySet<PublicKey>([
989
- ...axn.depositReserves,
990
- ...axn.borrowReserves,
991
- axn.reserve.address,
992
- axn.outflowReserve!.address,
993
- ]).toArray();
994
- const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
995
-
996
- if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
997
- await axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
998
- }
999
-
1000
786
  await axn.addSupportIxs(
1001
787
  'repay',
1002
788
  includeAtaIxns,
@@ -1004,6 +790,7 @@ export class KaminoAction {
1004
790
  includeUserMetadata,
1005
791
  addInitObligationForFarmForRepay,
1006
792
  useV2Ixs,
793
+ undefined,
1007
794
  createLookupTable,
1008
795
  twoTokenAction
1009
796
  );
@@ -1023,6 +810,19 @@ export class KaminoAction {
1023
810
  useV2Ixs
1024
811
  );
1025
812
  axn.addRefreshFarmsCleanupTxnIxsToCleanupIxs();
813
+ // Create the scope refresh ixn in here to ensure it's the first ixn in the txn
814
+ const allReserves = new PublicKeySet<PublicKey>([
815
+ ...axn.depositReserves,
816
+ ...axn.borrowReserves,
817
+ axn.reserve.address,
818
+ ...(axn.outflowReserve ? [axn.outflowReserve.address] : []),
819
+ ...(axn.preLoadedDepositReservesSameTx ? axn.preLoadedDepositReservesSameTx : []),
820
+ ]).toArray();
821
+ const tokenIds = getTokenIdsForScopeRefresh(axn.kaminoMarket, allReserves);
822
+
823
+ if (tokenIds.length > 0 && scopeRefreshConfig) {
824
+ await axn.addScopeRefreshIxs(scopeRefreshConfig.scope, tokenIds, scopeRefreshConfig.scopeFeed);
825
+ }
1026
826
  return axn;
1027
827
  }
1028
828
 
@@ -1033,6 +833,7 @@ export class KaminoAction {
1033
833
  owner: PublicKey,
1034
834
  obligation: KaminoObligation | ObligationType,
1035
835
  useV2Ixs: boolean,
836
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
1036
837
  extraComputeBudget: number = 1_000_000, // if > 0 then adds the ixn
1037
838
  includeAtaIxns: boolean = true, // if true it includes create and close wsol and token atas,
1038
839
  requestElevationGroup: boolean = false, // to be requested *after* the withdraw
@@ -1040,7 +841,6 @@ export class KaminoAction {
1040
841
  createLookupTable: boolean = true,
1041
842
  referrer: PublicKey = PublicKey.default,
1042
843
  currentSlot: number = 0,
1043
- scopeRefresh: ScopeRefresh | undefined = undefined,
1044
844
  overrideElevationGroupRequest?: number,
1045
845
  // Optional customizations which may be needed if the obligation was mutated by some previous ixn.
1046
846
  obligationCustomizations?: {
@@ -1066,17 +866,6 @@ export class KaminoAction {
1066
866
 
1067
867
  axn.depositReserves.push(...(obligationCustomizations?.addedDepositReserves || []));
1068
868
 
1069
- const allReserves = new PublicKeySet<PublicKey>([
1070
- ...axn.depositReserves,
1071
- ...axn.borrowReserves,
1072
- axn.reserve.address,
1073
- ]).toArray();
1074
- const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
1075
-
1076
- if (tokenIds.length > 0 && scopeRefresh && scopeRefresh.includeScopeRefresh) {
1077
- await axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
1078
- }
1079
-
1080
869
  await axn.addSupportIxs(
1081
870
  'withdraw',
1082
871
  includeAtaIxns,
@@ -1084,6 +873,7 @@ export class KaminoAction {
1084
873
  includeUserMetadata,
1085
874
  addInitObligationForFarm,
1086
875
  useV2Ixs,
876
+ scopeRefreshConfig,
1087
877
  createLookupTable,
1088
878
  false,
1089
879
  overrideElevationGroupRequest
@@ -1123,6 +913,7 @@ export class KaminoAction {
1123
913
  owner: PublicKey,
1124
914
  obligation: KaminoObligation | ObligationType,
1125
915
  useV2Ixs: boolean,
916
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
1126
917
  currentSlot: number,
1127
918
  payer: PublicKey | undefined = undefined,
1128
919
  extraComputeBudget: number = 1_000_000,
@@ -1130,8 +921,7 @@ export class KaminoAction {
1130
921
  requestElevationGroup: boolean = false,
1131
922
  includeUserMetadata: boolean = true,
1132
923
  createLookupTable: boolean = true,
1133
- referrer: PublicKey = PublicKey.default,
1134
- scopeRefresh: ScopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }
924
+ referrer: PublicKey = PublicKey.default
1135
925
  ) {
1136
926
  const axn = await KaminoAction.initialize(
1137
927
  'repay',
@@ -1150,17 +940,6 @@ export class KaminoAction {
1150
940
  axn.addComputeBudgetIxn(extraComputeBudget);
1151
941
  }
1152
942
 
1153
- const allReserves = new PublicKeySet<PublicKey>([
1154
- ...axn.depositReserves,
1155
- ...axn.borrowReserves,
1156
- axn.reserve.address,
1157
- ]).toArray();
1158
- const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
1159
-
1160
- if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
1161
- await axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
1162
- }
1163
-
1164
943
  await axn.addSupportIxs(
1165
944
  'repay',
1166
945
  includeAtaIxns,
@@ -1168,6 +947,7 @@ export class KaminoAction {
1168
947
  includeUserMetadata,
1169
948
  addInitObligationForFarm,
1170
949
  useV2Ixs,
950
+ scopeRefreshConfig,
1171
951
  createLookupTable
1172
952
  );
1173
953
  if (useV2Ixs) {
@@ -1190,6 +970,7 @@ export class KaminoAction {
1190
970
  obligationOwner: PublicKey,
1191
971
  obligation: KaminoObligation | ObligationType,
1192
972
  useV2Ixs: boolean,
973
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
1193
974
  extraComputeBudget: number = 1_000_000, // if > 0 then adds the ixn
1194
975
  includeAtaIxns: boolean = true, // if true it includes create and close wsol and token atas, and creates all other token atas if they don't exist
1195
976
  requestElevationGroup: boolean = false,
@@ -1197,8 +978,7 @@ export class KaminoAction {
1197
978
  createLookupTable: boolean = true,
1198
979
  referrer: PublicKey = PublicKey.default,
1199
980
  maxAllowedLtvOverridePercent: number = 0,
1200
- currentSlot: number = 0,
1201
- scopeRefresh: ScopeRefresh = { includeScopeRefresh: false, scopeFeed: 'hubble' }
981
+ currentSlot: number = 0
1202
982
  ) {
1203
983
  const axn = await KaminoAction.initializeMultiTokenAction(
1204
984
  kaminoMarket,
@@ -1219,18 +999,6 @@ export class KaminoAction {
1219
999
  axn.addComputeBudgetIxn(extraComputeBudget);
1220
1000
  }
1221
1001
 
1222
- const allReserves = new PublicKeySet<PublicKey>([
1223
- ...axn.depositReserves,
1224
- ...axn.borrowReserves,
1225
- axn.reserve.address,
1226
- axn.outflowReserve!.address,
1227
- ]).toArray();
1228
- const tokenIds = axn.getTokenIdsForScopeRefresh(kaminoMarket, allReserves);
1229
-
1230
- if (tokenIds.length > 0 && scopeRefresh.includeScopeRefresh) {
1231
- await axn.addScopeRefreshIxs(tokenIds, scopeRefresh.scopeFeed);
1232
- }
1233
-
1234
1002
  await axn.addSupportIxs(
1235
1003
  'liquidate',
1236
1004
  includeAtaIxns,
@@ -1238,6 +1006,7 @@ export class KaminoAction {
1238
1006
  includeUserMetadata,
1239
1007
  addInitObligationForFarm,
1240
1008
  useV2Ixs,
1009
+ scopeRefreshConfig,
1241
1010
  createLookupTable
1242
1011
  );
1243
1012
  if (useV2Ixs) {
@@ -1458,7 +1227,10 @@ export class KaminoAction {
1458
1227
  reserveFarmState: PROGRAM_ID,
1459
1228
  }
1460
1229
  : {
1461
- obligationFarmUserState: obligationFarmStatePda(this.reserve.state.farmCollateral, this.getObligationPda()),
1230
+ obligationFarmUserState: obligationFarmStatePda(
1231
+ this.getObligationPda(),
1232
+ this.reserve.state.farmCollateral
1233
+ )[0],
1462
1234
  reserveFarmState: this.reserve.state.farmCollateral,
1463
1235
  };
1464
1236
 
@@ -1523,7 +1295,10 @@ export class KaminoAction {
1523
1295
  reserveFarmState: PROGRAM_ID,
1524
1296
  }
1525
1297
  : {
1526
- obligationFarmUserState: obligationFarmStatePda(this.reserve.state.farmCollateral, this.getObligationPda()),
1298
+ obligationFarmUserState: obligationFarmStatePda(
1299
+ this.getObligationPda(),
1300
+ this.reserve.state.farmCollateral
1301
+ )[0],
1527
1302
  reserveFarmState: this.reserve.state.farmCollateral,
1528
1303
  };
1529
1304
 
@@ -1605,7 +1380,7 @@ export class KaminoAction {
1605
1380
  reserveFarmState: PROGRAM_ID,
1606
1381
  }
1607
1382
  : {
1608
- obligationFarmUserState: obligationFarmStatePda(this.reserve.state.farmDebt, this.getObligationPda()),
1383
+ obligationFarmUserState: obligationFarmStatePda(this.getObligationPda(), this.reserve.state.farmDebt)[0],
1609
1384
  reserveFarmState: this.reserve.state.farmDebt,
1610
1385
  };
1611
1386
 
@@ -1680,7 +1455,10 @@ export class KaminoAction {
1680
1455
  reserveFarmState: PROGRAM_ID,
1681
1456
  }
1682
1457
  : {
1683
- obligationFarmUserState: obligationFarmStatePda(this.reserve.state.farmCollateral, this.getObligationPda()),
1458
+ obligationFarmUserState: obligationFarmStatePda(
1459
+ this.getObligationPda(),
1460
+ this.reserve.state.farmCollateral
1461
+ )[0],
1684
1462
  reserveFarmState: this.reserve.state.farmCollateral,
1685
1463
  };
1686
1464
 
@@ -1764,7 +1542,7 @@ export class KaminoAction {
1764
1542
  reserveFarmState: PROGRAM_ID,
1765
1543
  }
1766
1544
  : {
1767
- obligationFarmUserState: obligationFarmStatePda(this.reserve.state.farmDebt, this.getObligationPda()),
1545
+ obligationFarmUserState: obligationFarmStatePda(this.getObligationPda(), this.reserve.state.farmDebt)[0],
1768
1546
  reserveFarmState: this.reserve.state.farmDebt,
1769
1547
  };
1770
1548
  const depositReserveAccountMetas = depositReservesList.map((reserve) => {
@@ -1800,208 +1578,6 @@ export class KaminoAction {
1800
1578
  this.lendingIxs.push(repayIx);
1801
1579
  }
1802
1580
 
1803
- addRepayAndWithdrawV2Ixs(withdrawCollateralAmount: BN) {
1804
- this.lendingIxsLabels.push(
1805
- `repayAndWithdrawAndRedeem(repayReserve=${this.reserve!.address})(withdrawReserve=${
1806
- this.outflowReserve!.address
1807
- })(obligation=${this.getObligationPda()})`
1808
- );
1809
-
1810
- const depositReservesList = this.getAdditionalDepositReservesList();
1811
-
1812
- const depositReserveAccountMetas = depositReservesList.map((reserve) => {
1813
- return { pubkey: reserve, isSigner: false, isWritable: true };
1814
- });
1815
- const borrowReserveAccountMetas = this.borrowReserves.map((reserve) => {
1816
- return { pubkey: reserve, isSigner: false, isWritable: true };
1817
- });
1818
-
1819
- if (!this.outflowAmount) {
1820
- throw new Error(`outflowAmount not set`);
1821
- }
1822
-
1823
- if (!this.outflowReserve) {
1824
- throw new Error(`outflowReserve not set`);
1825
- }
1826
-
1827
- if (!this.additionalTokenAccountAddress) {
1828
- throw new Error(`additionalTokenAccountAddress not set`);
1829
- }
1830
-
1831
- const collateralFarmsAccounts = this.outflowReserve.state.farmCollateral.equals(PublicKey.default)
1832
- ? {
1833
- obligationFarmUserState: this.kaminoMarket.programId,
1834
- reserveFarmState: this.kaminoMarket.programId,
1835
- }
1836
- : {
1837
- obligationFarmUserState: obligationFarmStatePda(
1838
- this.outflowReserve.state.farmCollateral,
1839
- this.getObligationPda()
1840
- ),
1841
- reserveFarmState: this.outflowReserve.state.farmCollateral,
1842
- };
1843
-
1844
- const debtFarmsAccounts = this.reserve.state.farmDebt.equals(PublicKey.default)
1845
- ? {
1846
- obligationFarmUserState: this.kaminoMarket.programId,
1847
- reserveFarmState: this.kaminoMarket.programId,
1848
- }
1849
- : {
1850
- obligationFarmUserState: obligationFarmStatePda(this.reserve.state.farmDebt, this.getObligationPda()),
1851
- reserveFarmState: this.reserve.state.farmDebt,
1852
- };
1853
-
1854
- const repayAndWithdrawIx = repayAndWithdrawAndRedeem(
1855
- {
1856
- repayAmount: this.amount,
1857
- withdrawCollateralAmount,
1858
- },
1859
- {
1860
- repayAccounts: {
1861
- owner: this.owner,
1862
- obligation: this.getObligationPda(),
1863
- lendingMarket: this.kaminoMarket.getAddress(),
1864
- repayReserve: this.reserve!.address,
1865
- reserveLiquidityMint: this.reserve.getLiquidityMint(),
1866
- userSourceLiquidity: this.userTokenAccountAddress,
1867
- reserveDestinationLiquidity: this.reserve.state.liquidity.supplyVault,
1868
- tokenProgram: this.reserve.getLiquidityTokenProgram(),
1869
- instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
1870
- },
1871
- withdrawAccounts: {
1872
- owner: this.owner,
1873
- obligation: this.getObligationPda(),
1874
- lendingMarket: this.kaminoMarket.getAddress(),
1875
- lendingMarketAuthority: this.kaminoMarket.getLendingMarketAuthority(),
1876
- withdrawReserve: this.outflowReserve.address,
1877
- reserveLiquidityMint: this.outflowReserve.getLiquidityMint(),
1878
- reserveCollateralMint: this.outflowReserve.getCTokenMint(),
1879
- reserveLiquiditySupply: this.outflowReserve.state.liquidity.supplyVault,
1880
- reserveSourceCollateral: this.outflowReserve.state.collateral.supplyVault,
1881
- userDestinationLiquidity: this.additionalTokenAccountAddress,
1882
- placeholderUserDestinationCollateral: this.kaminoMarket.programId,
1883
- collateralTokenProgram: TOKEN_PROGRAM_ID,
1884
- liquidityTokenProgram: this.outflowReserve.getLiquidityTokenProgram(),
1885
- instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
1886
- },
1887
- collateralFarmsAccounts,
1888
- debtFarmsAccounts,
1889
- farmsProgram: farmsId,
1890
- },
1891
- this.kaminoMarket.programId
1892
- );
1893
-
1894
- repayAndWithdrawIx.keys = repayAndWithdrawIx.keys.concat([
1895
- ...depositReserveAccountMetas,
1896
- ...borrowReserveAccountMetas,
1897
- ]);
1898
-
1899
- this.lendingIxs.push(repayAndWithdrawIx);
1900
- }
1901
-
1902
- addDepositAndWithdrawV2Ixs(withdrawCollateralAmount: BN) {
1903
- this.lendingIxsLabels.push(
1904
- `depositAndWithdrawV2(depositReserve=${this.reserve!.address})(withdrawReserve=${
1905
- this.outflowReserve!.address
1906
- })(obligation=${this.getObligationPda()})`
1907
- );
1908
-
1909
- const depositReservesList = this.getAdditionalDepositReservesList();
1910
-
1911
- const depositReserveAccountMetas = depositReservesList.map((reserve) => {
1912
- return { pubkey: reserve, isSigner: false, isWritable: true };
1913
- });
1914
- const borrowReserveAccountMetas = this.borrowReserves.map((reserve) => {
1915
- return { pubkey: reserve, isSigner: false, isWritable: true };
1916
- });
1917
-
1918
- if (!this.outflowAmount) {
1919
- throw new Error(`outflowAmount not set`);
1920
- }
1921
-
1922
- if (!this.outflowReserve) {
1923
- throw new Error(`outflowReserve not set`);
1924
- }
1925
-
1926
- if (!this.additionalTokenAccountAddress) {
1927
- throw new Error(`additionalTokenAccountAddress not set`);
1928
- }
1929
-
1930
- const depositFarmsAccounts = this.reserve.state.farmCollateral.equals(PublicKey.default)
1931
- ? {
1932
- obligationFarmUserState: this.kaminoMarket.programId,
1933
- reserveFarmState: this.kaminoMarket.programId,
1934
- }
1935
- : {
1936
- obligationFarmUserState: obligationFarmStatePda(this.reserve.state.farmDebt, this.getObligationPda()),
1937
- reserveFarmState: this.reserve.state.farmCollateral,
1938
- };
1939
- const withdrawFarmsAccounts = this.outflowReserve.state.farmCollateral.equals(PublicKey.default)
1940
- ? {
1941
- obligationFarmUserState: this.kaminoMarket.programId,
1942
- reserveFarmState: this.kaminoMarket.programId,
1943
- }
1944
- : {
1945
- obligationFarmUserState: obligationFarmStatePda(
1946
- this.outflowReserve.state.farmCollateral,
1947
- this.getObligationPda()
1948
- ),
1949
- reserveFarmState: this.outflowReserve.state.farmCollateral,
1950
- };
1951
-
1952
- const depositAndWithdrawIx = depositAndWithdraw(
1953
- {
1954
- liquidityAmount: this.amount,
1955
- withdrawCollateralAmount,
1956
- },
1957
- {
1958
- depositAccounts: {
1959
- owner: this.owner,
1960
- obligation: this.getObligationPda(),
1961
- lendingMarket: this.kaminoMarket.getAddress(),
1962
- lendingMarketAuthority: this.kaminoMarket.getLendingMarketAuthority(),
1963
- reserve: this.reserve.address,
1964
- reserveLiquidityMint: this.reserve.getLiquidityMint(),
1965
- reserveLiquiditySupply: this.reserve.state.liquidity.supplyVault,
1966
- reserveCollateralMint: this.reserve.getCTokenMint(),
1967
- reserveDestinationDepositCollateral: this.reserve.state.collateral.supplyVault, // destinationCollateral
1968
- userSourceLiquidity: this.userTokenAccountAddress,
1969
- placeholderUserDestinationCollateral: this.kaminoMarket.programId,
1970
- collateralTokenProgram: TOKEN_PROGRAM_ID,
1971
- liquidityTokenProgram: this.reserve.getLiquidityTokenProgram(),
1972
- instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
1973
- },
1974
- withdrawAccounts: {
1975
- owner: this.owner,
1976
- obligation: this.getObligationPda(),
1977
- lendingMarket: this.kaminoMarket.getAddress(),
1978
- lendingMarketAuthority: this.kaminoMarket.getLendingMarketAuthority(),
1979
- withdrawReserve: this.outflowReserve.address,
1980
- reserveLiquidityMint: this.outflowReserve.getLiquidityMint(),
1981
- reserveCollateralMint: this.outflowReserve.getCTokenMint(),
1982
- reserveLiquiditySupply: this.outflowReserve.state.liquidity.supplyVault,
1983
- reserveSourceCollateral: this.outflowReserve.state.collateral.supplyVault,
1984
- userDestinationLiquidity: this.additionalTokenAccountAddress,
1985
- placeholderUserDestinationCollateral: this.kaminoMarket.programId,
1986
- collateralTokenProgram: TOKEN_PROGRAM_ID,
1987
- liquidityTokenProgram: this.outflowReserve.getLiquidityTokenProgram(),
1988
- instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
1989
- },
1990
- depositFarmsAccounts,
1991
- withdrawFarmsAccounts,
1992
- farmsProgram: farmsId,
1993
- },
1994
- this.kaminoMarket.programId
1995
- );
1996
-
1997
- depositAndWithdrawIx.keys = depositAndWithdrawIx.keys.concat([
1998
- ...depositReserveAccountMetas,
1999
- ...borrowReserveAccountMetas,
2000
- ]);
2001
-
2002
- this.lendingIxs.push(depositAndWithdrawIx);
2003
- }
2004
-
2005
1581
  async addDepositAndBorrowIx() {
2006
1582
  this.lendingIxsLabels.push(`depositReserveLiquidityAndObligationCollateral`);
2007
1583
  this.lendingIxsLabels.push(`borrowObligationLiquidity`);
@@ -2087,7 +1663,10 @@ export class KaminoAction {
2087
1663
  reserveFarmState: PROGRAM_ID,
2088
1664
  }
2089
1665
  : {
2090
- obligationFarmUserState: obligationFarmStatePda(this.reserve.state.farmCollateral, this.getObligationPda()),
1666
+ obligationFarmUserState: obligationFarmStatePda(
1667
+ this.getObligationPda(),
1668
+ this.reserve.state.farmCollateral
1669
+ )[0],
2091
1670
  reserveFarmState: this.reserve.state.farmCollateral,
2092
1671
  };
2093
1672
 
@@ -2148,7 +1727,10 @@ export class KaminoAction {
2148
1727
  reserveFarmState: PROGRAM_ID,
2149
1728
  }
2150
1729
  : {
2151
- obligationFarmUserState: obligationFarmStatePda(this.outflowReserve.state.farmDebt, this.getObligationPda()),
1730
+ obligationFarmUserState: obligationFarmStatePda(
1731
+ this.getObligationPda(),
1732
+ this.outflowReserve.state.farmDebt!
1733
+ )[0],
2152
1734
  reserveFarmState: this.outflowReserve.state.farmDebt,
2153
1735
  };
2154
1736
 
@@ -2274,7 +1856,7 @@ export class KaminoAction {
2274
1856
  reserveFarmState: PROGRAM_ID,
2275
1857
  }
2276
1858
  : {
2277
- obligationFarmUserState: obligationFarmStatePda(this.reserve.state.farmDebt, this.getObligationPda()),
1859
+ obligationFarmUserState: obligationFarmStatePda(this.getObligationPda(), this.reserve.state.farmDebt)[0],
2278
1860
  reserveFarmState: this.reserve.state.farmDebt,
2279
1861
  };
2280
1862
 
@@ -2323,9 +1905,9 @@ export class KaminoAction {
2323
1905
  }
2324
1906
  : {
2325
1907
  obligationFarmUserState: obligationFarmStatePda(
2326
- this.outflowReserve.state.farmCollateral,
2327
- this.getObligationPda()
2328
- ),
1908
+ this.getObligationPda(),
1909
+ this.outflowReserve.state.farmCollateral
1910
+ )[0],
2329
1911
  reserveFarmState: this.outflowReserve.state.farmCollateral,
2330
1912
  };
2331
1913
 
@@ -2359,7 +1941,7 @@ export class KaminoAction {
2359
1941
  );
2360
1942
  }
2361
1943
 
2362
- addLiquidateIx(maxAllowedLtvOverridePercent: number = 0) {
1944
+ async addLiquidateIx(maxAllowedLtvOverridePercent: number = 0) {
2363
1945
  this.lendingIxsLabels.push(`liquidateObligationAndRedeemReserveCollateral`);
2364
1946
  if (!this.outflowReserve) {
2365
1947
  throw Error(`Withdraw reserve during liquidation is not defined`);
@@ -2432,9 +2014,9 @@ export class KaminoAction {
2432
2014
  }
2433
2015
  : {
2434
2016
  obligationFarmUserState: obligationFarmStatePda(
2435
- this.outflowReserve.state.farmCollateral,
2436
- this.getObligationPda()
2437
- ),
2017
+ this.getObligationPda(),
2018
+ this.outflowReserve.state.farmCollateral
2019
+ )[0],
2438
2020
  reserveFarmState: this.outflowReserve.state.farmCollateral,
2439
2021
  };
2440
2022
 
@@ -2444,7 +2026,7 @@ export class KaminoAction {
2444
2026
  reserveFarmState: PROGRAM_ID,
2445
2027
  }
2446
2028
  : {
2447
- obligationFarmUserState: obligationFarmStatePda(this.reserve.state.farmDebt, this.getObligationPda()),
2029
+ obligationFarmUserState: obligationFarmStatePda(this.getObligationPda(), this.reserve.state.farmDebt)[0],
2448
2030
  reserveFarmState: this.reserve.state.farmDebt,
2449
2031
  };
2450
2032
 
@@ -2556,7 +2138,6 @@ export class KaminoAction {
2556
2138
  'repay',
2557
2139
  'depositAndBorrow',
2558
2140
  'repayAndWithdraw',
2559
- 'repayAndWithdrawV2',
2560
2141
  'refreshObligation',
2561
2142
  ].includes(action)
2562
2143
  ) {
@@ -2575,17 +2156,12 @@ export class KaminoAction {
2575
2156
 
2576
2157
  let currentReserves: KaminoReserve[] = [];
2577
2158
 
2578
- if (
2579
- action === 'liquidate' ||
2580
- action === 'depositAndBorrow' ||
2581
- action === 'repayAndWithdraw' ||
2582
- action === 'repayAndWithdrawV2'
2583
- ) {
2159
+ if (action === 'liquidate' || action === 'depositAndBorrow' || action === 'repayAndWithdraw') {
2584
2160
  if (!this.outflowReserve) {
2585
2161
  throw new Error('outflowReserve is undefined');
2586
2162
  }
2587
2163
 
2588
- if (action === 'depositAndBorrow' || action === 'repayAndWithdraw' || action === 'repayAndWithdrawV2') {
2164
+ if (action === 'depositAndBorrow' || action === 'repayAndWithdraw') {
2589
2165
  currentReserves = [this.reserve, this.outflowReserve];
2590
2166
  if (action === 'depositAndBorrow') {
2591
2167
  if (this.obligation) {
@@ -2630,12 +2206,7 @@ export class KaminoAction {
2630
2206
  if (this.outflowReserve) {
2631
2207
  await this.addInitObligationForFarm(this.outflowReserve, ReserveFarmKind.Debt, addAsSupportIx);
2632
2208
  }
2633
- } else if (
2634
- action === 'repayAndWithdraw' ||
2635
- action === 'borrow' ||
2636
- action === 'repay' ||
2637
- action === 'repayAndWithdrawV2'
2638
- ) {
2209
+ } else if (action === 'repayAndWithdraw' || action === 'borrow' || action === 'repay') {
2639
2210
  // todo - probably don't need to add both debt and collateral for everything here
2640
2211
  await this.addInitObligationForFarm(this.reserve, ReserveFarmKind.Debt, addAsSupportIx);
2641
2212
  if (this.outflowReserve) {
@@ -2666,7 +2237,7 @@ export class KaminoAction {
2666
2237
  }
2667
2238
 
2668
2239
  if (requestElevationGroup) {
2669
- if (action === 'repay' || action === 'repayAndWithdrawV2') {
2240
+ if (action === 'repay') {
2670
2241
  const repayObligationLiquidity = this.obligation!.borrows.get(this.reserve.address);
2671
2242
 
2672
2243
  if (!repayObligationLiquidity) {
@@ -2828,6 +2399,7 @@ export class KaminoAction {
2828
2399
  includeUserMetadata: boolean,
2829
2400
  addInitObligationForFarm: boolean,
2830
2401
  useV2Ixs: boolean,
2402
+ scopeRefreshConfig: ScopePriceRefreshConfig | undefined,
2831
2403
  createLookupTable: boolean,
2832
2404
  twoTokenAction: boolean = false,
2833
2405
  overrideElevationGroupRequest?: number
@@ -2855,7 +2427,7 @@ export class KaminoAction {
2855
2427
  if (action === 'deposit' && this.outflowReserve) {
2856
2428
  await this.addInitReferrerTokenStateIx(this.outflowReserve);
2857
2429
  }
2858
- this.addInitObligationIxs();
2430
+ await this.addInitObligationIxs();
2859
2431
  }
2860
2432
 
2861
2433
  await this.addSupportIxsWithoutInitObligation(
@@ -2868,6 +2440,19 @@ export class KaminoAction {
2868
2440
  twoTokenAction,
2869
2441
  overrideElevationGroupRequest
2870
2442
  );
2443
+
2444
+ const allReserves = new PublicKeySet<PublicKey>([
2445
+ ...this.depositReserves,
2446
+ ...this.borrowReserves,
2447
+ this.reserve.address,
2448
+ ...(this.outflowReserve ? [this.outflowReserve.address] : []),
2449
+ ...(this.preLoadedDepositReservesSameTx ? this.preLoadedDepositReservesSameTx : []),
2450
+ ]).toArray();
2451
+ const tokenIds = getTokenIdsForScopeRefresh(this.kaminoMarket, allReserves);
2452
+
2453
+ if (tokenIds.length > 0 && scopeRefreshConfig) {
2454
+ await this.addScopeRefreshIxs(scopeRefreshConfig.scope, tokenIds, scopeRefreshConfig.scopeFeed);
2455
+ }
2871
2456
  }
2872
2457
 
2873
2458
  private static optionalAccount(pubkey: PublicKey, programId: PublicKey = PROGRAM_ID): PublicKey {
@@ -3087,7 +2672,7 @@ export class KaminoAction {
3087
2672
  farms.push([
3088
2673
  ReserveFarmKind.Collateral,
3089
2674
  kaminoReserve.state.farmCollateral,
3090
- obligationFarmStatePda(kaminoReserve.state.farmCollateral, this.getObligationPda()),
2675
+ obligationFarmStatePda(this.getObligationPda(), kaminoReserve.state.farmCollateral)[0],
3091
2676
  kaminoReserve,
3092
2677
  ]);
3093
2678
  }
@@ -3095,7 +2680,7 @@ export class KaminoAction {
3095
2680
  farms.push([
3096
2681
  ReserveFarmKind.Debt,
3097
2682
  kaminoReserve.state.farmDebt,
3098
- obligationFarmStatePda(kaminoReserve.state.farmDebt, this.getObligationPda()),
2683
+ obligationFarmStatePda(this.getObligationPda(), kaminoReserve.state.farmDebt)[0],
3099
2684
  kaminoReserve,
3100
2685
  ]);
3101
2686
  }
@@ -3179,18 +2764,18 @@ export class KaminoAction {
3179
2764
  const farms: [number, PublicKey, PublicKey][] = [];
3180
2765
 
3181
2766
  if (mode === ReserveFarmKind.Collateral && isNotNullPubkey(reserve.state.farmCollateral)) {
3182
- const pda = obligationFarmStatePda(reserve.state.farmCollateral, this.getObligationPda());
3183
- const account = await this.kaminoMarket.getConnection().getAccountInfo(pda);
2767
+ const userPda = obligationFarmStatePda(this.getObligationPda(), reserve.state.farmCollateral)[0];
2768
+ const account = await this.kaminoMarket.getConnection().getAccountInfo(userPda);
3184
2769
  if (!account) {
3185
- farms.push([ReserveFarmKind.Collateral.discriminator, reserve.state.farmCollateral, pda]);
2770
+ farms.push([ReserveFarmKind.Collateral.discriminator, reserve.state.farmCollateral, userPda]);
3186
2771
  }
3187
2772
  }
3188
2773
 
3189
2774
  if (mode === ReserveFarmKind.Debt && isNotNullPubkey(reserve.state.farmDebt)) {
3190
- const pda = obligationFarmStatePda(reserve.state.farmDebt, this.getObligationPda());
3191
- const account = await this.kaminoMarket.getConnection().getAccountInfo(pda);
2775
+ const userPda = obligationFarmStatePda(this.getObligationPda(), reserve.state.farmDebt)[0];
2776
+ const account = await this.kaminoMarket.getConnection().getAccountInfo(userPda);
3192
2777
  if (!account) {
3193
- farms.push([ReserveFarmKind.Debt.discriminator, reserve.state.farmDebt, pda]);
2778
+ farms.push([ReserveFarmKind.Debt.discriminator, reserve.state.farmDebt, userPda]);
3194
2779
  }
3195
2780
  }
3196
2781
 
@@ -3224,7 +2809,7 @@ export class KaminoAction {
3224
2809
  });
3225
2810
  }
3226
2811
 
3227
- private addInitObligationIxs() {
2812
+ private async addInitObligationIxs() {
3228
2813
  if (!this.obligation) {
3229
2814
  const obligationPda = this.getObligationPda();
3230
2815
  const [userMetadataAddress, _bump] = userMetadataPda(this.owner, this.kaminoMarket.programId);
@@ -3447,7 +3032,7 @@ export class KaminoAction {
3447
3032
 
3448
3033
  let safeRepay = new BN(this.amount);
3449
3034
 
3450
- if (this.obligation && (action === 'repay' || action === 'repayAndWithdrawV2') && this.amount.eq(new BN(U64_MAX))) {
3035
+ if (this.obligation && action === 'repay' && this.amount.eq(new BN(U64_MAX))) {
3451
3036
  const borrow = this.obligation.state.borrows.find(
3452
3037
  (borrow) => borrow.borrowReserve.toString() === this.reserve.address.toString()
3453
3038
  );
@@ -3461,7 +3046,7 @@ export class KaminoAction {
3461
3046
  this.currentSlot,
3462
3047
  this.kaminoMarket.state.referralFeeBps
3463
3048
  );
3464
-
3049
+ // TODO: shouldn't this calc be added to all other stuff as well?
3465
3050
  safeRepay = new BN(
3466
3051
  Math.floor(
3467
3052
  KaminoObligation.getBorrowAmount(borrow)
@@ -3489,7 +3074,6 @@ export class KaminoAction {
3489
3074
  const sendAction =
3490
3075
  action === 'deposit' ||
3491
3076
  action === 'repay' ||
3492
- action === 'repayAndWithdrawV2' ||
3493
3077
  action === 'mint' ||
3494
3078
  (action === 'liquidate' && this.secondaryMint?.equals(NATIVE_MINT)); // only sync WSOL amount if liquidator repays SOL which is secondaryMint
3495
3079
 
@@ -3599,7 +3183,7 @@ export class KaminoAction {
3599
3183
  additionalUserTokenAccountAddress = userOutflowTokenAccountAddress;
3600
3184
  primaryMint = inflowTokenMint;
3601
3185
  secondaryMint = outflowTokenMint;
3602
- } else if (action === 'repayAndWithdraw' || action === 'repayAndWithdrawV2') {
3186
+ } else if (action === 'repayAndWithdraw') {
3603
3187
  primaryMint = inflowTokenMint;
3604
3188
  secondaryMint = outflowTokenMint;
3605
3189
  userTokenAccountAddress = userInflowTokenAccountAddress;