@1delta/margin-fetcher 0.0.225 → 0.0.228

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 (55) hide show
  1. package/dist/abis/silo-v2/Silo.d.ts +101 -0
  2. package/dist/abis/silo-v2/Silo.d.ts.map +1 -0
  3. package/dist/abis/silo-v2/SiloConfig.d.ts +78 -0
  4. package/dist/abis/silo-v2/SiloConfig.d.ts.map +1 -0
  5. package/dist/abis/silo-v2/SiloLens.d.ts +50 -0
  6. package/dist/abis/silo-v2/SiloLens.d.ts.map +1 -0
  7. package/dist/abis/silo-v2/index.d.ts +4 -0
  8. package/dist/abis/silo-v2/index.d.ts.map +1 -0
  9. package/dist/index.js +1850 -95
  10. package/dist/index.js.map +1 -1
  11. package/dist/lending/public-data/aave-v4-type/fetcher/normalize.d.ts +1 -0
  12. package/dist/lending/public-data/aave-v4-type/fetcher/normalize.d.ts.map +1 -1
  13. package/dist/lending/public-data/fetchLender.d.ts.map +1 -1
  14. package/dist/lending/public-data/fetchLenderAll.d.ts.map +1 -1
  15. package/dist/lending/public-data/fetchLenderExt.d.ts.map +1 -1
  16. package/dist/lending/public-data/lista/getMarketsFromChain.d.ts.map +1 -1
  17. package/dist/lending/public-data/silo-v2/convertPublic.d.ts +28 -0
  18. package/dist/lending/public-data/silo-v2/convertPublic.d.ts.map +1 -0
  19. package/dist/lending/public-data/silo-v2/fetchPublic.d.ts +70 -0
  20. package/dist/lending/public-data/silo-v2/fetchPublic.d.ts.map +1 -0
  21. package/dist/lending/public-data/silo-v2/publicCallBuild.d.ts +23 -0
  22. package/dist/lending/public-data/silo-v2/publicCallBuild.d.ts.map +1 -0
  23. package/dist/lending/public-data/silo-v2/publicCallParse.d.ts +25 -0
  24. package/dist/lending/public-data/silo-v2/publicCallParse.d.ts.map +1 -0
  25. package/dist/lending/public-data/silo-v3/convertPublic.d.ts +18 -0
  26. package/dist/lending/public-data/silo-v3/convertPublic.d.ts.map +1 -0
  27. package/dist/lending/public-data/silo-v3/publicCallBuild.d.ts +19 -0
  28. package/dist/lending/public-data/silo-v3/publicCallBuild.d.ts.map +1 -0
  29. package/dist/lending/public-data/silo-v3/publicCallParse.d.ts +16 -0
  30. package/dist/lending/public-data/silo-v3/publicCallParse.d.ts.map +1 -0
  31. package/dist/lending/user-data/abis.d.ts.map +1 -1
  32. package/dist/lending/user-data/fetch-balances/parse.d.ts.map +1 -1
  33. package/dist/lending/user-data/fetch-balances/prepare.d.ts.map +1 -1
  34. package/dist/lending/user-data/silo-v2/userCallBuild.d.ts +21 -0
  35. package/dist/lending/user-data/silo-v2/userCallBuild.d.ts.map +1 -0
  36. package/dist/lending/user-data/silo-v2/userCallParse.d.ts +23 -0
  37. package/dist/lending/user-data/silo-v2/userCallParse.d.ts.map +1 -0
  38. package/dist/lending/user-data/utils/types.d.ts +20 -0
  39. package/dist/lending/user-data/utils/types.d.ts.map +1 -1
  40. package/dist/prices/oracle-prices/fetchOraclePrices.d.ts.map +1 -1
  41. package/dist/prices/oracle-prices/fetchers/index.d.ts +2 -0
  42. package/dist/prices/oracle-prices/fetchers/index.d.ts.map +1 -1
  43. package/dist/prices/oracle-prices/fetchers/siloV2.d.ts +108 -0
  44. package/dist/prices/oracle-prices/fetchers/siloV2.d.ts.map +1 -0
  45. package/dist/prices/oracle-prices/fetchers/siloV2Graphql.d.ts +36 -0
  46. package/dist/prices/oracle-prices/fetchers/siloV2Graphql.d.ts.map +1 -0
  47. package/dist/prices/oracle-prices/fetchers/siloV3.d.ts +52 -0
  48. package/dist/prices/oracle-prices/fetchers/siloV3.d.ts.map +1 -0
  49. package/dist/prices/oracle-prices/fetchers/siloV3Graphql.d.ts +19 -0
  50. package/dist/prices/oracle-prices/fetchers/siloV3Graphql.d.ts.map +1 -0
  51. package/dist/prices/oracle-prices/index.d.ts +2 -0
  52. package/dist/prices/oracle-prices/index.d.ts.map +1 -1
  53. package/dist/utils/index.d.ts +1 -1
  54. package/dist/utils/index.d.ts.map +1 -1
  55. package/package.json +6 -6
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { parseAbi, formatEther, BaseError, encodeFunctionData, formatUnits, decodeFunctionResult, decodeAbiParameters, AbiEncodingLengthMismatchError, concatHex, isAddress, InvalidAddressError, pad, stringToHex, boolToHex, integerRegex, numberToHex, bytesRegex, BytesSizeMismatchError, arrayRegex, UnsupportedPackedAbiType } from './chunk-ZVIJSUIM.js';
2
2
  import './chunk-BYTNVMX7.js';
3
3
  import './chunk-PR4QN5HX.js';
4
- import { Lender, isAaveType, isCompoundV3, isMultiMarket, isAaveV4Type, isInit, isMorphoType, isCompoundV2Type, isVenusType, isSumerType, AAVE_V3_LENDERS, AAVE_V2_LENDERS, isAaveV2Type, isAaveV32Type, isAaveV3Type, isEulerType, isYLDR, isCompoundV3Type, isLista, isTectonicType, isBenqiType } from '@1delta/lender-registry';
4
+ import { Lender, isAaveType, isCompoundV3, isMultiMarket, isSiloV2Type, isSiloV3Type, isAaveV4Type, isInit, isMorphoType, isCompoundV2Type, isVenusType, isSumerType, AAVE_V3_LENDERS, AAVE_V2_LENDERS, isAaveV2Type, isAaveV32Type, isAaveV3Type, isEulerType, isYLDR, isCompoundV3Type, isLista, isTectonicType, isBenqiType } from '@1delta/lender-registry';
5
5
  export { isAaveType, isAaveV2Type, isAaveV32Type, isAaveV3Type, isCompoundV3, isCompoundV3Type, isInit, isMorphoType, isMultiMarket, isYLDR } from '@1delta/lender-registry';
6
6
  import lodash from 'lodash';
7
7
  import { getEvmChain, getEvmClient, getEvmClientUniversal, multicallRetryUniversal } from '@1delta/providers';
@@ -6277,7 +6277,11 @@ globalThis[GLOBAL_LENDER_DATA_KEY] = {
6277
6277
  eulerVaults: {},
6278
6278
  aaveV4Spokes: {},
6279
6279
  aaveV4Oracles: {},
6280
- aaveV4Peripherals: {}
6280
+ aaveV4Peripherals: {},
6281
+ siloMarkets: {},
6282
+ siloPeripherals: {},
6283
+ siloMarketsV3: {},
6284
+ siloPeripheralsV3: {}
6281
6285
  };
6282
6286
  function getGlobalData2() {
6283
6287
  return globalThis[GLOBAL_LENDER_DATA_KEY];
@@ -6303,6 +6307,8 @@ var eulerConfigs = () => getGlobalData2()?.eulerConfigs;
6303
6307
  var eulerVaults = () => getGlobalData2()?.eulerVaults;
6304
6308
  var aaveV4Spokes = () => getGlobalData2()?.aaveV4Spokes;
6305
6309
  var aaveV4Oracles = () => getGlobalData2()?.aaveV4Oracles;
6310
+ var siloMarkets = () => getGlobalData2()?.siloMarkets;
6311
+ var siloMarketsV3 = () => getGlobalData2()?.siloMarketsV3;
6306
6312
  function aaveV4SpokeLenderKey(spoke) {
6307
6313
  if (!spoke || !spoke.startsWith("0x") || spoke.length !== 42) {
6308
6314
  throw new Error(`aaveV4SpokeLenderKey: invalid spoke address ${spoke}`);
@@ -6314,6 +6320,46 @@ function parseAaveV4SpokeLenderKey(lenderKey) {
6314
6320
  if (!match) return void 0;
6315
6321
  return { spokeAddrLower: "0x" + match[1].toLowerCase() };
6316
6322
  }
6323
+ function siloV2LenderKey(siloConfig) {
6324
+ if (!siloConfig || !siloConfig.startsWith("0x") || siloConfig.length !== 42) {
6325
+ throw new Error(`siloV2LenderKey: invalid siloConfig address ${siloConfig}`);
6326
+ }
6327
+ return `SILO_V2_${siloConfig.slice(2).toUpperCase()}`;
6328
+ }
6329
+ function parseSiloV2LenderKey(lenderKey) {
6330
+ const match = lenderKey.match(/^SILO_V2_([0-9A-F]{40})$/);
6331
+ if (!match) return void 0;
6332
+ return { siloConfigAddrLower: "0x" + match[1].toLowerCase() };
6333
+ }
6334
+ function getSiloV2MarketEntry(chainId, lenderKey) {
6335
+ const parsed = parseSiloV2LenderKey(lenderKey);
6336
+ if (!parsed) return void 0;
6337
+ const list = getGlobalData2()?.siloMarkets?.[chainId];
6338
+ if (!list) return void 0;
6339
+ return list.find(
6340
+ (m) => m.siloConfig.toLowerCase() === parsed.siloConfigAddrLower
6341
+ );
6342
+ }
6343
+ function siloV3LenderKey(siloConfig) {
6344
+ if (!siloConfig || !siloConfig.startsWith("0x") || siloConfig.length !== 42) {
6345
+ throw new Error(`siloV3LenderKey: invalid siloConfig address ${siloConfig}`);
6346
+ }
6347
+ return `SILO_V3_${siloConfig.slice(2).toUpperCase()}`;
6348
+ }
6349
+ function parseSiloV3LenderKey(lenderKey) {
6350
+ const match = lenderKey.match(/^SILO_V3_([0-9A-F]{40})$/);
6351
+ if (!match) return void 0;
6352
+ return { siloConfigAddrLower: "0x" + match[1].toLowerCase() };
6353
+ }
6354
+ function getSiloV3MarketEntry(chainId, lenderKey) {
6355
+ const parsed = parseSiloV3LenderKey(lenderKey);
6356
+ if (!parsed) return void 0;
6357
+ const list = getGlobalData2()?.siloMarketsV3?.[chainId];
6358
+ if (!list) return void 0;
6359
+ return list.find(
6360
+ (m) => m.siloConfig.toLowerCase() === parsed.siloConfigAddrLower
6361
+ );
6362
+ }
6317
6363
  var getListUrl = (chainId) => `https://raw.githubusercontent.com/1delta-DAO/token-lists/main/${chainId}.json`;
6318
6364
  async function fetchTokenList(chainId) {
6319
6365
  const data = await fetch(getListUrl(chainId));
@@ -7544,6 +7590,10 @@ var getLendersForChain = (c) => {
7544
7590
  if (data[c]?.length > 0) lenders.push(l);
7545
7591
  });
7546
7592
  }
7593
+ const siloChainPairs = siloMarkets()?.[c] ?? [];
7594
+ for (const market of siloChainPairs) {
7595
+ lenders.push(siloV2LenderKey(market.siloConfig));
7596
+ }
7547
7597
  const v4ChainSpokes = aaveV4Spokes()?.[c] ?? {};
7548
7598
  for (const spokeAddr of Object.keys(v4ChainSpokes)) {
7549
7599
  lenders.push(aaveV4SpokeLenderKey(spokeAddr));
@@ -13003,7 +13053,11 @@ function getListaMarketDataConverter(lender, chainId, prices, additionalYields =
13003
13053
  };
13004
13054
  const ltv = parseLtv(lltv);
13005
13055
  const metaCollateral = tokens[collateralAssetAddress] ?? collateralAsset;
13006
- const collateralMarketUid = createMarketUid(chainId, m, collateralAssetAddress);
13056
+ const collateralMarketUid = createMarketUid(
13057
+ chainId,
13058
+ m,
13059
+ collateralAssetAddress
13060
+ );
13007
13061
  data[m].data[collateralMarketUid] = {
13008
13062
  marketUid: collateralMarketUid,
13009
13063
  name: "Collateral " + (metaCollateral?.symbol ?? ""),
@@ -18330,7 +18384,8 @@ function normalizeAaveV4(spokeDataList, chainId, spokeLenderKeyArg, prices, addi
18330
18384
  collateralRiskBps,
18331
18385
  riskPremiumThresholdBps,
18332
18386
  depositable: depositableNum,
18333
- borrowLiquidity: borrowLiquidityNum
18387
+ borrowLiquidity: borrowLiquidityNum,
18388
+ borrowLiquidityUSD: borrowLiquidityNum * price
18334
18389
  };
18335
18390
  }
18336
18391
  if (Object.keys(data).length === 0) return void 0;
@@ -18552,6 +18607,399 @@ var getAaveV4ReservesDataConverter = (lender, chainId, prices, additionalYields,
18552
18607
  };
18553
18608
  return [converter, expectedCalls];
18554
18609
  };
18610
+
18611
+ // src/abis/silo-v2/Silo.ts
18612
+ var SiloAbi = [
18613
+ {
18614
+ type: "function",
18615
+ name: "totalAssets",
18616
+ stateMutability: "view",
18617
+ inputs: [],
18618
+ outputs: [{ name: "", type: "uint256" }]
18619
+ },
18620
+ {
18621
+ type: "function",
18622
+ name: "getDebtAssets",
18623
+ stateMutability: "view",
18624
+ inputs: [],
18625
+ outputs: [{ name: "", type: "uint256" }]
18626
+ },
18627
+ {
18628
+ type: "function",
18629
+ name: "getCollateralAssets",
18630
+ stateMutability: "view",
18631
+ inputs: [],
18632
+ outputs: [{ name: "", type: "uint256" }]
18633
+ },
18634
+ {
18635
+ type: "function",
18636
+ name: "asset",
18637
+ stateMutability: "view",
18638
+ inputs: [],
18639
+ outputs: [{ name: "", type: "address" }]
18640
+ },
18641
+ {
18642
+ type: "function",
18643
+ name: "balanceOf",
18644
+ stateMutability: "view",
18645
+ inputs: [{ name: "account", type: "address" }],
18646
+ outputs: [{ name: "", type: "uint256" }]
18647
+ },
18648
+ {
18649
+ type: "function",
18650
+ name: "convertToAssets",
18651
+ stateMutability: "view",
18652
+ inputs: [{ name: "shares", type: "uint256" }],
18653
+ outputs: [{ name: "", type: "uint256" }]
18654
+ },
18655
+ {
18656
+ type: "function",
18657
+ name: "maxRepay",
18658
+ stateMutability: "view",
18659
+ inputs: [{ name: "borrower", type: "address" }],
18660
+ outputs: [{ name: "", type: "uint256" }]
18661
+ }
18662
+ ];
18663
+ var SiloConvertToAssetsTypedAbi = [
18664
+ {
18665
+ type: "function",
18666
+ name: "convertToAssets",
18667
+ stateMutability: "view",
18668
+ inputs: [
18669
+ { name: "shares", type: "uint256" },
18670
+ { name: "assetType", type: "uint8" }
18671
+ ],
18672
+ outputs: [{ name: "", type: "uint256" }]
18673
+ }
18674
+ ];
18675
+
18676
+ // src/abis/silo-v2/SiloLens.ts
18677
+ var SiloLensAbi = [
18678
+ {
18679
+ type: "function",
18680
+ name: "getDepositAPR",
18681
+ stateMutability: "view",
18682
+ inputs: [{ name: "_silo", type: "address" }],
18683
+ outputs: [{ name: "depositAPR", type: "uint256" }]
18684
+ },
18685
+ {
18686
+ type: "function",
18687
+ name: "getBorrowAPR",
18688
+ stateMutability: "view",
18689
+ inputs: [{ name: "_silo", type: "address" }],
18690
+ outputs: [{ name: "borrowAPR", type: "uint256" }]
18691
+ },
18692
+ {
18693
+ type: "function",
18694
+ name: "getUtilization",
18695
+ stateMutability: "view",
18696
+ inputs: [{ name: "_silo", type: "address" }],
18697
+ outputs: [{ name: "utilization", type: "uint256" }]
18698
+ },
18699
+ {
18700
+ type: "function",
18701
+ name: "getRawLiquidity",
18702
+ stateMutability: "view",
18703
+ inputs: [{ name: "_silo", type: "address" }],
18704
+ outputs: [{ name: "liquidity", type: "uint256" }]
18705
+ }
18706
+ ];
18707
+
18708
+ // src/lending/public-data/silo-v2/publicCallBuild.ts
18709
+ var SILO_V2_CALLS_PER_SIDE = 2;
18710
+ var SILO_V2_CALLS_PER_PAIR = SILO_V2_CALLS_PER_SIDE * 2;
18711
+ function buildSiloV2LenderReserveCall(_chainId, lender) {
18712
+ const market = getSiloV2MarketEntry(_chainId, lender);
18713
+ if (!market) return [];
18714
+ const calls = [];
18715
+ for (const half of [market.silo0, market.silo1]) {
18716
+ calls.push(
18717
+ {
18718
+ address: half.silo,
18719
+ name: "totalAssets",
18720
+ params: [],
18721
+ abi: SiloAbi
18722
+ },
18723
+ {
18724
+ address: half.silo,
18725
+ name: "getDebtAssets",
18726
+ params: [],
18727
+ abi: SiloAbi
18728
+ }
18729
+ );
18730
+ }
18731
+ return calls;
18732
+ }
18733
+
18734
+ // src/lending/public-data/silo-v2/publicCallParse.ts
18735
+ var getSiloV2ReservesDataConverter = (lender, chainId, prices, additionalYields, tokenList = {}) => {
18736
+ const market = getSiloV2MarketEntry(chainId, lender);
18737
+ if (!market) return [() => void 0, 0];
18738
+ return [
18739
+ (data) => {
18740
+ if (!data || data.length !== SILO_V2_CALLS_PER_PAIR) return void 0;
18741
+ const out = {};
18742
+ const sides = [
18743
+ { self: market.silo0, other: market.silo1 },
18744
+ { self: market.silo1, other: market.silo0 }
18745
+ ];
18746
+ const toBigInt6 = (v) => {
18747
+ if (v === void 0 || v === null || v === "0x") return 0n;
18748
+ if (typeof v === "bigint") return v;
18749
+ try {
18750
+ return BigInt(v);
18751
+ } catch {
18752
+ return 0n;
18753
+ }
18754
+ };
18755
+ for (let s = 0; s < 2; s++) {
18756
+ const { self, other } = sides[s];
18757
+ const slot = s * SILO_V2_CALLS_PER_SIDE;
18758
+ const totalAssetsRaw = toBigInt6(data[slot]);
18759
+ const debtAssetsRaw = toBigInt6(data[slot + 1]);
18760
+ const decimals = self.decimals;
18761
+ const totalDeposits = Number(formatUnits(totalAssetsRaw, decimals));
18762
+ const totalDebt = Number(formatUnits(debtAssetsRaw, decimals));
18763
+ const totalLiquidity = totalDeposits - totalDebt;
18764
+ const utilization = totalDeposits > 0 ? totalDebt / totalDeposits : 0;
18765
+ const depositRatePct = 0;
18766
+ const variableBorrowRatePct = 0;
18767
+ const tokenAddrLc = self.token.toLowerCase();
18768
+ const assetMeta = tokenList[tokenAddrLc];
18769
+ const oracleKey = toOracleKey(assetMeta?.assetGroup ?? null) || toGenericPriceKey(tokenAddrLc, chainId);
18770
+ const price = prices[oracleKey] ?? 0;
18771
+ const collateralLt = Number(other.lt) / 1e18;
18772
+ const collateralMaxLtv = Number(other.maxLtv) / 1e18;
18773
+ const selfLt = Number(self.lt) / 1e18;
18774
+ const borrowingEnabled = collateralLt > 0;
18775
+ const collateralActive = selfLt > 0;
18776
+ const marketUid = createMarketUid(chainId, lender, self.silo);
18777
+ out[marketUid] = {
18778
+ marketUid,
18779
+ name: market.name ? `Silo V2 ${market.name} ${assetMeta?.symbol ?? ""}` : `Silo V2 ${assetMeta?.symbol ?? ""}`,
18780
+ poolId: self.silo.toLowerCase(),
18781
+ underlying: tokenAddrLc,
18782
+ asset: {
18783
+ ...assetMeta ?? {},
18784
+ chainId,
18785
+ decimals,
18786
+ address: tokenAddrLc,
18787
+ symbol: assetMeta?.symbol ?? self.symbol ?? "",
18788
+ name: assetMeta?.name ?? self.symbol ?? ""
18789
+ },
18790
+ // token amounts
18791
+ totalDeposits,
18792
+ totalDebt,
18793
+ totalDebtStable: 0,
18794
+ totalLiquidity,
18795
+ borrowLiquidity: totalLiquidity,
18796
+ // USD amounts
18797
+ totalDepositsUSD: totalDeposits * price,
18798
+ totalDebtUSD: totalDebt * price,
18799
+ totalDebtStableUSD: 0,
18800
+ totalLiquidityUSD: totalLiquidity * price,
18801
+ borrowLiquidityUSD: totalLiquidity * price,
18802
+ utilization,
18803
+ depositRate: depositRatePct,
18804
+ variableBorrowRate: variableBorrowRatePct,
18805
+ stableBorrowRate: 0,
18806
+ intrinsicYield: additionalYields?.intrinsicYields?.[assetMeta?.assetGroup] ?? 0,
18807
+ rewards: void 0,
18808
+ decimals,
18809
+ // Each Silo v2 per-pair lender represents exactly ONE pair, so
18810
+ // there is only one collateral counterparty (the OTHER silo) and
18811
+ // a single config entry. Key it as `'0'` to match the Morpho
18812
+ // convention (`config[0]` is the single mode with the market's
18813
+ // LLTV) — the counterparty silo address is still surfaced via
18814
+ // `params.counterpartySilo`.
18815
+ config: {
18816
+ 0: {
18817
+ category: 0,
18818
+ borrowCollateralFactor: collateralMaxLtv,
18819
+ collateralFactor: collateralLt,
18820
+ borrowFactor: 1,
18821
+ collateralDisabled: !borrowingEnabled,
18822
+ debtDisabled: !collateralActive
18823
+ }
18824
+ },
18825
+ collateralActive,
18826
+ borrowingEnabled,
18827
+ depositsEnabled: true,
18828
+ hasStable: false,
18829
+ isActive: true,
18830
+ isFrozen: false,
18831
+ params: {
18832
+ metadata: {
18833
+ silo: self.silo,
18834
+ counterpartySilo: other.silo,
18835
+ siloConfig: market.siloConfig,
18836
+ oracle: self.solvencyOracle,
18837
+ irm: self.interestRateModel,
18838
+ shareTokens: {
18839
+ collateral: self.collateralShareToken,
18840
+ protected: self.protectedShareToken,
18841
+ debt: self.debtShareToken
18842
+ },
18843
+ fees: {
18844
+ dao: self.daoFee,
18845
+ deployer: self.deployerFee,
18846
+ liquidation: self.liquidationFee,
18847
+ flashloan: self.flashloanFee
18848
+ }
18849
+ }
18850
+ }
18851
+ };
18852
+ }
18853
+ return { data: out, chainId };
18854
+ },
18855
+ SILO_V2_CALLS_PER_PAIR
18856
+ ];
18857
+ };
18858
+
18859
+ // src/lending/public-data/silo-v3/publicCallBuild.ts
18860
+ var SILO_V3_CALLS_PER_SIDE = 2;
18861
+ var SILO_V3_CALLS_PER_PAIR = SILO_V3_CALLS_PER_SIDE * 2;
18862
+ function buildSiloV3LenderReserveCall(_chainId, lender) {
18863
+ const market = getSiloV3MarketEntry(_chainId, lender);
18864
+ if (!market) return [];
18865
+ const calls = [];
18866
+ for (const half of [market.silo0, market.silo1]) {
18867
+ calls.push(
18868
+ {
18869
+ address: half.silo,
18870
+ name: "totalAssets",
18871
+ params: [],
18872
+ abi: SiloAbi
18873
+ },
18874
+ {
18875
+ address: half.silo,
18876
+ name: "getDebtAssets",
18877
+ params: [],
18878
+ abi: SiloAbi
18879
+ }
18880
+ );
18881
+ }
18882
+ return calls;
18883
+ }
18884
+
18885
+ // src/lending/public-data/silo-v3/publicCallParse.ts
18886
+ var getSiloV3ReservesDataConverter = (lender, chainId, prices, additionalYields, tokenList = {}) => {
18887
+ const market = getSiloV3MarketEntry(chainId, lender);
18888
+ if (!market) return [() => void 0, 0];
18889
+ return [
18890
+ (data) => {
18891
+ if (!data || data.length !== SILO_V3_CALLS_PER_PAIR) return void 0;
18892
+ const out = {};
18893
+ const sides = [
18894
+ { self: market.silo0, other: market.silo1 },
18895
+ { self: market.silo1, other: market.silo0 }
18896
+ ];
18897
+ const toBigInt6 = (v) => {
18898
+ if (v === void 0 || v === null || v === "0x") return 0n;
18899
+ if (typeof v === "bigint") return v;
18900
+ try {
18901
+ return BigInt(v);
18902
+ } catch {
18903
+ return 0n;
18904
+ }
18905
+ };
18906
+ for (let s = 0; s < 2; s++) {
18907
+ const { self, other } = sides[s];
18908
+ const slot = s * SILO_V3_CALLS_PER_SIDE;
18909
+ const totalAssetsRaw = toBigInt6(data[slot]);
18910
+ const debtAssetsRaw = toBigInt6(data[slot + 1]);
18911
+ const decimals = self.decimals;
18912
+ const totalDeposits = Number(formatUnits(totalAssetsRaw, decimals));
18913
+ const totalDebt = Number(formatUnits(debtAssetsRaw, decimals));
18914
+ const totalLiquidity = totalDeposits - totalDebt;
18915
+ const utilization = totalDeposits > 0 ? totalDebt / totalDeposits : 0;
18916
+ const depositRatePct = 0;
18917
+ const variableBorrowRatePct = 0;
18918
+ const tokenAddrLc = self.token.toLowerCase();
18919
+ const assetMeta = tokenList[tokenAddrLc];
18920
+ const oracleKey = toOracleKey(assetMeta?.assetGroup ?? null) || toGenericPriceKey(tokenAddrLc, chainId);
18921
+ const price = prices[oracleKey] ?? 0;
18922
+ const collateralLt = Number(other.lt) / 1e18;
18923
+ const collateralMaxLtv = Number(other.maxLtv) / 1e18;
18924
+ const selfLt = Number(self.lt) / 1e18;
18925
+ const borrowingEnabled = collateralLt > 0;
18926
+ const collateralActive = selfLt > 0;
18927
+ const marketUid = createMarketUid(chainId, lender, self.silo);
18928
+ out[marketUid] = {
18929
+ marketUid,
18930
+ name: market.name ? `Silo V3 ${market.name} ${assetMeta?.symbol ?? ""}` : `Silo V3 ${assetMeta?.symbol ?? ""}`,
18931
+ poolId: self.silo.toLowerCase(),
18932
+ underlying: tokenAddrLc,
18933
+ asset: {
18934
+ ...assetMeta ?? {},
18935
+ chainId,
18936
+ decimals,
18937
+ address: tokenAddrLc,
18938
+ symbol: assetMeta?.symbol ?? self.symbol ?? "",
18939
+ name: assetMeta?.name ?? self.symbol ?? ""
18940
+ },
18941
+ totalDeposits,
18942
+ totalDebt,
18943
+ totalDebtStable: 0,
18944
+ totalLiquidity,
18945
+ borrowLiquidity: totalLiquidity,
18946
+ totalDepositsUSD: totalDeposits * price,
18947
+ totalDebtUSD: totalDebt * price,
18948
+ totalDebtStableUSD: 0,
18949
+ totalLiquidityUSD: totalLiquidity * price,
18950
+ borrowLiquidityUSD: totalLiquidity * price,
18951
+ utilization,
18952
+ depositRate: depositRatePct,
18953
+ variableBorrowRate: variableBorrowRatePct,
18954
+ stableBorrowRate: 0,
18955
+ intrinsicYield: additionalYields?.intrinsicYields?.[assetMeta?.assetGroup] ?? 0,
18956
+ rewards: void 0,
18957
+ decimals,
18958
+ config: {
18959
+ 0: {
18960
+ category: 0,
18961
+ borrowCollateralFactor: collateralMaxLtv,
18962
+ collateralFactor: collateralLt,
18963
+ borrowFactor: 1,
18964
+ collateralDisabled: !borrowingEnabled,
18965
+ debtDisabled: !collateralActive
18966
+ }
18967
+ },
18968
+ collateralActive,
18969
+ borrowingEnabled,
18970
+ depositsEnabled: true,
18971
+ hasStable: false,
18972
+ isActive: true,
18973
+ isFrozen: false,
18974
+ params: {
18975
+ metadata: {
18976
+ silo: self.silo,
18977
+ counterpartySilo: other.silo,
18978
+ siloConfig: market.siloConfig,
18979
+ oracle: self.solvencyOracle,
18980
+ irm: self.interestRateModel,
18981
+ shareTokens: {
18982
+ collateral: self.collateralShareToken,
18983
+ protected: self.protectedShareToken,
18984
+ debt: self.debtShareToken
18985
+ },
18986
+ fees: {
18987
+ dao: self.daoFee,
18988
+ deployer: self.deployerFee,
18989
+ liquidation: self.liquidationFee,
18990
+ flashloan: self.flashloanFee
18991
+ }
18992
+ }
18993
+ }
18994
+ };
18995
+ }
18996
+ return { data: out, chainId };
18997
+ },
18998
+ SILO_V3_CALLS_PER_PAIR
18999
+ ];
19000
+ };
19001
+
19002
+ // src/lending/public-data/fetchLender.ts
18555
19003
  function getMorphoTypeMarketConverter(lender, chainId, prices, additionalYields, tokenList = {}, marketsOverride) {
18556
19004
  if (lender.startsWith("LISTA_DAO"))
18557
19005
  return getListaMarketDataConverter(
@@ -18586,6 +19034,8 @@ function buildLenderCall(chainId, lender) {
18586
19034
  return buildCompoundV2StyleLenderReserveCall(chainId, lender);
18587
19035
  if (isEulerType(lender)) return buildEulerV2LenderReserveCall(chainId, lender);
18588
19036
  if (isAaveV4Type(lender)) return buildAaveV4LenderReserveCall(chainId, lender);
19037
+ if (isSiloV2Type(lender)) return buildSiloV2LenderReserveCall(chainId, lender);
19038
+ if (isSiloV3Type(lender)) return buildSiloV3LenderReserveCall(chainId, lender);
18589
19039
  return [];
18590
19040
  }
18591
19041
  function getLenderDataConverter(lender, chainId, prices, additionalYields, tokenList = {}) {
@@ -18654,6 +19104,22 @@ function getLenderDataConverter(lender, chainId, prices, additionalYields, token
18654
19104
  additionalYields,
18655
19105
  tokenList
18656
19106
  );
19107
+ if (isSiloV2Type(lender))
19108
+ return getSiloV2ReservesDataConverter(
19109
+ lender,
19110
+ chainId,
19111
+ prices,
19112
+ additionalYields,
19113
+ tokenList
19114
+ );
19115
+ if (isSiloV3Type(lender))
19116
+ return getSiloV3ReservesDataConverter(
19117
+ lender,
19118
+ chainId,
19119
+ prices,
19120
+ additionalYields,
19121
+ tokenList
19122
+ );
18657
19123
  return [() => null, 0];
18658
19124
  }
18659
19125
  var getAbi = (lender) => {
@@ -18674,6 +19140,8 @@ var getAbi = (lender) => {
18674
19140
  if (isMorphoType(lender)) return MorphoLensAbi;
18675
19141
  if (isEulerType(lender)) return vaultLensAbi;
18676
19142
  if (isAaveV4Type(lender)) return [...AaveV4SpokeAbi, ...AaveV4OracleAbi, ...AaveV4HubAbi];
19143
+ if (isSiloV2Type(lender)) return [...SiloAbi, ...SiloLensAbi];
19144
+ if (isSiloV3Type(lender)) return [...SiloAbi, ...SiloLensAbi];
18677
19145
  if (isSumerType(lender)) return [...SumerLensAbi, ...SumerComptrollerAbi];
18678
19146
  if (lender === Lender.TAKARA) return [...TakaraMarketStateAbi];
18679
19147
  if (isCompoundV2Type(lender)) return VenusLensAbi;
@@ -18734,58 +19202,539 @@ var getLenderPublicData = async (chainId, lenders, prices, additionalYields, mul
18734
19202
  }
18735
19203
  return lenderData;
18736
19204
  };
18737
- async function getLenderDataFromApi(lender, chainId, prices, additionalYields, includeUnlisted = false) {
18738
- if (isMorphoType(lender))
18739
- return await fetchMorphoMarkets(chainId, includeUnlisted);
18740
- return {};
18741
- }
18742
- function convertLenderDataFromApi(lender, chainId, data, prices, additionalYields, list = {}) {
18743
- if (isMorphoType(lender))
18744
- return convertMarketsToMorphoResponse(data, chainId, additionalYields, list);
18745
- return {};
19205
+
19206
+ // src/lending/public-data/silo-v2/fetchPublic.ts
19207
+ var BASE_URL2 = "https://api-v3.silo.finance";
19208
+ var SILO_API_SUPPORTED_CHAIN_IDS = /* @__PURE__ */ new Set([
19209
+ "1",
19210
+ // Ethereum
19211
+ "42161",
19212
+ // Arbitrum
19213
+ "43114",
19214
+ // Avalanche
19215
+ "50",
19216
+ // XDC
19217
+ "1776"
19218
+ // Injective
19219
+ ]);
19220
+ var query2 = (chainId, limit) => `
19221
+ query GetSilos {
19222
+ silos(where: {chainId_in: [${chainId}]}, limit: ${limit}) {
19223
+ items {
19224
+ id
19225
+ chainId
19226
+ configAddress
19227
+ name
19228
+ protocol {
19229
+ protocolVersion
19230
+ }
19231
+ market1 {
19232
+ index
19233
+ inputTokenId
19234
+ inputToken { id symbol decimals }
19235
+ lt
19236
+ maxLtv
19237
+ liquidationTargetLtv
19238
+ daoFee
19239
+ deployerFee
19240
+ liquidationFee
19241
+ flashLoanFee
19242
+ borrowRate
19243
+ depositRate
19244
+ supply
19245
+ borrowed
19246
+ supplyUsd
19247
+ borrowedUsd
19248
+ liquidityUsd
19249
+ utilization
19250
+ solvencyOracleAddress
19251
+ maxLtvOracleAddress
19252
+ interestRateModelId
19253
+ sTokenId
19254
+ spTokenId
19255
+ dTokenId
19256
+ solvencyOracle {
19257
+ id
19258
+ quote
19259
+ quoteTimestamp
19260
+ baseTokenId
19261
+ quoteTokenId
19262
+ }
19263
+ maxLtvOracle {
19264
+ id
19265
+ quote
19266
+ quoteTimestamp
19267
+ }
19268
+ }
19269
+ market2 {
19270
+ index
19271
+ inputTokenId
19272
+ inputToken { id symbol decimals }
19273
+ lt
19274
+ maxLtv
19275
+ liquidationTargetLtv
19276
+ daoFee
19277
+ deployerFee
19278
+ liquidationFee
19279
+ flashLoanFee
19280
+ borrowRate
19281
+ depositRate
19282
+ supply
19283
+ borrowed
19284
+ supplyUsd
19285
+ borrowedUsd
19286
+ liquidityUsd
19287
+ utilization
19288
+ solvencyOracleAddress
19289
+ maxLtvOracleAddress
19290
+ interestRateModelId
19291
+ sTokenId
19292
+ spTokenId
19293
+ dTokenId
19294
+ solvencyOracle {
19295
+ id
19296
+ quote
19297
+ quoteTimestamp
19298
+ baseTokenId
19299
+ quoteTokenId
19300
+ }
19301
+ maxLtvOracle {
19302
+ id
19303
+ quote
19304
+ quoteTimestamp
19305
+ }
19306
+ }
19307
+ }
19308
+ }
18746
19309
  }
18747
- var getLenderPublicDataViaApi = async (chainId, lenders, prices, additionalYields, tokenList = async () => {
18748
- return {};
18749
- }, includeUnlisted = false) => {
18750
- let promises = [];
18751
- for (const lender of lenders) {
18752
- promises.push(
18753
- getLenderDataFromApi(
18754
- lender,
18755
- chainId,
18756
- prices,
18757
- additionalYields,
18758
- includeUnlisted
18759
- )
19310
+ `;
19311
+ async function fetchSiloMarkets(chainId, options) {
19312
+ if (!SILO_API_SUPPORTED_CHAIN_IDS.has(chainId)) return [];
19313
+ const limit = options?.limit ?? 500;
19314
+ const response = await fetch(BASE_URL2, {
19315
+ method: "POST",
19316
+ headers: { "Content-Type": "application/json" },
19317
+ body: JSON.stringify({ query: query2(chainId, limit) })
19318
+ });
19319
+ if (!response.ok) {
19320
+ throw new Error(
19321
+ `[silo-api] Network error: ${response.status} - ${response.statusText}`
18760
19322
  );
18761
19323
  }
18762
- const settled = await Promise.allSettled([tokenList(), ...promises]);
18763
- const listResult = settled[0];
18764
- const list = listResult.status === "fulfilled" ? listResult.value : {};
18765
- if (listResult.status === "rejected") {
18766
- console.warn(
18767
- `[lending] tokenList fetch failed on chain ${chainId}:`,
18768
- listResult.reason
19324
+ const payload = await response.json();
19325
+ if (payload?.errors?.length) {
19326
+ throw new Error(
19327
+ `[silo-api] GraphQL error: ${payload.errors.map((e) => e?.message).join("; ")}`
18769
19328
  );
18770
19329
  }
18771
- const lenderData = {};
18772
- for (let i = 0; i < lenders.length; i++) {
19330
+ const items = payload?.data?.silos?.items ?? [];
19331
+ if (!options?.protocolVersion) return items;
19332
+ return items.filter(
19333
+ (s) => s.protocol?.protocolVersion === options.protocolVersion
19334
+ );
19335
+ }
19336
+
19337
+ // src/lending/public-data/silo-v2/convertPublic.ts
19338
+ function convertSiloMarketsToPublicResponse(apiItems, chainId, prices, additionalYields = {
19339
+ intrinsicYields: {},
19340
+ lenderRewards: {},
19341
+ loaded: true
19342
+ }, tokenList = {}) {
19343
+ const out = {};
19344
+ for (const item of apiItems) {
19345
+ if (item.protocol && item.protocol.protocolVersion !== "v2") continue;
19346
+ let lenderKey;
18773
19347
  try {
18774
- const result = settled[i + 1];
18775
- if (result.status === "rejected") {
18776
- console.warn(
18777
- `[lending] API fetch failed for ${lenders[i]} on chain ${chainId}:`,
18778
- result.reason?.message ?? result.reason
18779
- );
18780
- continue;
18781
- }
18782
- const lender = lenders[i];
18783
- if (isMultiMarket(lender)) {
18784
- const dataObtained = result.value;
18785
- const converted = convertLenderDataFromApi(
18786
- lender,
18787
- chainId,
18788
- dataObtained,
19348
+ lenderKey = siloV2LenderKey(item.configAddress);
19349
+ } catch {
19350
+ continue;
19351
+ }
19352
+ const registryEntry = getSiloV2MarketEntry(chainId, lenderKey);
19353
+ if (!registryEntry) continue;
19354
+ const [apiSide0, apiSide1] = item.market1.index === 0 ? [item.market1, item.market2] : [item.market2, item.market1];
19355
+ const sides = [
19356
+ { api: apiSide0, self: registryEntry.silo0, other: registryEntry.silo1 },
19357
+ { api: apiSide1, self: registryEntry.silo1, other: registryEntry.silo0 }
19358
+ ];
19359
+ const data = {};
19360
+ for (const { api, self, other } of sides) {
19361
+ const decimals = api.inputToken?.decimals ?? self.decimals;
19362
+ const tokenAddrLc = (api.inputTokenId ?? self.token).toLowerCase();
19363
+ const totalDeposits = safeNumber(api.supply);
19364
+ const totalDebt = safeNumber(api.borrowed);
19365
+ const totalLiquidity = totalDeposits - totalDebt;
19366
+ const utilization = totalDeposits > 0 ? totalDebt / totalDeposits : safeNumber(api.utilization);
19367
+ const variableBorrowRatePct = safeNumber(api.borrowRate) * 100;
19368
+ const depositRatePct = safeNumber(api.depositRate) * 100;
19369
+ const assetMeta = tokenList[tokenAddrLc];
19370
+ const oracleKey = toOracleKey(assetMeta?.assetGroup ?? null) || toGenericPriceKey(tokenAddrLc, chainId);
19371
+ const fallbackPrice = prices[oracleKey] ?? 0;
19372
+ const totalDepositsUSD = api.supplyUsd != null && api.supplyUsd > 0 ? api.supplyUsd : totalDeposits * fallbackPrice;
19373
+ const totalDebtUSD = api.borrowedUsd != null && api.borrowedUsd > 0 ? api.borrowedUsd : totalDebt * fallbackPrice;
19374
+ const totalLiquidityUSD = Math.max(totalDepositsUSD - totalDebtUSD, 0);
19375
+ const collateralLt = safeLtvOrFee(api, "lt", other.lt);
19376
+ const collateralMaxLtv = safeLtvOrFee(api, "maxLtv", other.maxLtv);
19377
+ const selfLt = bigintToLtv(api.lt ?? self.lt);
19378
+ const collateralLtFromApi = sides[0].api === api ? bigintToLtv(apiSide1.lt) : bigintToLtv(apiSide0.lt);
19379
+ const collateralMaxLtvFromApi = sides[0].api === api ? bigintToLtv(apiSide1.maxLtv) : bigintToLtv(apiSide0.maxLtv);
19380
+ const borrowingEnabled = (collateralLtFromApi || collateralLt) > 0;
19381
+ const collateralActive = selfLt > 0;
19382
+ const siloAddrLc = self.silo.toLowerCase();
19383
+ const marketUid = createMarketUid(chainId, lenderKey, siloAddrLc);
19384
+ data[marketUid] = {
19385
+ marketUid,
19386
+ name: item.name ? `Silo V2 ${item.name} ${assetMeta?.symbol ?? api.inputToken?.symbol ?? ""}` : `Silo V2 ${assetMeta?.symbol ?? api.inputToken?.symbol ?? ""}`,
19387
+ poolId: siloAddrLc,
19388
+ underlying: tokenAddrLc,
19389
+ asset: {
19390
+ ...assetMeta ?? {},
19391
+ chainId,
19392
+ decimals,
19393
+ address: tokenAddrLc,
19394
+ symbol: assetMeta?.symbol ?? api.inputToken?.symbol ?? self.symbol ?? "",
19395
+ name: assetMeta?.name ?? api.inputToken?.symbol ?? self.symbol ?? ""
19396
+ },
19397
+ // token amounts
19398
+ totalDeposits,
19399
+ totalDebt,
19400
+ totalDebtStable: 0,
19401
+ totalLiquidity,
19402
+ borrowLiquidity: totalLiquidity,
19403
+ // USD amounts
19404
+ totalDepositsUSD,
19405
+ totalDebtUSD,
19406
+ totalDebtStableUSD: 0,
19407
+ totalLiquidityUSD,
19408
+ borrowLiquidityUSD: totalLiquidityUSD,
19409
+ utilization,
19410
+ depositRate: depositRatePct,
19411
+ variableBorrowRate: variableBorrowRatePct,
19412
+ stableBorrowRate: 0,
19413
+ intrinsicYield: additionalYields?.intrinsicYields?.[assetMeta?.assetGroup] ?? 0,
19414
+ rewards: void 0,
19415
+ decimals,
19416
+ config: {
19417
+ 0: {
19418
+ category: 0,
19419
+ borrowCollateralFactor: collateralMaxLtvFromApi || collateralMaxLtv,
19420
+ collateralFactor: collateralLtFromApi || collateralLt,
19421
+ borrowFactor: 1,
19422
+ collateralDisabled: !borrowingEnabled,
19423
+ debtDisabled: !collateralActive
19424
+ }
19425
+ },
19426
+ collateralActive,
19427
+ borrowingEnabled,
19428
+ depositsEnabled: true,
19429
+ hasStable: false,
19430
+ isActive: true,
19431
+ isFrozen: false,
19432
+ params: {
19433
+ metadata: {
19434
+ silo: self.silo.toLowerCase(),
19435
+ counterpartySilo: other.silo.toLowerCase(),
19436
+ siloConfig: registryEntry.siloConfig.toLowerCase(),
19437
+ oracle: (api.solvencyOracleAddress ?? self.solvencyOracle).toLowerCase(),
19438
+ irm: (api.interestRateModelId ?? self.interestRateModel).toLowerCase(),
19439
+ shareTokens: {
19440
+ collateral: self.collateralShareToken,
19441
+ protected: self.protectedShareToken,
19442
+ debt: self.debtShareToken
19443
+ },
19444
+ fees: {
19445
+ dao: api.daoFee ?? self.daoFee,
19446
+ deployer: api.deployerFee ?? self.deployerFee,
19447
+ liquidation: api.liquidationFee ?? self.liquidationFee,
19448
+ flashloan: api.flashLoanFee ?? self.flashloanFee
19449
+ }
19450
+ }
19451
+ }
19452
+ };
19453
+ }
19454
+ out[lenderKey] = { data, chainId };
19455
+ }
19456
+ return out;
19457
+ }
19458
+ function safeNumber(v) {
19459
+ if (v == null) return 0;
19460
+ const n = typeof v === "number" ? v : Number(v);
19461
+ return Number.isFinite(n) ? n : 0;
19462
+ }
19463
+ function bigintToLtv(v) {
19464
+ if (!v) return 0;
19465
+ try {
19466
+ return Number(BigInt(v)) / 1e18;
19467
+ } catch {
19468
+ const n = Number(v);
19469
+ return Number.isFinite(n) ? n / 1e18 : 0;
19470
+ }
19471
+ }
19472
+ function safeLtvOrFee(api, field5, fallback) {
19473
+ return bigintToLtv(api[field5] ?? fallback);
19474
+ }
19475
+
19476
+ // src/lending/public-data/silo-v3/convertPublic.ts
19477
+ function convertSiloV3MarketsToPublicResponse(apiItems, chainId, prices, additionalYields = {
19478
+ intrinsicYields: {},
19479
+ lenderRewards: {},
19480
+ loaded: true
19481
+ }, tokenList = {}) {
19482
+ const out = {};
19483
+ for (const item of apiItems) {
19484
+ if (item.protocol && item.protocol.protocolVersion !== "v3") continue;
19485
+ let lenderKey;
19486
+ try {
19487
+ lenderKey = siloV3LenderKey(item.configAddress);
19488
+ } catch {
19489
+ continue;
19490
+ }
19491
+ const registryEntry = getSiloV3MarketEntry(chainId, lenderKey);
19492
+ if (!registryEntry) continue;
19493
+ const [apiSide0, apiSide1] = item.market1.index === 0 ? [item.market1, item.market2] : [item.market2, item.market1];
19494
+ const sides = [
19495
+ { api: apiSide0, self: registryEntry.silo0, other: registryEntry.silo1 },
19496
+ { api: apiSide1, self: registryEntry.silo1, other: registryEntry.silo0 }
19497
+ ];
19498
+ const data = {};
19499
+ for (const { api, self, other } of sides) {
19500
+ const decimals = api.inputToken?.decimals ?? self.decimals;
19501
+ const tokenAddrLc = (api.inputTokenId ?? self.token).toLowerCase();
19502
+ const totalDeposits = safeNumber2(api.supply);
19503
+ const totalDebt = safeNumber2(api.borrowed);
19504
+ const totalLiquidity = totalDeposits - totalDebt;
19505
+ const utilization = totalDeposits > 0 ? totalDebt / totalDeposits : safeNumber2(api.utilization);
19506
+ const variableBorrowRatePct = safeNumber2(api.borrowRate) * 100;
19507
+ const depositRatePct = safeNumber2(api.depositRate) * 100;
19508
+ const assetMeta = tokenList[tokenAddrLc];
19509
+ const oracleKey = toOracleKey(assetMeta?.assetGroup ?? null) || toGenericPriceKey(tokenAddrLc, chainId);
19510
+ const fallbackPrice = prices[oracleKey] ?? 0;
19511
+ const totalDepositsUSD = api.supplyUsd != null && api.supplyUsd > 0 ? api.supplyUsd : totalDeposits * fallbackPrice;
19512
+ const totalDebtUSD = api.borrowedUsd != null && api.borrowedUsd > 0 ? api.borrowedUsd : totalDebt * fallbackPrice;
19513
+ const totalLiquidityUSD = Math.max(totalDepositsUSD - totalDebtUSD, 0);
19514
+ const collateralLt = safeLtvOrFee2(api, "lt", other.lt);
19515
+ const collateralMaxLtv = safeLtvOrFee2(api, "maxLtv", other.maxLtv);
19516
+ const selfLt = bigintToLtv2(api.lt ?? self.lt);
19517
+ const collateralLtFromApi = sides[0].api === api ? bigintToLtv2(apiSide1.lt) : bigintToLtv2(apiSide0.lt);
19518
+ const collateralMaxLtvFromApi = sides[0].api === api ? bigintToLtv2(apiSide1.maxLtv) : bigintToLtv2(apiSide0.maxLtv);
19519
+ const borrowingEnabled = (collateralLtFromApi || collateralLt) > 0;
19520
+ const collateralActive = selfLt > 0;
19521
+ const siloAddrLc = self.silo.toLowerCase();
19522
+ const marketUid = createMarketUid(chainId, lenderKey, siloAddrLc);
19523
+ data[marketUid] = {
19524
+ marketUid,
19525
+ name: item.name ? `Silo V3 ${item.name} ${assetMeta?.symbol ?? api.inputToken?.symbol ?? ""}` : `Silo V3 ${assetMeta?.symbol ?? api.inputToken?.symbol ?? ""}`,
19526
+ poolId: siloAddrLc,
19527
+ underlying: tokenAddrLc,
19528
+ asset: {
19529
+ ...assetMeta ?? {},
19530
+ chainId,
19531
+ decimals,
19532
+ address: tokenAddrLc,
19533
+ symbol: assetMeta?.symbol ?? api.inputToken?.symbol ?? self.symbol ?? "",
19534
+ name: assetMeta?.name ?? api.inputToken?.symbol ?? self.symbol ?? ""
19535
+ },
19536
+ totalDeposits,
19537
+ totalDebt,
19538
+ totalDebtStable: 0,
19539
+ totalLiquidity,
19540
+ borrowLiquidity: totalLiquidity,
19541
+ totalDepositsUSD,
19542
+ totalDebtUSD,
19543
+ totalDebtStableUSD: 0,
19544
+ totalLiquidityUSD,
19545
+ borrowLiquidityUSD: totalLiquidityUSD,
19546
+ utilization,
19547
+ depositRate: depositRatePct,
19548
+ variableBorrowRate: variableBorrowRatePct,
19549
+ stableBorrowRate: 0,
19550
+ intrinsicYield: additionalYields?.intrinsicYields?.[assetMeta?.assetGroup] ?? 0,
19551
+ rewards: void 0,
19552
+ decimals,
19553
+ config: {
19554
+ 0: {
19555
+ category: 0,
19556
+ borrowCollateralFactor: collateralMaxLtvFromApi || collateralMaxLtv,
19557
+ collateralFactor: collateralLtFromApi || collateralLt,
19558
+ borrowFactor: 1,
19559
+ collateralDisabled: !borrowingEnabled,
19560
+ debtDisabled: !collateralActive
19561
+ }
19562
+ },
19563
+ collateralActive,
19564
+ borrowingEnabled,
19565
+ depositsEnabled: true,
19566
+ hasStable: false,
19567
+ isActive: true,
19568
+ isFrozen: false,
19569
+ params: {
19570
+ metadata: {
19571
+ silo: self.silo.toLowerCase(),
19572
+ counterpartySilo: other.silo.toLowerCase(),
19573
+ siloConfig: registryEntry.siloConfig.toLowerCase(),
19574
+ oracle: (api.solvencyOracleAddress ?? self.solvencyOracle).toLowerCase(),
19575
+ irm: (api.interestRateModelId ?? self.interestRateModel).toLowerCase(),
19576
+ shareTokens: {
19577
+ collateral: self.collateralShareToken,
19578
+ protected: self.protectedShareToken,
19579
+ debt: self.debtShareToken
19580
+ },
19581
+ fees: {
19582
+ dao: api.daoFee ?? self.daoFee,
19583
+ deployer: api.deployerFee ?? self.deployerFee,
19584
+ liquidation: api.liquidationFee ?? self.liquidationFee,
19585
+ flashloan: api.flashLoanFee ?? self.flashloanFee
19586
+ }
19587
+ }
19588
+ }
19589
+ };
19590
+ }
19591
+ out[lenderKey] = { data, chainId };
19592
+ }
19593
+ return out;
19594
+ }
19595
+ function safeNumber2(v) {
19596
+ if (v == null) return 0;
19597
+ const n = typeof v === "number" ? v : Number(v);
19598
+ return Number.isFinite(n) ? n : 0;
19599
+ }
19600
+ function bigintToLtv2(v) {
19601
+ if (!v) return 0;
19602
+ try {
19603
+ return Number(BigInt(v)) / 1e18;
19604
+ } catch {
19605
+ const n = Number(v);
19606
+ return Number.isFinite(n) ? n / 1e18 : 0;
19607
+ }
19608
+ }
19609
+ function safeLtvOrFee2(api, field5, fallback) {
19610
+ return bigintToLtv2(api[field5] ?? fallback);
19611
+ }
19612
+
19613
+ // src/lending/public-data/fetchLenderExt.ts
19614
+ async function getLenderDataFromApi(lender, chainId, prices, additionalYields, includeUnlisted = false) {
19615
+ if (isMorphoType(lender))
19616
+ return await fetchMorphoMarkets(chainId, includeUnlisted);
19617
+ return {};
19618
+ }
19619
+ function convertLenderDataFromApi(lender, chainId, data, prices, additionalYields, list = {}) {
19620
+ if (isMorphoType(lender))
19621
+ return convertMarketsToMorphoResponse(data, chainId, additionalYields, list);
19622
+ return {};
19623
+ }
19624
+ var getLenderPublicDataViaApi = async (chainId, lenders, prices, additionalYields, tokenList = async () => {
19625
+ return {};
19626
+ }, includeUnlisted = false) => {
19627
+ const siloV2Lenders = lenders.filter((l) => isSiloV2Type(l));
19628
+ const siloV3Lenders = lenders.filter((l) => isSiloV3Type(l));
19629
+ const otherLenders = lenders.filter(
19630
+ (l) => !isSiloV2Type(l) && !isSiloV3Type(l)
19631
+ );
19632
+ const siloV2Promise = siloV2Lenders.length > 0 ? fetchSiloMarkets(chainId, { protocolVersion: "v2" }).then((items) => ({
19633
+ __silo_items__: items
19634
+ })) : Promise.resolve({});
19635
+ const siloV3Promise = siloV3Lenders.length > 0 ? fetchSiloMarkets(chainId, { protocolVersion: "v3" }).then((items) => ({
19636
+ __silo_items__: items
19637
+ })) : Promise.resolve({});
19638
+ let promises = [];
19639
+ for (const lender of otherLenders) {
19640
+ promises.push(
19641
+ getLenderDataFromApi(
19642
+ lender,
19643
+ chainId,
19644
+ prices,
19645
+ additionalYields,
19646
+ includeUnlisted
19647
+ )
19648
+ );
19649
+ }
19650
+ const settled = await Promise.allSettled([
19651
+ tokenList(),
19652
+ siloV2Promise,
19653
+ siloV3Promise,
19654
+ ...promises
19655
+ ]);
19656
+ const listResult = settled[0];
19657
+ const list = listResult.status === "fulfilled" ? listResult.value : {};
19658
+ if (listResult.status === "rejected") {
19659
+ console.warn(
19660
+ `[lending] tokenList fetch failed on chain ${chainId}:`,
19661
+ listResult.reason
19662
+ );
19663
+ }
19664
+ const lenderData = {};
19665
+ const siloV2Result = settled[1];
19666
+ if (siloV2Lenders.length > 0) {
19667
+ if (siloV2Result.status === "fulfilled") {
19668
+ const items = siloV2Result.value?.__silo_items__ ?? [];
19669
+ try {
19670
+ const converted = convertSiloMarketsToPublicResponse(
19671
+ items,
19672
+ chainId,
19673
+ prices,
19674
+ additionalYields,
19675
+ list
19676
+ );
19677
+ for (const lk of siloV2Lenders) {
19678
+ if (converted[lk]) lenderData[lk] = converted[lk];
19679
+ }
19680
+ } catch (e) {
19681
+ console.warn(
19682
+ `[lending] Silo v2 API convert failed on chain ${chainId}:`,
19683
+ e?.message ?? e
19684
+ );
19685
+ }
19686
+ } else {
19687
+ console.warn(
19688
+ `[lending] Silo v2 API fetch failed on chain ${chainId}:`,
19689
+ siloV2Result.reason?.message ?? siloV2Result.reason
19690
+ );
19691
+ }
19692
+ }
19693
+ const siloV3Result = settled[2];
19694
+ if (siloV3Lenders.length > 0) {
19695
+ if (siloV3Result.status === "fulfilled") {
19696
+ const items = siloV3Result.value?.__silo_items__ ?? [];
19697
+ try {
19698
+ const converted = convertSiloV3MarketsToPublicResponse(
19699
+ items,
19700
+ chainId,
19701
+ prices,
19702
+ additionalYields,
19703
+ list
19704
+ );
19705
+ for (const lk of siloV3Lenders) {
19706
+ if (converted[lk]) lenderData[lk] = converted[lk];
19707
+ }
19708
+ } catch (e) {
19709
+ console.warn(
19710
+ `[lending] Silo v3 API convert failed on chain ${chainId}:`,
19711
+ e?.message ?? e
19712
+ );
19713
+ }
19714
+ } else {
19715
+ console.warn(
19716
+ `[lending] Silo v3 API fetch failed on chain ${chainId}:`,
19717
+ siloV3Result.reason?.message ?? siloV3Result.reason
19718
+ );
19719
+ }
19720
+ }
19721
+ for (let i = 0; i < otherLenders.length; i++) {
19722
+ try {
19723
+ const result = settled[i + 3];
19724
+ if (result.status === "rejected") {
19725
+ console.warn(
19726
+ `[lending] API fetch failed for ${otherLenders[i]} on chain ${chainId}:`,
19727
+ result.reason?.message ?? result.reason
19728
+ );
19729
+ continue;
19730
+ }
19731
+ const lender = otherLenders[i];
19732
+ if (isMultiMarket(lender)) {
19733
+ const dataObtained = result.value;
19734
+ const converted = convertLenderDataFromApi(
19735
+ lender,
19736
+ chainId,
19737
+ dataObtained,
18789
19738
  prices,
18790
19739
  additionalYields,
18791
19740
  list
@@ -18807,7 +19756,7 @@ var getLenderPublicDataViaApi = async (chainId, lenders, prices, additionalYield
18807
19756
  }
18808
19757
  return lenderData;
18809
19758
  };
18810
- function lenderCanUseApi(lender, chainId) {
19759
+ function lenderApiOnly(lender, chainId) {
18811
19760
  if (lender === Lender.MORPHO_BLUE) {
18812
19761
  if (chainId === Chain.SONEIUM) return false;
18813
19762
  if (chainId === Chain.HEMI_NETWORK) return false;
@@ -18818,9 +19767,17 @@ function lenderCanUseApi(lender, chainId) {
18818
19767
  }
18819
19768
  return false;
18820
19769
  }
19770
+ function lenderApiWithOnChainFallback(lender, chainId) {
19771
+ if (isSiloV2Type(lender) || isSiloV3Type(lender)) {
19772
+ return SILO_API_SUPPORTED_CHAIN_IDS.has(chainId);
19773
+ }
19774
+ return false;
19775
+ }
18821
19776
  var getLenderPublicDataAll = async (chainId, lenders, prices, additionalYields, multicallRetry, tokenList, includeUnlistedMorphoMarkets = false) => {
18822
- const lendersApi = lenders.filter((l) => lenderCanUseApi(l, chainId));
18823
- const lendersOnChain = lenders.filter((l) => !lenderCanUseApi(l, chainId));
19777
+ const lendersApi = lenders.filter(
19778
+ (l) => lenderApiOnly(l, chainId) || lenderApiWithOnChainFallback(l, chainId)
19779
+ );
19780
+ const lendersOnChain = lenders.filter((l) => !lenderApiOnly(l, chainId));
18824
19781
  const onChain = getLenderPublicData(
18825
19782
  chainId,
18826
19783
  lendersOnChain,
@@ -19133,7 +20090,7 @@ function fetchEulerSubAccountIndexes(chainId, owner) {
19133
20090
  async function fetchSubAccountsFromSubgraph(chainId, owner) {
19134
20091
  const url = EULER_SUBGRAPH_URLS[chainId];
19135
20092
  if (!url) return [0];
19136
- const query2 = `{
20093
+ const query3 = `{
19137
20094
  accounts(first: 100, where: { owner: "${owner.toLowerCase()}" }) {
19138
20095
  id
19139
20096
  subAccount
@@ -19142,7 +20099,7 @@ async function fetchSubAccountsFromSubgraph(chainId, owner) {
19142
20099
  const response = await fetch(url, {
19143
20100
  method: "POST",
19144
20101
  headers: { "Content-Type": "application/json" },
19145
- body: JSON.stringify({ query: query2 })
20102
+ body: JSON.stringify({ query: query3 })
19146
20103
  });
19147
20104
  if (!response.ok) return [0];
19148
20105
  const data = await response.json();
@@ -19245,6 +20202,55 @@ var buildAaveV4UserCall = (chainId, lender, account) => {
19245
20202
  return calls;
19246
20203
  };
19247
20204
 
20205
+ // src/lending/user-data/silo-v2/userCallBuild.ts
20206
+ var ASSET_TYPE_PROTECTED = 0;
20207
+ var ASSET_TYPE_COLLATERAL = 1;
20208
+ var SILO_V2_USER_CALLS_PER_SIDE = 5;
20209
+ var SILO_V2_USER_CALLS_PER_PAIR = SILO_V2_USER_CALLS_PER_SIDE * 2;
20210
+ var buildSiloV2UserCall = (chainId, lender, account) => {
20211
+ const market = getSiloV2MarketEntry(chainId, lender);
20212
+ if (!market) return [];
20213
+ const calls = [];
20214
+ for (const half of [market.silo0, market.silo1]) {
20215
+ const oneUnit = BigInt(10) ** BigInt(half.decimals);
20216
+ calls.push(
20217
+ // [0] collateral shares (silo IS the collateral share token)
20218
+ {
20219
+ address: half.silo,
20220
+ name: "balanceOf",
20221
+ params: [account]
20222
+ },
20223
+ // [1] protected shares (separate ERC-20)
20224
+ {
20225
+ address: half.protectedShareToken,
20226
+ name: "balanceOf",
20227
+ params: [account]
20228
+ },
20229
+ // [2] collateral rate: assets per unit of collateral shares
20230
+ {
20231
+ address: half.silo,
20232
+ name: "convertToAssets",
20233
+ params: [oneUnit, ASSET_TYPE_COLLATERAL],
20234
+ abi: SiloConvertToAssetsTypedAbi
20235
+ },
20236
+ // [3] protected rate: assets per unit of protected shares
20237
+ {
20238
+ address: half.silo,
20239
+ name: "convertToAssets",
20240
+ params: [oneUnit, ASSET_TYPE_PROTECTED],
20241
+ abi: SiloConvertToAssetsTypedAbi
20242
+ },
20243
+ // [4] debt position (already in assets, includes accrued interest)
20244
+ {
20245
+ address: half.silo,
20246
+ name: "maxRepay",
20247
+ params: [account]
20248
+ }
20249
+ );
20250
+ }
20251
+ return calls;
20252
+ };
20253
+
19248
20254
  // src/lending/user-data/fetch-balances/prepare.ts
19249
20255
  async function buildUserCall(chainId, lender, account, params) {
19250
20256
  if (isAaveV4Type(lender)) return buildAaveV4UserCall(chainId, lender, account);
@@ -19257,6 +20263,8 @@ async function buildUserCall(chainId, lender, account, params) {
19257
20263
  return buildCompoundV3UserCall(chainId, lender, account);
19258
20264
  if (isEulerType(lender))
19259
20265
  return buildEulerUserCall(chainId, lender, account, params?.subAccountIndexes);
20266
+ if (isSiloV2Type(lender))
20267
+ return buildSiloV2UserCall(chainId, lender, account);
19260
20268
  return buildCompoundV2UserCall(chainId, lender, account);
19261
20269
  }
19262
20270
  function organizeUserQueries(queries) {
@@ -20759,6 +21767,104 @@ function createAaveV4Entry(base, data, key, meta, spokeAddr) {
20759
21767
  };
20760
21768
  }
20761
21769
 
21770
+ // src/lending/user-data/silo-v2/userCallParse.ts
21771
+ var getSiloV2UserDataConverter = (lender, chainId, account, metaMap) => {
21772
+ const market = getSiloV2MarketEntry(chainId, lender);
21773
+ if (!market) return [() => void 0, 0];
21774
+ return [
21775
+ (data) => {
21776
+ if (!data || data.length !== SILO_V2_USER_CALLS_PER_PAIR)
21777
+ return void 0;
21778
+ const sides = [
21779
+ { self: market.silo0, other: market.silo1 },
21780
+ { self: market.silo1, other: market.silo0 }
21781
+ ];
21782
+ const lendingPositions = {};
21783
+ let addedDeposits = 0;
21784
+ let addedDebt = 0;
21785
+ let hasAnyPosition = false;
21786
+ for (let s = 0; s < 2; s++) {
21787
+ const { self } = sides[s];
21788
+ const slot = s * SILO_V2_USER_CALLS_PER_SIDE;
21789
+ const collateralShares = toBigInt5(data[slot]);
21790
+ const protectedShares = toBigInt5(data[slot + 1]);
21791
+ const collateralRate = toBigInt5(data[slot + 2]);
21792
+ const protectedRate = toBigInt5(data[slot + 3]);
21793
+ const repayRaw = toBigInt5(data[slot + 4]);
21794
+ const decimals = self.decimals;
21795
+ const oneUnit = BigInt(10) ** BigInt(decimals);
21796
+ const collateralAssets = oneUnit > 0n ? collateralShares * collateralRate / oneUnit : 0n;
21797
+ const protectedAssets = oneUnit > 0n ? protectedShares * protectedRate / oneUnit : 0n;
21798
+ const depositAssetsRaw = collateralAssets + protectedAssets;
21799
+ if (depositAssetsRaw === 0n && repayRaw === 0n) continue;
21800
+ hasAnyPosition = true;
21801
+ const marketUid = createMarketUid(chainId, lender, self.silo);
21802
+ const meta = metaMap?.[marketUid];
21803
+ const metaDecimals = meta?.asset?.decimals ?? decimals;
21804
+ const depositsStr = parseRawAmount(
21805
+ depositAssetsRaw.toString(),
21806
+ metaDecimals
21807
+ );
21808
+ const debtStr = parseRawAmount(repayRaw.toString(), metaDecimals);
21809
+ const depositsNum = Number(depositsStr);
21810
+ const debtNum = Number(debtStr);
21811
+ const displayPrice = meta ? getDisplayPrice(meta) : 0;
21812
+ const oraclePrice = meta ? getOraclePrice(meta) : 0;
21813
+ const priceHist = meta?.price?.priceUsd24h ?? displayPrice;
21814
+ const depositsUSD = depositsNum * displayPrice;
21815
+ const debtUSD = debtNum * displayPrice;
21816
+ const depositsUSDOracle = depositsNum * oraclePrice;
21817
+ const debtUSDOracle = debtNum * oraclePrice;
21818
+ addedDeposits += depositsNum * priceHist;
21819
+ addedDebt += debtNum * priceHist;
21820
+ const selfLt = Number(self.lt) / 1e18;
21821
+ const collateralEnabled = selfLt > 0 && depositAssetsRaw > 0n;
21822
+ lendingPositions[marketUid] = {
21823
+ marketUid,
21824
+ underlying: self.token.toLowerCase(),
21825
+ deposits: depositsStr,
21826
+ debt: debtStr,
21827
+ debtStable: "0",
21828
+ depositsUSD,
21829
+ debtUSD,
21830
+ debtStableUSD: 0,
21831
+ depositsUSDOracle,
21832
+ debtUSDOracle,
21833
+ debtStableUSDOracle: 0,
21834
+ stableBorrowRate: "0",
21835
+ collateralEnabled,
21836
+ claimableRewards: 0
21837
+ };
21838
+ }
21839
+ if (!hasAnyPosition) return void 0;
21840
+ const payload = {
21841
+ chainId,
21842
+ account,
21843
+ lendingPositions,
21844
+ rewards: [],
21845
+ userEMode: 0
21846
+ };
21847
+ return createBaseTypeUserState(
21848
+ payload,
21849
+ metaMap,
21850
+ addedDeposits,
21851
+ addedDebt,
21852
+ lender
21853
+ );
21854
+ },
21855
+ SILO_V2_USER_CALLS_PER_PAIR
21856
+ ];
21857
+ };
21858
+ function toBigInt5(v) {
21859
+ if (v === void 0 || v === null || v === "0x") return 0n;
21860
+ if (typeof v === "bigint") return v;
21861
+ try {
21862
+ return BigInt(v);
21863
+ } catch {
21864
+ return 0n;
21865
+ }
21866
+ }
21867
+
20762
21868
  // src/lending/user-data/fetch-balances/parse.ts
20763
21869
  function getUserDataConverter(lender, chainId, account, params, meta) {
20764
21870
  if (isAaveV4Type(lender))
@@ -20793,6 +21899,8 @@ function getUserDataConverter(lender, chainId, account, params, meta) {
20793
21899
  );
20794
21900
  if (isEulerType(lender))
20795
21901
  return getEulerUserDataConverter(lender, chainId, account, meta?.[lender], params?.subAccountIndexes);
21902
+ if (isSiloV2Type(lender))
21903
+ return getSiloV2UserDataConverter(lender, chainId, account, meta?.[lender]);
20796
21904
  return getCompoundV2UserDataConverter(
20797
21905
  lender,
20798
21906
  chainId,
@@ -20814,19 +21922,19 @@ var convertLenderUserDataResult = (chainId, queriesRaw, rawResults, lenderState)
20814
21922
  const queries = organizeUserQueries(queriesRaw);
20815
21923
  const lenderData = {};
20816
21924
  let currentSlice = 0;
20817
- for (const query2 of queries) {
21925
+ for (const query3 of queries) {
20818
21926
  const [converter, sliceLength] = getUserDataConverter(
20819
- query2.lender,
21927
+ query3.lender,
20820
21928
  chainId,
20821
- query2.account,
20822
- query2.params,
21929
+ query3.account,
21930
+ query3.params,
20823
21931
  lenderState
20824
21932
  );
20825
21933
  try {
20826
21934
  const data = rawResults.slice(currentSlice, currentSlice + sliceLength);
20827
21935
  const convertedData = converter(data);
20828
21936
  if (convertedData) {
20829
- if (isMultiMarket(query2.lender)) {
21937
+ if (isMultiMarket(query3.lender)) {
20830
21938
  Object.keys(convertedData).forEach((market) => {
20831
21939
  const filtered = filterEmptyUserData(convertedData[market]);
20832
21940
  if (filtered) {
@@ -20837,8 +21945,8 @@ var convertLenderUserDataResult = (chainId, queriesRaw, rawResults, lenderState)
20837
21945
  } else {
20838
21946
  const filtered = filterEmptyUserData(convertedData);
20839
21947
  if (filtered) {
20840
- filtered.lender = query2.lender;
20841
- lenderData[query2.lender] = filtered;
21948
+ filtered.lender = query3.lender;
21949
+ lenderData[query3.lender] = filtered;
20842
21950
  }
20843
21951
  }
20844
21952
  }
@@ -25472,6 +26580,7 @@ var getAbi2 = (lender) => {
25472
26580
  if (isEulerType(lender)) return accountLensAbi;
25473
26581
  if (isCompoundV2Type(lender))
25474
26582
  return [...ComptrollerAbi, ...CompoundV2CollateralToken];
26583
+ if (isSiloV2Type(lender)) return [...SiloAbi];
25475
26584
  return [];
25476
26585
  };
25477
26586
 
@@ -25578,15 +26687,15 @@ function unflattenLenderData(pools) {
25578
26687
  var getLenderUserDataResult = async (chainId, queriesRaw, getEvmClient3, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, retries = 3, logs = false) => {
25579
26688
  const queries = organizeUserQueries(queriesRaw);
25580
26689
  const builtCalls = await Promise.all(
25581
- queries.map(async (query2) => {
25582
- const abi = getAbi2(query2.lender);
26690
+ queries.map(async (query3) => {
26691
+ const abi = getAbi2(query3.lender);
25583
26692
  const callData = await buildUserCall(
25584
26693
  chainId,
25585
- query2.lender,
25586
- query2.account,
25587
- query2.params
26694
+ query3.lender,
26695
+ query3.account,
26696
+ query3.params
25588
26697
  );
25589
- return callData.map((call) => ({ call, abi }));
26698
+ return callData.map((call) => ({ call, abi: call.abi ?? abi }));
25590
26699
  })
25591
26700
  );
25592
26701
  const calls = builtCalls.flat();
@@ -25607,15 +26716,15 @@ var prepareLenderUserDataRpcCalls = async (chainId, queriesRaw, batchSize = MULT
25607
26716
  const multicallAddress = getEvmChain(chainId).contracts?.multicall3?.address;
25608
26717
  const queries = organizeUserQueries(queriesRaw);
25609
26718
  const builtCalls = await Promise.all(
25610
- queries.map(async (query2) => {
25611
- const abi = getAbi2(query2.lender);
26719
+ queries.map(async (query3) => {
26720
+ const abi = getAbi2(query3.lender);
25612
26721
  const callData = await buildUserCall(
25613
26722
  chainId,
25614
- query2.lender,
25615
- query2.account,
25616
- query2.params
26723
+ query3.lender,
26724
+ query3.account,
26725
+ query3.params
25617
26726
  );
25618
- return callData.map((call) => ({ call, abi }));
26727
+ return callData.map((call) => ({ call, abi: call.abi ?? abi }));
25619
26728
  })
25620
26729
  );
25621
26730
  const calls = builtCalls.flat();
@@ -25724,13 +26833,13 @@ async function prepareMergedRpcCalls(chainId, balanceQueries, permissionParams,
25724
26833
  );
25725
26834
  let balanceCalls = [];
25726
26835
  const organizedQueries = organizeUserQueries(balanceQueries);
25727
- for (const query2 of organizedQueries) {
25728
- const abi = getAbi2(query2.lender);
26836
+ for (const query3 of organizedQueries) {
26837
+ const abi = getAbi2(query3.lender);
25729
26838
  const callData = await buildUserCall(
25730
26839
  chainId,
25731
- query2.lender,
25732
- query2.account,
25733
- query2.params
26840
+ query3.lender,
26841
+ query3.account,
26842
+ query3.params
25734
26843
  );
25735
26844
  const mappedCalls = callData.map((call) => ({ call, abi }));
25736
26845
  balanceCalls = [...balanceCalls, ...mappedCalls];
@@ -25789,13 +26898,13 @@ async function prepareMergedMulticallParams(chainId, balanceQueries, permissionP
25789
26898
  const permissionAbis = permissionCalls.map(() => permissionResult.abi);
25790
26899
  let balanceCalls = [];
25791
26900
  const organizedQueries = organizeUserQueries(balanceQueries);
25792
- for (const query2 of organizedQueries) {
25793
- const abi = getAbi2(query2.lender);
26901
+ for (const query3 of organizedQueries) {
26902
+ const abi = getAbi2(query3.lender);
25794
26903
  const callData = await buildUserCall(
25795
26904
  chainId,
25796
- query2.lender,
25797
- query2.account,
25798
- query2.params
26905
+ query3.lender,
26906
+ query3.account,
26907
+ query3.params
25799
26908
  );
25800
26909
  const mappedCalls = callData.map((call) => ({ call, abi }));
25801
26910
  balanceCalls = [...balanceCalls, ...mappedCalls];
@@ -28592,12 +29701,12 @@ function getMorphoCalls(chainId, context) {
28592
29701
  const queries = getMorphoMarketsForChain(chainId, context?.marketOverrides);
28593
29702
  if (queries.length === 0) return [];
28594
29703
  const oracleGroups = /* @__PURE__ */ new Map();
28595
- for (const query2 of queries) {
28596
- const oracleLc = query2.oracle.toLowerCase();
29704
+ for (const query3 of queries) {
29705
+ const oracleLc = query3.oracle.toLowerCase();
28597
29706
  if (!oracleGroups.has(oracleLc)) {
28598
29707
  oracleGroups.set(oracleLc, []);
28599
29708
  }
28600
- oracleGroups.get(oracleLc).push(query2);
29709
+ oracleGroups.get(oracleLc).push(query3);
28601
29710
  }
28602
29711
  return Array.from(oracleGroups.values()).map((markets) => {
28603
29712
  const call = {
@@ -29333,6 +30442,550 @@ var aaveV4Fetcher = {
29333
30442
  getAbi: getAaveV4Abi
29334
30443
  };
29335
30444
 
30445
+ // src/prices/oracle-prices/fetchers/siloV2.ts
30446
+ var SiloOracleAbi = [
30447
+ {
30448
+ inputs: [
30449
+ { name: "_baseAmount", type: "uint256" },
30450
+ { name: "_baseToken", type: "address" }
30451
+ ],
30452
+ name: "quote",
30453
+ outputs: [{ name: "quoteAmount", type: "uint256" }],
30454
+ stateMutability: "view",
30455
+ type: "function"
30456
+ },
30457
+ {
30458
+ inputs: [],
30459
+ name: "quoteToken",
30460
+ outputs: [{ name: "", type: "address" }],
30461
+ stateMutability: "view",
30462
+ type: "function"
30463
+ }
30464
+ ];
30465
+ var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
30466
+ function lookupUSD(context, asset) {
30467
+ const lc = asset.toLowerCase();
30468
+ const groupKey = context.tokenList?.[lc]?.assetGroup ?? `${context.chainId}-${lc}`;
30469
+ return context.usdPrices[groupKey] ?? context.usdPrices[lc] ?? 0;
30470
+ }
30471
+ function getSiloV2Calls(chainId) {
30472
+ const allMarkets = siloMarkets()?.[chainId];
30473
+ if (!allMarkets || allMarkets.length === 0) return [];
30474
+ const tokensWithRealOracle = /* @__PURE__ */ new Set();
30475
+ for (const market of allMarkets) {
30476
+ for (const half of [market.silo0, market.silo1]) {
30477
+ if (half.solvencyOracle && half.solvencyOracle !== ZERO_ADDRESS) {
30478
+ tokensWithRealOracle.add(half.token.toLowerCase());
30479
+ }
30480
+ }
30481
+ }
30482
+ const calls = [];
30483
+ const callIndexMap = {};
30484
+ const quoteTokenIndexMap = {};
30485
+ const entries = [];
30486
+ for (const market of allMarkets) {
30487
+ const lenderKey = siloV2LenderKey(market.siloConfig);
30488
+ const halves = [market.silo0, market.silo1];
30489
+ const isStatic = halves.map(
30490
+ (h) => !h.solvencyOracle || h.solvencyOracle === ZERO_ADDRESS
30491
+ );
30492
+ if (isStatic[0] && isStatic[1]) {
30493
+ const t0 = halves[0].token.toLowerCase();
30494
+ const t1 = halves[1].token.toLowerCase();
30495
+ if (!tokensWithRealOracle.has(t0) && !tokensWithRealOracle.has(t1)) {
30496
+ continue;
30497
+ }
30498
+ }
30499
+ for (let i = 0; i < 2; i++) {
30500
+ const half = halves[i];
30501
+ const partner = halves[1 - i];
30502
+ const tokenLc = half.token.toLowerCase();
30503
+ const partnerLc = partner.token.toLowerCase();
30504
+ if (isStatic[i]) {
30505
+ entries.push({
30506
+ token: tokenLc,
30507
+ decimals: half.decimals,
30508
+ silo: half.silo.toLowerCase(),
30509
+ lenderKey,
30510
+ oracle: ZERO_ADDRESS,
30511
+ partnerToken: partnerLc,
30512
+ isStatic: true
30513
+ });
30514
+ continue;
30515
+ }
30516
+ const oracleLc = half.solvencyOracle.toLowerCase();
30517
+ entries.push({
30518
+ token: tokenLc,
30519
+ decimals: half.decimals,
30520
+ silo: half.silo.toLowerCase(),
30521
+ lenderKey,
30522
+ oracle: oracleLc,
30523
+ partnerToken: partnerLc,
30524
+ isStatic: false
30525
+ });
30526
+ const quoteKey = `${oracleLc}:${tokenLc}`;
30527
+ if (!(quoteKey in callIndexMap)) {
30528
+ callIndexMap[quoteKey] = calls.length;
30529
+ calls.push({
30530
+ address: half.solvencyOracle,
30531
+ name: "quote",
30532
+ params: [BigInt(10) ** BigInt(half.decimals), half.token]
30533
+ });
30534
+ }
30535
+ if (!(oracleLc in quoteTokenIndexMap)) {
30536
+ quoteTokenIndexMap[oracleLc] = calls.length;
30537
+ calls.push({
30538
+ address: half.solvencyOracle,
30539
+ name: "quoteToken",
30540
+ params: []
30541
+ });
30542
+ }
30543
+ }
30544
+ }
30545
+ if (entries.length === 0) return [];
30546
+ return [
30547
+ {
30548
+ calls,
30549
+ meta: { entries, callIndexMap, quoteTokenIndexMap },
30550
+ lender: "SILO_V2"
30551
+ }
30552
+ ];
30553
+ }
30554
+ function parseSiloV2Results(data, meta, context) {
30555
+ const entries = [];
30556
+ const seen = /* @__PURE__ */ new Set();
30557
+ for (const entry of meta.entries) {
30558
+ const dedupKey = `${entry.lenderKey}:${entry.token}`;
30559
+ if (seen.has(dedupKey)) continue;
30560
+ try {
30561
+ let priceUSD = 0;
30562
+ let rawPrice = 1;
30563
+ if (entry.isStatic) {
30564
+ const ownUSD = lookupUSD(context, entry.token);
30565
+ const partnerUSD = lookupUSD(context, entry.partnerToken);
30566
+ priceUSD = ownUSD || partnerUSD;
30567
+ if (!priceUSD) continue;
30568
+ rawPrice = 1;
30569
+ } else {
30570
+ const quoteCallIdx = meta.callIndexMap[`${entry.oracle}:${entry.token}`];
30571
+ if (quoteCallIdx === void 0) continue;
30572
+ const rawQuote = data[quoteCallIdx];
30573
+ if (!rawQuote || rawQuote === "0x") continue;
30574
+ const quoteAmount = BigInt(rawQuote.toString());
30575
+ if (quoteAmount === 0n) continue;
30576
+ const qtIdx = meta.quoteTokenIndexMap[entry.oracle];
30577
+ if (qtIdx === void 0) continue;
30578
+ const rawQt = data[qtIdx];
30579
+ if (!rawQt || rawQt === "0x") continue;
30580
+ const quoteTokenAddr = rawQt.toLowerCase();
30581
+ const qtMeta = context.tokenList?.[quoteTokenAddr];
30582
+ const qtDecimals = qtMeta?.decimals ?? 18;
30583
+ const priceInQt = Number(quoteAmount) / Number(10n ** BigInt(qtDecimals));
30584
+ if (isNaN(priceInQt) || priceInQt === 0) continue;
30585
+ const qtUSD = lookupUSD(context, quoteTokenAddr);
30586
+ if (!qtUSD) continue;
30587
+ rawPrice = priceInQt;
30588
+ priceUSD = priceInQt * qtUSD;
30589
+ }
30590
+ if (isNaN(priceUSD) || priceUSD === 0) continue;
30591
+ entries.push({
30592
+ asset: entry.token,
30593
+ price: rawPrice,
30594
+ priceUSD,
30595
+ marketUid: createMarketUid(
30596
+ context.chainId,
30597
+ entry.lenderKey,
30598
+ entry.silo
30599
+ ),
30600
+ targetLender: entry.lenderKey,
30601
+ ...entry.isStatic ? { staticBase: true, baseAsset: entry.token } : {}
30602
+ });
30603
+ seen.add(dedupKey);
30604
+ } catch {
30605
+ }
30606
+ }
30607
+ return entries;
30608
+ }
30609
+ function getSiloV2Abi() {
30610
+ return SiloOracleAbi;
30611
+ }
30612
+ var siloV2Fetcher = {
30613
+ getCalls: getSiloV2Calls,
30614
+ parse: parseSiloV2Results,
30615
+ getAbi: getSiloV2Abi
30616
+ };
30617
+
30618
+ // src/prices/oracle-prices/fetchers/siloV3.ts
30619
+ var SiloOracleAbi2 = [
30620
+ {
30621
+ inputs: [
30622
+ { name: "_baseAmount", type: "uint256" },
30623
+ { name: "_baseToken", type: "address" }
30624
+ ],
30625
+ name: "quote",
30626
+ outputs: [{ name: "quoteAmount", type: "uint256" }],
30627
+ stateMutability: "view",
30628
+ type: "function"
30629
+ },
30630
+ {
30631
+ inputs: [],
30632
+ name: "quoteToken",
30633
+ outputs: [{ name: "", type: "address" }],
30634
+ stateMutability: "view",
30635
+ type: "function"
30636
+ }
30637
+ ];
30638
+ var ZERO_ADDRESS2 = "0x0000000000000000000000000000000000000000";
30639
+ function lookupUSD2(context, asset) {
30640
+ const lc = asset.toLowerCase();
30641
+ const groupKey = context.tokenList?.[lc]?.assetGroup ?? `${context.chainId}-${lc}`;
30642
+ return context.usdPrices[groupKey] ?? context.usdPrices[lc] ?? 0;
30643
+ }
30644
+ function getSiloV3Calls(chainId) {
30645
+ const allMarkets = siloMarketsV3()?.[chainId];
30646
+ if (!allMarkets || allMarkets.length === 0) return [];
30647
+ const tokensWithRealOracle = /* @__PURE__ */ new Set();
30648
+ for (const market of allMarkets) {
30649
+ for (const half of [market.silo0, market.silo1]) {
30650
+ if (half.solvencyOracle && half.solvencyOracle !== ZERO_ADDRESS2) {
30651
+ tokensWithRealOracle.add(half.token.toLowerCase());
30652
+ }
30653
+ }
30654
+ }
30655
+ const calls = [];
30656
+ const callIndexMap = {};
30657
+ const quoteTokenIndexMap = {};
30658
+ const entries = [];
30659
+ for (const market of allMarkets) {
30660
+ const lenderKey = siloV3LenderKey(market.siloConfig);
30661
+ const halves = [market.silo0, market.silo1];
30662
+ const isStatic = halves.map(
30663
+ (h) => !h.solvencyOracle || h.solvencyOracle === ZERO_ADDRESS2
30664
+ );
30665
+ if (isStatic[0] && isStatic[1]) {
30666
+ const t0 = halves[0].token.toLowerCase();
30667
+ const t1 = halves[1].token.toLowerCase();
30668
+ if (!tokensWithRealOracle.has(t0) && !tokensWithRealOracle.has(t1)) {
30669
+ continue;
30670
+ }
30671
+ }
30672
+ for (let i = 0; i < 2; i++) {
30673
+ const half = halves[i];
30674
+ const partner = halves[1 - i];
30675
+ const tokenLc = half.token.toLowerCase();
30676
+ const partnerLc = partner.token.toLowerCase();
30677
+ if (isStatic[i]) {
30678
+ entries.push({
30679
+ token: tokenLc,
30680
+ decimals: half.decimals,
30681
+ silo: half.silo.toLowerCase(),
30682
+ lenderKey,
30683
+ oracle: ZERO_ADDRESS2,
30684
+ partnerToken: partnerLc,
30685
+ isStatic: true
30686
+ });
30687
+ continue;
30688
+ }
30689
+ const oracleLc = half.solvencyOracle.toLowerCase();
30690
+ entries.push({
30691
+ token: tokenLc,
30692
+ decimals: half.decimals,
30693
+ silo: half.silo.toLowerCase(),
30694
+ lenderKey,
30695
+ oracle: oracleLc,
30696
+ partnerToken: partnerLc,
30697
+ isStatic: false
30698
+ });
30699
+ const quoteKey = `${oracleLc}:${tokenLc}`;
30700
+ if (!(quoteKey in callIndexMap)) {
30701
+ callIndexMap[quoteKey] = calls.length;
30702
+ calls.push({
30703
+ address: half.solvencyOracle,
30704
+ name: "quote",
30705
+ params: [BigInt(10) ** BigInt(half.decimals), half.token]
30706
+ });
30707
+ }
30708
+ if (!(oracleLc in quoteTokenIndexMap)) {
30709
+ quoteTokenIndexMap[oracleLc] = calls.length;
30710
+ calls.push({
30711
+ address: half.solvencyOracle,
30712
+ name: "quoteToken",
30713
+ params: []
30714
+ });
30715
+ }
30716
+ }
30717
+ }
30718
+ if (entries.length === 0) return [];
30719
+ return [
30720
+ {
30721
+ calls,
30722
+ meta: { entries, callIndexMap, quoteTokenIndexMap },
30723
+ lender: "SILO_V3"
30724
+ }
30725
+ ];
30726
+ }
30727
+ function parseSiloV3Results(data, meta, context) {
30728
+ const entries = [];
30729
+ const seen = /* @__PURE__ */ new Set();
30730
+ for (const entry of meta.entries) {
30731
+ const dedupKey = `${entry.lenderKey}:${entry.token}`;
30732
+ if (seen.has(dedupKey)) continue;
30733
+ try {
30734
+ let priceUSD = 0;
30735
+ let rawPrice = 1;
30736
+ if (entry.isStatic) {
30737
+ const ownUSD = lookupUSD2(context, entry.token);
30738
+ const partnerUSD = lookupUSD2(context, entry.partnerToken);
30739
+ priceUSD = ownUSD || partnerUSD;
30740
+ if (!priceUSD) continue;
30741
+ rawPrice = 1;
30742
+ } else {
30743
+ const quoteCallIdx = meta.callIndexMap[`${entry.oracle}:${entry.token}`];
30744
+ if (quoteCallIdx === void 0) continue;
30745
+ const rawQuote = data[quoteCallIdx];
30746
+ if (!rawQuote || rawQuote === "0x") continue;
30747
+ const quoteAmount = BigInt(rawQuote.toString());
30748
+ if (quoteAmount === 0n) continue;
30749
+ const qtIdx = meta.quoteTokenIndexMap[entry.oracle];
30750
+ if (qtIdx === void 0) continue;
30751
+ const rawQt = data[qtIdx];
30752
+ if (!rawQt || rawQt === "0x") continue;
30753
+ const quoteTokenAddr = rawQt.toLowerCase();
30754
+ const qtMeta = context.tokenList?.[quoteTokenAddr];
30755
+ const qtDecimals = qtMeta?.decimals ?? 18;
30756
+ const priceInQt = Number(quoteAmount) / Number(10n ** BigInt(qtDecimals));
30757
+ if (isNaN(priceInQt) || priceInQt === 0) continue;
30758
+ const qtUSD = lookupUSD2(context, quoteTokenAddr);
30759
+ if (!qtUSD) continue;
30760
+ rawPrice = priceInQt;
30761
+ priceUSD = priceInQt * qtUSD;
30762
+ }
30763
+ if (isNaN(priceUSD) || priceUSD === 0) continue;
30764
+ entries.push({
30765
+ asset: entry.token,
30766
+ price: rawPrice,
30767
+ priceUSD,
30768
+ marketUid: createMarketUid(
30769
+ context.chainId,
30770
+ entry.lenderKey,
30771
+ entry.silo
30772
+ ),
30773
+ targetLender: entry.lenderKey,
30774
+ ...entry.isStatic ? { staticBase: true, baseAsset: entry.token } : {}
30775
+ });
30776
+ seen.add(dedupKey);
30777
+ } catch {
30778
+ }
30779
+ }
30780
+ return entries;
30781
+ }
30782
+ function getSiloV3Abi() {
30783
+ return SiloOracleAbi2;
30784
+ }
30785
+ var siloV3Fetcher = {
30786
+ getCalls: getSiloV3Calls,
30787
+ parse: parseSiloV3Results,
30788
+ getAbi: getSiloV3Abi
30789
+ };
30790
+
30791
+ // src/prices/oracle-prices/fetchers/siloV2Graphql.ts
30792
+ async function fetchSiloV2GraphQLMarkets(chainId) {
30793
+ if (!SILO_API_SUPPORTED_CHAIN_IDS.has(chainId)) return null;
30794
+ try {
30795
+ const items = await fetchSiloMarkets(chainId, { protocolVersion: "v2" });
30796
+ return items;
30797
+ } catch (e) {
30798
+ console.warn(
30799
+ `[prices] Silo v2 GraphQL fetch failed on chain ${chainId}:`,
30800
+ e?.message ?? e
30801
+ );
30802
+ return null;
30803
+ }
30804
+ }
30805
+ function safeNumber3(v) {
30806
+ if (v == null) return 0;
30807
+ const n = typeof v === "number" ? v : Number(v);
30808
+ return Number.isFinite(n) ? n : 0;
30809
+ }
30810
+ function lookupUSD3(context, asset) {
30811
+ const lc = asset.toLowerCase();
30812
+ const groupKey = context.tokenList?.[lc]?.assetGroup ?? `${context.chainId}-${lc}`;
30813
+ return context.usdPrices[groupKey] ?? context.usdPrices[lc] ?? 0;
30814
+ }
30815
+ function parseSiloV2GraphQLResults(items, context) {
30816
+ const ZERO_ADDRESS3 = "0x0000000000000000000000000000000000000000";
30817
+ const out = [];
30818
+ const seen = /* @__PURE__ */ new Set();
30819
+ for (const item of items) {
30820
+ let lenderKey;
30821
+ try {
30822
+ lenderKey = siloV2LenderKey(item.configAddress);
30823
+ } catch {
30824
+ continue;
30825
+ }
30826
+ const registryEntry = getSiloV2MarketEntry(context.chainId, lenderKey);
30827
+ if (!registryEntry) continue;
30828
+ const [apiSide0, apiSide1] = item.market1.index === 0 ? [item.market1, item.market2] : [item.market2, item.market1];
30829
+ const sideTuples = [
30830
+ { api: apiSide0, self: registryEntry.silo0, other: registryEntry.silo1 },
30831
+ { api: apiSide1, self: registryEntry.silo1, other: registryEntry.silo0 }
30832
+ ];
30833
+ for (const { api: side, self, other } of sideTuples) {
30834
+ const tokenLc = (side.inputTokenId ?? side.inputToken?.id ?? self.token).toLowerCase();
30835
+ if (!tokenLc) continue;
30836
+ const partnerTokenLc = other.token.toLowerCase();
30837
+ const dedupKey = `${lenderKey}:${tokenLc}`;
30838
+ if (seen.has(dedupKey)) continue;
30839
+ const oracleAddr = (side.solvencyOracleAddress ?? side.solvencyOracle?.id ?? self.solvencyOracle ?? ZERO_ADDRESS3).toLowerCase();
30840
+ const isStatic = !oracleAddr || oracleAddr === ZERO_ADDRESS3;
30841
+ const siloAddrLc = self.silo.toLowerCase();
30842
+ try {
30843
+ let priceUSD = 0;
30844
+ let rawPrice = 1;
30845
+ const supplyNum = safeNumber3(side.supply);
30846
+ const supplyUsdNum = side.supplyUsd != null ? Number(side.supplyUsd) : 0;
30847
+ const borrowedNum = safeNumber3(side.borrowed);
30848
+ const borrowedUsdNum = side.borrowedUsd != null ? Number(side.borrowedUsd) : 0;
30849
+ if (supplyNum > 0 && supplyUsdNum > 0) {
30850
+ priceUSD = supplyUsdNum / supplyNum;
30851
+ rawPrice = isStatic ? 1 : priceUSD;
30852
+ } else if (borrowedNum > 0 && borrowedUsdNum > 0) {
30853
+ priceUSD = borrowedUsdNum / borrowedNum;
30854
+ rawPrice = isStatic ? 1 : priceUSD;
30855
+ } else if (isStatic) {
30856
+ const ownUSD = lookupUSD3(context, tokenLc);
30857
+ const partnerUSD = partnerTokenLc ? lookupUSD3(context, partnerTokenLc) : 0;
30858
+ priceUSD = ownUSD || partnerUSD;
30859
+ if (!priceUSD) continue;
30860
+ rawPrice = 1;
30861
+ } else {
30862
+ const quoteStr = side.solvencyOracle?.quote;
30863
+ if (!quoteStr) continue;
30864
+ const quoteNum = Number(quoteStr);
30865
+ if (!Number.isFinite(quoteNum) || quoteNum === 0) continue;
30866
+ const quoteTokenLc = (side.solvencyOracle?.quoteTokenId ?? "").toLowerCase();
30867
+ if (!quoteTokenLc) continue;
30868
+ const qtUSD = lookupUSD3(context, quoteTokenLc);
30869
+ if (!qtUSD) continue;
30870
+ rawPrice = quoteNum;
30871
+ priceUSD = quoteNum * qtUSD;
30872
+ }
30873
+ if (!Number.isFinite(priceUSD) || priceUSD === 0) continue;
30874
+ out.push({
30875
+ asset: tokenLc,
30876
+ price: rawPrice,
30877
+ priceUSD,
30878
+ marketUid: createMarketUid(context.chainId, lenderKey, siloAddrLc),
30879
+ targetLender: lenderKey,
30880
+ ...isStatic ? { staticBase: true, baseAsset: tokenLc } : {}
30881
+ });
30882
+ seen.add(dedupKey);
30883
+ } catch {
30884
+ }
30885
+ }
30886
+ }
30887
+ return out;
30888
+ }
30889
+
30890
+ // src/prices/oracle-prices/fetchers/siloV3Graphql.ts
30891
+ async function fetchSiloV3GraphQLMarkets(chainId) {
30892
+ if (!SILO_API_SUPPORTED_CHAIN_IDS.has(chainId)) return null;
30893
+ try {
30894
+ const items = await fetchSiloMarkets(chainId, { protocolVersion: "v3" });
30895
+ return items;
30896
+ } catch (e) {
30897
+ console.warn(
30898
+ `[prices] Silo v3 GraphQL fetch failed on chain ${chainId}:`,
30899
+ e?.message ?? e
30900
+ );
30901
+ return null;
30902
+ }
30903
+ }
30904
+ function safeNumber4(v) {
30905
+ if (v == null) return 0;
30906
+ const n = typeof v === "number" ? v : Number(v);
30907
+ return Number.isFinite(n) ? n : 0;
30908
+ }
30909
+ function lookupUSD4(context, asset) {
30910
+ const lc = asset.toLowerCase();
30911
+ const groupKey = context.tokenList?.[lc]?.assetGroup ?? `${context.chainId}-${lc}`;
30912
+ return context.usdPrices[groupKey] ?? context.usdPrices[lc] ?? 0;
30913
+ }
30914
+ function parseSiloV3GraphQLResults(items, context) {
30915
+ const ZERO_ADDRESS3 = "0x0000000000000000000000000000000000000000";
30916
+ const out = [];
30917
+ const seen = /* @__PURE__ */ new Set();
30918
+ for (const item of items) {
30919
+ let lenderKey;
30920
+ try {
30921
+ lenderKey = siloV3LenderKey(item.configAddress);
30922
+ } catch {
30923
+ continue;
30924
+ }
30925
+ const registryEntry = getSiloV3MarketEntry(context.chainId, lenderKey);
30926
+ if (!registryEntry) continue;
30927
+ const [apiSide0, apiSide1] = item.market1.index === 0 ? [item.market1, item.market2] : [item.market2, item.market1];
30928
+ const sideTuples = [
30929
+ { api: apiSide0, self: registryEntry.silo0, other: registryEntry.silo1 },
30930
+ { api: apiSide1, self: registryEntry.silo1, other: registryEntry.silo0 }
30931
+ ];
30932
+ for (const { api: side, self, other } of sideTuples) {
30933
+ const tokenLc = (side.inputTokenId ?? side.inputToken?.id ?? self.token).toLowerCase();
30934
+ if (!tokenLc) continue;
30935
+ const partnerTokenLc = other.token.toLowerCase();
30936
+ const dedupKey = `${lenderKey}:${tokenLc}`;
30937
+ if (seen.has(dedupKey)) continue;
30938
+ const oracleAddr = (side.solvencyOracleAddress ?? side.solvencyOracle?.id ?? self.solvencyOracle ?? ZERO_ADDRESS3).toLowerCase();
30939
+ const isStatic = !oracleAddr || oracleAddr === ZERO_ADDRESS3;
30940
+ const siloAddrLc = self.silo.toLowerCase();
30941
+ try {
30942
+ let priceUSD = 0;
30943
+ let rawPrice = 1;
30944
+ const supplyNum = safeNumber4(side.supply);
30945
+ const supplyUsdNum = side.supplyUsd != null ? Number(side.supplyUsd) : 0;
30946
+ const borrowedNum = safeNumber4(side.borrowed);
30947
+ const borrowedUsdNum = side.borrowedUsd != null ? Number(side.borrowedUsd) : 0;
30948
+ if (supplyNum > 0 && supplyUsdNum > 0) {
30949
+ priceUSD = supplyUsdNum / supplyNum;
30950
+ rawPrice = isStatic ? 1 : priceUSD;
30951
+ } else if (borrowedNum > 0 && borrowedUsdNum > 0) {
30952
+ priceUSD = borrowedUsdNum / borrowedNum;
30953
+ rawPrice = isStatic ? 1 : priceUSD;
30954
+ } else if (isStatic) {
30955
+ const ownUSD = lookupUSD4(context, tokenLc);
30956
+ const partnerUSD = partnerTokenLc ? lookupUSD4(context, partnerTokenLc) : 0;
30957
+ priceUSD = ownUSD || partnerUSD;
30958
+ if (!priceUSD) continue;
30959
+ rawPrice = 1;
30960
+ } else {
30961
+ const quoteStr = side.solvencyOracle?.quote;
30962
+ if (!quoteStr) continue;
30963
+ const quoteNum = Number(quoteStr);
30964
+ if (!Number.isFinite(quoteNum) || quoteNum === 0) continue;
30965
+ const quoteTokenLc = (side.solvencyOracle?.quoteTokenId ?? "").toLowerCase();
30966
+ if (!quoteTokenLc) continue;
30967
+ const qtUSD = lookupUSD4(context, quoteTokenLc);
30968
+ if (!qtUSD) continue;
30969
+ rawPrice = quoteNum;
30970
+ priceUSD = quoteNum * qtUSD;
30971
+ }
30972
+ if (!Number.isFinite(priceUSD) || priceUSD === 0) continue;
30973
+ out.push({
30974
+ asset: tokenLc,
30975
+ price: rawPrice,
30976
+ priceUSD,
30977
+ marketUid: createMarketUid(context.chainId, lenderKey, siloAddrLc),
30978
+ targetLender: lenderKey,
30979
+ ...isStatic ? { staticBase: true, baseAsset: tokenLc } : {}
30980
+ });
30981
+ seen.add(dedupKey);
30982
+ } catch {
30983
+ }
30984
+ }
30985
+ }
30986
+ return out;
30987
+ }
30988
+
29336
30989
  // src/prices/oracle-prices/fetchOraclePrices.ts
29337
30990
  function countFailures(data, offset, count) {
29338
30991
  let failures = 0;
@@ -29483,6 +31136,16 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
29483
31136
  }),
29484
31137
  getCallsErrors
29485
31138
  ) : [];
31139
+ const siloV2Results = isActive("silov2") ? safeGetCalls(
31140
+ "siloV2",
31141
+ () => siloV2Fetcher.getCalls(chainId),
31142
+ getCallsErrors
31143
+ ) : [];
31144
+ const siloV3Results = isActive("silov3") ? safeGetCalls(
31145
+ "siloV3",
31146
+ () => siloV3Fetcher.getCalls(chainId),
31147
+ getCallsErrors
31148
+ ) : [];
29486
31149
  const aaveGroup = buildGroup(
29487
31150
  "aave",
29488
31151
  aaveResults,
@@ -29525,6 +31188,18 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
29525
31188
  morphoFetcher.parse,
29526
31189
  ProxyOracleAbi
29527
31190
  );
31191
+ const siloV2Group = buildGroup(
31192
+ "siloV2",
31193
+ siloV2Results,
31194
+ siloV2Fetcher.parse,
31195
+ getSiloV2Abi()
31196
+ );
31197
+ const siloV3Group = buildGroup(
31198
+ "siloV3",
31199
+ siloV3Results,
31200
+ siloV3Fetcher.parse,
31201
+ getSiloV3Abi()
31202
+ );
29528
31203
  const allGroups = [
29529
31204
  aaveGroup,
29530
31205
  compoundV2Group,
@@ -29532,7 +31207,9 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
29532
31207
  listaGroup,
29533
31208
  eulerGroup,
29534
31209
  aaveV4Group,
29535
- morphoGroup
31210
+ morphoGroup,
31211
+ siloV2Group,
31212
+ siloV3Group
29536
31213
  ];
29537
31214
  const totalCalls = allGroups.reduce((s, g) => s + g.calls.length, 0);
29538
31215
  if (totalCalls === 0 && !isActive("morpho")) {
@@ -29551,6 +31228,8 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
29551
31228
  }
29552
31229
  const chainBatchSize = batchSize?.[chainId];
29553
31230
  const morphoGqlPromise = isActive("morpho") ? fetchMorphoGraphQLPrices(chainId) : Promise.resolve(null);
31231
+ const siloV2GqlPromise = fetchSiloV2GraphQLMarkets(chainId);
31232
+ const siloV3GqlPromise = fetchSiloV3GraphQLMarkets(chainId);
29554
31233
  const [
29555
31234
  aaveData,
29556
31235
  compoundV2Data,
@@ -29558,7 +31237,9 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
29558
31237
  listaData,
29559
31238
  eulerData,
29560
31239
  aaveV4Data,
29561
- morphoGqlEntries
31240
+ morphoGqlEntries,
31241
+ siloV2GqlItems,
31242
+ siloV3GqlItems
29562
31243
  ] = await Promise.all([
29563
31244
  executeGroup(
29564
31245
  aaveGroup,
@@ -29608,10 +31289,40 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
29608
31289
  allowFailure,
29609
31290
  rpcOverrides
29610
31291
  ),
29611
- morphoGqlPromise
31292
+ morphoGqlPromise,
31293
+ siloV2GqlPromise,
31294
+ siloV3GqlPromise
29612
31295
  ]);
31296
+ if (siloV2GqlItems == null && siloV2Group.calls.length > 0) {
31297
+ console.warn(
31298
+ `[prices] chain ${chainId}: Silo v2 GraphQL unavailable, falling back to on-chain (${siloV2Group.trackers.length} trackers)`
31299
+ );
31300
+ }
31301
+ const siloV2Data = siloV2GqlItems != null ? { results: [], error: void 0 } : await executeGroup(
31302
+ siloV2Group,
31303
+ chainId,
31304
+ chainBatchSize,
31305
+ retries,
31306
+ allowFailure,
31307
+ rpcOverrides
31308
+ );
31309
+ if (siloV3GqlItems == null && siloV3Group.calls.length > 0) {
31310
+ console.warn(
31311
+ `[prices] chain ${chainId}: Silo v3 GraphQL unavailable, falling back to on-chain (${siloV3Group.trackers.length} trackers)`
31312
+ );
31313
+ }
31314
+ const siloV3Data = siloV3GqlItems != null ? { results: [], error: void 0 } : await executeGroup(
31315
+ siloV3Group,
31316
+ chainId,
31317
+ chainBatchSize,
31318
+ retries,
31319
+ allowFailure,
31320
+ rpcOverrides
31321
+ );
29613
31322
  if (morphoGqlEntries == null && isActive("morpho")) {
29614
- console.warn(`[prices] chain ${chainId}: Morpho GraphQL returned null, falling back to on-chain (${morphoGroup.trackers.length} trackers)`);
31323
+ console.warn(
31324
+ `[prices] chain ${chainId}: Morpho GraphQL returned null, falling back to on-chain (${morphoGroup.trackers.length} trackers)`
31325
+ );
29615
31326
  }
29616
31327
  const morphoData = morphoGqlEntries != null ? { results: [], error: void 0 } : await executeGroup(
29617
31328
  morphoGroup,
@@ -29629,6 +31340,8 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
29629
31340
  { group: listaGroup, data: listaData },
29630
31341
  { group: eulerGroup, data: eulerData },
29631
31342
  { group: aaveV4Group, data: aaveV4Data },
31343
+ ...siloV2GqlItems != null ? [] : [{ group: siloV2Group, data: siloV2Data }],
31344
+ ...siloV3GqlItems != null ? [] : [{ group: siloV3Group, data: siloV3Data }],
29632
31345
  ...useMorphoGql ? [] : [{ group: morphoGroup, data: morphoData }]
29633
31346
  ];
29634
31347
  for (const { group, data } of groupResults) {
@@ -29713,6 +31426,48 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
29713
31426
  true,
29714
31427
  (t) => !!t.meta.baseAssetSource
29715
31428
  );
31429
+ if (siloV2GqlItems != null) {
31430
+ const context = { chainId, usdPrices, tokenList };
31431
+ const entries = parseSiloV2GraphQLResults(siloV2GqlItems, context);
31432
+ const diag2 = {
31433
+ lender: "SILO_V2 (GraphQL)",
31434
+ callCount: 0,
31435
+ failedCalls: 0,
31436
+ parsedEntries: entries.length
31437
+ };
31438
+ for (const entry of entries) {
31439
+ const lender = entry.targetLender ?? "SILO_V2";
31440
+ if (!chainResult[lender]) chainResult[lender] = [];
31441
+ chainResult[lender].push(entry);
31442
+ const oracleKey = tokenList[entry.asset]?.assetGroup ?? `${chainId}-${entry.asset}`;
31443
+ usdPrices[oracleKey] = entry.priceUSD;
31444
+ usdPrices[entry.asset] = entry.priceUSD;
31445
+ }
31446
+ trackerDiags.push(diag2);
31447
+ } else {
31448
+ parseTrackers(siloV2Group, siloV2Data.results);
31449
+ }
31450
+ if (siloV3GqlItems != null) {
31451
+ const context = { chainId, usdPrices, tokenList };
31452
+ const entries = parseSiloV3GraphQLResults(siloV3GqlItems, context);
31453
+ const diag2 = {
31454
+ lender: "SILO_V3 (GraphQL)",
31455
+ callCount: 0,
31456
+ failedCalls: 0,
31457
+ parsedEntries: entries.length
31458
+ };
31459
+ for (const entry of entries) {
31460
+ const lender = entry.targetLender ?? "SILO_V3";
31461
+ if (!chainResult[lender]) chainResult[lender] = [];
31462
+ chainResult[lender].push(entry);
31463
+ const oracleKey = tokenList[entry.asset]?.assetGroup ?? `${chainId}-${entry.asset}`;
31464
+ usdPrices[oracleKey] = entry.priceUSD;
31465
+ usdPrices[entry.asset] = entry.priceUSD;
31466
+ }
31467
+ trackerDiags.push(diag2);
31468
+ } else {
31469
+ parseTrackers(siloV3Group, siloV3Data.results);
31470
+ }
29716
31471
  if (useMorphoGql) {
29717
31472
  const morphoGqlDiag = {
29718
31473
  lender: "MORPHO_BLUE (GraphQL)",
@@ -30588,21 +32343,21 @@ function prepareTokenBalanceRpcCalls(chainId, account, tokens, blockTag = "lates
30588
32343
  encodedCalldata
30589
32344
  };
30590
32345
  }
30591
- function parseTokenBalanceResult(rawResult, query2) {
32346
+ function parseTokenBalanceResult(rawResult, query3) {
30592
32347
  if (!rawResult || rawResult === "0x") {
30593
32348
  return {};
30594
32349
  }
30595
32350
  const parsed = parseBalanceFetcherResult(
30596
32351
  rawResult,
30597
- [query2.account],
30598
- query2.tokens
32352
+ [query3.account],
32353
+ query3.tokens
30599
32354
  );
30600
32355
  if (parsed.balances.length === 0) {
30601
32356
  return {};
30602
32357
  }
30603
32358
  const result = {};
30604
32359
  const userBalances = parsed.balances[0].balances;
30605
- for (const token of query2.tokens) {
32360
+ for (const token of query3.tokens) {
30606
32361
  const balanceEntry = userBalances[token];
30607
32362
  if (balanceEntry) {
30608
32363
  result[token] = {