@kamino-finance/klend-sdk 7.3.10-beta.0 → 7.3.10-beta.1

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 (131) hide show
  1. package/dist/classes/action.d.ts +21 -91
  2. package/dist/classes/action.d.ts.map +1 -1
  3. package/dist/classes/action.js +152 -139
  4. package/dist/classes/action.js.map +1 -1
  5. package/dist/classes/actionTypes.d.ts +310 -0
  6. package/dist/classes/actionTypes.d.ts.map +1 -0
  7. package/dist/classes/actionTypes.js +3 -0
  8. package/dist/classes/actionTypes.js.map +1 -0
  9. package/dist/classes/configItems.d.ts +1 -6
  10. package/dist/classes/configItems.d.ts.map +1 -1
  11. package/dist/classes/configItems.js +1 -93
  12. package/dist/classes/configItems.js.map +1 -1
  13. package/dist/classes/farm_utils.d.ts +1 -1
  14. package/dist/classes/farm_utils.d.ts.map +1 -1
  15. package/dist/classes/farm_utils.js +3 -1
  16. package/dist/classes/farm_utils.js.map +1 -1
  17. package/dist/classes/market.d.ts +15 -10
  18. package/dist/classes/market.d.ts.map +1 -1
  19. package/dist/classes/market.js +49 -26
  20. package/dist/classes/market.js.map +1 -1
  21. package/dist/classes/obligation.d.ts +9 -9
  22. package/dist/classes/obligation.d.ts.map +1 -1
  23. package/dist/classes/obligation.js +48 -50
  24. package/dist/classes/obligation.js.map +1 -1
  25. package/dist/classes/obligationOrder.d.ts.map +1 -1
  26. package/dist/classes/obligationOrder.js +6 -3
  27. package/dist/classes/obligationOrder.js.map +1 -1
  28. package/dist/classes/reserve.d.ts +7 -3
  29. package/dist/classes/reserve.d.ts.map +1 -1
  30. package/dist/classes/reserve.js +31 -43
  31. package/dist/classes/reserve.js.map +1 -1
  32. package/dist/classes/shared.d.ts +3 -2
  33. package/dist/classes/shared.d.ts.map +1 -1
  34. package/dist/classes/vault.d.ts +28 -1
  35. package/dist/classes/vault.d.ts.map +1 -1
  36. package/dist/classes/vault.js +103 -6
  37. package/dist/classes/vault.js.map +1 -1
  38. package/dist/classes/vault_types.d.ts +2 -1
  39. package/dist/classes/vault_types.d.ts.map +1 -1
  40. package/dist/client/commands/borrow.d.ts +1 -1
  41. package/dist/client/commands/borrow.d.ts.map +1 -1
  42. package/dist/client/commands/borrow.js +11 -2
  43. package/dist/client/commands/borrow.js.map +1 -1
  44. package/dist/client/commands/deposit.d.ts +1 -1
  45. package/dist/client/commands/deposit.d.ts.map +1 -1
  46. package/dist/client/commands/deposit.js +11 -2
  47. package/dist/client/commands/deposit.js.map +1 -1
  48. package/dist/client/commands/printReserve.d.ts +1 -1
  49. package/dist/client/commands/printReserve.d.ts.map +1 -1
  50. package/dist/client/commands/printReserve.js +2 -4
  51. package/dist/client/commands/printReserve.js.map +1 -1
  52. package/dist/client/commands/repay.d.ts +1 -1
  53. package/dist/client/commands/repay.d.ts.map +1 -1
  54. package/dist/client/commands/repay.js +12 -2
  55. package/dist/client/commands/repay.js.map +1 -1
  56. package/dist/client/commands/withdraw.d.ts +1 -1
  57. package/dist/client/commands/withdraw.d.ts.map +1 -1
  58. package/dist/client/commands/withdraw.js +11 -2
  59. package/dist/client/commands/withdraw.js.map +1 -1
  60. package/dist/lending_operations/repay_with_collateral_calcs.d.ts +1 -1
  61. package/dist/lending_operations/repay_with_collateral_calcs.d.ts.map +1 -1
  62. package/dist/lending_operations/repay_with_collateral_calcs.js +2 -2
  63. package/dist/lending_operations/repay_with_collateral_calcs.js.map +1 -1
  64. package/dist/lending_operations/repay_with_collateral_operations.d.ts +4 -4
  65. package/dist/lending_operations/repay_with_collateral_operations.d.ts.map +1 -1
  66. package/dist/lending_operations/repay_with_collateral_operations.js +43 -10
  67. package/dist/lending_operations/repay_with_collateral_operations.js.map +1 -1
  68. package/dist/lending_operations/swap_collateral_operations.d.ts +4 -4
  69. package/dist/lending_operations/swap_collateral_operations.d.ts.map +1 -1
  70. package/dist/lending_operations/swap_collateral_operations.js +40 -21
  71. package/dist/lending_operations/swap_collateral_operations.js.map +1 -1
  72. package/dist/leverage/operations.d.ts +6 -6
  73. package/dist/leverage/operations.d.ts.map +1 -1
  74. package/dist/leverage/operations.js +167 -52
  75. package/dist/leverage/operations.js.map +1 -1
  76. package/dist/leverage/types.d.ts +2 -2
  77. package/dist/leverage/types.d.ts.map +1 -1
  78. package/dist/manager/client_kamino_manager.js +0 -2
  79. package/dist/manager/client_kamino_manager.js.map +1 -1
  80. package/dist/obligation_orders/price_based.js +5 -3
  81. package/dist/obligation_orders/price_based.js.map +1 -1
  82. package/dist/utils/Logger.d.ts +14 -0
  83. package/dist/utils/Logger.d.ts.map +1 -0
  84. package/dist/utils/Logger.js +12 -0
  85. package/dist/utils/Logger.js.map +1 -0
  86. package/dist/utils/ObligationType.d.ts +33 -1
  87. package/dist/utils/ObligationType.d.ts.map +1 -1
  88. package/dist/utils/ObligationType.js +81 -2
  89. package/dist/utils/ObligationType.js.map +1 -1
  90. package/dist/utils/api.d.ts +13 -4
  91. package/dist/utils/api.d.ts.map +1 -1
  92. package/dist/utils/api.js +33 -31
  93. package/dist/utils/api.js.map +1 -1
  94. package/dist/utils/userMetadata.d.ts +2 -2
  95. package/dist/utils/userMetadata.d.ts.map +1 -1
  96. package/dist/utils/userMetadata.js +49 -25
  97. package/dist/utils/userMetadata.js.map +1 -1
  98. package/dist/utils/validations.d.ts +1 -0
  99. package/dist/utils/validations.d.ts.map +1 -1
  100. package/dist/utils/validations.js +5 -0
  101. package/dist/utils/validations.js.map +1 -1
  102. package/package.json +1 -1
  103. package/src/classes/action.ts +346 -372
  104. package/src/classes/actionTypes.ts +295 -0
  105. package/src/classes/configItems.ts +1 -99
  106. package/src/classes/farm_utils.ts +5 -1
  107. package/src/classes/market.ts +74 -31
  108. package/src/classes/obligation.ts +54 -53
  109. package/src/classes/obligationOrder.ts +6 -3
  110. package/src/classes/reserve.ts +118 -122
  111. package/src/classes/shared.ts +4 -2
  112. package/src/classes/vault.ts +160 -7
  113. package/src/classes/vault_types.ts +2 -1
  114. package/src/client/client.ts +17 -18
  115. package/src/client/commands/borrow.ts +10 -9
  116. package/src/client/commands/deposit.ts +10 -9
  117. package/src/client/commands/printReserve.ts +2 -4
  118. package/src/client/commands/repay.ts +11 -10
  119. package/src/client/commands/withdraw.ts +15 -9
  120. package/src/lending_operations/repay_with_collateral_calcs.ts +3 -4
  121. package/src/lending_operations/repay_with_collateral_operations.ts +40 -38
  122. package/src/lending_operations/swap_collateral_operations.ts +47 -41
  123. package/src/leverage/operations.ts +168 -129
  124. package/src/leverage/types.ts +2 -2
  125. package/src/manager/client_kamino_manager.ts +0 -2
  126. package/src/obligation_orders/price_based.ts +7 -5
  127. package/src/utils/Logger.ts +14 -0
  128. package/src/utils/ObligationType.ts +92 -1
  129. package/src/utils/api.ts +56 -33
  130. package/src/utils/userMetadata.ts +64 -30
  131. package/src/utils/validations.ts +5 -0
@@ -24,6 +24,7 @@ import {
24
24
  INITIAL_COLLATERAL_RATE,
25
25
  lendingMarketAuthPda,
26
26
  MarketWithAddress,
27
+ MIN_INITIAL_DEPOSIT,
27
28
  ONE_HUNDRED_PCT_IN_BPS,
28
29
  reservePdas,
29
30
  SLOTS_PER_DAY,
@@ -36,7 +37,7 @@ import { FeeCalculation, Fees, ReserveDataType, ReserveFarmInfo, ReserveRewardYi
36
37
  import { Reserve, ReserveFields } from '../@codegen/klend/accounts';
37
38
  import { CurvePointFields, ReserveConfig, UpdateConfigMode, UpdateConfigModeKind } from '../@codegen/klend/types';
38
39
  import { calculateAPYFromAPR, getBorrowRate, lamportsToNumberDecimal, parseTokenSymbol, positiveOrZero } from './utils';
39
- import { CompositeConfigItem, encodeUsingLayout, EntireReserveConfigUpdater } from './configItems';
40
+ import { CompositeConfigItem, encodeUsingLayout, ConfigUpdater } from './configItems';
40
41
  import { bfToDecimal, Fraction } from './fraction';
41
42
  import { ActionType } from './action';
42
43
  import { BorrowCapsAndCounters, ElevationGroupDescription, KaminoMarket } from './market';
@@ -48,7 +49,7 @@ import {
48
49
  UpdateReserveConfigArgs,
49
50
  } from '../lib';
50
51
  import { aprToApy, KaminoPrices } from '@kamino-finance/kliquidity-sdk';
51
- import { FarmState, RewardInfo } from '@kamino-finance/farms-sdk';
52
+ import { FarmAndKey, FarmState, RewardInfo } from '@kamino-finance/farms-sdk';
52
53
  import { TOKEN_PROGRAM_ADDRESS } from '@solana-program/token';
53
54
  import { maxBigInt } from '../utils/bigint';
54
55
  import { getCreateAccountInstruction, SYSTEM_PROGRAM_ADDRESS } from '@solana-program/system';
@@ -69,7 +70,7 @@ export class KaminoReserve {
69
70
 
70
71
  tokenOraclePrice: TokenOracleData;
71
72
  stats: ReserveDataType;
72
- private farmData: ReserveFarmInfo = { fetched: false, farmStates: [] };
73
+ private farmData: ReserveFarmInfo = { fetched: false, farms: [] };
73
74
 
74
75
  private rpc: Rpc<KaminoReserveRpcApi>;
75
76
  private readonly recentSlotDurationMs: number;
@@ -812,22 +813,22 @@ export class KaminoReserve {
812
813
 
813
814
  async loadFarmStates() {
814
815
  if (!this.farmData.fetched) {
815
- const farmStates: FarmState[] = [];
816
+ const farmStates: FarmAndKey[] = [];
816
817
  const debtFarmAddress = this.getDebtFarmAddress();
817
818
  if (isSome(debtFarmAddress)) {
818
819
  const farmState = await FarmState.fetch(this.rpc, debtFarmAddress.value);
819
820
  if (farmState !== null) {
820
- farmStates.push(farmState);
821
+ farmStates.push({ farmState, key: debtFarmAddress.value });
821
822
  }
822
823
  }
823
824
  const collateralFarmAddress = this.getCollateralFarmAddress();
824
825
  if (isSome(collateralFarmAddress)) {
825
826
  const farmState = await FarmState.fetch(this.rpc, collateralFarmAddress.value);
826
827
  if (farmState !== null) {
827
- farmStates.push(farmState);
828
+ farmStates.push({ farmState, key: collateralFarmAddress.value });
828
829
  }
829
830
  }
830
- this.farmData.farmStates = farmStates;
831
+ this.farmData.farms = farmStates;
831
832
  this.farmData.fetched = true;
832
833
  }
833
834
  }
@@ -838,14 +839,19 @@ export class KaminoReserve {
838
839
  throw Error('KaminoMarket must call loadReserves.');
839
840
  }
840
841
 
841
- const isDebtReward = this.state.farmDebt === this.address;
842
842
  await this.loadFarmStates();
843
843
  const yields: ReserveRewardYield[] = [];
844
- for (const farmState of this.farmData.farmStates) {
845
- for (const rewardInfo of farmState.rewardInfos.filter(
844
+ for (const farmAndKey of this.farmData.farms) {
845
+ const isDebtReward = this.state.farmDebt === farmAndKey.key;
846
+ for (const rewardInfo of farmAndKey.farmState.rewardInfos.filter(
846
847
  (x) => x.token.mint !== DEFAULT_PUBLIC_KEY && !x.rewardsAvailable.isZero()
847
848
  )) {
848
- const { apy, apr } = this.calculateRewardYield(prices, rewardInfo, isDebtReward);
849
+ const { apy, apr } = this.calculateRewardYield(
850
+ prices,
851
+ rewardInfo,
852
+ isDebtReward,
853
+ new Decimal(farmAndKey.farmState.totalActiveStakeScaled.toString())
854
+ );
849
855
  if (apy.isZero() && apr.isZero()) {
850
856
  continue;
851
857
  }
@@ -855,9 +861,14 @@ export class KaminoReserve {
855
861
  return yields;
856
862
  }
857
863
 
858
- private calculateRewardYield(prices: KaminoPrices, rewardInfo: RewardInfo, isDebtReward: boolean) {
864
+ calculateRewardYield(
865
+ prices: KaminoPrices,
866
+ rewardInfo: RewardInfo,
867
+ isDebtReward: boolean,
868
+ farmTotalStakeLamports: Decimal
869
+ ) {
859
870
  const mintAddress = this.getLiquidityMint();
860
- const rewardPerTimeUnitSecond = getRewardPerTimeUnitSecond(rewardInfo);
871
+ const rewardPerTimeUnitSecond = getRewardPerTimeUnitSecond(rewardInfo, farmTotalStakeLamports);
861
872
  const reserveToken = prices.spot[mintAddress.toString()];
862
873
  const rewardToken = prices.spot[rewardInfo.token.mint.toString()];
863
874
 
@@ -1239,74 +1250,69 @@ export async function updateReserveConfigIx(
1239
1250
  return updateReserveConfig(args, accounts, undefined, programId);
1240
1251
  }
1241
1252
 
1242
- export const RESERVE_CONFIG_UPDATER = new EntireReserveConfigUpdater(
1243
- UpdateConfigMode.fromDecoded,
1244
- ReserveConfig,
1245
- (config) => ({
1246
- [UpdateConfigMode.UpdateLoanToValuePct.kind]: config.loanToValuePct,
1247
- [UpdateConfigMode.UpdateMaxLiquidationBonusBps.kind]: config.maxLiquidationBonusBps,
1248
- [UpdateConfigMode.UpdateLiquidationThresholdPct.kind]: config.liquidationThresholdPct,
1249
- [UpdateConfigMode.UpdateProtocolLiquidationFee.kind]: config.protocolLiquidationFeePct,
1250
- [UpdateConfigMode.UpdateProtocolTakeRate.kind]: config.protocolTakeRatePct,
1251
- [UpdateConfigMode.UpdateFeesOriginationFee.kind]: config.fees.originationFeeSf,
1252
- [UpdateConfigMode.UpdateFeesFlashLoanFee.kind]: config.fees.flashLoanFeeSf,
1253
- [UpdateConfigMode.DeprecatedUpdateFeesReferralFeeBps.kind]: [], // deprecated
1254
- [UpdateConfigMode.UpdateDepositLimit.kind]: config.depositLimit,
1255
- [UpdateConfigMode.UpdateBorrowLimit.kind]: config.borrowLimit,
1256
- [UpdateConfigMode.UpdateTokenInfoLowerHeuristic.kind]: config.tokenInfo.heuristic.lower,
1257
- [UpdateConfigMode.UpdateTokenInfoUpperHeuristic.kind]: config.tokenInfo.heuristic.upper,
1258
- [UpdateConfigMode.UpdateTokenInfoExpHeuristic.kind]: config.tokenInfo.heuristic.exp,
1259
- [UpdateConfigMode.UpdateTokenInfoTwapDivergence.kind]: config.tokenInfo.maxTwapDivergenceBps,
1260
- [UpdateConfigMode.UpdateTokenInfoScopeTwap.kind]: config.tokenInfo.scopeConfiguration.twapChain,
1261
- [UpdateConfigMode.UpdateTokenInfoScopeChain.kind]: config.tokenInfo.scopeConfiguration.priceChain,
1262
- [UpdateConfigMode.UpdateTokenInfoName.kind]: config.tokenInfo.name,
1263
- [UpdateConfigMode.UpdateTokenInfoPriceMaxAge.kind]: config.tokenInfo.maxAgePriceSeconds,
1264
- [UpdateConfigMode.UpdateTokenInfoTwapMaxAge.kind]: config.tokenInfo.maxAgeTwapSeconds,
1265
- [UpdateConfigMode.UpdateScopePriceFeed.kind]: config.tokenInfo.scopeConfiguration.priceFeed,
1266
- [UpdateConfigMode.UpdatePythPrice.kind]: config.tokenInfo.pythConfiguration.price,
1267
- [UpdateConfigMode.UpdateSwitchboardFeed.kind]: config.tokenInfo.switchboardConfiguration.priceAggregator,
1268
- [UpdateConfigMode.UpdateSwitchboardTwapFeed.kind]: config.tokenInfo.switchboardConfiguration.twapAggregator,
1269
- [UpdateConfigMode.UpdateBorrowRateCurve.kind]: config.borrowRateCurve,
1270
- [UpdateConfigMode.UpdateEntireReserveConfig.kind]: [], // technically `config` would be a valid thing here, but we actually do NOT want entire config update among ixs produced for field-by-field updates
1271
- [UpdateConfigMode.UpdateDebtWithdrawalCap.kind]: new CompositeConfigItem(
1272
- config.debtWithdrawalCap.configCapacity,
1273
- config.debtWithdrawalCap.configIntervalLengthSeconds
1274
- ),
1275
- [UpdateConfigMode.UpdateDepositWithdrawalCap.kind]: new CompositeConfigItem(
1276
- config.depositWithdrawalCap.configCapacity,
1277
- config.depositWithdrawalCap.configIntervalLengthSeconds
1278
- ),
1279
- [UpdateConfigMode.DeprecatedUpdateDebtWithdrawalCapCurrentTotal.kind]: [], // deprecated
1280
- [UpdateConfigMode.DeprecatedUpdateDepositWithdrawalCapCurrentTotal.kind]: [], // deprecated
1281
- [UpdateConfigMode.UpdateBadDebtLiquidationBonusBps.kind]: config.badDebtLiquidationBonusBps,
1282
- [UpdateConfigMode.UpdateMinLiquidationBonusBps.kind]: config.minLiquidationBonusBps,
1283
- [UpdateConfigMode.UpdateDeleveragingMarginCallPeriod.kind]: config.deleveragingMarginCallPeriodSecs,
1284
- [UpdateConfigMode.UpdateBorrowFactor.kind]: config.borrowFactorPct,
1285
- [UpdateConfigMode.UpdateAssetTier.kind]: config.assetTier,
1286
- [UpdateConfigMode.UpdateElevationGroup.kind]: config.elevationGroups,
1287
- [UpdateConfigMode.UpdateDeleveragingThresholdDecreaseBpsPerDay.kind]: config.deleveragingThresholdDecreaseBpsPerDay,
1288
- [UpdateConfigMode.DeprecatedUpdateMultiplierSideBoost.kind]: [], // deprecated
1289
- [UpdateConfigMode.DeprecatedUpdateMultiplierTagBoost.kind]: [], // deprecated
1290
- [UpdateConfigMode.UpdateReserveStatus.kind]: config.status,
1291
- [UpdateConfigMode.UpdateFarmCollateral.kind]: [], // the farm fields live on the `Reserve` level...
1292
- [UpdateConfigMode.UpdateFarmDebt.kind]: [], // ...so we are not concerned with them in the `ReserveConfig`'s field-by-field update tx
1293
- [UpdateConfigMode.UpdateDisableUsageAsCollateralOutsideEmode.kind]: config.disableUsageAsCollOutsideEmode,
1294
- [UpdateConfigMode.UpdateBlockBorrowingAboveUtilizationPct.kind]: config.utilizationLimitBlockBorrowingAbovePct,
1295
- [UpdateConfigMode.UpdateBlockPriceUsage.kind]: config.tokenInfo.blockPriceUsage,
1296
- [UpdateConfigMode.UpdateBorrowLimitOutsideElevationGroup.kind]: config.borrowLimitOutsideElevationGroup,
1297
- [UpdateConfigMode.UpdateBorrowLimitsInElevationGroupAgainstThisReserve.kind]:
1298
- config.borrowLimitAgainstThisCollateralInElevationGroup,
1299
- [UpdateConfigMode.UpdateHostFixedInterestRateBps.kind]: config.hostFixedInterestRateBps,
1300
- [UpdateConfigMode.UpdateAutodeleverageEnabled.kind]: config.autodeleverageEnabled,
1301
- [UpdateConfigMode.UpdateDeleveragingBonusIncreaseBpsPerDay.kind]: config.deleveragingBonusIncreaseBpsPerDay,
1302
- [UpdateConfigMode.UpdateProtocolOrderExecutionFee.kind]: config.protocolOrderExecutionFeePct,
1303
- [UpdateConfigMode.UpdateProposerAuthorityLock.kind]: config.proposerAuthorityLocked,
1304
- [UpdateConfigMode.UpdateMinDeleveragingBonusBps.kind]: config.minDeleveragingBonusBps,
1305
- [UpdateConfigMode.UpdateBlockCTokenUsage.kind]: config.blockCtokenUsage,
1306
- })
1307
- );
1308
-
1309
- // TODO : this needs to be deprecated
1253
+ export const RESERVE_CONFIG_UPDATER = new ConfigUpdater(UpdateConfigMode.fromDecoded, ReserveConfig, (config) => ({
1254
+ [UpdateConfigMode.UpdateLoanToValuePct.kind]: config.loanToValuePct,
1255
+ [UpdateConfigMode.UpdateMaxLiquidationBonusBps.kind]: config.maxLiquidationBonusBps,
1256
+ [UpdateConfigMode.UpdateLiquidationThresholdPct.kind]: config.liquidationThresholdPct,
1257
+ [UpdateConfigMode.UpdateProtocolLiquidationFee.kind]: config.protocolLiquidationFeePct,
1258
+ [UpdateConfigMode.UpdateProtocolTakeRate.kind]: config.protocolTakeRatePct,
1259
+ [UpdateConfigMode.UpdateFeesOriginationFee.kind]: config.fees.originationFeeSf,
1260
+ [UpdateConfigMode.UpdateFeesFlashLoanFee.kind]: config.fees.flashLoanFeeSf,
1261
+ [UpdateConfigMode.DeprecatedUpdateFeesReferralFeeBps.kind]: [], // deprecated
1262
+ [UpdateConfigMode.UpdateDepositLimit.kind]: config.depositLimit,
1263
+ [UpdateConfigMode.UpdateBorrowLimit.kind]: config.borrowLimit,
1264
+ [UpdateConfigMode.UpdateTokenInfoLowerHeuristic.kind]: config.tokenInfo.heuristic.lower,
1265
+ [UpdateConfigMode.UpdateTokenInfoUpperHeuristic.kind]: config.tokenInfo.heuristic.upper,
1266
+ [UpdateConfigMode.UpdateTokenInfoExpHeuristic.kind]: config.tokenInfo.heuristic.exp,
1267
+ [UpdateConfigMode.UpdateTokenInfoTwapDivergence.kind]: config.tokenInfo.maxTwapDivergenceBps,
1268
+ [UpdateConfigMode.UpdateTokenInfoScopeTwap.kind]: config.tokenInfo.scopeConfiguration.twapChain,
1269
+ [UpdateConfigMode.UpdateTokenInfoScopeChain.kind]: config.tokenInfo.scopeConfiguration.priceChain,
1270
+ [UpdateConfigMode.UpdateTokenInfoName.kind]: config.tokenInfo.name,
1271
+ [UpdateConfigMode.UpdateTokenInfoPriceMaxAge.kind]: config.tokenInfo.maxAgePriceSeconds,
1272
+ [UpdateConfigMode.UpdateTokenInfoTwapMaxAge.kind]: config.tokenInfo.maxAgeTwapSeconds,
1273
+ [UpdateConfigMode.UpdateScopePriceFeed.kind]: config.tokenInfo.scopeConfiguration.priceFeed,
1274
+ [UpdateConfigMode.UpdatePythPrice.kind]: config.tokenInfo.pythConfiguration.price,
1275
+ [UpdateConfigMode.UpdateSwitchboardFeed.kind]: config.tokenInfo.switchboardConfiguration.priceAggregator,
1276
+ [UpdateConfigMode.UpdateSwitchboardTwapFeed.kind]: config.tokenInfo.switchboardConfiguration.twapAggregator,
1277
+ [UpdateConfigMode.UpdateBorrowRateCurve.kind]: config.borrowRateCurve,
1278
+ [UpdateConfigMode.UpdateEntireReserveConfig.kind]: [], // technically `config` would be a valid thing here, but we actually do NOT want entire config update among ixs produced for field-by-field updates
1279
+ [UpdateConfigMode.UpdateDebtWithdrawalCap.kind]: new CompositeConfigItem(
1280
+ config.debtWithdrawalCap.configCapacity,
1281
+ config.debtWithdrawalCap.configIntervalLengthSeconds
1282
+ ),
1283
+ [UpdateConfigMode.UpdateDepositWithdrawalCap.kind]: new CompositeConfigItem(
1284
+ config.depositWithdrawalCap.configCapacity,
1285
+ config.depositWithdrawalCap.configIntervalLengthSeconds
1286
+ ),
1287
+ [UpdateConfigMode.DeprecatedUpdateDebtWithdrawalCapCurrentTotal.kind]: [], // deprecated
1288
+ [UpdateConfigMode.DeprecatedUpdateDepositWithdrawalCapCurrentTotal.kind]: [], // deprecated
1289
+ [UpdateConfigMode.UpdateBadDebtLiquidationBonusBps.kind]: config.badDebtLiquidationBonusBps,
1290
+ [UpdateConfigMode.UpdateMinLiquidationBonusBps.kind]: config.minLiquidationBonusBps,
1291
+ [UpdateConfigMode.UpdateDeleveragingMarginCallPeriod.kind]: config.deleveragingMarginCallPeriodSecs,
1292
+ [UpdateConfigMode.UpdateBorrowFactor.kind]: config.borrowFactorPct,
1293
+ [UpdateConfigMode.UpdateAssetTier.kind]: config.assetTier,
1294
+ [UpdateConfigMode.UpdateElevationGroup.kind]: config.elevationGroups,
1295
+ [UpdateConfigMode.UpdateDeleveragingThresholdDecreaseBpsPerDay.kind]: config.deleveragingThresholdDecreaseBpsPerDay,
1296
+ [UpdateConfigMode.DeprecatedUpdateMultiplierSideBoost.kind]: [], // deprecated
1297
+ [UpdateConfigMode.DeprecatedUpdateMultiplierTagBoost.kind]: [], // deprecated
1298
+ [UpdateConfigMode.UpdateReserveStatus.kind]: config.status,
1299
+ [UpdateConfigMode.UpdateFarmCollateral.kind]: [], // the farm fields live on the `Reserve` level...
1300
+ [UpdateConfigMode.UpdateFarmDebt.kind]: [], // ...so we are not concerned with them in the `ReserveConfig`'s field-by-field update tx
1301
+ [UpdateConfigMode.UpdateDisableUsageAsCollateralOutsideEmode.kind]: config.disableUsageAsCollOutsideEmode,
1302
+ [UpdateConfigMode.UpdateBlockBorrowingAboveUtilizationPct.kind]: config.utilizationLimitBlockBorrowingAbovePct,
1303
+ [UpdateConfigMode.UpdateBlockPriceUsage.kind]: config.tokenInfo.blockPriceUsage,
1304
+ [UpdateConfigMode.UpdateBorrowLimitOutsideElevationGroup.kind]: config.borrowLimitOutsideElevationGroup,
1305
+ [UpdateConfigMode.UpdateBorrowLimitsInElevationGroupAgainstThisReserve.kind]:
1306
+ config.borrowLimitAgainstThisCollateralInElevationGroup,
1307
+ [UpdateConfigMode.UpdateHostFixedInterestRateBps.kind]: config.hostFixedInterestRateBps,
1308
+ [UpdateConfigMode.UpdateAutodeleverageEnabled.kind]: config.autodeleverageEnabled,
1309
+ [UpdateConfigMode.UpdateDeleveragingBonusIncreaseBpsPerDay.kind]: config.deleveragingBonusIncreaseBpsPerDay,
1310
+ [UpdateConfigMode.UpdateProtocolOrderExecutionFee.kind]: config.protocolOrderExecutionFeePct,
1311
+ [UpdateConfigMode.UpdateProposerAuthorityLock.kind]: config.proposerAuthorityLocked,
1312
+ [UpdateConfigMode.UpdateMinDeleveragingBonusBps.kind]: config.minDeleveragingBonusBps,
1313
+ [UpdateConfigMode.UpdateBlockCTokenUsage.kind]: config.blockCtokenUsage,
1314
+ }));
1315
+
1310
1316
  export async function updateEntireReserveConfigIx(
1311
1317
  signer: TransactionSigner,
1312
1318
  marketAddress: Address,
@@ -1342,20 +1348,19 @@ export function parseForChangesReserveConfigAndGetIxs(
1342
1348
  lendingMarketOwner: TransactionSigner = noopSigner(marketWithAddress.state.lendingMarketOwner)
1343
1349
  ): Promise<Instruction[]> {
1344
1350
  const encodedConfigUpdates = RESERVE_CONFIG_UPDATER.encodeAllUpdates(reserve?.config, reserveConfig);
1351
+ encodedConfigUpdates.sort((left, right) => priorityOf(left.mode) - priorityOf(right.mode));
1345
1352
  return Promise.all(
1346
- encodedConfigUpdates
1347
- .filter((encodedConfigUpdate) => !isAdminOnly(encodedConfigUpdate.mode))
1348
- .map(async (encodedConfigUpdate) =>
1349
- updateReserveConfigIx(
1350
- lendingMarketOwner,
1351
- marketWithAddress.address,
1352
- reserveAddress,
1353
- encodedConfigUpdate.mode,
1354
- encodedConfigUpdate.value,
1355
- programId,
1356
- shouldSkipValidation(encodedConfigUpdate.mode, reserve)
1357
- )
1353
+ encodedConfigUpdates.map(async (encodedConfigUpdate) =>
1354
+ updateReserveConfigIx(
1355
+ lendingMarketOwner,
1356
+ marketWithAddress.address,
1357
+ reserveAddress,
1358
+ encodedConfigUpdate.mode,
1359
+ encodedConfigUpdate.value,
1360
+ programId,
1361
+ shouldSkipValidation(encodedConfigUpdate.mode, reserve)
1358
1362
  )
1363
+ )
1359
1364
  );
1360
1365
  }
1361
1366
 
@@ -1364,39 +1369,30 @@ export type ReserveWithAddress = {
1364
1369
  state: Reserve;
1365
1370
  };
1366
1371
 
1367
- // Updating the deposit/borrow limit will automatically unblock usage and force validation inside the smart contract
1368
- const VALIDATED_DISCRIMINATORS = [
1369
- UpdateConfigMode.UpdateDepositLimit.discriminator,
1370
- UpdateConfigMode.UpdateBorrowLimit.discriminator,
1372
+ const NON_VALIDATED_DISCRIMINATORS = [
1373
+ UpdateConfigMode.UpdateScopePriceFeed.discriminator,
1374
+ UpdateConfigMode.UpdateTokenInfoScopeChain.discriminator,
1375
+ UpdateConfigMode.UpdateTokenInfoScopeTwap.discriminator,
1376
+ UpdateConfigMode.UpdateTokenInfoExpHeuristic.discriminator,
1377
+ UpdateConfigMode.UpdateTokenInfoTwapDivergence.discriminator,
1378
+ UpdateConfigMode.UpdateTokenInfoPriceMaxAge.discriminator,
1379
+ UpdateConfigMode.UpdateTokenInfoTwapMaxAge.discriminator,
1371
1380
  ];
1372
1381
 
1373
1382
  function shouldSkipValidation(mode: UpdateConfigModeKind, reserve: Reserve | undefined): boolean {
1374
- if (VALIDATED_DISCRIMINATORS.includes(mode.discriminator)) {
1375
- return false;
1376
- }
1377
- if (reserve == undefined) {
1378
- return true;
1379
- }
1380
- const is_usage_blocked = reserve.config.depositLimit.isZero() && reserve.config.borrowLimit.isZero();
1381
- return is_usage_blocked;
1383
+ return (
1384
+ NON_VALIDATED_DISCRIMINATORS.includes(mode.discriminator) &&
1385
+ !reserve?.liquidity.availableAmount.gten(MIN_INITIAL_DEPOSIT)
1386
+ );
1382
1387
  }
1383
1388
 
1384
- function isAdminOnly(mode: UpdateConfigModeKind): boolean {
1385
- for (const adminOnlyMode of ADMIN_ONLY_MODES) {
1386
- if (mode.discriminator === adminOnlyMode.discriminator) {
1387
- return true;
1388
- }
1389
+ function priorityOf(mode: UpdateConfigModeKind): number {
1390
+ switch (mode.discriminator) {
1391
+ case UpdateConfigMode.UpdateScopePriceFeed.discriminator:
1392
+ return 0;
1393
+ case UpdateConfigMode.UpdateTokenInfoScopeChain.discriminator:
1394
+ return 0;
1395
+ default:
1396
+ return 1;
1389
1397
  }
1390
- return false;
1391
1398
  }
1392
-
1393
- // These need to be skipped when updating the entire reserve config
1394
- const ADMIN_ONLY_MODES = [
1395
- UpdateConfigMode.UpdateProtocolTakeRate,
1396
- UpdateConfigMode.UpdateProtocolLiquidationFee,
1397
- UpdateConfigMode.UpdateHostFixedInterestRateBps,
1398
- UpdateConfigMode.UpdateProtocolOrderExecutionFee,
1399
- UpdateConfigMode.UpdateFeesOriginationFee,
1400
- UpdateConfigMode.UpdateFeesFlashLoanFee,
1401
- UpdateConfigMode.UpdateBlockCTokenUsage,
1402
- ];
@@ -1,6 +1,6 @@
1
1
  import { Address } from '@solana/kit';
2
2
  import Decimal from 'decimal.js';
3
- import { FarmState, RewardInfo } from '@kamino-finance/farms-sdk';
3
+ import { FarmAndKey, RewardInfo } from '@kamino-finance/farms-sdk';
4
4
 
5
5
  export type ConfigType = Array<MarketConfigType>;
6
6
 
@@ -55,7 +55,7 @@ export type ReserveRewardYield = {
55
55
 
56
56
  export type ReserveFarmInfo = {
57
57
  fetched: boolean;
58
- farmStates: FarmState[];
58
+ farms: FarmAndKey[];
59
59
  };
60
60
 
61
61
  export enum FeeCalculation {
@@ -77,6 +77,8 @@ export type TokenAmount = {
77
77
  */
78
78
  mint: Address;
79
79
 
80
+ reserveAddress: Address;
81
+
80
82
  /**
81
83
  * Amount, in lamports.
82
84
  */
@@ -123,7 +123,13 @@ import {
123
123
  } from './vault_types';
124
124
  import { batchFetch, collToLamportsDecimal, ZERO } from '@kamino-finance/kliquidity-sdk';
125
125
  import { FullBPSDecimal } from '@kamino-finance/kliquidity-sdk/dist/utils/CreationParameters';
126
- import { FarmConfigOption, FarmIncentives, FarmState, getUserStatePDA } from '@kamino-finance/farms-sdk/dist';
126
+ import {
127
+ FarmConfigOption,
128
+ FarmIncentives,
129
+ FarmState,
130
+ getUserStatePDA,
131
+ scaleDownWads,
132
+ } from '@kamino-finance/farms-sdk/dist';
127
133
  import { getAccountsInLut, initLookupTableIx, insertIntoLookupTableIxs } from '../utils/lookupTable';
128
134
  import {
129
135
  FARMS_ADMIN_MAINNET,
@@ -843,6 +849,8 @@ export class KaminoVaultClient {
843
849
  data: this.getValueForModeAsBuffer(mode, value),
844
850
  };
845
851
 
852
+ await this.updateVaultConfigValidations(mode, value, vaultState);
853
+
846
854
  const vaultReserves = this.getVaultReserves(vaultState);
847
855
  const vaultReservesState = await this.loadVaultReserves(vaultState);
848
856
 
@@ -906,6 +914,24 @@ export class KaminoVaultClient {
906
914
  return updateVaultConfigIxs;
907
915
  }
908
916
 
917
+ async updateVaultConfigValidations(mode: VaultConfigFieldKind, value: string, vaultState: VaultState) {
918
+ if (
919
+ mode.kind === new VaultConfigField.FirstLossCapitalFarm().kind ||
920
+ mode.kind === new VaultConfigField.Farm().kind
921
+ ) {
922
+ const farmAddress = address(value);
923
+ const farmState = await FarmState.fetch(this.getConnection(), farmAddress);
924
+ if (!farmState) {
925
+ throw new Error(`Farm ${farmAddress.toString()} not found for FirstLossCapitalFarm`);
926
+ }
927
+ if (
928
+ mode.kind === new VaultConfigField.FirstLossCapitalFarm().kind &&
929
+ !(await this.isFlcFarmValid(farmState, vaultState))
930
+ ) {
931
+ throw new Error(`Farm ${farmAddress.toString()} is not valid for FirstLossCapitalFarm`);
932
+ }
933
+ }
934
+ }
909
935
  /**
910
936
  * Add or update a reserve whitelist entry. This controls whether the reserve is whitelisted for adding/updating
911
937
  * allocations or for invest, depending on the mode parameter.
@@ -1199,7 +1225,7 @@ export class KaminoVaultClient {
1199
1225
  * @param tokenAmount - token amount to be deposited, in decimals (will be converted in lamports)
1200
1226
  * @param [vaultReservesMap] - optional parameter; a 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
1201
1227
  * @param [farmState] - the state of the vault farm, if the vault has a farm. Optional. If not provided, it will be fetched
1202
- * @returns - an instance of DepositIxs which contains the instructions to deposit in vault and the instructions to stake the shares in the farm if the vault has a farm
1228
+ * @returns - an instance of DepositIxs which contains the instructions to deposit in vault and the instructions to stake the shares in the farm if the vault has a farm as well as ixs to stake in the first loss capital farm if the vault has one - only one set on ixs so stake in a farm can be used -> staking can be either done in the farm or in the first loss capital farm
1203
1229
  */
1204
1230
  async depositIxs(
1205
1231
  user: TransactionSigner,
@@ -1313,14 +1339,17 @@ export class KaminoVaultClient {
1313
1339
  const result: DepositIxs = {
1314
1340
  depositIxs: [...createAtasIxs, entryIx, ...closeAtasIxs],
1315
1341
  stakeInFarmIfNeededIxs: [],
1342
+ stakeInFlcFarmIfNeededIxs: [],
1316
1343
  };
1317
1344
 
1318
- if (!(await vault.hasFarm())) {
1319
- return result;
1345
+ if (await vault.hasFarm()) {
1346
+ const stakeSharesIxs = await this.stakeSharesIxs(user, vault, undefined, farmState);
1347
+ result.stakeInFarmIfNeededIxs = stakeSharesIxs;
1348
+ }
1349
+ if (await vault.hasFlcFarm()) {
1350
+ const stakeSharesInFlcFarmIxs = await this.stakeSharesInFlcFarmIxs(user, vault, undefined, undefined);
1351
+ result.stakeInFlcFarmIfNeededIxs = stakeSharesInFlcFarmIxs;
1320
1352
  }
1321
-
1322
- const stakeSharesIxs = await this.stakeSharesIxs(user, vault, undefined, farmState);
1323
- result.stakeInFarmIfNeededIxs = stakeSharesIxs;
1324
1353
  return result;
1325
1354
  }
1326
1355
 
@@ -1354,6 +1383,42 @@ export class KaminoVaultClient {
1354
1383
  return getFarmStakeIxs(this.getConnection(), user, sharesToStakeLamports, vaultState.vaultFarm, farmState);
1355
1384
  }
1356
1385
 
1386
+ /**
1387
+ * This function creates instructions to stake the shares in the vault firstLossCapital farm if the vault has a farm
1388
+ * @param user - user to stake
1389
+ * @param vault - vault to deposit into its flc farm (if the state is not provided, it will be fetched)
1390
+ * @param [sharesAmount] - token amount to be deposited, in decimals (will be converted in lamports). Optional. If not provided, the user's share balance will be used
1391
+ * @param [farmState] - the state of the vault flc farm, if the vault has a farm. Optional. If not provided, it will be fetched
1392
+ * @returns - a list of instructions for the user to stake shares into the vault's firstLossCapital farm, including the creation of prerequisite accounts if needed
1393
+ */
1394
+ async stakeSharesInFlcFarmIxs(
1395
+ user: TransactionSigner,
1396
+ vault: KaminoVault,
1397
+ sharesAmount?: Decimal,
1398
+ farmState?: FarmState
1399
+ ): Promise<Instruction[]> {
1400
+ const vaultState = await vault.getState();
1401
+
1402
+ let sharesToStakeLamports = new Decimal(U64_MAX);
1403
+ if (sharesAmount) {
1404
+ sharesToStakeLamports = numberToLamportsDecimal(sharesAmount, vaultState.sharesMintDecimals.toNumber());
1405
+ }
1406
+
1407
+ // if tokens to be staked are 0 or vault has no farm there is no stake needed
1408
+ if (sharesToStakeLamports.lte(0) || !(await vault.hasFlcFarm())) {
1409
+ return [];
1410
+ }
1411
+
1412
+ // returns the ix to create the farm state account if needed and the ix to stake the shares
1413
+ return getFarmStakeIxs(
1414
+ this.getConnection(),
1415
+ user,
1416
+ sharesToStakeLamports,
1417
+ vaultState.firstLossCapitalFarm,
1418
+ farmState
1419
+ );
1420
+ }
1421
+
1357
1422
  /**
1358
1423
  * This function will return a struct with the instructions to unstake from the farm if necessary and the instructions for the missing ATA creation instructions, as well as one or multiple withdraw instructions, based on how many reserves it's needed to withdraw from. This might have to be split in multiple transactions
1359
1424
  * @param user - user to withdraw
@@ -3096,6 +3161,7 @@ export class KaminoVaultClient {
3096
3161
  slotForOverview,
3097
3162
  tokensPrices
3098
3163
  );
3164
+ const vaultFlcFarmStatsPromise = this.getVaultFlcFarmStats(vault);
3099
3165
 
3100
3166
  // all the async part of the functions above just read the vaultReservesState which is read beforehand, so excepting vaultCollateralsPromise they should do no additional network calls
3101
3167
  const [
@@ -3108,6 +3174,7 @@ export class KaminoVaultClient {
3108
3174
  vaultFarmIncentives,
3109
3175
  vaultReservesFarmIncentives,
3110
3176
  vaultDelegatedFarmIncentives,
3177
+ vaultFlcFarmStats,
3111
3178
  ] = await Promise.all([
3112
3179
  vaultHoldingsWithUSDValuePromise,
3113
3180
  vaultTheoreticalAPYPromise,
@@ -3118,6 +3185,7 @@ export class KaminoVaultClient {
3118
3185
  vaultFarmIncentivesPromise,
3119
3186
  vaultReservesFarmIncentivesPromise,
3120
3187
  vaultDelegatedFarmIncentivesPromise,
3188
+ vaultFlcFarmStatsPromise,
3121
3189
  ]);
3122
3190
 
3123
3191
  return {
@@ -3134,6 +3202,7 @@ export class KaminoVaultClient {
3134
3202
  utilizationRatio: totalInvestedAndBorrowed.utilizationRatio,
3135
3203
  totalSupplied: totalInvestedAndBorrowed.totalInvested,
3136
3204
  totalSuppliedUSD: totalInvestedAndBorrowed.totalInvested.mul(vaultTokenPrice),
3205
+ flcFarmStats: vaultFlcFarmStats,
3137
3206
  };
3138
3207
  }
3139
3208
 
@@ -3774,6 +3843,69 @@ export class KaminoVaultClient {
3774
3843
  };
3775
3844
  }
3776
3845
 
3846
+ async getVaultFlcFarmStats(vaultOrState: KaminoVault | VaultState): Promise<FlcFarmStats | undefined> {
3847
+ const vaultState = 'getState' in vaultOrState ? await vaultOrState.getState() : vaultOrState;
3848
+
3849
+ if (vaultState.firstLossCapitalFarm === DEFAULT_PUBLIC_KEY) {
3850
+ return undefined;
3851
+ }
3852
+
3853
+ const kFarmsClient = new Farms(this.getConnection());
3854
+
3855
+ const flcFarmState = await FarmState.fetch(this.getConnection(), vaultState.firstLossCapitalFarm);
3856
+
3857
+ if (!flcFarmState) {
3858
+ return undefined;
3859
+ }
3860
+
3861
+ if (!(await this.isFlcFarmValid(flcFarmState, vaultState))) {
3862
+ return undefined;
3863
+ }
3864
+
3865
+ const userStates = await kFarmsClient.getAllUserStatesForFarm(vaultState.firstLossCapitalFarm);
3866
+ const pendingUnstakes: FarmPendingUnstakeInfo[] = [];
3867
+
3868
+ for (const { userState, key } of userStates) {
3869
+ const pendingWithdrawalUnstake = new Decimal(scaleDownWads(userState.pendingWithdrawalUnstakeScaled));
3870
+ if (pendingWithdrawalUnstake.gt(0)) {
3871
+ pendingUnstakes.push({
3872
+ userStateAddress: key,
3873
+ pendingUnstakeAmountLamports: pendingWithdrawalUnstake,
3874
+ pendingUnstakeAvailableAtTimestamp: userState.pendingWithdrawalUnstakeTs.toNumber(),
3875
+ });
3876
+ }
3877
+ }
3878
+
3879
+ return {
3880
+ address: vaultState.firstLossCapitalFarm,
3881
+ farmState: flcFarmState,
3882
+ totalStakedShares: new Decimal(scaleDownWads(flcFarmState.totalActiveStakeScaled)),
3883
+ withdrawalCooldownDurationSeconds: flcFarmState.withdrawalCooldownPeriod,
3884
+ isPendingUnstake: pendingUnstakes.length > 0,
3885
+ pendingUnstakeInfo: pendingUnstakes,
3886
+ };
3887
+ }
3888
+
3889
+ async isFlcFarmValid(flcFarmState: FarmState, vaultOrState: KaminoVault | VaultState): Promise<boolean> {
3890
+ const vaultState = 'getState' in vaultOrState ? await vaultOrState.getState() : vaultOrState;
3891
+
3892
+ if (flcFarmState.timeUnit !== 0) {
3893
+ // timeUnit = 0 -> seconds
3894
+ return false;
3895
+ }
3896
+
3897
+ if (flcFarmState.withdrawalCooldownPeriod === 0) {
3898
+ // invalid FLC farm, should have > 0 withdrawal cooldown
3899
+ return false;
3900
+ }
3901
+
3902
+ if (flcFarmState.token.mint !== vaultState.sharesMint) {
3903
+ // staked token mint should be the vault shares mint
3904
+ return false;
3905
+ }
3906
+ return true;
3907
+ }
3908
+
3777
3909
  /// reads the pending rewards for a user in the vault farm
3778
3910
  /// @param user - the user address
3779
3911
  /// @param vault - the vault
@@ -4203,6 +4335,11 @@ export class KaminoVault {
4203
4335
  return state.vaultFarm !== DEFAULT_PUBLIC_KEY;
4204
4336
  }
4205
4337
 
4338
+ async hasFlcFarm(): Promise<boolean> {
4339
+ const state = await this.getState();
4340
+ return state.firstLossCapitalFarm !== DEFAULT_PUBLIC_KEY;
4341
+ }
4342
+
4206
4343
  /**
4207
4344
  * This will return an VaultHoldings object which contains the amount available (uninvested) in vault, total amount invested in reseves and a breakdown of the amount invested in each reserve
4208
4345
  * @returns an VaultHoldings object representing the amount available (uninvested) in vault, total amount invested in reseves and a breakdown of the amount invested in each reserve
@@ -4579,6 +4716,7 @@ export type VaultOverview = {
4579
4716
  totalSupplied: Decimal;
4580
4717
  totalSuppliedUSD: Decimal;
4581
4718
  utilizationRatio: Decimal;
4719
+ flcFarmStats: FlcFarmStats | undefined;
4582
4720
  };
4583
4721
 
4584
4722
  export type VaultReservesFarmsIncentives = {
@@ -4586,6 +4724,21 @@ export type VaultReservesFarmsIncentives = {
4586
4724
  totalIncentivesAPY: Decimal;
4587
4725
  };
4588
4726
 
4727
+ export type FlcFarmStats = {
4728
+ address: Address;
4729
+ farmState: FarmState;
4730
+ totalStakedShares: Decimal;
4731
+ withdrawalCooldownDurationSeconds: number;
4732
+ isPendingUnstake: boolean;
4733
+ pendingUnstakeInfo: FarmPendingUnstakeInfo[];
4734
+ };
4735
+
4736
+ export type FarmPendingUnstakeInfo = {
4737
+ userStateAddress: Address;
4738
+ pendingUnstakeAmountLamports: Decimal;
4739
+ pendingUnstakeAvailableAtTimestamp: number;
4740
+ };
4741
+
4589
4742
  export type VaultFeesPct = {
4590
4743
  managementFeePct: Decimal;
4591
4744
  performanceFeePct: Decimal;
@@ -50,10 +50,11 @@ export type SyncVaultLUTIxs = {
50
50
  syncLUTIxs: Instruction[];
51
51
  };
52
52
 
53
- /** If the stakeInFarmIfNeededIxs exist they have to be executed after the deposit so the shares received from the deposit are staked in the vault farm */
53
+ /** If the stakeInFarmIfNeededIxs/stakeInFlcFarmIfNeededIxs exist they have to be executed after the deposit so the shares received from the deposit are staked in the vault farm. Only one of the stake ixs can be executed, either for the vault farms or the first loss capital farm*/
54
54
  export type DepositIxs = {
55
55
  depositIxs: Instruction[];
56
56
  stakeInFarmIfNeededIxs: Instruction[];
57
+ stakeInFlcFarmIfNeededIxs: Instruction[]; // if the vault has a firstLossCapital farm, these ixs will stake the shares in the flc farm
57
58
  };
58
59
 
59
60
  /** the ixs to unstake shares from farm and withdraw them from the vault. The `unstakeFromFarmIfNeededIxs` should be in the tx before `withdrawIxs`*/