@1delta/margin-fetcher 0.0.247 → 0.0.251

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 (44) hide show
  1. package/dist/index.d.ts +2 -2
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +900 -77
  4. package/dist/index.js.map +1 -1
  5. package/dist/lending/index.d.ts +1 -1
  6. package/dist/lending/index.d.ts.map +1 -1
  7. package/dist/lending/public-data/aave-v3-type/publicCallBuild.d.ts.map +1 -1
  8. package/dist/lending/public-data/aave-v3-type/publicCallParse.d.ts.map +1 -1
  9. package/dist/lending/user-data/aave-v4-type/createAaveV4UserState.d.ts.map +1 -1
  10. package/dist/lending/user-data/gearbox/userCallParse.d.ts.map +1 -1
  11. package/dist/lending/user-data/morpho/fetchUserPositionsFromSubgraph.d.ts +44 -0
  12. package/dist/lending/user-data/morpho/fetchUserPositionsFromSubgraph.d.ts.map +1 -0
  13. package/dist/lending/user-data/morpho/index.d.ts +1 -0
  14. package/dist/lending/user-data/morpho/index.d.ts.map +1 -1
  15. package/dist/lending/user-data/with-permissions/types.d.ts +6 -0
  16. package/dist/lending/user-data/with-permissions/types.d.ts.map +1 -1
  17. package/dist/types/lenderTypes.d.ts +16 -1
  18. package/dist/types/lenderTypes.d.ts.map +1 -1
  19. package/dist/utils/index.d.ts.map +1 -1
  20. package/dist/vaults/fetchVaultsAll.d.ts +56 -0
  21. package/dist/vaults/fetchVaultsAll.d.ts.map +1 -0
  22. package/dist/vaults/fluid/types.d.ts +9 -0
  23. package/dist/vaults/fluid/types.d.ts.map +1 -1
  24. package/dist/vaults/gearbox/types.d.ts +9 -0
  25. package/dist/vaults/gearbox/types.d.ts.map +1 -1
  26. package/dist/vaults/index.d.ts +3 -0
  27. package/dist/vaults/index.d.ts.map +1 -1
  28. package/dist/vaults/morpho/fetchFromApi.d.ts +14 -0
  29. package/dist/vaults/morpho/fetchFromApi.d.ts.map +1 -0
  30. package/dist/vaults/morpho/fetchFromSubgraph.d.ts +12 -0
  31. package/dist/vaults/morpho/fetchFromSubgraph.d.ts.map +1 -0
  32. package/dist/vaults/morpho/fetchPublic.d.ts +24 -0
  33. package/dist/vaults/morpho/fetchPublic.d.ts.map +1 -0
  34. package/dist/vaults/morpho/index.d.ts +5 -0
  35. package/dist/vaults/morpho/index.d.ts.map +1 -0
  36. package/dist/vaults/morpho/types.d.ts +82 -0
  37. package/dist/vaults/morpho/types.d.ts.map +1 -0
  38. package/dist/vaults/silo/fetchPublic.d.ts +22 -0
  39. package/dist/vaults/silo/fetchPublic.d.ts.map +1 -0
  40. package/dist/vaults/silo/index.d.ts +3 -0
  41. package/dist/vaults/silo/index.d.ts.map +1 -0
  42. package/dist/vaults/silo/types.d.ts +84 -0
  43. package/dist/vaults/silo/types.d.ts.map +1 -0
  44. package/package.json +5 -4
package/dist/index.js CHANGED
@@ -8,6 +8,7 @@ import { getEvmChain, getEvmClient, getEvmClientUniversal, multicallRetryUnivers
8
8
  import { FluidLendingResolverAbi, MorphoLensAbi, AaveV4SpokeAbi, AaveV4OracleAbi, AaveV4HubAbi, FluidVaultResolverAbi, GearboxMarketCompressorV310Abi, MorphoBlueAbi, GearboxCreditAccountCompressorV310Abi } from '@1delta/abis';
9
9
  export { MorphoLensAbi } from '@1delta/abis';
10
10
  import { prepareDebitDataMulticall, prepareLenderDebitMulticall, parseDebitDataResult, parseLenderDebitResult, getPermit2ContractAddress, getCompoundV3CometAddress as getCompoundV3CometAddress$1, getMorphoAddress, getAaveCollateralTokenAddress, getSiloHalfForUnderlying, InitMarginAddresses } from '@1delta/calldata-sdk';
11
+ import { proxyNativeFetch } from '@1delta/proxy-fetch';
11
12
  import { BALANCER_V2_FORKS, BALANCER_V3_FORKS, UNISWAP_V4_FORKS, isFlashLoanSourceExcluded, FLASH_LOAN_IDS } from '@1delta/dex-registry';
12
13
 
13
14
  // src/abis/aave-v2/ProtocolDataProvider.ts
@@ -7542,6 +7543,9 @@ var Chain = /* @__PURE__ */ ((Chain2) => {
7542
7543
  Chain2["STUDIO_BLOCKCHAIN_MAINNET"] = "240241";
7543
7544
  Chain2["JOVAY_MAINNET"] = "5734951";
7544
7545
  Chain2["MANTRACHAIN_MAINNET"] = "5888";
7546
+ Chain2["MEGAETH_MAINNET"] = "4326";
7547
+ Chain2["STABLE_MAINNET"] = "988";
7548
+ Chain2["PHAROS_MAINNET"] = "1672";
7545
7549
  return Chain2;
7546
7550
  })(Chain || {});
7547
7551
 
@@ -7572,6 +7576,12 @@ var ENABLED_COMPOUNDS = [
7572
7576
  var DISABLED_COMPOUNDS = {
7573
7577
  [Chain.ETHEREUM_MAINNET]: [Lender.CREAM_FINANCE]
7574
7578
  };
7579
+ var isExcludedLender = (lender) => {
7580
+ if (lender === Lender.PLOUTOS) return true;
7581
+ if (lender?.startsWith("ZEROLEND")) return true;
7582
+ if (lender?.startsWith("TAKO_TAKO")) return true;
7583
+ return false;
7584
+ };
7575
7585
  var ENABLED_EULER_V2_CHAINS = [
7576
7586
  Chain.ETHEREUM_MAINNET,
7577
7587
  Chain.BNB_SMART_CHAIN_MAINNET,
@@ -7633,7 +7643,7 @@ var getLendersForChain = (c) => {
7633
7643
  if (gearboxResolvers()?.chains?.[c]?.marketConfigurators) {
7634
7644
  lenders.push(Lender.GEARBOX_V3);
7635
7645
  }
7636
- return lenders;
7646
+ return lenders.filter((l) => !isExcludedLender(l));
7637
7647
  };
7638
7648
  var filterLendersByProtocol = (allLenders, protocolList) => {
7639
7649
  if (!protocolList || protocolList.length === 0) {
@@ -7714,6 +7724,25 @@ var buildAaveV2StyleLenderReserveCall = (chainId, lender) => {
7714
7724
  ];
7715
7725
  }
7716
7726
  };
7727
+ var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
7728
+ var ERC20_BALANCE_OF_ABI = [
7729
+ {
7730
+ inputs: [{ name: "account", type: "address" }],
7731
+ name: "balanceOf",
7732
+ outputs: [{ name: "", type: "uint256" }],
7733
+ stateMutability: "view",
7734
+ type: "function"
7735
+ }
7736
+ ];
7737
+ function balanceOfCall(underlying, aToken) {
7738
+ return {
7739
+ // @ts-ignore — per-call abi override picked up by fetchLender.ts
7740
+ abi: ERC20_BALANCE_OF_ABI,
7741
+ address: underlying,
7742
+ name: "balanceOf",
7743
+ params: [aToken ?? ZERO_ADDRESS]
7744
+ };
7745
+ }
7717
7746
  function range(n) {
7718
7747
  return Array.from({ length: n + 1 }, (_3, i) => i);
7719
7748
  }
@@ -7733,7 +7762,7 @@ var AAVE_V3_EMODES = (chain, lender) => {
7733
7762
  }
7734
7763
  return [0, 1, 2, 3, 4, 5, 6];
7735
7764
  };
7736
- function yldrBaseline(assetsToQuery, providerAddress) {
7765
+ function yldrBaseline(assetsToQuery, providerAddress, aaveTokenMap) {
7737
7766
  return assetsToQuery.flatMap((tk) => [
7738
7767
  {
7739
7768
  address: providerAddress,
@@ -7744,10 +7773,11 @@ function yldrBaseline(assetsToQuery, providerAddress) {
7744
7773
  address: providerAddress,
7745
7774
  name: "getReserveConfigurationData",
7746
7775
  params: [tk]
7747
- }
7776
+ },
7777
+ balanceOfCall(tk, aaveTokenMap?.[tk]?.aToken)
7748
7778
  ]);
7749
7779
  }
7750
- function aaveV3baseline(assetsToQuery, providerAddress, poolAddress, legacy = false) {
7780
+ function aaveV3baseline(assetsToQuery, providerAddress, poolAddress, aaveTokenMap, legacy = false) {
7751
7781
  const callDecimals = {
7752
7782
  address: providerAddress,
7753
7783
  name: "getDebtCeilingDecimals",
@@ -7790,7 +7820,8 @@ function aaveV3baseline(assetsToQuery, providerAddress, poolAddress, legacy = fa
7790
7820
  name: "getReserveEModeCategory",
7791
7821
  params: [tk]
7792
7822
  }
7793
- ] : []
7823
+ ] : [],
7824
+ balanceOfCall(tk, aaveTokenMap?.[tk]?.aToken)
7794
7825
  ]);
7795
7826
  return {
7796
7827
  callsBase,
@@ -7802,6 +7833,7 @@ var buildAaveV3StyleLenderReserveCall = (chainId, lender) => {
7802
7833
  const providerAddress = getAaveTypePoolDataProviderAddress(chainId, lender);
7803
7834
  const assetsToQuery = getAaveAssets(chainId, lender);
7804
7835
  const poolAddress = getAaveTypePoolAddress(chainId, lender);
7836
+ const aaveTokenMap = getAaveStyleProtocolTokenMap(chainId, lender);
7805
7837
  if (isAaveV32Type(lender)) {
7806
7838
  const getEModeCategoryData = AAVE_V3_EMODES(
7807
7839
  chainId,
@@ -7828,7 +7860,8 @@ var buildAaveV3StyleLenderReserveCall = (chainId, lender) => {
7828
7860
  const { callDecimals, callReservesList, callsBase } = aaveV3baseline(
7829
7861
  assetsToQuery,
7830
7862
  providerAddress,
7831
- poolAddress
7863
+ poolAddress,
7864
+ aaveTokenMap
7832
7865
  );
7833
7866
  const calls = [
7834
7867
  ...callsBase,
@@ -7840,7 +7873,7 @@ var buildAaveV3StyleLenderReserveCall = (chainId, lender) => {
7840
7873
  }
7841
7874
  switch (lender) {
7842
7875
  case Lender.YLDR: {
7843
- const calls = yldrBaseline(assetsToQuery, providerAddress);
7876
+ const calls = yldrBaseline(assetsToQuery, providerAddress, aaveTokenMap);
7844
7877
  return calls;
7845
7878
  }
7846
7879
  default: {
@@ -7856,6 +7889,7 @@ var buildAaveV3StyleLenderReserveCall = (chainId, lender) => {
7856
7889
  assetsToQuery,
7857
7890
  providerAddress,
7858
7891
  poolAddress,
7892
+ aaveTokenMap,
7859
7893
  true
7860
7894
  );
7861
7895
  const calls = [...callsBase, ...getEModeCategoryData, callDecimals];
@@ -8367,7 +8401,8 @@ var getAaveV3ReservesDataConverter = (lender, chainId, prices, additionalYields,
8367
8401
  default: {
8368
8402
  const assetsToQuery = getAaveAssets(chainId, lender);
8369
8403
  const allModes = AAVE_V3_EMODES(chainId, lender);
8370
- const expectedNumberOfCalls = assetsToQuery.length * 6 + allModes.length + 1;
8404
+ const stride = 7;
8405
+ const expectedNumberOfCalls = assetsToQuery.length * stride + allModes.length + 1;
8371
8406
  const aaveTokenMap = getAaveStyleProtocolTokenMap(chainId, lender);
8372
8407
  return [
8373
8408
  (data) => {
@@ -8375,8 +8410,8 @@ var getAaveV3ReservesDataConverter = (lender, chainId, prices, additionalYields,
8375
8410
  return void 0;
8376
8411
  }
8377
8412
  const emodeDataResult = data.slice(
8378
- assetsToQuery.length * 6,
8379
- assetsToQuery.length * 6 + allModes.length
8413
+ assetsToQuery.length * stride,
8414
+ assetsToQuery.length * stride + allModes.length
8380
8415
  );
8381
8416
  const resultReserves = {};
8382
8417
  const decimalsCeiling = data[expectedNumberOfCalls - 1];
@@ -8395,11 +8430,12 @@ var getAaveV3ReservesDataConverter = (lender, chainId, prices, additionalYields,
8395
8430
  });
8396
8431
  for (let i = 0; i < assetsToQuery.length; i++) {
8397
8432
  const asset = assetsToQuery[i];
8398
- const reserveData = data[i * 6];
8399
- const configData = data[i * 6 + 1];
8400
- const reserveCaps = data[i * 6 + 3];
8401
- const debtCeiling = data[i * 6 + 4];
8402
- const reserveEMode = data[i * 6 + 5];
8433
+ const reserveData = data[i * stride];
8434
+ const configData = data[i * stride + 1];
8435
+ const reserveCaps = data[i * stride + 3];
8436
+ const debtCeiling = data[i * stride + 4];
8437
+ const reserveEMode = data[i * stride + 5];
8438
+ const aTokenBalanceRaw = data[i * stride + 6];
8403
8439
  const assetMeta = tokenList[asset];
8404
8440
  const decimals = assetMeta?.decimals ?? 18;
8405
8441
  const totalDeposits = parseRawAmount(
@@ -8414,7 +8450,12 @@ var getAaveV3ReservesDataConverter = (lender, chainId, prices, additionalYields,
8414
8450
  reserveData?.[4 /* totalVariableDebt */]?.toString(),
8415
8451
  decimals
8416
8452
  );
8417
- const liquidity = Number(totalDeposits) - Number(totalDebt) - Number(totalDebtStable);
8453
+ const aTokenHasAddress = !!aaveTokenMap[asset]?.aToken;
8454
+ const availableLiquidityRaw = aTokenHasAddress && aTokenBalanceRaw !== "0x" ? aTokenBalanceRaw : void 0;
8455
+ const liquidity = availableLiquidityRaw !== void 0 ? Number(parseRawAmount(availableLiquidityRaw?.toString(), decimals)) : Math.max(
8456
+ 0,
8457
+ Number(totalDeposits) - Number(totalDebt) - Number(totalDebtStable)
8458
+ );
8418
8459
  const price = prices[toOracleKey(assetMeta?.assetGroup) ?? toGenericPriceKey(asset, chainId)] ?? 0;
8419
8460
  const usageAsCollateralEnabled = configData?.[5 /* usageAsCollateralEnabled */];
8420
8461
  const borrowingEnabled = configData?.[6 /* borrowingEnabled */];
@@ -8615,7 +8656,8 @@ function isReserveEnabledOnBitmap(bitmap, reserveIndex) {
8615
8656
  function parseYLDRCall(chainId, lender, additionalYields, prices, tokenList) {
8616
8657
  const assetsToQuery = getAaveAssets(chainId, lender);
8617
8658
  const aaveTokenMap = getAaveStyleProtocolTokenMap(chainId, lender);
8618
- const expectedNumberOfCalls = assetsToQuery.length * 2;
8659
+ const stride = 3;
8660
+ const expectedNumberOfCalls = assetsToQuery.length * stride;
8619
8661
  return [
8620
8662
  (data) => {
8621
8663
  if (data.length !== expectedNumberOfCalls) {
@@ -8624,8 +8666,9 @@ function parseYLDRCall(chainId, lender, additionalYields, prices, tokenList) {
8624
8666
  const resultReserves = {};
8625
8667
  for (let i = 0; i < assetsToQuery.length; i++) {
8626
8668
  const asset = assetsToQuery[i];
8627
- const reserveData = data[i * 2];
8628
- const configData = data[i * 2 + 1];
8669
+ const reserveData = data[i * stride];
8670
+ const configData = data[i * stride + 1];
8671
+ const aTokenBalanceRaw = data[i * stride + 2];
8629
8672
  const assetMeta = tokenList[asset];
8630
8673
  const decimals = assetMeta?.decimals ?? 18;
8631
8674
  const totalVariableDebt = parseRawAmount(
@@ -8636,7 +8679,9 @@ function parseYLDRCall(chainId, lender, additionalYields, prices, tokenList) {
8636
8679
  reserveData?.[1 /* totalYToken */]?.toString(),
8637
8680
  decimals
8638
8681
  );
8639
- const liquidity = Number(totalAToken) - Number(totalVariableDebt);
8682
+ const aTokenHasAddress = !!aaveTokenMap[asset]?.aToken;
8683
+ const availableLiquidityRaw = aTokenHasAddress && aTokenBalanceRaw !== "0x" ? aTokenBalanceRaw : void 0;
8684
+ const liquidity = availableLiquidityRaw !== void 0 ? Number(parseRawAmount(availableLiquidityRaw?.toString(), decimals)) : Math.max(0, Number(totalAToken) - Number(totalVariableDebt));
8640
8685
  const oracleKey = toOracleKey(assetMeta?.assetGroup) ?? toGenericPriceKey(asset, chainId);
8641
8686
  const price = prices[oracleKey] ?? 0;
8642
8687
  const totalDepositsUSD = Number(totalAToken) * price;
@@ -8729,15 +8774,16 @@ function parseAave32(chainId, lender, prices, additionalYields, tokenList) {
8729
8774
  const assetsToQuery = getAaveAssets(chainId, lender);
8730
8775
  const aaveTokenMap = getAaveStyleProtocolTokenMap(chainId, lender);
8731
8776
  const allModes = AAVE_V3_EMODES(chainId, lender);
8732
- const expectedNumberOfCalls = assetsToQuery.length * 5 + allModes.length * 3 + 2;
8777
+ const stride = 6;
8778
+ const expectedNumberOfCalls = assetsToQuery.length * stride + allModes.length * 3 + 2;
8733
8779
  return [
8734
8780
  (data) => {
8735
8781
  if (data.length !== expectedNumberOfCalls) {
8736
8782
  return void 0;
8737
8783
  }
8738
8784
  const emodeDataResult = data.slice(
8739
- assetsToQuery.length * 5,
8740
- assetsToQuery.length * 5 + allModes.length * 3
8785
+ assetsToQuery.length * stride,
8786
+ assetsToQuery.length * stride + allModes.length * 3
8741
8787
  );
8742
8788
  const resultReserves = {};
8743
8789
  const reservesList = data[expectedNumberOfCalls - 2];
@@ -8764,10 +8810,11 @@ function parseAave32(chainId, lender, prices, additionalYields, tokenList) {
8764
8810
  );
8765
8811
  for (let i = 0; i < assetsToQuery.length; i++) {
8766
8812
  const asset = assetsToQuery[i];
8767
- const reserveData = data[i * 5];
8768
- const configData = data[i * 5 + 1];
8769
- const reserveCaps = data[i * 5 + 3];
8770
- const debtCeiling = data[i * 5 + 4];
8813
+ const reserveData = data[i * stride];
8814
+ const configData = data[i * stride + 1];
8815
+ const reserveCaps = data[i * stride + 3];
8816
+ const debtCeiling = data[i * stride + 4];
8817
+ const aTokenBalanceRaw = data[i * stride + 5];
8771
8818
  const assetMeta = tokenList[asset];
8772
8819
  const decimals = assetMeta?.decimals ?? 18;
8773
8820
  const totalDeposits = parseRawAmount(
@@ -8782,7 +8829,12 @@ function parseAave32(chainId, lender, prices, additionalYields, tokenList) {
8782
8829
  reserveData?.[4 /* totalVariableDebt */]?.toString(),
8783
8830
  decimals
8784
8831
  );
8785
- const liquidity = Number(totalDeposits) - Number(totalDebt) - Number(totalDebtStable);
8832
+ const aTokenHasAddress = !!aaveTokenMap[asset]?.aToken;
8833
+ const availableLiquidityRaw = aTokenHasAddress && aTokenBalanceRaw !== "0x" ? aTokenBalanceRaw : void 0;
8834
+ const liquidity = availableLiquidityRaw !== void 0 ? Number(parseRawAmount(availableLiquidityRaw?.toString(), decimals)) : Math.max(
8835
+ 0,
8836
+ Number(totalDeposits) - Number(totalDebt) - Number(totalDebtStable)
8837
+ );
8786
8838
  const price = prices[toOracleKey(assetMeta?.assetGroup) ?? toGenericPriceKey(asset, chainId)] ?? 0;
8787
8839
  const marketUid = createMarketUid(chainId, lender, asset);
8788
8840
  resultReserves[marketUid] = {
@@ -18879,7 +18931,7 @@ function calculateSiloRates(utilization, params) {
18879
18931
  }
18880
18932
 
18881
18933
  // src/lending/public-data/silo-v2/publicCallParse.ts
18882
- var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
18934
+ var ZERO_ADDRESS2 = "0x0000000000000000000000000000000000000000";
18883
18935
  var getSiloV2ReservesDataConverter = (lender, chainId, prices, additionalYields, tokenList = {}) => {
18884
18936
  const market = getSiloV2MarketEntry(chainId, lender);
18885
18937
  if (!market) return [() => void 0, 0];
@@ -18991,8 +19043,8 @@ var getSiloV2ReservesDataConverter = (lender, chainId, prices, additionalYields,
18991
19043
  silo: self.silo,
18992
19044
  counterpartySilo: other.silo,
18993
19045
  siloConfig: market.siloConfig,
18994
- oracle: self.solvencyOracle || ZERO_ADDRESS,
18995
- irm: self.interestRateModel || ZERO_ADDRESS,
19046
+ oracle: self.solvencyOracle || ZERO_ADDRESS2,
19047
+ irm: self.interestRateModel || ZERO_ADDRESS2,
18996
19048
  shareTokens: {
18997
19049
  collateral: self.collateralShareToken,
18998
19050
  protected: self.protectedShareToken,
@@ -19047,7 +19099,7 @@ function buildSiloV3LenderReserveCall(_chainId, lender) {
19047
19099
  }
19048
19100
 
19049
19101
  // src/lending/public-data/silo-v3/publicCallParse.ts
19050
- var ZERO_ADDRESS2 = "0x0000000000000000000000000000000000000000";
19102
+ var ZERO_ADDRESS3 = "0x0000000000000000000000000000000000000000";
19051
19103
  var getSiloV3ReservesDataConverter = (lender, chainId, prices, additionalYields, tokenList = {}) => {
19052
19104
  const market = getSiloV3MarketEntry(chainId, lender);
19053
19105
  if (!market) return [() => void 0, 0];
@@ -19151,8 +19203,8 @@ var getSiloV3ReservesDataConverter = (lender, chainId, prices, additionalYields,
19151
19203
  silo: self.silo,
19152
19204
  counterpartySilo: other.silo,
19153
19205
  siloConfig: market.siloConfig,
19154
- oracle: self.solvencyOracle || ZERO_ADDRESS2,
19155
- irm: self.interestRateModel || ZERO_ADDRESS2,
19206
+ oracle: self.solvencyOracle || ZERO_ADDRESS3,
19207
+ irm: self.interestRateModel || ZERO_ADDRESS3,
19156
19208
  shareTokens: {
19157
19209
  collateral: self.collateralShareToken,
19158
19210
  protected: self.protectedShareToken,
@@ -20162,7 +20214,7 @@ function bigintToLtv(v) {
20162
20214
  }
20163
20215
 
20164
20216
  // src/lending/public-data/silo-v3/convertPublic.ts
20165
- var ZERO_ADDRESS3 = "0x0000000000000000000000000000000000000000";
20217
+ var ZERO_ADDRESS4 = "0x0000000000000000000000000000000000000000";
20166
20218
  function convertSiloV3MarketsToPublicResponse(apiItems, chainId, prices, additionalYields = {
20167
20219
  intrinsicYields: {},
20168
20220
  lenderRewards: {},
@@ -20259,8 +20311,8 @@ function convertSiloV3MarketsToPublicResponse(apiItems, chainId, prices, additio
20259
20311
  silo: self.silo.toLowerCase(),
20260
20312
  counterpartySilo: other.silo.toLowerCase(),
20261
20313
  siloConfig: registryEntry.siloConfig.toLowerCase(),
20262
- oracle: (api.solvencyOracleAddress || self.solvencyOracle || ZERO_ADDRESS3).toLowerCase(),
20263
- irm: (api.interestRateModelId || self.interestRateModel || ZERO_ADDRESS3).toLowerCase(),
20314
+ oracle: (api.solvencyOracleAddress || self.solvencyOracle || ZERO_ADDRESS4).toLowerCase(),
20315
+ irm: (api.interestRateModelId || self.interestRateModel || ZERO_ADDRESS4).toLowerCase(),
20264
20316
  shareTokens: {
20265
20317
  collateral: self.collateralShareToken,
20266
20318
  protected: self.protectedShareToken,
@@ -21071,11 +21123,14 @@ async function buildUserCall(chainId, lender, account, params) {
21071
21123
  }
21072
21124
  function organizeUserQueries(queries) {
21073
21125
  const morphos = queries.filter((q) => isMorphoType(q.lender));
21074
- if (morphos.length === 0) return queries;
21075
- const nonMorphos = queries.filter((q) => !isMorphoType(q.lender));
21126
+ const gearbox = queries.filter((q) => isGearboxV3(q.lender));
21127
+ if (morphos.length === 0 && gearbox.length === 0) return queries;
21128
+ const others = queries.filter(
21129
+ (q) => !isMorphoType(q.lender) && !isGearboxV3(q.lender)
21130
+ );
21076
21131
  const morphoBlue = morphos.filter((q) => q.lender.startsWith("MORPHO_BLUE"));
21077
21132
  const moolah = morphos.filter((q) => q.lender.startsWith("LISTA_DAO"));
21078
- const result = [...nonMorphos];
21133
+ const result = [...others];
21079
21134
  if (morphoBlue.length > 0) {
21080
21135
  result.push({
21081
21136
  lender: Lender.MORPHO_BLUE,
@@ -21092,6 +21147,14 @@ function organizeUserQueries(queries) {
21092
21147
  assets: void 0
21093
21148
  });
21094
21149
  }
21150
+ if (gearbox.length > 0) {
21151
+ result.push({
21152
+ lender: Lender.GEARBOX_V3,
21153
+ account: gearbox[0].account,
21154
+ params: gearbox.map((p) => p.lender),
21155
+ assets: void 0
21156
+ });
21157
+ }
21095
21158
  return result;
21096
21159
  }
21097
21160
 
@@ -22257,7 +22320,7 @@ function createAaveV4UserState(payload, lenderData, totalDeposits24h = 0, totalD
22257
22320
  }
22258
22321
  let riskPremiumBps = 0;
22259
22322
  if (totalDebtForPremium > 0) {
22260
- const sorted = collaterals.slice().sort((a, b) => a.riskBps - b.riskBps);
22323
+ const sorted = collaterals.slice().sort((a, b) => a.riskBps - b.riskBps || b.valueUsd - a.valueUsd);
22261
22324
  let debtLeft = totalDebtForPremium;
22262
22325
  let weightedSum = 0;
22263
22326
  for (const c of sorted) {
@@ -22267,7 +22330,7 @@ function createAaveV4UserState(payload, lenderData, totalDeposits24h = 0, totalD
22267
22330
  debtLeft -= used;
22268
22331
  }
22269
22332
  const covered = totalDebtForPremium - debtLeft;
22270
- riskPremiumBps = covered > 0 ? weightedSum / covered : 0;
22333
+ riskPremiumBps = covered > 0 ? Math.ceil(weightedSum / covered) : 0;
22271
22334
  }
22272
22335
  let depositInterest = 0;
22273
22336
  let borrowInterest = 0;
@@ -22303,14 +22366,10 @@ function createAaveV4UserState(payload, lenderData, totalDeposits24h = 0, totalD
22303
22366
  configs,
22304
22367
  pos.userConfigKey
22305
22368
  );
22306
- const positionThresholdBps = Number(
22307
- meta.riskPremiumThresholdBps ?? 0
22308
- );
22309
- const clampedPremiumBps = positionThresholdBps > 0 ? Math.min(riskPremiumBps, positionThresholdBps) : riskPremiumBps;
22310
- const userPremiumMultiplier = 1 + clampedPremiumBps / 1e4;
22369
+ const userPremiumMultiplier = 1 + riskPremiumBps / 1e4;
22311
22370
  const effectiveVariableBorrowRate = (variableBorrowRate ?? 0) * userPremiumMultiplier;
22312
22371
  pos.variableBorrowRate = effectiveVariableBorrowRate;
22313
- pos.riskPremiumBps = clampedPremiumBps;
22372
+ pos.riskPremiumBps = riskPremiumBps;
22314
22373
  deposits += depositsUSD;
22315
22374
  debt += debtUSD + (debtStableUSD ?? 0);
22316
22375
  oracleDebt += debtUSDOracle + (pos.debtStableUSDOracle ?? debtStableUSD ?? 0);
@@ -22351,6 +22410,8 @@ function createAaveV4UserState(payload, lenderData, totalDeposits24h = 0, totalD
22351
22410
  deposits24h: totalDeposits24h,
22352
22411
  debt24h: totalDebt24h,
22353
22412
  nav24h: totalDeposits24h - totalDebt24h,
22413
+ // Spoke-level risk premium in BPS — matches Spoke.getUserAccountData().riskPremium
22414
+ riskPremiumBps,
22354
22415
  ...payload.rewards ? { rewards: payload.rewards } : {}
22355
22416
  };
22356
22417
  const aprData2 = {
@@ -22940,12 +23001,45 @@ function toBigInt8(v) {
22940
23001
  return 0n;
22941
23002
  }
22942
23003
  }
23004
+ function ensureMetaStub(metaMap, marketUid, underlying) {
23005
+ if (metaMap[marketUid]) return;
23006
+ metaMap[marketUid] = {
23007
+ marketUid,
23008
+ underlying,
23009
+ asset: { address: underlying, decimals: 18, symbol: "" },
23010
+ price: { priceUsd: 0, priceUsd24h: 0 },
23011
+ depositRate: 0,
23012
+ variableBorrowRate: 0,
23013
+ stableBorrowRate: 0,
23014
+ intrinsicYield: 0,
23015
+ rewards: [],
23016
+ configs: null,
23017
+ flags: {
23018
+ isActive: true,
23019
+ isFrozen: false,
23020
+ borrowingEnabled: false,
23021
+ collateralActive: true,
23022
+ hasStable: false
23023
+ },
23024
+ borrowLiquidity: null,
23025
+ withdrawLiquidity: null,
23026
+ depositable: null,
23027
+ params: null
23028
+ };
23029
+ }
22943
23030
  var getGearboxV3UserDataConverter = (_lender, chainId, account, meta) => {
22944
23031
  return [
22945
23032
  (data) => {
22946
23033
  if (!data || data.length !== GEARBOX_V3_USER_CALL_COUNT) return void 0;
22947
23034
  const first = data[0];
22948
- const creditAccounts = Array.isArray(first) ? first : first?.data ?? first?.[0];
23035
+ let creditAccounts;
23036
+ if (Array.isArray(first) && first.length === 2 && Array.isArray(first[0]) && (first[0].length === 0 || typeof first[0][0] === "object")) {
23037
+ creditAccounts = first[0];
23038
+ } else if (Array.isArray(first)) {
23039
+ creditAccounts = first;
23040
+ } else {
23041
+ creditAccounts = first?.data ?? first?.[0];
23042
+ }
22949
23043
  if (!Array.isArray(creditAccounts) || creditAccounts.length === 0)
22950
23044
  return void 0;
22951
23045
  const perCM = /* @__PURE__ */ new Map();
@@ -22965,12 +23059,12 @@ var getGearboxV3UserDataConverter = (_lender, chainId, account, meta) => {
22965
23059
  } catch {
22966
23060
  continue;
22967
23061
  }
22968
- const metaMap = meta?.[lenderKey];
22969
- if (!metaMap) continue;
23062
+ const metaMap = meta?.[lenderKey] ? { ...meta[lenderKey] } : {};
22970
23063
  const firstCa = accounts[0];
22971
23064
  const rawUnderlying = (firstCa.underlying ?? "").toString().toLowerCase();
22972
23065
  const underlying = rawUnderlying;
22973
23066
  const loanMarketUid = createMarketUid(chainId, lenderKey, underlying);
23067
+ ensureMetaStub(metaMap, loanMarketUid, underlying);
22974
23068
  const loanMeta = metaMap[loanMarketUid];
22975
23069
  const loanDec = loanMeta?.asset?.decimals ?? 18;
22976
23070
  const loanDisplayPrice = loanMeta ? getDisplayPrice(loanMeta) : 0;
@@ -22984,10 +23078,6 @@ var getGearboxV3UserDataConverter = (_lender, chainId, account, meta) => {
22984
23078
  if (!caAddress) continue;
22985
23079
  const debtRaw = toBigInt8(ca.debt);
22986
23080
  const tokens = Array.isArray(ca.tokens) ? ca.tokens : Array.isArray(ca.balances) ? ca.balances : [];
22987
- const hasAnyBalance = tokens.some(
22988
- (b) => toBigInt8(b?.balance) > 0n
22989
- );
22990
- if (debtRaw === 0n && !hasAnyBalance) continue;
22991
23081
  modes[caAddress] = 0;
22992
23082
  const posData = {};
22993
23083
  let totalDepositsUSD = 0;
@@ -23000,6 +23090,7 @@ var getGearboxV3UserDataConverter = (_lender, chainId, account, meta) => {
23000
23090
  const quotaRaw = toBigInt8(bal.quota);
23001
23091
  const isQuoted = quotaRaw > 0n || !!bal?.isQuoted;
23002
23092
  const colMarketUid = createMarketUid(chainId, lenderKey, token);
23093
+ ensureMetaStub(metaMap, colMarketUid, token);
23003
23094
  const colMeta = metaMap[colMarketUid];
23004
23095
  const colDec = colMeta?.asset?.decimals ?? 18;
23005
23096
  const colDisplayPrice = colMeta ? getDisplayPrice(colMeta) : 0;
@@ -28248,8 +28339,8 @@ function resolveDebitDataKey(chainId, lender, tokenAddress, cToken, isProtected)
28248
28339
  if (cToken) return cToken.toLowerCase();
28249
28340
  const tokenMap = getCompoundV2CollateralTokens(chainId, lender);
28250
28341
  if (tokenMap) {
28251
- const resolved = tokenMap[tokenAddress.toLowerCase()];
28252
- if (resolved) return resolved.toLowerCase();
28342
+ const resolved2 = tokenMap[tokenAddress.toLowerCase()];
28343
+ if (resolved2) return resolved2.toLowerCase();
28253
28344
  }
28254
28345
  }
28255
28346
  if (isCompoundV3Type(lender)) {
@@ -28321,6 +28412,200 @@ function needsTokenApproval(params) {
28321
28412
  const allowance = debitData.allowances?.[spenderLower] ?? 0n;
28322
28413
  return allowance < amount;
28323
28414
  }
28415
+ var MORPHO_USER_SUBGRAPH_URLS = {
28416
+ [Chain.SEI_NETWORK]: "https://api.goldsky.com/api/public/project_cmiergfbv4vma01vb642yaeam/subgraphs/morphoblue-sei/1.0.1/gn",
28417
+ [Chain.CELO_MAINNET]: "https://api.goldsky.com/api/public/project_cmiergfbv4vma01vb642yaeam/subgraphs/morphoblue-celo/1.0.4/gn",
28418
+ [Chain.LISK]: "https://api.goldsky.com/api/public/project_cmiergfbv4vma01vb642yaeam/subgraphs/morphobluelisk/1.0.1/gn",
28419
+ [Chain.SONEIUM]: "https://api.goldsky.com/api/public/project_cmiergfbv4vma01vb642yaeam/subgraphs/morphobluesoneium/1.0.2/gn",
28420
+ [Chain.TAC_MAINNET]: "https://api.goldsky.com/api/public/project_cmiergfbv4vma01vb642yaeam/subgraphs/morphoblue-tac/1.0.0/gn",
28421
+ // Hemi uses a different provider, but speaks the same GraphQL schema.
28422
+ [Chain.HEMI_NETWORK]: "https://feather.securesecrets.org/hemi-mopho-blue/"
28423
+ };
28424
+ var MORPHO_BLUE_API_URL = "https://blue-api.morpho.org/graphql";
28425
+ var MORPHO_API_CHAIN_IDS = {
28426
+ [Chain.ETHEREUM_MAINNET]: 1,
28427
+ [Chain.BASE]: 8453,
28428
+ [Chain.ARBITRUM_ONE]: 42161,
28429
+ [Chain.OP_MAINNET]: 10,
28430
+ [Chain.POLYGON_MAINNET]: 137,
28431
+ [Chain.GNOSIS]: 100,
28432
+ [Chain.FRAXTAL]: 252,
28433
+ [Chain.BLAST]: 81457,
28434
+ [Chain.LINEA]: 59144,
28435
+ [Chain.TAIKO_ALETHIA]: 167e3,
28436
+ [Chain.AVALANCHE_C_CHAIN]: 43114,
28437
+ [Chain.ZKSYNC_MAINNET]: 324,
28438
+ [Chain.SONIC_MAINNET]: 146,
28439
+ [Chain.SCROLL]: 534352,
28440
+ [Chain.BERACHAIN]: 80094,
28441
+ [Chain.HYPEREVM]: 999,
28442
+ [Chain.UNICHAIN]: 130
28443
+ };
28444
+ var FETCH_TIMEOUT_MS = 3e3;
28445
+ var CACHE_TTL_MS = 2e3;
28446
+ var buildSubgraphQuery = (account) => `
28447
+ {
28448
+ account(id: "${account.toLowerCase()}") {
28449
+ positions {
28450
+ market { id }
28451
+ side
28452
+ balance
28453
+ shares
28454
+ }
28455
+ }
28456
+ }`;
28457
+ var buildApiQuery = (account, chainId) => `
28458
+ {
28459
+ userByAddress(address: "${account}", chainId: ${chainId}) {
28460
+ marketPositions {
28461
+ market { uniqueKey }
28462
+ supplyShares
28463
+ borrowShares
28464
+ collateral
28465
+ }
28466
+ }
28467
+ }`;
28468
+ function isNonZero(value) {
28469
+ if (value === null || value === void 0) return false;
28470
+ return value !== "0" && value !== 0;
28471
+ }
28472
+ async function attemptFetchJson(url, body, proxyConfig) {
28473
+ const controller = new AbortController();
28474
+ const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
28475
+ try {
28476
+ const response = await proxyNativeFetch(url, proxyConfig, {
28477
+ method: "POST",
28478
+ headers: { "Content-Type": "application/json" },
28479
+ body,
28480
+ signal: controller.signal
28481
+ });
28482
+ if (!response.ok) return void 0;
28483
+ return await response.json();
28484
+ } catch {
28485
+ return void 0;
28486
+ } finally {
28487
+ clearTimeout(timer);
28488
+ }
28489
+ }
28490
+ async function fetchJsonWithProxyFallback(url, body, proxyConfig) {
28491
+ const direct = await attemptFetchJson(url, body, void 0);
28492
+ if (direct !== void 0) return direct;
28493
+ if (!proxyConfig) return void 0;
28494
+ return attemptFetchJson(url, body, proxyConfig);
28495
+ }
28496
+ var inflight = /* @__PURE__ */ new Map();
28497
+ var resolved = /* @__PURE__ */ new Map();
28498
+ function cacheKey(chainId, account) {
28499
+ return `${chainId}:${account.toLowerCase()}`;
28500
+ }
28501
+ async function dedupedFetch(chainId, account, loader) {
28502
+ const key = cacheKey(chainId, account);
28503
+ const now = Date.now();
28504
+ const cached = resolved.get(key);
28505
+ if (cached && cached.expiresAt > now) {
28506
+ return cached.value;
28507
+ }
28508
+ const existing = inflight.get(key);
28509
+ if (existing) return existing;
28510
+ const promise = loader().then((value) => {
28511
+ resolved.set(key, { value, expiresAt: Date.now() + CACHE_TTL_MS });
28512
+ return value;
28513
+ }).finally(() => {
28514
+ inflight.delete(key);
28515
+ });
28516
+ inflight.set(key, promise);
28517
+ return promise;
28518
+ }
28519
+ function hasMorphoUserSubgraph(chainId) {
28520
+ return chainId in MORPHO_USER_SUBGRAPH_URLS;
28521
+ }
28522
+ function hasMorphoUserApi(chainId) {
28523
+ return chainId in MORPHO_API_CHAIN_IDS;
28524
+ }
28525
+ function hasMorphoPositionIndex(chainId) {
28526
+ return hasMorphoUserSubgraph(chainId) || hasMorphoUserApi(chainId);
28527
+ }
28528
+ async function fetchMorphoUserBalances(chainId, account, proxyConfig) {
28529
+ if (hasMorphoUserSubgraph(chainId)) {
28530
+ return dedupedFetch(
28531
+ chainId,
28532
+ account,
28533
+ () => fetchBalancesFromSubgraph(chainId, account, proxyConfig)
28534
+ );
28535
+ }
28536
+ if (hasMorphoUserApi(chainId)) {
28537
+ return dedupedFetch(
28538
+ chainId,
28539
+ account,
28540
+ () => fetchBalancesFromApi(chainId, account, proxyConfig)
28541
+ );
28542
+ }
28543
+ return void 0;
28544
+ }
28545
+ async function fetchMorphoUserPositionMarkets(chainId, account, proxyConfig) {
28546
+ const balances = await fetchMorphoUserBalances(chainId, account, proxyConfig);
28547
+ if (balances === void 0) return void 0;
28548
+ return new Set(balances.map((b) => b.marketId));
28549
+ }
28550
+ async function fetchBalancesFromSubgraph(chainId, account, proxyConfig) {
28551
+ const subgraphUrl = MORPHO_USER_SUBGRAPH_URLS[chainId];
28552
+ const json = await fetchJsonWithProxyFallback(
28553
+ subgraphUrl,
28554
+ JSON.stringify({ query: buildSubgraphQuery(account) }),
28555
+ proxyConfig
28556
+ );
28557
+ if (!json) return void 0;
28558
+ const positions = json.data?.account?.positions ?? [];
28559
+ const byMarket = /* @__PURE__ */ new Map();
28560
+ for (const pos of positions) {
28561
+ const marketId = pos.market.id.toLowerCase();
28562
+ if (!byMarket.has(marketId)) {
28563
+ byMarket.set(marketId, {
28564
+ supplyShares: "0",
28565
+ borrowShares: "0",
28566
+ collateral: "0"
28567
+ });
28568
+ }
28569
+ const entry = byMarket.get(marketId);
28570
+ if (pos.side === "SUPPLIER" && pos.shares) {
28571
+ entry.supplyShares = pos.shares;
28572
+ } else if (pos.side === "BORROWER" && pos.shares) {
28573
+ entry.borrowShares = pos.shares;
28574
+ } else if (pos.side === "COLLATERAL") {
28575
+ entry.collateral = pos.balance ?? "0";
28576
+ }
28577
+ }
28578
+ const result = [];
28579
+ for (const [marketId, entry] of byMarket) {
28580
+ if (isNonZero(entry.supplyShares) || isNonZero(entry.borrowShares) || isNonZero(entry.collateral)) {
28581
+ result.push({ marketId, ...entry });
28582
+ }
28583
+ }
28584
+ return result;
28585
+ }
28586
+ async function fetchBalancesFromApi(chainId, account, proxyConfig) {
28587
+ const numericChainId = MORPHO_API_CHAIN_IDS[chainId];
28588
+ const json = await fetchJsonWithProxyFallback(
28589
+ MORPHO_BLUE_API_URL,
28590
+ JSON.stringify({ query: buildApiQuery(account, numericChainId) }),
28591
+ proxyConfig
28592
+ );
28593
+ if (!json) return void 0;
28594
+ const positions = json.data?.userByAddress?.marketPositions ?? [];
28595
+ const result = [];
28596
+ for (const pos of positions) {
28597
+ if (!isNonZero(pos.supplyShares) && !isNonZero(pos.borrowShares) && !isNonZero(pos.collateral)) {
28598
+ continue;
28599
+ }
28600
+ result.push({
28601
+ marketId: pos.market.uniqueKey.toLowerCase(),
28602
+ supplyShares: String(pos.supplyShares),
28603
+ borrowShares: String(pos.borrowShares),
28604
+ collateral: String(pos.collateral)
28605
+ });
28606
+ }
28607
+ return result;
28608
+ }
28324
28609
 
28325
28610
  // src/lending/user-data/summary/utils.ts
28326
28611
  function calculateWeightedAverage(items) {
@@ -30697,10 +30982,10 @@ function createMerklRewardFetcher(config) {
30697
30982
  for (const opp of opps) {
30698
30983
  if (opp.action !== "LEND" && opp.action !== "BORROW") continue;
30699
30984
  if (!opp.apr || opp.apr <= 0) continue;
30700
- const resolved = resolve(opp);
30701
- if (!resolved) continue;
30702
- const lender = resolved.lender ?? config.lenderKey;
30703
- const reward = ensureReward(result, chainId, lender, resolved.asset);
30985
+ const resolved2 = resolve(opp);
30986
+ if (!resolved2) continue;
30987
+ const lender = resolved2.lender ?? config.lenderKey;
30988
+ const reward = ensureReward(result, chainId, lender, resolved2.asset);
30704
30989
  const breakdowns = extractRewardBreakdowns(opp);
30705
30990
  reward.link = getMerkleUrl(opp);
30706
30991
  if (opp.action === "LEND") {
@@ -31832,7 +32117,7 @@ var SiloOracleAbi = [
31832
32117
  type: "function"
31833
32118
  }
31834
32119
  ];
31835
- var ZERO_ADDRESS4 = "0x0000000000000000000000000000000000000000";
32120
+ var ZERO_ADDRESS5 = "0x0000000000000000000000000000000000000000";
31836
32121
  function lookupUSD(context, asset) {
31837
32122
  const lc = asset.toLowerCase();
31838
32123
  const groupKey = context.tokenList?.[lc]?.assetGroup ?? `${context.chainId}-${lc}`;
@@ -31844,7 +32129,7 @@ function getSiloV2Calls(chainId) {
31844
32129
  const tokensWithRealOracle = /* @__PURE__ */ new Set();
31845
32130
  for (const market of allMarkets) {
31846
32131
  for (const half of [market.silo0, market.silo1]) {
31847
- if (half.solvencyOracle && half.solvencyOracle !== ZERO_ADDRESS4) {
32132
+ if (half.solvencyOracle && half.solvencyOracle !== ZERO_ADDRESS5) {
31848
32133
  tokensWithRealOracle.add(half.token.toLowerCase());
31849
32134
  }
31850
32135
  }
@@ -31857,7 +32142,7 @@ function getSiloV2Calls(chainId) {
31857
32142
  const lenderKey = siloV2LenderKey(market.siloConfig);
31858
32143
  const halves = [market.silo0, market.silo1];
31859
32144
  const isStatic = halves.map(
31860
- (h) => !h.solvencyOracle || h.solvencyOracle === ZERO_ADDRESS4
32145
+ (h) => !h.solvencyOracle || h.solvencyOracle === ZERO_ADDRESS5
31861
32146
  );
31862
32147
  if (isStatic[0] && isStatic[1]) {
31863
32148
  const t0 = halves[0].token.toLowerCase();
@@ -31877,7 +32162,7 @@ function getSiloV2Calls(chainId) {
31877
32162
  decimals: half.decimals,
31878
32163
  silo: half.silo.toLowerCase(),
31879
32164
  lenderKey,
31880
- oracle: ZERO_ADDRESS4,
32165
+ oracle: ZERO_ADDRESS5,
31881
32166
  partnerToken: partnerLc,
31882
32167
  isStatic: true
31883
32168
  });
@@ -32003,7 +32288,7 @@ var SiloOracleAbi2 = [
32003
32288
  type: "function"
32004
32289
  }
32005
32290
  ];
32006
- var ZERO_ADDRESS5 = "0x0000000000000000000000000000000000000000";
32291
+ var ZERO_ADDRESS6 = "0x0000000000000000000000000000000000000000";
32007
32292
  function lookupUSD2(context, asset) {
32008
32293
  const lc = asset.toLowerCase();
32009
32294
  const groupKey = context.tokenList?.[lc]?.assetGroup ?? `${context.chainId}-${lc}`;
@@ -32015,7 +32300,7 @@ function getSiloV3Calls(chainId) {
32015
32300
  const tokensWithRealOracle = /* @__PURE__ */ new Set();
32016
32301
  for (const market of allMarkets) {
32017
32302
  for (const half of [market.silo0, market.silo1]) {
32018
- if (half.solvencyOracle && half.solvencyOracle !== ZERO_ADDRESS5) {
32303
+ if (half.solvencyOracle && half.solvencyOracle !== ZERO_ADDRESS6) {
32019
32304
  tokensWithRealOracle.add(half.token.toLowerCase());
32020
32305
  }
32021
32306
  }
@@ -32028,7 +32313,7 @@ function getSiloV3Calls(chainId) {
32028
32313
  const lenderKey = siloV3LenderKey(market.siloConfig);
32029
32314
  const halves = [market.silo0, market.silo1];
32030
32315
  const isStatic = halves.map(
32031
- (h) => !h.solvencyOracle || h.solvencyOracle === ZERO_ADDRESS5
32316
+ (h) => !h.solvencyOracle || h.solvencyOracle === ZERO_ADDRESS6
32032
32317
  );
32033
32318
  if (isStatic[0] && isStatic[1]) {
32034
32319
  const t0 = halves[0].token.toLowerCase();
@@ -32048,7 +32333,7 @@ function getSiloV3Calls(chainId) {
32048
32333
  decimals: half.decimals,
32049
32334
  silo: half.silo.toLowerCase(),
32050
32335
  lenderKey,
32051
- oracle: ZERO_ADDRESS5,
32336
+ oracle: ZERO_ADDRESS6,
32052
32337
  partnerToken: partnerLc,
32053
32338
  isStatic: true
32054
32339
  });
@@ -32379,7 +32664,7 @@ function lookupUSD3(context, asset) {
32379
32664
  return context.usdPrices[groupKey] ?? context.usdPrices[lc] ?? 0;
32380
32665
  }
32381
32666
  function parseSiloV2GraphQLResults(items, context) {
32382
- const ZERO_ADDRESS6 = "0x0000000000000000000000000000000000000000";
32667
+ const ZERO_ADDRESS7 = "0x0000000000000000000000000000000000000000";
32383
32668
  const out = [];
32384
32669
  const seen = /* @__PURE__ */ new Set();
32385
32670
  for (const item of items) {
@@ -32402,8 +32687,8 @@ function parseSiloV2GraphQLResults(items, context) {
32402
32687
  const partnerTokenLc = other.token.toLowerCase();
32403
32688
  const dedupKey = `${lenderKey}:${tokenLc}`;
32404
32689
  if (seen.has(dedupKey)) continue;
32405
- const oracleAddr = (side.solvencyOracleAddress ?? side.solvencyOracle?.id ?? self.solvencyOracle ?? ZERO_ADDRESS6).toLowerCase();
32406
- const isStatic = !oracleAddr || oracleAddr === ZERO_ADDRESS6;
32690
+ const oracleAddr = (side.solvencyOracleAddress ?? side.solvencyOracle?.id ?? self.solvencyOracle ?? ZERO_ADDRESS7).toLowerCase();
32691
+ const isStatic = !oracleAddr || oracleAddr === ZERO_ADDRESS7;
32407
32692
  const siloAddrLc = self.silo.toLowerCase();
32408
32693
  try {
32409
32694
  let priceUSD = 0;
@@ -32523,7 +32808,7 @@ function lookupUSD4(context, asset) {
32523
32808
  return context.usdPrices[groupKey] ?? context.usdPrices[lc] ?? 0;
32524
32809
  }
32525
32810
  function parseSiloV3GraphQLResults(items, context) {
32526
- const ZERO_ADDRESS6 = "0x0000000000000000000000000000000000000000";
32811
+ const ZERO_ADDRESS7 = "0x0000000000000000000000000000000000000000";
32527
32812
  const out = [];
32528
32813
  const seen = /* @__PURE__ */ new Set();
32529
32814
  for (const item of items) {
@@ -32546,8 +32831,8 @@ function parseSiloV3GraphQLResults(items, context) {
32546
32831
  const partnerTokenLc = other.token.toLowerCase();
32547
32832
  const dedupKey = `${lenderKey}:${tokenLc}`;
32548
32833
  if (seen.has(dedupKey)) continue;
32549
- const oracleAddr = (side.solvencyOracleAddress ?? side.solvencyOracle?.id ?? self.solvencyOracle ?? ZERO_ADDRESS6).toLowerCase();
32550
- const isStatic = !oracleAddr || oracleAddr === ZERO_ADDRESS6;
32834
+ const oracleAddr = (side.solvencyOracleAddress ?? side.solvencyOracle?.id ?? self.solvencyOracle ?? ZERO_ADDRESS7).toLowerCase();
32835
+ const isStatic = !oracleAddr || oracleAddr === ZERO_ADDRESS7;
32551
32836
  const siloAddrLc = self.silo.toLowerCase();
32552
32837
  try {
32553
32838
  let priceUSD = 0;
@@ -33677,6 +33962,8 @@ function parseFTokens(fTokens, chainId, prices, tokenList) {
33677
33962
  const priceUsd = prices[oracleKey] ?? 0;
33678
33963
  const supplyRate = scaleFluidRate2(ft.supplyRate);
33679
33964
  const rewardsRate = scaleFluidRate2(ft.rewardsRate);
33965
+ const liquidityRaw = ft.liquidityUserSupplyData?.withdrawable?.toString() ?? "0";
33966
+ const liquidityFormatted = Number(parseRawAmount(liquidityRaw, decimals));
33680
33967
  const entry = {
33681
33968
  address: ft.tokenAddress,
33682
33969
  underlying,
@@ -33695,7 +33982,10 @@ function parseFTokens(fTokens, chainId, prices, tokenList) {
33695
33982
  asset: assetMeta,
33696
33983
  priceUsd: priceUsd || void 0,
33697
33984
  totalAssetsFormatted,
33698
- totalAssetsUsd: totalAssetsFormatted * priceUsd
33985
+ totalAssetsUsd: totalAssetsFormatted * priceUsd,
33986
+ liquidity: liquidityRaw,
33987
+ liquidityFormatted,
33988
+ liquidityUsd: liquidityFormatted * priceUsd
33699
33989
  };
33700
33990
  out[underlying] = entry;
33701
33991
  }
@@ -33713,6 +34003,539 @@ var fetchFluidFTokens = async (chainId, multicallRetry, prices = {}, tokenList =
33713
34003
  return converter(raw) ?? {};
33714
34004
  };
33715
34005
 
34006
+ // src/vaults/gearbox/publicCallBuild.ts
34007
+ var buildGearboxV3PoolsCall = (chainId) => {
34008
+ const compressor = gearboxMarketCompressor();
34009
+ const configurators = gearboxMarketConfigurators(chainId);
34010
+ if (!compressor || !configurators) return [];
34011
+ const curatorAddrs = Object.keys(configurators);
34012
+ if (curatorAddrs.length === 0) return [];
34013
+ return [
34014
+ {
34015
+ address: compressor,
34016
+ name: "getMarkets",
34017
+ params: [
34018
+ {
34019
+ configurators: curatorAddrs,
34020
+ pools: [],
34021
+ underlying: zeroAddress
34022
+ }
34023
+ ]
34024
+ }
34025
+ ];
34026
+ };
34027
+
34028
+ // src/vaults/gearbox/publicCallParse.ts
34029
+ var WETH_MAINNET = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2";
34030
+ var normalizeUnderlying5 = (addr, chainId) => {
34031
+ const lower = addr.toLowerCase();
34032
+ if (chainId === "1" && lower === WETH_MAINNET) return zeroAddress;
34033
+ return lower;
34034
+ };
34035
+ var RAY_TO_PERCENT2 = 1e25;
34036
+ var scaleRate = (raw) => {
34037
+ if (raw === void 0 || raw === null) return 0;
34038
+ return Number(raw) / RAY_TO_PERCENT2;
34039
+ };
34040
+ var getGearboxV3PoolsConverter = (chainId, prices = {}, tokenList = {}) => {
34041
+ const expectedNumberOfCalls = 1;
34042
+ return [
34043
+ (data) => {
34044
+ if (data.length !== expectedNumberOfCalls) return void 0;
34045
+ const [markets] = data;
34046
+ return parseMarkets(markets ?? [], chainId, prices, tokenList);
34047
+ },
34048
+ expectedNumberOfCalls
34049
+ ];
34050
+ };
34051
+ function parseMarkets(markets, chainId, prices, tokenList) {
34052
+ const out = {};
34053
+ for (const m of markets) {
34054
+ const pool = m?.pool;
34055
+ if (!pool) continue;
34056
+ if (pool.isPaused) continue;
34057
+ const rawAddress = (pool.baseParams?.addr ?? "").toString().toLowerCase();
34058
+ const rawUnderlying = (pool.underlying ?? "").toString().toLowerCase();
34059
+ if (!rawAddress || !rawUnderlying) continue;
34060
+ const underlying = normalizeUnderlying5(rawUnderlying, chainId);
34061
+ const assetMeta = tokenList[underlying];
34062
+ const decimals = Number(assetMeta?.decimals ?? pool.decimals ?? 18);
34063
+ const totalAssetsRaw = pool.expectedLiquidity?.toString() ?? "0";
34064
+ const totalAssetsFormatted = Number(
34065
+ parseRawAmount(totalAssetsRaw, decimals)
34066
+ );
34067
+ const oracleKey = toOracleKey(assetMeta?.assetGroup) ?? toGenericPriceKey(underlying, chainId);
34068
+ const priceUsd = prices[oracleKey] ?? prices[underlying] ?? 0;
34069
+ const liquidityRaw = pool.availableLiquidity?.toString() ?? "0";
34070
+ const liquidityFormatted = Number(parseRawAmount(liquidityRaw, decimals));
34071
+ const entry = {
34072
+ address: rawAddress,
34073
+ underlying,
34074
+ symbol: pool.symbol ?? "",
34075
+ name: pool.name ?? "",
34076
+ decimals,
34077
+ totalAssets: totalAssetsRaw,
34078
+ totalSupply: pool.totalSupply?.toString() ?? "0",
34079
+ totalBorrowed: pool.totalBorrowed?.toString() ?? "0",
34080
+ availableLiquidity: pool.availableLiquidity?.toString() ?? "0",
34081
+ expectedLiquidity: pool.expectedLiquidity?.toString() ?? "0",
34082
+ dieselRate: pool.dieselRate?.toString() ?? "0",
34083
+ withdrawFeeBps: Number(pool.withdrawFee ?? 0),
34084
+ supplyRate: scaleRate(pool.supplyRate),
34085
+ baseInterestRate: scaleRate(pool.baseInterestRate),
34086
+ asset: assetMeta,
34087
+ priceUsd: priceUsd || void 0,
34088
+ totalAssetsFormatted,
34089
+ totalAssetsUsd: totalAssetsFormatted * priceUsd,
34090
+ liquidity: liquidityRaw,
34091
+ liquidityFormatted,
34092
+ liquidityUsd: liquidityFormatted * priceUsd
34093
+ };
34094
+ out[underlying] = entry;
34095
+ }
34096
+ return out;
34097
+ }
34098
+ var fetchGearboxV3Pools = async (chainId, multicallRetry, prices = {}, tokenList = {}) => {
34099
+ const calls = buildGearboxV3PoolsCall(chainId);
34100
+ if (calls.length === 0) return {};
34101
+ const raw = await multicallRetry({
34102
+ chain: chainId,
34103
+ calls,
34104
+ abi: calls.map(() => GearboxMarketCompressorV310Abi)
34105
+ });
34106
+ const [converter] = getGearboxV3PoolsConverter(chainId, prices, tokenList);
34107
+ return converter(raw) ?? {};
34108
+ };
34109
+
34110
+ // src/vaults/morpho/fetchFromApi.ts
34111
+ var MORPHO_API_URL = "https://blue-api.morpho.org/graphql";
34112
+ var PAGE_SIZE = 200;
34113
+ var vaultsQuery = (first, skip, chainId) => `
34114
+ query GetVaults {
34115
+ vaults(
34116
+ first: ${first},
34117
+ skip: ${skip},
34118
+ where: { chainId_in: [${chainId}], whitelisted: true },
34119
+ orderBy: TotalAssetsUsd,
34120
+ orderDirection: Desc
34121
+ ) {
34122
+ items {
34123
+ address
34124
+ symbol
34125
+ name
34126
+ whitelisted
34127
+ asset {
34128
+ address
34129
+ name
34130
+ symbol
34131
+ decimals
34132
+ priceUsd
34133
+ }
34134
+ liquidity {
34135
+ underlying
34136
+ usd
34137
+ }
34138
+ state {
34139
+ totalAssets
34140
+ totalAssetsUsd
34141
+ totalSupply
34142
+ apy
34143
+ netApy
34144
+ fee
34145
+ timelock
34146
+ owner
34147
+ curator
34148
+ guardian
34149
+ rewards {
34150
+ supplyApr
34151
+ asset {
34152
+ address
34153
+ }
34154
+ }
34155
+ }
34156
+ }
34157
+ }
34158
+ }
34159
+ `;
34160
+ async function fetchPage(chainId, first, skip) {
34161
+ const response = await fetch(MORPHO_API_URL, {
34162
+ method: "POST",
34163
+ headers: { "Content-Type": "application/json" },
34164
+ body: JSON.stringify({ query: vaultsQuery(first, skip, chainId) })
34165
+ });
34166
+ if (!response.ok) {
34167
+ throw new Error(
34168
+ `Morpho vaults API failed: ${response.status} - ${response.statusText}`
34169
+ );
34170
+ }
34171
+ const json = await response.json();
34172
+ return json?.data?.vaults?.items ?? [];
34173
+ }
34174
+ var sumRewardsApr = (rewards) => {
34175
+ if (!rewards) return 0;
34176
+ let total = 0;
34177
+ for (const r of rewards) {
34178
+ const apr = Number(r?.supplyApr ?? 0);
34179
+ if (Number.isFinite(apr)) total += apr;
34180
+ }
34181
+ return total * 100;
34182
+ };
34183
+ function parseVault2(v, chainId, prices, tokenList) {
34184
+ const address = (v?.address ?? "").toLowerCase();
34185
+ const assetAddr = (v?.asset?.address ?? "").toLowerCase();
34186
+ if (!address || !assetAddr) return null;
34187
+ const state = v.state ?? {};
34188
+ const assetMeta = tokenList[assetAddr];
34189
+ const decimals = Number(v.asset?.decimals ?? assetMeta?.decimals ?? 18);
34190
+ const totalAssetsRaw = state.totalAssets?.toString() ?? "0";
34191
+ const totalAssetsFormatted = Number(parseRawAmount(totalAssetsRaw, decimals));
34192
+ const liquidityRaw = v.liquidity?.underlying?.toString() ?? "0";
34193
+ const liquidityFormatted = Number(parseRawAmount(liquidityRaw, decimals));
34194
+ const liquidityUsd = Number(v.liquidity?.usd ?? 0);
34195
+ const oracleKey = toOracleKey(assetMeta?.assetGroup) ?? toGenericPriceKey(assetAddr, chainId);
34196
+ const apiPriceUsd = Number(v.asset?.priceUsd ?? 0);
34197
+ const resolvedPriceUsd = prices[oracleKey] ?? prices[assetAddr] ?? apiPriceUsd ?? 0;
34198
+ const netApy = Number(state.netApy ?? state.apy ?? 0);
34199
+ const supplyRate = apyToAprPercent(netApy * 100);
34200
+ const rewardsRate = sumRewardsApr(state.rewards);
34201
+ const apiTotalAssetsUsd = Number(state.totalAssetsUsd ?? 0);
34202
+ const totalAssetsUsd = apiTotalAssetsUsd || totalAssetsFormatted * resolvedPriceUsd;
34203
+ return {
34204
+ address,
34205
+ underlying: assetAddr,
34206
+ symbol: v.symbol ?? "",
34207
+ name: v.name ?? "",
34208
+ decimals,
34209
+ totalAssets: totalAssetsRaw,
34210
+ totalSupply: state.totalSupply?.toString() ?? "0",
34211
+ supplyRate,
34212
+ rewardsRate,
34213
+ depositRate: supplyRate + rewardsRate,
34214
+ fee: Number(state.fee ?? 0) * 100,
34215
+ timelock: Number(state.timelock ?? 0),
34216
+ whitelisted: v.whitelisted ?? true,
34217
+ owner: state.owner?.toLowerCase() || void 0,
34218
+ curator: state.curator?.toLowerCase() || void 0,
34219
+ guardian: state.guardian?.toLowerCase() || void 0,
34220
+ asset: assetMeta,
34221
+ priceUsd: resolvedPriceUsd || void 0,
34222
+ totalAssetsFormatted,
34223
+ totalAssetsUsd,
34224
+ liquidity: liquidityRaw,
34225
+ liquidityFormatted,
34226
+ liquidityUsd: liquidityUsd || liquidityFormatted * resolvedPriceUsd
34227
+ };
34228
+ }
34229
+ async function fetchMorphoVaultsFromApi(chainId, prices = {}, tokenList = {}, maxItems = 600) {
34230
+ const out = {};
34231
+ let skip = 0;
34232
+ while (skip < maxItems) {
34233
+ const page = await fetchPage(chainId, PAGE_SIZE, skip);
34234
+ if (page.length === 0) break;
34235
+ for (const v of page) {
34236
+ const parsed = parseVault2(v, chainId, prices, tokenList);
34237
+ if (parsed) out[parsed.address] = parsed;
34238
+ }
34239
+ if (page.length < PAGE_SIZE) break;
34240
+ skip += PAGE_SIZE;
34241
+ }
34242
+ return out;
34243
+ }
34244
+
34245
+ // src/vaults/morpho/fetchFromSubgraph.ts
34246
+ var MORPHO_VAULT_SUBGRAPH_URLS = {
34247
+ [Chain.SEI_NETWORK]: "https://api.goldsky.com/api/public/project_cmiergfbv4vma01vb642yaeam/subgraphs/morphoblue-sei/1.0.1/gn",
34248
+ [Chain.CELO_MAINNET]: "https://api.goldsky.com/api/public/project_cmiergfbv4vma01vb642yaeam/subgraphs/morphoblue-celo/1.0.4/gn",
34249
+ [Chain.LISK]: "https://api.goldsky.com/api/public/project_cmiergfbv4vma01vb642yaeam/subgraphs/morphobluelisk/1.0.1/gn",
34250
+ [Chain.SONEIUM]: "https://api.goldsky.com/api/public/project_cmiergfbv4vma01vb642yaeam/subgraphs/morphobluesoneium/1.0.2/gn",
34251
+ [Chain.TAC_MAINNET]: "https://api.goldsky.com/api/public/project_cmiergfbv4vma01vb642yaeam/subgraphs/morphoblue-tac/1.0.0/gn",
34252
+ [Chain.HEMI_NETWORK]: "https://feather.securesecrets.org/hemi-mopho-blue/"
34253
+ };
34254
+ var hasMorphoVaultSubgraph = (chainId) => chainId in MORPHO_VAULT_SUBGRAPH_URLS;
34255
+ var META_MORPHOS_QUERY = `
34256
+ {
34257
+ metaMorphos(first: 100, skip: 0) {
34258
+ id
34259
+ name
34260
+ symbol
34261
+ decimals
34262
+ asset { id }
34263
+ curator { id }
34264
+ owner { id }
34265
+ guardian { id }
34266
+ timelock
34267
+ fee
34268
+ rate { id rate }
34269
+ lastTotalAssets
34270
+ totalShares
34271
+ }
34272
+ }
34273
+ `;
34274
+ function parseVaultRate(rate) {
34275
+ if (!rate) return 0;
34276
+ const numeric = Number(rate.rate) * 100;
34277
+ return Number.isFinite(numeric) ? numeric : 0;
34278
+ }
34279
+ function parseVault3(v, chainId, prices, tokenList) {
34280
+ const address = (v?.id ?? "").toLowerCase();
34281
+ const assetAddr = (v?.asset?.id ?? "").toLowerCase();
34282
+ if (!address || !assetAddr) return null;
34283
+ const assetMeta = tokenList[assetAddr];
34284
+ const decimals = Number(v.decimals ?? assetMeta?.decimals ?? 18);
34285
+ const totalAssetsRaw = v.lastTotalAssets?.toString() ?? "0";
34286
+ const totalAssetsFormatted = Number(parseRawAmount(totalAssetsRaw, decimals));
34287
+ const oracleKey = toOracleKey(assetMeta?.assetGroup) ?? toGenericPriceKey(assetAddr, chainId);
34288
+ const priceUsd = prices[oracleKey] ?? prices[assetAddr] ?? 0;
34289
+ const supplyRate = parseVaultRate(v.rate);
34290
+ const feeRaw = Number(v.fee ?? 0);
34291
+ const fee = Number.isFinite(feeRaw) ? feeRaw * 100 : 0;
34292
+ return {
34293
+ address,
34294
+ underlying: assetAddr,
34295
+ symbol: v.symbol ?? "",
34296
+ name: v.name ?? "",
34297
+ decimals,
34298
+ totalAssets: totalAssetsRaw,
34299
+ totalSupply: v.totalShares?.toString() ?? "0",
34300
+ supplyRate,
34301
+ // Rewards APR is not carried in the subgraph schema — surface 0 so
34302
+ // downstream math still works; callers that need rewards on
34303
+ // Goldsky-sourced chains must layer them in separately.
34304
+ rewardsRate: 0,
34305
+ depositRate: supplyRate,
34306
+ fee,
34307
+ timelock: Number(v.timelock ?? 0),
34308
+ whitelisted: true,
34309
+ owner: v.owner?.id?.toLowerCase() || void 0,
34310
+ curator: v.curator?.id?.toLowerCase() || void 0,
34311
+ guardian: v.guardian?.id?.toLowerCase() || void 0,
34312
+ asset: assetMeta,
34313
+ priceUsd: priceUsd || void 0,
34314
+ totalAssetsFormatted,
34315
+ totalAssetsUsd: totalAssetsFormatted * priceUsd,
34316
+ // Subgraph does not expose current withdrawable liquidity — default
34317
+ // to totalAssets as an optimistic upper bound so callers still get a
34318
+ // value. Users on Goldsky-sourced chains should not rely on this for
34319
+ // hard withdraw validation.
34320
+ liquidity: totalAssetsRaw,
34321
+ liquidityFormatted: totalAssetsFormatted,
34322
+ liquidityUsd: totalAssetsFormatted * priceUsd
34323
+ };
34324
+ }
34325
+ async function fetchMorphoVaultsFromSubgraph(chainId, prices = {}, tokenList = {}) {
34326
+ const url = MORPHO_VAULT_SUBGRAPH_URLS[chainId];
34327
+ if (!url) return {};
34328
+ const response = await fetch(url, {
34329
+ method: "POST",
34330
+ headers: { "Content-Type": "application/json" },
34331
+ body: JSON.stringify({ query: META_MORPHOS_QUERY })
34332
+ });
34333
+ if (!response.ok) {
34334
+ throw new Error(
34335
+ `Morpho vaults subgraph failed for chain ${chainId}: ${response.status} - ${response.statusText}`
34336
+ );
34337
+ }
34338
+ const json = await response.json();
34339
+ const items = json?.data?.metaMorphos ?? [];
34340
+ const out = {};
34341
+ for (const v of items) {
34342
+ const parsed = parseVault3(v, chainId, prices, tokenList);
34343
+ if (parsed) out[parsed.address] = parsed;
34344
+ }
34345
+ return out;
34346
+ }
34347
+
34348
+ // src/vaults/morpho/fetchPublic.ts
34349
+ var fetchMorphoVaults = async (chainId, prices = {}, tokenList = {}) => {
34350
+ if (hasMorphoVaultSubgraph(chainId)) {
34351
+ return fetchMorphoVaultsFromSubgraph(chainId, prices, tokenList);
34352
+ }
34353
+ return fetchMorphoVaultsFromApi(chainId, prices, tokenList);
34354
+ };
34355
+
34356
+ // src/vaults/silo/fetchPublic.ts
34357
+ var SILO_API_URL = "https://api-v3.silo.finance";
34358
+ var vaultsQuery2 = (chainId, limit) => `
34359
+ query GetSiloVaults {
34360
+ vaults(where: {chainId_in: [${chainId}]}, limit: ${limit}) {
34361
+ items {
34362
+ id
34363
+ chainId
34364
+ name
34365
+ symbol
34366
+ decimals
34367
+ protocolId
34368
+ protocol { id protocolVersion }
34369
+ asset { id symbol decimals }
34370
+ ownerId
34371
+ curatorId
34372
+ guardianId
34373
+ feeRecipient
34374
+ totalAssets
34375
+ totalAssetsUsd
34376
+ totalSupply
34377
+ performanceFee
34378
+ timelock
34379
+ apr
34380
+ userApr
34381
+ }
34382
+ }
34383
+ }
34384
+ `;
34385
+ var PERFORMANCE_FEE_SCALE = 1e16;
34386
+ var toRawAmount = (decimalString, decimals) => {
34387
+ if (!decimalString) return "0";
34388
+ try {
34389
+ return parseUnits(decimalString, decimals).toString();
34390
+ } catch {
34391
+ return "0";
34392
+ }
34393
+ };
34394
+ function parseVault4(v, chainId, prices, tokenList) {
34395
+ const address = (v?.id ?? "").toLowerCase();
34396
+ const assetAddr = (v?.asset?.id ?? "").toLowerCase();
34397
+ if (!address || !assetAddr) return null;
34398
+ const assetMeta = tokenList[assetAddr];
34399
+ const decimals = Number(
34400
+ v.decimals ?? v.asset?.decimals ?? assetMeta?.decimals ?? 18
34401
+ );
34402
+ const totalAssetsFormatted = Number(v.totalAssets ?? 0) || 0;
34403
+ const totalAssetsRaw = toRawAmount(v.totalAssets, decimals);
34404
+ const totalSupplyRaw = toRawAmount(v.totalSupply, decimals);
34405
+ const oracleKey = toOracleKey(assetMeta?.assetGroup) ?? toGenericPriceKey(assetAddr, chainId);
34406
+ const priceUsd = prices[oracleKey] ?? prices[assetAddr] ?? 0;
34407
+ const supplyRate = Number(v.userApr ?? 0) || 0;
34408
+ const grossRate = Number(v.apr ?? 0) || 0;
34409
+ const feeRaw = Number(v.performanceFee ?? 0);
34410
+ const fee = Number.isFinite(feeRaw) ? feeRaw / PERFORMANCE_FEE_SCALE : 0;
34411
+ const apiTotalAssetsUsd = Number(v.totalAssetsUsd ?? 0) || 0;
34412
+ const totalAssetsUsd = apiTotalAssetsUsd || totalAssetsFormatted * priceUsd;
34413
+ return {
34414
+ address,
34415
+ underlying: assetAddr,
34416
+ symbol: v.symbol ?? "",
34417
+ name: v.name ?? "",
34418
+ decimals,
34419
+ protocolVersion: v.protocol?.protocolVersion ?? "",
34420
+ protocolId: (v.protocolId ?? v.protocol?.id ?? "").toLowerCase(),
34421
+ totalAssets: totalAssetsRaw,
34422
+ totalSupply: totalSupplyRaw,
34423
+ supplyRate,
34424
+ grossRate,
34425
+ rewardsRate: 0,
34426
+ depositRate: supplyRate,
34427
+ fee,
34428
+ timelock: Number(v.timelock ?? 0),
34429
+ owner: v.ownerId?.toLowerCase() || void 0,
34430
+ curator: v.curatorId?.toLowerCase() || void 0,
34431
+ guardian: v.guardianId?.toLowerCase() || void 0,
34432
+ feeRecipient: v.feeRecipient?.toLowerCase() || void 0,
34433
+ asset: assetMeta,
34434
+ priceUsd: priceUsd || void 0,
34435
+ totalAssetsFormatted,
34436
+ totalAssetsUsd,
34437
+ // Silo's indexer doesn't expose an immediate-withdraw figure; the
34438
+ // effective cap is per-allocation silo utilisation, which would need
34439
+ // a second-pass aggregation. Fall back to `totalAssets` as an
34440
+ // optimistic ceiling so consumers still get a field for parity with
34441
+ // Morpho / Fluid / Gearbox. Not suitable for hard withdraw validation.
34442
+ liquidity: totalAssetsRaw,
34443
+ liquidityFormatted: totalAssetsFormatted,
34444
+ liquidityUsd: totalAssetsUsd
34445
+ };
34446
+ }
34447
+ var fetchSiloVaults = async (chainId, prices = {}, tokenList = {}, options) => {
34448
+ if (!SILO_API_SUPPORTED_CHAIN_IDS.has(chainId)) return {};
34449
+ const limit = options?.limit ?? 500;
34450
+ const response = await fetch(SILO_API_URL, {
34451
+ method: "POST",
34452
+ headers: { "Content-Type": "application/json" },
34453
+ body: JSON.stringify({ query: vaultsQuery2(chainId, limit) })
34454
+ });
34455
+ if (!response.ok) {
34456
+ throw new Error(
34457
+ `[silo-vaults] Network error: ${response.status} - ${response.statusText}`
34458
+ );
34459
+ }
34460
+ const payload = await response.json();
34461
+ if (payload?.errors?.length) {
34462
+ throw new Error(
34463
+ `[silo-vaults] GraphQL error: ${payload.errors.map((e) => e?.message).join("; ")}`
34464
+ );
34465
+ }
34466
+ const items = payload?.data?.vaults?.items ?? [];
34467
+ const out = {};
34468
+ for (const v of items) {
34469
+ if (options?.protocolVersion && v.protocol?.protocolVersion !== options.protocolVersion) {
34470
+ continue;
34471
+ }
34472
+ const parsed = parseVault4(v, chainId, prices, tokenList);
34473
+ if (parsed) out[parsed.address] = parsed;
34474
+ }
34475
+ return out;
34476
+ };
34477
+ var warn3 = (...args) => {
34478
+ };
34479
+ var getVaultPublicDataAll = async (chainId, providers, multicallRetry, prices = {}, tokenList = {}, options) => {
34480
+ const requested = new Set(providers);
34481
+ if (requested.size === 0) return {};
34482
+ const tasks = [];
34483
+ const out = {};
34484
+ if (requested.has("fluid")) {
34485
+ tasks.push(
34486
+ fetchFluidFTokens(chainId, multicallRetry, prices, tokenList).then((res) => {
34487
+ out.fluid = res;
34488
+ }).catch((e) => {
34489
+ warn3(
34490
+ `[vaults] fluid fetch failed for chain ${chainId}:`,
34491
+ e?.message ?? e
34492
+ );
34493
+ })
34494
+ );
34495
+ }
34496
+ if (requested.has("gearbox")) {
34497
+ tasks.push(
34498
+ fetchGearboxV3Pools(chainId, multicallRetry, prices, tokenList).then((res) => {
34499
+ out.gearbox = res;
34500
+ }).catch((e) => {
34501
+ warn3(
34502
+ `[vaults] gearbox fetch failed for chain ${chainId}:`,
34503
+ e?.message ?? e
34504
+ );
34505
+ })
34506
+ );
34507
+ }
34508
+ if (requested.has("morpho")) {
34509
+ tasks.push(
34510
+ fetchMorphoVaults(chainId, prices, tokenList).then((res) => {
34511
+ out.morpho = res;
34512
+ }).catch((e) => {
34513
+ warn3(
34514
+ `[vaults] morpho fetch failed for chain ${chainId}:`,
34515
+ e?.message ?? e
34516
+ );
34517
+ })
34518
+ );
34519
+ }
34520
+ if (requested.has("silo")) {
34521
+ tasks.push(
34522
+ fetchSiloVaults(chainId, prices, tokenList, {
34523
+ protocolVersion: options?.siloProtocolVersion,
34524
+ limit: options?.siloLimit
34525
+ }).then((res) => {
34526
+ out.silo = res;
34527
+ }).catch((e) => {
34528
+ warn3(
34529
+ `[vaults] silo fetch failed for chain ${chainId}:`,
34530
+ e?.message ?? e
34531
+ );
34532
+ })
34533
+ );
34534
+ }
34535
+ await Promise.all(tasks);
34536
+ return out;
34537
+ };
34538
+
33716
34539
  // src/lending/margin/e-mode/index.ts
33717
34540
  function computeEModeSwitchHealth(positions, lenderMeta, currentCollateral, currentAdjustedDebt, currentMode, targetMode) {
33718
34541
  if (currentAdjustedDebt === 0) return null;
@@ -34199,6 +35022,6 @@ async function fetchTokenBalances(chainId, account, tokens, options = {}) {
34199
35022
  return parseTokenBalanceResult(rawResult, prepared.query);
34200
35023
  }
34201
35024
 
34202
- export { EMPTY_BALANCE, MORPHO_LENS, MaxParamThresholds, applyPositionDelta, attachPricesToFlashLiquidity, buildFluidFTokensCall, buildLoopResult, buildMorphoTypeCall, buildMorphoTypeUserCallWithLens, buildPortfolioTotals, buildSumerAccumulators, buildSummaries, calculateLeverage, calculateNetApr, calculateOverallNetApr, calculateWeightedAverage, computeBorrowDelta2 as computeBorrowDelta, computeCloseTradeDeltas, computeCollateralSwapDeltas, computeDebtSwapDeltas, computeDepositDelta2 as computeDepositDelta, computeEModeAnalysis, computeOpenTradeDeltas, computePostTradeMetrics, computeRepayDelta2 as computeRepayDelta, computeSumerBorrowDelta, computeSumerDepositDelta, computeSumerRepayDelta, computeSumerWaterfall, computeSumerWithdrawDelta, computeWithdrawDelta2 as computeWithdrawDelta, computeZapTradeDeltas, convertLenderUserDataResult, createMarketUid, createMulticallRpcCall, createRawRpcCalls, decodeListaMarkets, decodeMarkets, decodePackedListaUserDataset, decodePackedMorphoUserDataset, encodeBalanceFetcherCalldata, fetchEulerSubAccountIndexes, fetchFlashLiquidityForChain, fetchFluidFTokens, fetchGeneralYields, fetchGeneralYieldsByMarketUid, fetchOraclePrices, fetchPendlePrices, fetchTokenBalances, fetchTokenMetadata, filterActiveLenders, filterLendersByProtocol, fuseLenderData, generateLendingPools, getAavesForChain, getAssetConfig, getBalanceForMarketUid, getBorrowCapacity, getFluidFTokensConverter, getHealthFactor, getLenderAssets, getLenderPublicData, getLenderPublicDataAll, getLenderPublicDataViaApi, getLenderUserDataMulti, getLenderUserDataResult, getLendersForChain, getMaxAmountClose, getMaxAmountCollateralSwap, getMaxAmountDebtSwap, getMaxAmountOpen, getMergedUserData, getMorphoTypeMarketConverter, getSubAccountAddress, getSubAccountIndex, keysFromMaps, multicall3Abi, nanTo, needsLenderApproval, needsTokenApproval, noOpResult, normalizeToBytes, parseBalanceFetcherResult, parseMergedResult, parseMulticallRpcResponses, parseRawRpcBatchResponses, parseRawRpcResponses, parseTokenBalanceResult, positivePart2 as positivePart, prepareLenderUserDataRpcCalls, prepareMergedMulticallParams, prepareMergedRpcCalls, prepareMulticallInputs, prepareTokenBalanceRpcCalls, selectAssetGroupPrices, unflattenLenderData };
35025
+ export { EMPTY_BALANCE, MORPHO_LENS, MaxParamThresholds, applyPositionDelta, attachPricesToFlashLiquidity, buildFluidFTokensCall, buildLoopResult, buildMorphoTypeCall, buildMorphoTypeUserCallWithLens, buildPortfolioTotals, buildSumerAccumulators, buildSummaries, calculateLeverage, calculateNetApr, calculateOverallNetApr, calculateWeightedAverage, computeBorrowDelta2 as computeBorrowDelta, computeCloseTradeDeltas, computeCollateralSwapDeltas, computeDebtSwapDeltas, computeDepositDelta2 as computeDepositDelta, computeEModeAnalysis, computeOpenTradeDeltas, computePostTradeMetrics, computeRepayDelta2 as computeRepayDelta, computeSumerBorrowDelta, computeSumerDepositDelta, computeSumerRepayDelta, computeSumerWaterfall, computeSumerWithdrawDelta, computeWithdrawDelta2 as computeWithdrawDelta, computeZapTradeDeltas, convertLenderUserDataResult, createMarketUid, createMulticallRpcCall, createRawRpcCalls, decodeListaMarkets, decodeMarkets, decodePackedListaUserDataset, decodePackedMorphoUserDataset, encodeBalanceFetcherCalldata, fetchEulerSubAccountIndexes, fetchFlashLiquidityForChain, fetchFluidFTokens, fetchGeneralYields, fetchGeneralYieldsByMarketUid, fetchMorphoUserBalances, fetchMorphoUserPositionMarkets, fetchMorphoVaults, fetchMorphoVaultsFromApi, fetchMorphoVaultsFromSubgraph, fetchOraclePrices, fetchPendlePrices, fetchSiloVaults, fetchTokenBalances, fetchTokenMetadata, filterActiveLenders, filterLendersByProtocol, fuseLenderData, generateLendingPools, getAavesForChain, getAssetConfig, getBalanceForMarketUid, getBorrowCapacity, getFluidFTokensConverter, getHealthFactor, getLenderAssets, getLenderPublicData, getLenderPublicDataAll, getLenderPublicDataViaApi, getLenderUserDataMulti, getLenderUserDataResult, getLendersForChain, getMaxAmountClose, getMaxAmountCollateralSwap, getMaxAmountDebtSwap, getMaxAmountOpen, getMergedUserData, getMorphoTypeMarketConverter, getSubAccountAddress, getSubAccountIndex, getVaultPublicDataAll, hasMorphoPositionIndex, hasMorphoUserApi, hasMorphoUserSubgraph, hasMorphoVaultSubgraph, keysFromMaps, multicall3Abi, nanTo, needsLenderApproval, needsTokenApproval, noOpResult, normalizeToBytes, parseBalanceFetcherResult, parseMergedResult, parseMulticallRpcResponses, parseRawRpcBatchResponses, parseRawRpcResponses, parseTokenBalanceResult, positivePart2 as positivePart, prepareLenderUserDataRpcCalls, prepareMergedMulticallParams, prepareMergedRpcCalls, prepareMulticallInputs, prepareTokenBalanceRpcCalls, selectAssetGroupPrices, unflattenLenderData };
34203
35026
  //# sourceMappingURL=index.js.map
34204
35027
  //# sourceMappingURL=index.js.map