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

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/dist/classes/action.d.ts +1 -1
  2. package/dist/classes/action.d.ts.map +1 -1
  3. package/dist/classes/action.js +32 -16
  4. package/dist/classes/action.js.map +1 -1
  5. package/dist/classes/manager.d.ts +29 -18
  6. package/dist/classes/manager.d.ts.map +1 -1
  7. package/dist/classes/manager.js +66 -49
  8. package/dist/classes/manager.js.map +1 -1
  9. package/dist/classes/market.d.ts +12 -11
  10. package/dist/classes/market.d.ts.map +1 -1
  11. package/dist/classes/market.js +77 -37
  12. package/dist/classes/market.js.map +1 -1
  13. package/dist/classes/obligation.d.ts +32 -2
  14. package/dist/classes/obligation.d.ts.map +1 -1
  15. package/dist/classes/obligation.js +150 -24
  16. package/dist/classes/obligation.js.map +1 -1
  17. package/dist/classes/vault.d.ts +5 -3
  18. package/dist/classes/vault.d.ts.map +1 -1
  19. package/dist/classes/vault.js +8 -6
  20. package/dist/classes/vault.js.map +1 -1
  21. package/dist/client_kamino_manager.d.ts.map +1 -1
  22. package/dist/client_kamino_manager.js +30 -22
  23. package/dist/client_kamino_manager.js.map +1 -1
  24. package/dist/lending_operations/repay_with_collateral_operations.d.ts.map +1 -1
  25. package/dist/lending_operations/repay_with_collateral_operations.js +36 -32
  26. package/dist/lending_operations/repay_with_collateral_operations.js.map +1 -1
  27. package/dist/lending_operations/swap_collateral_operations.d.ts.map +1 -1
  28. package/dist/lending_operations/swap_collateral_operations.js +4 -4
  29. package/dist/lending_operations/swap_collateral_operations.js.map +1 -1
  30. package/dist/leverage/operations.d.ts +4 -3
  31. package/dist/leverage/operations.d.ts.map +1 -1
  32. package/dist/leverage/operations.js +186 -154
  33. package/dist/leverage/operations.js.map +1 -1
  34. package/dist/leverage/types.d.ts +1 -0
  35. package/dist/leverage/types.d.ts.map +1 -1
  36. package/dist/utils/managerTypes.d.ts +1 -2
  37. package/dist/utils/managerTypes.d.ts.map +1 -1
  38. package/dist/utils/managerTypes.js +9 -9
  39. package/dist/utils/managerTypes.js.map +1 -1
  40. package/dist/utils/obligations.d.ts +5 -0
  41. package/dist/utils/obligations.d.ts.map +1 -0
  42. package/dist/utils/obligations.js +53 -0
  43. package/dist/utils/obligations.js.map +1 -0
  44. package/dist/utils/oracle.d.ts +3 -3
  45. package/dist/utils/oracle.d.ts.map +1 -1
  46. package/dist/utils/oracle.js +2 -2
  47. package/dist/utils/oracle.js.map +1 -1
  48. package/dist/utils/pubkey.d.ts +1 -0
  49. package/dist/utils/pubkey.d.ts.map +1 -1
  50. package/dist/utils/pubkey.js +10 -0
  51. package/dist/utils/pubkey.js.map +1 -1
  52. package/package.json +3 -3
  53. package/src/classes/action.ts +32 -20
  54. package/src/classes/manager.ts +87 -54
  55. package/src/classes/market.ts +132 -52
  56. package/src/classes/obligation.ts +201 -36
  57. package/src/classes/vault.ts +17 -6
  58. package/src/client.ts +4 -4
  59. package/src/client_kamino_manager.ts +40 -35
  60. package/src/lending_operations/repay_with_collateral_operations.ts +76 -72
  61. package/src/lending_operations/swap_collateral_operations.ts +13 -11
  62. package/src/leverage/operations.ts +362 -328
  63. package/src/leverage/types.ts +1 -0
  64. package/src/utils/managerTypes.ts +1 -2
  65. package/src/utils/obligations.ts +69 -0
  66. package/src/utils/oracle.ts +5 -4
  67. package/src/utils/pubkey.ts +9 -0
@@ -39,6 +39,11 @@ export type Position = {
39
39
  marketValueRefreshed: Decimal;
40
40
  };
41
41
 
42
+ export type PositionChange = {
43
+ reserveAddress: PublicKey;
44
+ amountChangeLamports: Decimal;
45
+ };
46
+
42
47
  export type ObligationStats = {
43
48
  userTotalDeposit: Decimal;
44
49
  userTotalCollateralDeposit: Decimal;
@@ -491,19 +496,20 @@ export class KaminoObligation {
491
496
 
492
497
  simulateDepositChange(
493
498
  obligationDeposits: ObligationCollateral[],
494
- changeInLamports: number,
495
- changeReserve: PublicKey,
499
+ depositChange: PositionChange,
496
500
  collateralExchangeRates: Map<PublicKey, Decimal>
497
501
  ): ObligationCollateral[] {
498
502
  const newDeposits: ObligationCollateral[] = [];
499
- const depositIndex = obligationDeposits.findIndex((deposit) => deposit.depositReserve.equals(changeReserve));
503
+ const depositIndex = obligationDeposits.findIndex((deposit) =>
504
+ deposit.depositReserve.equals(depositChange.reserveAddress)
505
+ );
500
506
 
501
507
  // Always copy the previous deposits and modify the changeReserve one if it exists
502
508
  for (let i = 0; i < obligationDeposits.length; i++) {
503
- if (obligationDeposits[i].depositReserve.equals(changeReserve)) {
509
+ if (obligationDeposits[i].depositReserve.equals(depositChange.reserveAddress)) {
504
510
  const coll: ObligationCollateralFields = { ...obligationDeposits[i] };
505
- const exchangeRate = collateralExchangeRates.get(changeReserve)!;
506
- const changeInCollateral = new Decimal(changeInLamports).mul(exchangeRate).toFixed(0);
511
+ const exchangeRate = collateralExchangeRates.get(depositChange.reserveAddress)!;
512
+ const changeInCollateral = new Decimal(depositChange.amountChangeLamports).mul(exchangeRate).toFixed(0);
507
513
  const updatedDeposit = new Decimal(obligationDeposits[i].depositedAmount.toNumber()).add(changeInCollateral);
508
514
  coll.depositedAmount = new BN(positiveOrZero(updatedDeposit).toString());
509
515
  newDeposits.push(new ObligationCollateral(coll));
@@ -523,10 +529,10 @@ export class KaminoObligation {
523
529
  }
524
530
 
525
531
  const coll: ObligationCollateralFields = { ...obligationDeposits[firstBorrowIndexAvailable] };
526
- const exchangeRate = collateralExchangeRates.get(changeReserve)!;
527
- const changeInCollateral = new Decimal(changeInLamports).mul(exchangeRate).toFixed(0);
532
+ const exchangeRate = collateralExchangeRates.get(depositChange.reserveAddress)!;
533
+ const changeInCollateral = new Decimal(depositChange.amountChangeLamports).mul(exchangeRate).toFixed(0);
528
534
  coll.depositedAmount = new BN(positiveOrZero(new Decimal(changeInCollateral)).toString());
529
- coll.depositReserve = changeReserve;
535
+ coll.depositReserve = depositChange.reserveAddress;
530
536
 
531
537
  newDeposits[firstBorrowIndexAvailable] = new ObligationCollateral(coll);
532
538
  }
@@ -536,18 +542,21 @@ export class KaminoObligation {
536
542
 
537
543
  simulateBorrowChange(
538
544
  obligationBorrows: ObligationLiquidity[],
539
- changeInLamports: number,
540
- changeReserve: PublicKey,
545
+ borrowChange: PositionChange,
541
546
  cumulativeBorrowRate: Decimal
542
547
  ): ObligationLiquidity[] {
543
548
  const newBorrows: ObligationLiquidity[] = [];
544
- const borrowIndex = obligationBorrows.findIndex((borrow) => borrow.borrowReserve.equals(changeReserve));
549
+ const borrowIndex = obligationBorrows.findIndex((borrow) =>
550
+ borrow.borrowReserve.equals(borrowChange.reserveAddress)
551
+ );
545
552
 
546
553
  // Always copy the previous borrows and modify the changeReserve one if it exists
547
554
  for (let i = 0; i < obligationBorrows.length; i++) {
548
- if (obligationBorrows[i].borrowReserve.equals(changeReserve)) {
555
+ if (obligationBorrows[i].borrowReserve.equals(borrowChange.reserveAddress)) {
549
556
  const borrow: ObligationLiquidityFields = { ...obligationBorrows[borrowIndex] };
550
- const newBorrowedAmount: Decimal = new Fraction(borrow.borrowedAmountSf).toDecimal().add(changeInLamports);
557
+ const newBorrowedAmount: Decimal = new Fraction(borrow.borrowedAmountSf)
558
+ .toDecimal()
559
+ .add(borrowChange.amountChangeLamports);
551
560
  const newBorrowedAmountSf = Fraction.fromDecimal(positiveOrZero(newBorrowedAmount)).getValue();
552
561
  borrow.borrowedAmountSf = newBorrowedAmountSf;
553
562
 
@@ -568,8 +577,8 @@ export class KaminoObligation {
568
577
  }
569
578
 
570
579
  const borrow: ObligationLiquidityFields = { ...obligationBorrows[firstBorrowIndexAvailable] };
571
- borrow.borrowedAmountSf = Fraction.fromDecimal(new Decimal(changeInLamports)).getValue();
572
- borrow.borrowReserve = changeReserve;
580
+ borrow.borrowedAmountSf = Fraction.fromDecimal(new Decimal(borrowChange.amountChangeLamports)).getValue();
581
+ borrow.borrowReserve = borrowChange.reserveAddress;
573
582
  borrow.cumulativeBorrowRateBsf = {
574
583
  padding: [],
575
584
  value: [Fraction.fromDecimal(cumulativeBorrowRate).getValue(), new BN(0), new BN(0), new BN(0)],
@@ -643,8 +652,10 @@ export class KaminoObligation {
643
652
  }
644
653
  newObligationDeposits = this.simulateDepositChange(
645
654
  this.state.deposits,
646
- amountCollateral.toNumber(),
647
- collateralReservePk!,
655
+ {
656
+ reserveAddress: collateralReservePk!,
657
+ amountChangeLamports: amountCollateral,
658
+ },
648
659
  collateralExchangeRates
649
660
  );
650
661
  break;
@@ -656,8 +667,10 @@ export class KaminoObligation {
656
667
 
657
668
  newObligationBorrows = this.simulateBorrowChange(
658
669
  this.state.borrows,
659
- amountDebt.toNumber(),
660
- debtReservePk!,
670
+ {
671
+ reserveAddress: debtReservePk!,
672
+ amountChangeLamports: amountDebt,
673
+ },
661
674
  debtReserveCumulativeBorrowRate!
662
675
  );
663
676
  break;
@@ -669,8 +682,10 @@ export class KaminoObligation {
669
682
 
670
683
  newObligationBorrows = this.simulateBorrowChange(
671
684
  this.state.borrows,
672
- amountDebt.neg().toNumber(),
673
- debtReservePk!,
685
+ {
686
+ reserveAddress: debtReservePk!,
687
+ amountChangeLamports: amountDebt.neg(),
688
+ },
674
689
  debtReserveCumulativeBorrowRate!
675
690
  );
676
691
 
@@ -683,8 +698,10 @@ export class KaminoObligation {
683
698
  }
684
699
  newObligationDeposits = this.simulateDepositChange(
685
700
  this.state.deposits,
686
- amountCollateral.neg().toNumber(),
687
- collateralReservePk!,
701
+ {
702
+ reserveAddress: collateralReservePk!,
703
+ amountChangeLamports: amountCollateral.neg(),
704
+ },
688
705
  collateralExchangeRates
689
706
  );
690
707
  break;
@@ -700,15 +717,19 @@ export class KaminoObligation {
700
717
  }
701
718
  newObligationDeposits = this.simulateDepositChange(
702
719
  this.state.deposits,
703
- amountCollateral.toNumber(),
704
- collateralReservePk!,
720
+ {
721
+ reserveAddress: collateralReservePk!,
722
+ amountChangeLamports: amountCollateral,
723
+ },
705
724
  collateralExchangeRates
706
725
  );
707
726
 
708
727
  newObligationBorrows = this.simulateBorrowChange(
709
728
  this.state.borrows,
710
- amountDebt.toNumber(),
711
- debtReservePk!,
729
+ {
730
+ reserveAddress: debtReservePk!,
731
+ amountChangeLamports: amountDebt,
732
+ },
712
733
  debtReserveCumulativeBorrowRate!
713
734
  );
714
735
  break;
@@ -724,14 +745,18 @@ export class KaminoObligation {
724
745
  }
725
746
  newObligationDeposits = this.simulateDepositChange(
726
747
  this.state.deposits,
727
- amountCollateral.neg().toNumber(),
728
- collateralReservePk!,
748
+ {
749
+ reserveAddress: collateralReservePk!,
750
+ amountChangeLamports: amountCollateral.neg(),
751
+ },
729
752
  collateralExchangeRates
730
753
  );
731
754
  newObligationBorrows = this.simulateBorrowChange(
732
755
  this.state.borrows,
733
- amountDebt.neg().toNumber(),
734
- debtReservePk!,
756
+ {
757
+ reserveAddress: debtReservePk!,
758
+ amountChangeLamports: amountDebt.neg(),
759
+ },
735
760
  debtReserveCumulativeBorrowRate!
736
761
  );
737
762
  break;
@@ -803,14 +828,18 @@ export class KaminoObligation {
803
828
  let newObligationDeposits = this.state.deposits;
804
829
  newObligationDeposits = this.simulateDepositChange(
805
830
  newObligationDeposits,
806
- withdrawAmountLamports.neg().toNumber(),
807
- withdrawReserveAddress,
831
+ {
832
+ reserveAddress: withdrawReserveAddress,
833
+ amountChangeLamports: withdrawAmountLamports.neg(),
834
+ },
808
835
  collateralExchangeRates
809
836
  );
810
837
  newObligationDeposits = this.simulateDepositChange(
811
838
  newObligationDeposits,
812
- depositAmountLamports.toNumber(),
813
- depositReserveAddress,
839
+ {
840
+ reserveAddress: depositReserveAddress,
841
+ amountChangeLamports: depositAmountLamports,
842
+ },
814
843
  collateralExchangeRates
815
844
  );
816
845
 
@@ -947,6 +976,7 @@ export class KaminoObligation {
947
976
  } else {
948
977
  exchangeRate = reserve.getCollateralExchangeRate();
949
978
  }
979
+
950
980
  const supplyAmount = new Decimal(deposit.depositedAmount.toString()).div(exchangeRate);
951
981
 
952
982
  const depositValueUsd = supplyAmount.mul(getPx(reserve)).div(reserve.getMintFactor());
@@ -1074,6 +1104,73 @@ export class KaminoObligation {
1074
1104
  return borrowLimit.div(userTotalCollateralDeposit);
1075
1105
  }
1076
1106
 
1107
+ /**
1108
+ * Creates a new KaminoObligation with simulated position changes applied.
1109
+ * This allows you to model what the obligation would look like with deposits/borrows
1110
+ * without actually executing those transactions.
1111
+ *
1112
+ * @param market - The KaminoMarket instance
1113
+ * @param slot - The slot number for rate calculations
1114
+ * @param depositChanges - Optional array of deposit changes to apply
1115
+ * @param borrowChanges - Optional array of borrow changes to apply
1116
+ * @returns A new KaminoObligation instance with the changes applied
1117
+ */
1118
+ withPositionChanges(
1119
+ market: KaminoMarket,
1120
+ slot: number,
1121
+ depositChanges?: PositionChange[],
1122
+ borrowChanges?: PositionChange[]
1123
+ ): KaminoObligation {
1124
+ const reservesToRefresh: PublicKey[] = [];
1125
+
1126
+ if (depositChanges) {
1127
+ reservesToRefresh.push(...depositChanges.map((change) => change.reserveAddress));
1128
+ }
1129
+ if (borrowChanges) {
1130
+ reservesToRefresh.push(...borrowChanges.map((change) => change.reserveAddress));
1131
+ }
1132
+
1133
+ const { collateralExchangeRates, cumulativeBorrowRates } = KaminoObligation.getRatesForObligation(
1134
+ market,
1135
+ this.state,
1136
+ slot,
1137
+ reservesToRefresh
1138
+ );
1139
+
1140
+ let newDeposits: ObligationCollateral[] = this.state.deposits;
1141
+ if (depositChanges) {
1142
+ for (const depositChange of depositChanges) {
1143
+ newDeposits = this.simulateDepositChange(newDeposits, depositChange, collateralExchangeRates);
1144
+ }
1145
+ }
1146
+
1147
+ let newBorrows: ObligationLiquidity[] = this.state.borrows;
1148
+ if (borrowChanges) {
1149
+ for (const borrowChange of borrowChanges) {
1150
+ const reserve = market.getReserveByAddress(borrowChange.reserveAddress);
1151
+ if (!reserve) {
1152
+ throw new Error(`Reserve not found: ${borrowChange.reserveAddress}`);
1153
+ }
1154
+ newBorrows = this.simulateBorrowChange(newBorrows, borrowChange, reserve.getCumulativeBorrowRate());
1155
+ }
1156
+ }
1157
+
1158
+ // Create a deep copy of the obligation state and override deposits/borrows
1159
+ const newObligationState = new Obligation({
1160
+ ...this.state,
1161
+ deposits: newDeposits,
1162
+ borrows: newBorrows,
1163
+ });
1164
+
1165
+ return new KaminoObligation(
1166
+ market,
1167
+ this.obligationAddress,
1168
+ newObligationState,
1169
+ collateralExchangeRates,
1170
+ cumulativeBorrowRates
1171
+ );
1172
+ }
1173
+
1077
1174
  /*
1078
1175
  How much of a given token can a user borrow extra given an elevation group,
1079
1176
  regardless of caps and liquidity or assuming infinite liquidity and infinite caps,
@@ -1196,6 +1293,36 @@ export class KaminoObligation {
1196
1293
  }
1197
1294
  }
1198
1295
 
1296
+ /*
1297
+ Same as getMaxBorrowAmountV2 but assumes a deposit is made first, calculating
1298
+ the new borrow power after the deposit, without overriding the obligation itself.
1299
+
1300
+ * @param market - The KaminoMarket instance.
1301
+ * @param liquidityMint - The liquidity mint Address.
1302
+ * @param slot - The slot number.
1303
+ * @param elevationGroup - The elevation group number (default: this.state.elevationGroup).
1304
+ * @returns The maximum borrow amount as a Decimal.
1305
+ * @throws Error if the reserve is not found.
1306
+ */
1307
+ getMaxBorrowAmountV2WithDeposit(
1308
+ market: KaminoMarket,
1309
+ liquidityMint: PublicKey,
1310
+ slot: number,
1311
+ elevationGroup: number = this.state.elevationGroup,
1312
+ depositAmountLamports: Decimal,
1313
+ depositReserveAddress: PublicKey
1314
+ ): Decimal {
1315
+ const depositChanges = [
1316
+ {
1317
+ reserveAddress: depositReserveAddress,
1318
+ amountChangeLamports: depositAmountLamports,
1319
+ },
1320
+ ];
1321
+ const obligationWithDeposit = this.withPositionChanges(market, slot, depositChanges);
1322
+
1323
+ return obligationWithDeposit.getMaxBorrowAmountV2(market, liquidityMint, slot, elevationGroup);
1324
+ }
1325
+
1199
1326
  /*
1200
1327
  Returns true if the loan is eligible for the elevation group, including for the default one.
1201
1328
  * @param market - The KaminoMarket object representing the market.
@@ -1447,6 +1574,44 @@ export class KaminoObligation {
1447
1574
  );
1448
1575
  }
1449
1576
 
1577
+ /**
1578
+ * Same as getMaxWithdrawAmount but assumes a repay is made first, calculating
1579
+ * the new withdraw power after the repay, without overriding the obligation itself.
1580
+ *
1581
+ * @param market - The KaminoMarket instance.
1582
+ * @param tokenMint - The liquidity mint Address.
1583
+ * @param slot - The slot number.
1584
+ * @param repayAmountLamports - The amount to repay in lamports (use U64_MAX for full repay).
1585
+ * @param repayReserveAddress - The reserve address of the borrow being repaid.
1586
+ * @returns The maximum withdraw amount as a Decimal.
1587
+ * @throws Error if the reserve is not found.
1588
+ */
1589
+ getMaxWithdrawAmountWithRepay(
1590
+ market: KaminoMarket,
1591
+ tokenMint: PublicKey,
1592
+ slot: number,
1593
+ repayAmountLamports: Decimal,
1594
+ repayReserveAddress: PublicKey
1595
+ ): Decimal {
1596
+ const repayReserve = market.getReserveByAddress(repayReserveAddress);
1597
+ if (!repayReserve) {
1598
+ throw new Error('Reserve not found');
1599
+ }
1600
+
1601
+ const repayAmount = repayAmountLamports.equals(U64_MAX)
1602
+ ? this.getBorrowAmountByReserve(repayReserve)
1603
+ : repayAmountLamports;
1604
+ const borrowChanges = [
1605
+ {
1606
+ reserveAddress: repayReserveAddress,
1607
+ amountChangeLamports: repayAmount.neg(), // as it's a repay
1608
+ },
1609
+ ];
1610
+ const obligationWithRepay = this.withPositionChanges(market, slot, undefined, borrowChanges);
1611
+
1612
+ return obligationWithRepay.getMaxWithdrawAmount(market, tokenMint, slot);
1613
+ }
1614
+
1450
1615
  getObligationLiquidityByReserve(reserveAddress: PublicKey): ObligationLiquidity {
1451
1616
  const obligationLiquidity = this.state.borrows.find((borrow) => borrow.borrowReserve.equals(reserveAddress));
1452
1617
 
@@ -28,6 +28,7 @@ import {
28
28
  PubkeyHashMap,
29
29
  Reserve,
30
30
  UserState,
31
+ AllOracleAccounts,
31
32
  } from '../lib';
32
33
  import {
33
34
  DepositAccounts,
@@ -838,7 +839,7 @@ export class KaminoVaultClient {
838
839
  const [{ ata: adminTokenAta, createAtaIx }] = createAtasIdempotent(vaultState.vaultAdminAuthority, [
839
840
  {
840
841
  mint: vaultState.tokenMint,
841
- tokenProgram: TOKEN_PROGRAM_ID,
842
+ tokenProgram: vaultState.tokenProgram,
842
843
  },
843
844
  ]);
844
845
 
@@ -1635,7 +1636,7 @@ export class KaminoVaultClient {
1635
1636
  baseVaultAuthority: vaultState.baseVaultAuthority,
1636
1637
  tokenAta: adminTokenAta,
1637
1638
  tokenMint: vaultState.tokenMint,
1638
- tokenProgram: TOKEN_PROGRAM_ID,
1639
+ tokenProgram: vaultState.tokenProgram,
1639
1640
  /** CPI accounts */
1640
1641
  lendingMarket: marketAddress,
1641
1642
  lendingMarketAuthority: lendingMarketAuth,
@@ -2324,9 +2325,13 @@ export class KaminoVaultClient {
2324
2325
  /**
2325
2326
  * This will load the onchain state for all the reserves that the vaults have allocations for, deduplicating the reserves
2326
2327
  * @param vaults - the vault states to load reserves for
2328
+ * @param oracleAccounts
2327
2329
  * @returns a hashmap from each reserve pubkey to the reserve state
2328
2330
  */
2329
- async loadVaultsReserves(vaults: VaultState[]): Promise<PubkeyHashMap<PublicKey, KaminoReserve>> {
2331
+ async loadVaultsReserves(
2332
+ vaults: VaultState[],
2333
+ oracleAccounts?: AllOracleAccounts
2334
+ ): Promise<PubkeyHashMap<PublicKey, KaminoReserve>> {
2330
2335
  const vaultReservesAddressesSet = new PublicKeySet(vaults.flatMap((vault) => this.getVaultReserves(vault)));
2331
2336
  const vaultReservesAddresses = vaultReservesAddressesSet.toArray();
2332
2337
  const reserveAccounts = await this.getConnection().getMultipleAccountsInfo(vaultReservesAddresses, 'processed');
@@ -2343,7 +2348,7 @@ export class KaminoVaultClient {
2343
2348
  return reserveAccount;
2344
2349
  });
2345
2350
 
2346
- const reservesAndOracles = await getTokenOracleData(this.getConnection(), deserializedReserves);
2351
+ const reservesAndOracles = await getTokenOracleData(this.getConnection(), deserializedReserves, oracleAccounts);
2347
2352
 
2348
2353
  const kaminoReserves = new PubkeyHashMap<PublicKey, KaminoReserve>();
2349
2354
 
@@ -2371,13 +2376,15 @@ export class KaminoVaultClient {
2371
2376
  * @param [slot] - the slot for which to retrieve the vault collaterals for. Optional. If not provided the function will fetch the current slot
2372
2377
  * @param [vaultReservesMap] - hashmap from each reserve pubkey to the reserve state. Optional. If provided the function will be significantly faster as it will not have to fetch the reserves
2373
2378
  * @param [kaminoMarkets] - a list of all the kamino markets. Optional. If provided the function will be significantly faster as it will not have to fetch the markets
2379
+ * @param oracleAccounts
2374
2380
  * @returns a hashmap from each reserve pubkey to the market overview of the collaterals that can be used and the min and max loan to value ratio in that market
2375
2381
  */
2376
2382
  async getVaultCollaterals(
2377
2383
  vaultState: VaultState,
2378
2384
  slot: number,
2379
2385
  vaultReservesMap?: PubkeyHashMap<PublicKey, KaminoReserve>,
2380
- kaminoMarkets?: KaminoMarket[]
2386
+ kaminoMarkets?: KaminoMarket[],
2387
+ oracleAccounts?: AllOracleAccounts
2381
2388
  ): Promise<PubkeyHashMap<PublicKey, MarketOverview>> {
2382
2389
  const vaultReservesStateMap = vaultReservesMap ? vaultReservesMap : await this.loadVaultReserves(vaultState);
2383
2390
  const vaultReservesState: KaminoReserve[] = [];
@@ -2401,7 +2408,11 @@ export class KaminoVaultClient {
2401
2408
  const missingReservesStates = (await Reserve.fetchMultiple(this.getConnection(), missingReserves.toArray())).filter(
2402
2409
  (reserve) => reserve !== null
2403
2410
  );
2404
- const missingReservesAndOracles = await getTokenOracleData(this.getConnection(), missingReservesStates);
2411
+ const missingReservesAndOracles = await getTokenOracleData(
2412
+ this.getConnection(),
2413
+ missingReservesStates,
2414
+ oracleAccounts
2415
+ );
2405
2416
  missingReservesAndOracles.forEach(([reserve, oracle], index) => {
2406
2417
  const fetchedReserve = new KaminoReserve(
2407
2418
  reserve,
package/src/client.ts CHANGED
@@ -362,7 +362,7 @@ async function deposit(connection: Connection, wallet: Keypair, token: string, d
362
362
  wallet.publicKey,
363
363
  new VanillaObligation(STAGING_LENDING_MARKET),
364
364
  true,
365
- { scope: new Scope('mainnet-beta', connection), scopeFeed: 'hubble' }
365
+ { scope: new Scope('mainnet-beta', connection), scopeConfigurations: [] }
366
366
  );
367
367
  console.log('User obligation', kaminoAction.getObligationPda().toString());
368
368
 
@@ -384,7 +384,7 @@ async function withdraw(connection: Connection, wallet: Keypair, token: string,
384
384
  wallet.publicKey,
385
385
  new VanillaObligation(new PublicKey(STAGING_LENDING_MARKET)),
386
386
  true,
387
- { scope: new Scope('mainnet-beta', connection), scopeFeed: 'hubble' }
387
+ { scope: new Scope('mainnet-beta', connection), scopeConfigurations: [] }
388
388
  );
389
389
  console.log('User obligation', kaminoAction.getObligationPda().toString());
390
390
 
@@ -406,7 +406,7 @@ async function borrow(connection: Connection, wallet: Keypair, token: string, bo
406
406
  wallet.publicKey,
407
407
  new VanillaObligation(new PublicKey(STAGING_LENDING_MARKET)),
408
408
  true,
409
- { scope: new Scope('mainnet-beta', connection), scopeFeed: 'hubble' }
409
+ { scope: new Scope('mainnet-beta', connection), scopeConfigurations: [] }
410
410
  );
411
411
  console.log('User obligation', kaminoAction.getObligationPda().toString());
412
412
 
@@ -428,7 +428,7 @@ async function repay(connection: Connection, wallet: Keypair, token: string, bor
428
428
  wallet.publicKey,
429
429
  new VanillaObligation(new PublicKey(STAGING_LENDING_MARKET)),
430
430
  true,
431
- { scope: new Scope('mainnet-beta', connection), scopeFeed: 'hubble' },
431
+ { scope: new Scope('mainnet-beta', connection), scopeConfigurations: [] },
432
432
  await connection.getSlot()
433
433
  );
434
434
  console.log('User obligation', kaminoAction.getObligationPda().toString());
@@ -52,18 +52,18 @@ import {
52
52
  TokenInfo,
53
53
  WithdrawalCaps,
54
54
  } from './idl_codegen/types';
55
- import { Fraction } from './classes/fraction';
55
+ import { Fraction } from './classes';
56
56
  import Decimal from 'decimal.js';
57
57
  import { BN } from '@coral-xyz/anchor';
58
58
  import { PythConfiguration, SwitchboardConfiguration } from './idl_codegen_kamino_vault/types';
59
59
  import * as fs from 'fs';
60
- import { MarketWithAddress } from './utils/managerTypes';
60
+ import { MarketWithAddress } from './utils';
61
61
  import {
62
62
  ManagementFeeBps,
63
63
  PendingVaultAdmin,
64
64
  PerformanceFeeBps,
65
65
  } from './idl_codegen_kamino_vault/types/VaultConfigField';
66
- import { getAccountOwner } from './utils/rpc';
66
+ import { getAccountOwner } from './utils';
67
67
  import { getAssociatedTokenAddressSync } from '@solana/spl-token';
68
68
 
69
69
  dotenv.config({
@@ -157,12 +157,12 @@ async function main() {
157
157
 
158
158
  console.log('reserve: ', reserve.publicKey);
159
159
 
160
- const _createReserveSig = await processTxn(env.client, env.payer, txnIxs[0], mode, 2500, [reserve]);
160
+ await processTxn(env.client, env.payer, txnIxs[0], mode, 2500, [reserve]);
161
161
 
162
162
  const [lut, createLutIxs] = await createUpdateReserveConfigLutIxs(env, marketAddress, reserve.publicKey);
163
163
  await processTxn(env.client, env.payer, createLutIxs, mode, 2500, []);
164
164
 
165
- const _updateSig = await processTxn(env.client, env.payer, txnIxs[1], mode, 2500, [], 400_000, 1000, [lut]);
165
+ await processTxn(env.client, env.payer, txnIxs[1], mode, 2500, [], 400_000, 1000, [lut]);
166
166
 
167
167
  mode === 'execute' &&
168
168
  console.log(
@@ -224,7 +224,7 @@ async function main() {
224
224
  updateEntireConfig
225
225
  );
226
226
 
227
- const _updateReserveSig = await processTxn(env.client, env.payer, ixs, mode, 2500, [], 400_000);
227
+ await processTxn(env.client, env.payer, ixs, mode, 2500, [], 400_000);
228
228
 
229
229
  mode === 'execute' && console.log('Reserve Updated with config -> ', JSON.parse(JSON.stringify(reserveConfig)));
230
230
  });
@@ -296,7 +296,7 @@ async function main() {
296
296
 
297
297
  const { vault: vaultKp, initVaultIxs: instructions } = await kaminoManager.createVaultIxs(kaminoVaultConfig);
298
298
 
299
- const _createVaultSig = await processTxn(
299
+ await processTxn(
300
300
  env.client,
301
301
  env.payer,
302
302
  [...instructions.createAtaIfNeededIxs, ...instructions.initVaultIxs, instructions.createLUTIx],
@@ -305,7 +305,7 @@ async function main() {
305
305
  [vaultKp]
306
306
  );
307
307
  await sleep(2000);
308
- const _populateLUTSig = await processTxn(
308
+ await processTxn(
309
309
  env.client,
310
310
  env.payer,
311
311
  [...instructions.populateLUTIxs, ...instructions.cleanupIxs],
@@ -314,14 +314,7 @@ async function main() {
314
314
  []
315
315
  );
316
316
 
317
- const _setSharesMetadataSig = await processTxn(
318
- env.client,
319
- env.payer,
320
- [instructions.initSharesMetadataIx],
321
- mode,
322
- 2500,
323
- []
324
- );
317
+ await processTxn(env.client, env.payer, [instructions.initSharesMetadataIx], mode, 2500, []);
325
318
  mode === 'execute' && console.log('Vault created:', vaultKp.publicKey.toBase58());
326
319
  });
327
320
 
@@ -1173,19 +1166,33 @@ async function main() {
1173
1166
  }
1174
1167
  });
1175
1168
 
1176
- commands.command('get-oracle-mappings').action(async () => {
1177
- const env = initializeClient(false, false);
1178
- const kaminoManager = new KaminoManager(
1179
- env.connection,
1180
- DEFAULT_RECENT_SLOT_DURATION_MS,
1181
- env.kLendProgramId,
1182
- env.kVaultProgramId
1183
- );
1169
+ commands
1170
+ .command('get-oracle-mappings')
1171
+ .requiredOption('--lending-market <string>', 'Lending Market Address')
1172
+ .action(async ({ lendingMarket }) => {
1173
+ const env = initializeClient(false, false);
1174
+ const kaminoManager = new KaminoManager(
1175
+ env.connection,
1176
+ DEFAULT_RECENT_SLOT_DURATION_MS,
1177
+ env.kLendProgramId,
1178
+ env.kVaultProgramId
1179
+ );
1180
+ const market = await KaminoMarket.load(
1181
+ env.connection,
1182
+ new PublicKey(lendingMarket),
1183
+ DEFAULT_RECENT_SLOT_DURATION_MS,
1184
+ env.kLendProgramId
1185
+ );
1186
+ if (!market) {
1187
+ throw Error(`Lending market ${lendingMarket} not found`);
1188
+ }
1184
1189
 
1185
- console.log('Getting oracle mappings');
1186
- const oracleConfigs = await kaminoManager.getScopeOracleConfigs();
1187
- console.log('oracleConfigs', JSON.parse(JSON.stringify(oracleConfigs)));
1188
- });
1190
+ console.log('Getting oracle mappings');
1191
+ const oracleConfigs = await kaminoManager.getScopeOracleConfigs(market);
1192
+ for (const [oraclePrices, configs] of oracleConfigs.entries()) {
1193
+ console.log(`OraclePrices pubkey: ${oraclePrices.toString()}`, 'Configs:', JSON.parse(JSON.stringify(configs)));
1194
+ }
1195
+ });
1189
1196
 
1190
1197
  commands.command('get-all-vaults').action(async () => {
1191
1198
  const env = initializeClient(false, false);
@@ -1370,7 +1377,7 @@ async function main() {
1370
1377
  // executing 6 ixs in a txn to make sure they fit
1371
1378
  for (let ixnIndex = 0; ixnIndex < ixs.length; ixnIndex += 6) {
1372
1379
  const ixnToExecute = ixs.slice(ixnIndex, ixnIndex + 6);
1373
- const _updateLendingMarketSig = await processTxn(env.client, env.payer, ixnToExecute, mode, 2500, [], 400_000);
1380
+ await processTxn(env.client, env.payer, ixnToExecute, mode, 2500, [], 400_000);
1374
1381
  }
1375
1382
 
1376
1383
  mode === 'execute' &&
@@ -1410,7 +1417,7 @@ async function main() {
1410
1417
 
1411
1418
  const ix = kaminoManager.updateLendingMarketOwnerIxs(marketWithAddress);
1412
1419
 
1413
- const _updateLendingMarketSig = await processTxn(env.client, env.payer, [ix], mode, 2500, [], 400_000);
1420
+ await processTxn(env.client, env.payer, [ix], mode, 2500, [], 400_000);
1414
1421
 
1415
1422
  mode === 'execute' &&
1416
1423
  console.log(
@@ -1465,7 +1472,7 @@ async function main() {
1465
1472
 
1466
1473
  const ixs = kaminoManager.updateLendingMarketIxs(marketWithAddress, newLendingMarket);
1467
1474
 
1468
- const _updateLendingMarketSig = await processTxn(env.client, env.payer, ixs, mode, 2500, [], 400_000);
1475
+ await processTxn(env.client, env.payer, ixs, mode, 2500, [], 400_000);
1469
1476
 
1470
1477
  mode === 'execute' &&
1471
1478
  console.log(
@@ -1520,7 +1527,7 @@ async function main() {
1520
1527
 
1521
1528
  const ixs = await kaminoManager.updateReserveIxs(marketWithAddress, reserveAddress, newReserveConfig);
1522
1529
 
1523
- const _updateLendingMarketSig = await processTxn(env.client, env.payer, ixs, mode, 2500, [], 400_000);
1530
+ await processTxn(env.client, env.payer, ixs, mode, 2500, [], 400_000);
1524
1531
 
1525
1532
  mode === 'execute' &&
1526
1533
  console.log(
@@ -1811,9 +1818,7 @@ function parseBorrowRateCurve(reserveConfigFromFile: any): BorrowRateCurve {
1811
1818
 
1812
1819
  curvePoints.forEach((curvePoint, index) => (finalCurvePoints[index] = curvePoint));
1813
1820
 
1814
- const borrowRateCurve = new BorrowRateCurve({ points: finalCurvePoints });
1815
-
1816
- return borrowRateCurve;
1821
+ return new BorrowRateCurve({ points: finalCurvePoints });
1817
1822
  }
1818
1823
 
1819
1824
  function parseReserveBorrowLimitAgainstCollInEmode(reserveConfigFromFile: any): BN[] {