@1delta/margin-fetcher 0.0.226 → 0.0.229

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 (53) 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 +1946 -125
  10. package/dist/index.js.map +1 -1
  11. package/dist/lending/public-data/fetchLender.d.ts.map +1 -1
  12. package/dist/lending/public-data/fetchLenderAll.d.ts.map +1 -1
  13. package/dist/lending/public-data/fetchLenderExt.d.ts.map +1 -1
  14. package/dist/lending/public-data/lista/getMarketsFromChain.d.ts.map +1 -1
  15. package/dist/lending/public-data/silo-v2/convertPublic.d.ts +28 -0
  16. package/dist/lending/public-data/silo-v2/convertPublic.d.ts.map +1 -0
  17. package/dist/lending/public-data/silo-v2/fetchPublic.d.ts +82 -0
  18. package/dist/lending/public-data/silo-v2/fetchPublic.d.ts.map +1 -0
  19. package/dist/lending/public-data/silo-v2/publicCallBuild.d.ts +23 -0
  20. package/dist/lending/public-data/silo-v2/publicCallBuild.d.ts.map +1 -0
  21. package/dist/lending/public-data/silo-v2/publicCallParse.d.ts +25 -0
  22. package/dist/lending/public-data/silo-v2/publicCallParse.d.ts.map +1 -0
  23. package/dist/lending/public-data/silo-v3/convertPublic.d.ts +9 -0
  24. package/dist/lending/public-data/silo-v3/convertPublic.d.ts.map +1 -0
  25. package/dist/lending/public-data/silo-v3/publicCallBuild.d.ts +19 -0
  26. package/dist/lending/public-data/silo-v3/publicCallBuild.d.ts.map +1 -0
  27. package/dist/lending/public-data/silo-v3/publicCallParse.d.ts +9 -0
  28. package/dist/lending/public-data/silo-v3/publicCallParse.d.ts.map +1 -0
  29. package/dist/lending/user-data/abis.d.ts.map +1 -1
  30. package/dist/lending/user-data/fetch-balances/parse.d.ts.map +1 -1
  31. package/dist/lending/user-data/fetch-balances/prepare.d.ts.map +1 -1
  32. package/dist/lending/user-data/silo-v2/userCallBuild.d.ts +21 -0
  33. package/dist/lending/user-data/silo-v2/userCallBuild.d.ts.map +1 -0
  34. package/dist/lending/user-data/silo-v2/userCallParse.d.ts +23 -0
  35. package/dist/lending/user-data/silo-v2/userCallParse.d.ts.map +1 -0
  36. package/dist/lending/user-data/utils/types.d.ts +20 -0
  37. package/dist/lending/user-data/utils/types.d.ts.map +1 -1
  38. package/dist/prices/oracle-prices/fetchOraclePrices.d.ts.map +1 -1
  39. package/dist/prices/oracle-prices/fetchers/index.d.ts +2 -0
  40. package/dist/prices/oracle-prices/fetchers/index.d.ts.map +1 -1
  41. package/dist/prices/oracle-prices/fetchers/siloV2.d.ts +108 -0
  42. package/dist/prices/oracle-prices/fetchers/siloV2.d.ts.map +1 -0
  43. package/dist/prices/oracle-prices/fetchers/siloV2Graphql.d.ts +36 -0
  44. package/dist/prices/oracle-prices/fetchers/siloV2Graphql.d.ts.map +1 -0
  45. package/dist/prices/oracle-prices/fetchers/siloV3.d.ts +52 -0
  46. package/dist/prices/oracle-prices/fetchers/siloV3.d.ts.map +1 -0
  47. package/dist/prices/oracle-prices/fetchers/siloV3Graphql.d.ts +19 -0
  48. package/dist/prices/oracle-prices/fetchers/siloV3Graphql.d.ts.map +1 -0
  49. package/dist/prices/oracle-prices/index.d.ts +2 -0
  50. package/dist/prices/oracle-prices/index.d.ts.map +1 -1
  51. package/dist/utils/index.d.ts +1 -1
  52. package/dist/utils/index.d.ts.map +1 -1
  53. 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,14 @@ 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
+ }
7597
+ const siloV3ChainPairs = siloMarketsV3()?.[c] ?? [];
7598
+ for (const market of siloV3ChainPairs) {
7599
+ lenders.push(siloV3LenderKey(market.siloConfig));
7600
+ }
7547
7601
  const v4ChainSpokes = aaveV4Spokes()?.[c] ?? {};
7548
7602
  for (const spokeAddr of Object.keys(v4ChainSpokes)) {
7549
7603
  lenders.push(aaveV4SpokeLenderKey(spokeAddr));
@@ -13003,7 +13057,11 @@ function getListaMarketDataConverter(lender, chainId, prices, additionalYields =
13003
13057
  };
13004
13058
  const ltv = parseLtv(lltv);
13005
13059
  const metaCollateral = tokens[collateralAssetAddress] ?? collateralAsset;
13006
- const collateralMarketUid = createMarketUid(chainId, m, collateralAssetAddress);
13060
+ const collateralMarketUid = createMarketUid(
13061
+ chainId,
13062
+ m,
13063
+ collateralAssetAddress
13064
+ );
13007
13065
  data[m].data[collateralMarketUid] = {
13008
13066
  marketUid: collateralMarketUid,
13009
13067
  name: "Collateral " + (metaCollateral?.symbol ?? ""),
@@ -18553,6 +18611,400 @@ var getAaveV4ReservesDataConverter = (lender, chainId, prices, additionalYields,
18553
18611
  };
18554
18612
  return [converter, expectedCalls];
18555
18613
  };
18614
+
18615
+ // src/abis/silo-v2/Silo.ts
18616
+ var SiloAbi = [
18617
+ {
18618
+ type: "function",
18619
+ name: "totalAssets",
18620
+ stateMutability: "view",
18621
+ inputs: [],
18622
+ outputs: [{ name: "", type: "uint256" }]
18623
+ },
18624
+ {
18625
+ type: "function",
18626
+ name: "getDebtAssets",
18627
+ stateMutability: "view",
18628
+ inputs: [],
18629
+ outputs: [{ name: "", type: "uint256" }]
18630
+ },
18631
+ {
18632
+ type: "function",
18633
+ name: "getCollateralAssets",
18634
+ stateMutability: "view",
18635
+ inputs: [],
18636
+ outputs: [{ name: "", type: "uint256" }]
18637
+ },
18638
+ {
18639
+ type: "function",
18640
+ name: "asset",
18641
+ stateMutability: "view",
18642
+ inputs: [],
18643
+ outputs: [{ name: "", type: "address" }]
18644
+ },
18645
+ {
18646
+ type: "function",
18647
+ name: "balanceOf",
18648
+ stateMutability: "view",
18649
+ inputs: [{ name: "account", type: "address" }],
18650
+ outputs: [{ name: "", type: "uint256" }]
18651
+ },
18652
+ {
18653
+ type: "function",
18654
+ name: "convertToAssets",
18655
+ stateMutability: "view",
18656
+ inputs: [{ name: "shares", type: "uint256" }],
18657
+ outputs: [{ name: "", type: "uint256" }]
18658
+ },
18659
+ {
18660
+ type: "function",
18661
+ name: "maxRepay",
18662
+ stateMutability: "view",
18663
+ inputs: [{ name: "borrower", type: "address" }],
18664
+ outputs: [{ name: "", type: "uint256" }]
18665
+ }
18666
+ ];
18667
+ var SiloConvertToAssetsTypedAbi = [
18668
+ {
18669
+ type: "function",
18670
+ name: "convertToAssets",
18671
+ stateMutability: "view",
18672
+ inputs: [
18673
+ { name: "shares", type: "uint256" },
18674
+ { name: "assetType", type: "uint8" }
18675
+ ],
18676
+ outputs: [{ name: "", type: "uint256" }]
18677
+ }
18678
+ ];
18679
+
18680
+ // src/abis/silo-v2/SiloLens.ts
18681
+ var SiloLensAbi = [
18682
+ {
18683
+ type: "function",
18684
+ name: "getDepositAPR",
18685
+ stateMutability: "view",
18686
+ inputs: [{ name: "_silo", type: "address" }],
18687
+ outputs: [{ name: "depositAPR", type: "uint256" }]
18688
+ },
18689
+ {
18690
+ type: "function",
18691
+ name: "getBorrowAPR",
18692
+ stateMutability: "view",
18693
+ inputs: [{ name: "_silo", type: "address" }],
18694
+ outputs: [{ name: "borrowAPR", type: "uint256" }]
18695
+ },
18696
+ {
18697
+ type: "function",
18698
+ name: "getUtilization",
18699
+ stateMutability: "view",
18700
+ inputs: [{ name: "_silo", type: "address" }],
18701
+ outputs: [{ name: "utilization", type: "uint256" }]
18702
+ },
18703
+ {
18704
+ type: "function",
18705
+ name: "getRawLiquidity",
18706
+ stateMutability: "view",
18707
+ inputs: [{ name: "_silo", type: "address" }],
18708
+ outputs: [{ name: "liquidity", type: "uint256" }]
18709
+ }
18710
+ ];
18711
+
18712
+ // src/lending/public-data/silo-v2/publicCallBuild.ts
18713
+ var SILO_V2_CALLS_PER_SIDE = 2;
18714
+ var SILO_V2_CALLS_PER_PAIR = SILO_V2_CALLS_PER_SIDE * 2;
18715
+ function buildSiloV2LenderReserveCall(_chainId, lender) {
18716
+ const market = getSiloV2MarketEntry(_chainId, lender);
18717
+ if (!market) return [];
18718
+ const calls = [];
18719
+ for (const half of [market.silo0, market.silo1]) {
18720
+ calls.push(
18721
+ {
18722
+ address: half.silo,
18723
+ name: "totalAssets",
18724
+ params: [],
18725
+ abi: SiloAbi
18726
+ },
18727
+ {
18728
+ address: half.silo,
18729
+ name: "getDebtAssets",
18730
+ params: [],
18731
+ abi: SiloAbi
18732
+ }
18733
+ );
18734
+ }
18735
+ return calls;
18736
+ }
18737
+
18738
+ // src/lending/public-data/silo-v2/publicCallParse.ts
18739
+ var getSiloV2ReservesDataConverter = (lender, chainId, prices, additionalYields, tokenList = {}) => {
18740
+ const market = getSiloV2MarketEntry(chainId, lender);
18741
+ if (!market) return [() => void 0, 0];
18742
+ return [
18743
+ (data) => {
18744
+ if (!data || data.length !== SILO_V2_CALLS_PER_PAIR) return void 0;
18745
+ const out = {};
18746
+ const sides = [
18747
+ { self: market.silo0, other: market.silo1 },
18748
+ { self: market.silo1, other: market.silo0 }
18749
+ ];
18750
+ const toBigInt6 = (v) => {
18751
+ if (v === void 0 || v === null || v === "0x") return 0n;
18752
+ if (typeof v === "bigint") return v;
18753
+ try {
18754
+ return BigInt(v);
18755
+ } catch {
18756
+ return 0n;
18757
+ }
18758
+ };
18759
+ for (let s = 0; s < 2; s++) {
18760
+ const { self, other } = sides[s];
18761
+ const slot = s * SILO_V2_CALLS_PER_SIDE;
18762
+ const totalAssetsRaw = toBigInt6(data[slot]);
18763
+ const debtAssetsRaw = toBigInt6(data[slot + 1]);
18764
+ const decimals = self.decimals;
18765
+ const totalDeposits = Number(formatUnits(totalAssetsRaw, decimals));
18766
+ const totalDebt = Number(formatUnits(debtAssetsRaw, decimals));
18767
+ const totalLiquidity = totalDeposits - totalDebt;
18768
+ const utilization = totalDeposits > 0 ? totalDebt / totalDeposits : 0;
18769
+ const depositRatePct = 0;
18770
+ const variableBorrowRatePct = 0;
18771
+ const tokenAddrLc = self.token.toLowerCase();
18772
+ const assetMeta = tokenList[tokenAddrLc];
18773
+ const oracleKey = toOracleKey(assetMeta?.assetGroup ?? null) || toGenericPriceKey(tokenAddrLc, chainId);
18774
+ const price = prices[oracleKey] ?? 0;
18775
+ const collateralLt = Number(other.lt) / 1e18;
18776
+ const collateralMaxLtv = Number(other.maxLtv) / 1e18;
18777
+ const selfLt = Number(self.lt) / 1e18;
18778
+ const borrowingEnabled = collateralLt > 0;
18779
+ const collateralActive = selfLt > 0;
18780
+ const marketUid = createMarketUid(chainId, lender, self.silo);
18781
+ out[marketUid] = {
18782
+ marketUid,
18783
+ name: market.name ? `Silo V2 ${market.name} ${assetMeta?.symbol ?? ""}` : `Silo V2 ${assetMeta?.symbol ?? ""}`,
18784
+ poolId: self.silo.toLowerCase(),
18785
+ underlying: tokenAddrLc,
18786
+ asset: {
18787
+ ...assetMeta ?? {},
18788
+ chainId,
18789
+ decimals,
18790
+ address: tokenAddrLc,
18791
+ symbol: assetMeta?.symbol ?? self.symbol ?? "",
18792
+ name: assetMeta?.name ?? self.symbol ?? ""
18793
+ },
18794
+ // token amounts
18795
+ totalDeposits,
18796
+ totalDebt,
18797
+ totalDebtStable: 0,
18798
+ totalLiquidity,
18799
+ borrowLiquidity: totalLiquidity,
18800
+ // USD amounts
18801
+ totalDepositsUSD: totalDeposits * price,
18802
+ totalDebtUSD: totalDebt * price,
18803
+ totalDebtStableUSD: 0,
18804
+ totalLiquidityUSD: totalLiquidity * price,
18805
+ borrowLiquidityUSD: totalLiquidity * price,
18806
+ utilization,
18807
+ depositRate: depositRatePct,
18808
+ variableBorrowRate: variableBorrowRatePct,
18809
+ stableBorrowRate: 0,
18810
+ intrinsicYield: additionalYields?.intrinsicYields?.[assetMeta?.assetGroup] ?? 0,
18811
+ rewards: void 0,
18812
+ decimals,
18813
+ // Each Silo v2 per-pair lender represents exactly ONE pair, so
18814
+ // there is only one collateral counterparty (the OTHER silo) and
18815
+ // a single config entry. Key it as `'0'` to match the Morpho
18816
+ // convention (`config[0]` is the single mode with the market's
18817
+ // LLTV) — the counterparty silo address is still surfaced via
18818
+ // `params.counterpartySilo`.
18819
+ config: {
18820
+ 0: {
18821
+ category: 0,
18822
+ borrowCollateralFactor: collateralMaxLtv,
18823
+ collateralFactor: collateralLt,
18824
+ borrowFactor: 1,
18825
+ collateralDisabled: !borrowingEnabled,
18826
+ debtDisabled: !collateralActive
18827
+ }
18828
+ },
18829
+ collateralActive,
18830
+ borrowingEnabled,
18831
+ depositsEnabled: true,
18832
+ hasStable: false,
18833
+ isActive: true,
18834
+ isFrozen: false,
18835
+ params: {
18836
+ metadata: {
18837
+ silo: self.silo,
18838
+ counterpartySilo: other.silo,
18839
+ siloConfig: market.siloConfig,
18840
+ oracle: self.solvencyOracle,
18841
+ irm: self.interestRateModel,
18842
+ shareTokens: {
18843
+ collateral: self.collateralShareToken,
18844
+ protected: self.protectedShareToken,
18845
+ debt: self.debtShareToken
18846
+ },
18847
+ fees: {
18848
+ dao: self.daoFee,
18849
+ deployer: self.deployerFee,
18850
+ liquidation: self.liquidationFee,
18851
+ flashloan: self.flashloanFee
18852
+ }
18853
+ }
18854
+ }
18855
+ };
18856
+ }
18857
+ return { data: out, chainId };
18858
+ },
18859
+ SILO_V2_CALLS_PER_PAIR
18860
+ ];
18861
+ };
18862
+
18863
+ // src/lending/public-data/silo-v3/publicCallBuild.ts
18864
+ var SILO_V3_CALLS_PER_SIDE = 2;
18865
+ var SILO_V3_CALLS_PER_PAIR = SILO_V3_CALLS_PER_SIDE * 2;
18866
+ function buildSiloV3LenderReserveCall(_chainId, lender) {
18867
+ const market = getSiloV3MarketEntry(_chainId, lender);
18868
+ if (!market) return [];
18869
+ const calls = [];
18870
+ for (const half of [market.silo0, market.silo1]) {
18871
+ calls.push(
18872
+ {
18873
+ address: half.silo,
18874
+ name: "totalAssets",
18875
+ params: [],
18876
+ abi: SiloAbi
18877
+ },
18878
+ {
18879
+ address: half.silo,
18880
+ name: "getDebtAssets",
18881
+ params: [],
18882
+ abi: SiloAbi
18883
+ }
18884
+ );
18885
+ }
18886
+ return calls;
18887
+ }
18888
+
18889
+ // src/lending/public-data/silo-v3/publicCallParse.ts
18890
+ var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
18891
+ var getSiloV3ReservesDataConverter = (lender, chainId, prices, additionalYields, tokenList = {}) => {
18892
+ const market = getSiloV3MarketEntry(chainId, lender);
18893
+ if (!market) return [() => void 0, 0];
18894
+ return [
18895
+ (data) => {
18896
+ if (!data || data.length !== SILO_V3_CALLS_PER_PAIR) return void 0;
18897
+ const out = {};
18898
+ const sides = [
18899
+ { self: market.silo0, other: market.silo1 },
18900
+ { self: market.silo1, other: market.silo0 }
18901
+ ];
18902
+ const toBigInt6 = (v) => {
18903
+ if (v === void 0 || v === null || v === "0x") return 0n;
18904
+ if (typeof v === "bigint") return v;
18905
+ try {
18906
+ return BigInt(v);
18907
+ } catch {
18908
+ return 0n;
18909
+ }
18910
+ };
18911
+ for (let s = 0; s < 2; s++) {
18912
+ const { self, other } = sides[s];
18913
+ const slot = s * SILO_V3_CALLS_PER_SIDE;
18914
+ const totalAssetsRaw = toBigInt6(data[slot]);
18915
+ const debtAssetsRaw = toBigInt6(data[slot + 1]);
18916
+ const decimals = self.decimals;
18917
+ const totalDeposits = Number(formatUnits(totalAssetsRaw, decimals));
18918
+ const totalDebt = Number(formatUnits(debtAssetsRaw, decimals));
18919
+ const totalLiquidity = totalDeposits - totalDebt;
18920
+ const utilization = totalDeposits > 0 ? totalDebt / totalDeposits : 0;
18921
+ const depositRatePct = 0;
18922
+ const variableBorrowRatePct = 0;
18923
+ const tokenAddrLc = self.token.toLowerCase();
18924
+ const assetMeta = tokenList[tokenAddrLc];
18925
+ const oracleKey = toOracleKey(assetMeta?.assetGroup ?? null) || toGenericPriceKey(tokenAddrLc, chainId);
18926
+ const price = prices[oracleKey] ?? 0;
18927
+ const collateralLt = Number(other.lt) / 1e18;
18928
+ const collateralMaxLtv = Number(other.maxLtv) / 1e18;
18929
+ const selfLt = Number(self.lt) / 1e18;
18930
+ const borrowingEnabled = collateralLt > 0;
18931
+ const collateralActive = selfLt > 0;
18932
+ const marketUid = createMarketUid(chainId, lender, self.silo);
18933
+ out[marketUid] = {
18934
+ marketUid,
18935
+ name: market.name ? `Silo V3 ${market.name} ${assetMeta?.symbol ?? ""}` : `Silo V3 ${assetMeta?.symbol ?? ""}`,
18936
+ poolId: self.silo.toLowerCase(),
18937
+ underlying: tokenAddrLc,
18938
+ asset: {
18939
+ ...assetMeta ?? {},
18940
+ chainId,
18941
+ decimals,
18942
+ address: tokenAddrLc,
18943
+ symbol: assetMeta?.symbol ?? self.symbol ?? "",
18944
+ name: assetMeta?.name ?? self.symbol ?? ""
18945
+ },
18946
+ totalDeposits,
18947
+ totalDebt,
18948
+ totalDebtStable: 0,
18949
+ totalLiquidity,
18950
+ borrowLiquidity: totalLiquidity,
18951
+ totalDepositsUSD: totalDeposits * price,
18952
+ totalDebtUSD: totalDebt * price,
18953
+ totalDebtStableUSD: 0,
18954
+ totalLiquidityUSD: totalLiquidity * price,
18955
+ borrowLiquidityUSD: totalLiquidity * price,
18956
+ utilization,
18957
+ depositRate: depositRatePct,
18958
+ variableBorrowRate: variableBorrowRatePct,
18959
+ stableBorrowRate: 0,
18960
+ intrinsicYield: additionalYields?.intrinsicYields?.[assetMeta?.assetGroup] ?? 0,
18961
+ rewards: void 0,
18962
+ decimals,
18963
+ config: {
18964
+ 0: {
18965
+ category: 0,
18966
+ borrowCollateralFactor: collateralMaxLtv,
18967
+ collateralFactor: collateralLt,
18968
+ borrowFactor: 1,
18969
+ collateralDisabled: !borrowingEnabled,
18970
+ debtDisabled: !collateralActive
18971
+ }
18972
+ },
18973
+ collateralActive,
18974
+ borrowingEnabled,
18975
+ depositsEnabled: true,
18976
+ hasStable: false,
18977
+ isActive: true,
18978
+ isFrozen: false,
18979
+ params: {
18980
+ metadata: {
18981
+ silo: self.silo,
18982
+ counterpartySilo: other.silo,
18983
+ siloConfig: market.siloConfig,
18984
+ oracle: self.solvencyOracle || ZERO_ADDRESS,
18985
+ irm: self.interestRateModel || ZERO_ADDRESS,
18986
+ shareTokens: {
18987
+ collateral: self.collateralShareToken,
18988
+ protected: self.protectedShareToken,
18989
+ debt: self.debtShareToken
18990
+ },
18991
+ fees: {
18992
+ dao: self.daoFee,
18993
+ deployer: self.deployerFee,
18994
+ liquidation: self.liquidationFee,
18995
+ flashloan: self.flashloanFee
18996
+ }
18997
+ }
18998
+ }
18999
+ };
19000
+ }
19001
+ return { data: out, chainId };
19002
+ },
19003
+ SILO_V3_CALLS_PER_PAIR
19004
+ ];
19005
+ };
19006
+
19007
+ // src/lending/public-data/fetchLender.ts
18556
19008
  function getMorphoTypeMarketConverter(lender, chainId, prices, additionalYields, tokenList = {}, marketsOverride) {
18557
19009
  if (lender.startsWith("LISTA_DAO"))
18558
19010
  return getListaMarketDataConverter(
@@ -18587,6 +19039,8 @@ function buildLenderCall(chainId, lender) {
18587
19039
  return buildCompoundV2StyleLenderReserveCall(chainId, lender);
18588
19040
  if (isEulerType(lender)) return buildEulerV2LenderReserveCall(chainId, lender);
18589
19041
  if (isAaveV4Type(lender)) return buildAaveV4LenderReserveCall(chainId, lender);
19042
+ if (isSiloV2Type(lender)) return buildSiloV2LenderReserveCall(chainId, lender);
19043
+ if (isSiloV3Type(lender)) return buildSiloV3LenderReserveCall(chainId, lender);
18590
19044
  return [];
18591
19045
  }
18592
19046
  function getLenderDataConverter(lender, chainId, prices, additionalYields, tokenList = {}) {
@@ -18655,6 +19109,22 @@ function getLenderDataConverter(lender, chainId, prices, additionalYields, token
18655
19109
  additionalYields,
18656
19110
  tokenList
18657
19111
  );
19112
+ if (isSiloV2Type(lender))
19113
+ return getSiloV2ReservesDataConverter(
19114
+ lender,
19115
+ chainId,
19116
+ prices,
19117
+ additionalYields,
19118
+ tokenList
19119
+ );
19120
+ if (isSiloV3Type(lender))
19121
+ return getSiloV3ReservesDataConverter(
19122
+ lender,
19123
+ chainId,
19124
+ prices,
19125
+ additionalYields,
19126
+ tokenList
19127
+ );
18658
19128
  return [() => null, 0];
18659
19129
  }
18660
19130
  var getAbi = (lender) => {
@@ -18675,6 +19145,8 @@ var getAbi = (lender) => {
18675
19145
  if (isMorphoType(lender)) return MorphoLensAbi;
18676
19146
  if (isEulerType(lender)) return vaultLensAbi;
18677
19147
  if (isAaveV4Type(lender)) return [...AaveV4SpokeAbi, ...AaveV4OracleAbi, ...AaveV4HubAbi];
19148
+ if (isSiloV2Type(lender)) return [...SiloAbi, ...SiloLensAbi];
19149
+ if (isSiloV3Type(lender)) return [...SiloAbi, ...SiloLensAbi];
18678
19150
  if (isSumerType(lender)) return [...SumerLensAbi, ...SumerComptrollerAbi];
18679
19151
  if (lender === Lender.TAKARA) return [...TakaraMarketStateAbi];
18680
19152
  if (isCompoundV2Type(lender)) return VenusLensAbi;
@@ -18735,58 +19207,595 @@ var getLenderPublicData = async (chainId, lenders, prices, additionalYields, mul
18735
19207
  }
18736
19208
  return lenderData;
18737
19209
  };
18738
- async function getLenderDataFromApi(lender, chainId, prices, additionalYields, includeUnlisted = false) {
18739
- if (isMorphoType(lender))
18740
- return await fetchMorphoMarkets(chainId, includeUnlisted);
18741
- return {};
19210
+
19211
+ // src/lending/public-data/silo-v2/fetchPublic.ts
19212
+ var BASE_URL2 = "https://api-v3.silo.finance";
19213
+ var SILO_API_SUPPORTED_CHAIN_IDS = /* @__PURE__ */ new Set([
19214
+ "1",
19215
+ // Ethereum
19216
+ "42161",
19217
+ // Arbitrum
19218
+ "43114",
19219
+ // Avalanche
19220
+ "50",
19221
+ // XDC
19222
+ "1776"
19223
+ // Injective
19224
+ ]);
19225
+ var query2 = (chainId, limit) => `
19226
+ query GetSilos {
19227
+ silos(where: {chainId_in: [${chainId}]}, limit: ${limit}) {
19228
+ items {
19229
+ id
19230
+ chainId
19231
+ configAddress
19232
+ name
19233
+ protocol {
19234
+ protocolVersion
19235
+ }
19236
+ market1 {
19237
+ index
19238
+ inputTokenId
19239
+ inputToken { id symbol decimals }
19240
+ lt
19241
+ maxLtv
19242
+ liquidationTargetLtv
19243
+ daoFee
19244
+ deployerFee
19245
+ liquidationFee
19246
+ flashLoanFee
19247
+ borrowRate
19248
+ depositRate
19249
+ supply
19250
+ borrowed
19251
+ supplyUsd
19252
+ borrowedUsd
19253
+ liquidityUsd
19254
+ utilization
19255
+ solvencyOracleAddress
19256
+ maxLtvOracleAddress
19257
+ interestRateModelId
19258
+ sTokenId
19259
+ spTokenId
19260
+ dTokenId
19261
+ solvencyOracle {
19262
+ id
19263
+ quote
19264
+ quoteTimestamp
19265
+ baseTokenId
19266
+ quoteTokenId
19267
+ }
19268
+ maxLtvOracle {
19269
+ id
19270
+ quote
19271
+ quoteTimestamp
19272
+ }
19273
+ }
19274
+ market2 {
19275
+ index
19276
+ inputTokenId
19277
+ inputToken { id symbol decimals }
19278
+ lt
19279
+ maxLtv
19280
+ liquidationTargetLtv
19281
+ daoFee
19282
+ deployerFee
19283
+ liquidationFee
19284
+ flashLoanFee
19285
+ borrowRate
19286
+ depositRate
19287
+ supply
19288
+ borrowed
19289
+ supplyUsd
19290
+ borrowedUsd
19291
+ liquidityUsd
19292
+ utilization
19293
+ solvencyOracleAddress
19294
+ maxLtvOracleAddress
19295
+ interestRateModelId
19296
+ sTokenId
19297
+ spTokenId
19298
+ dTokenId
19299
+ solvencyOracle {
19300
+ id
19301
+ quote
19302
+ quoteTimestamp
19303
+ baseTokenId
19304
+ quoteTokenId
19305
+ }
19306
+ maxLtvOracle {
19307
+ id
19308
+ quote
19309
+ quoteTimestamp
19310
+ }
19311
+ }
19312
+ }
19313
+ }
18742
19314
  }
18743
- function convertLenderDataFromApi(lender, chainId, data, prices, additionalYields, list = {}) {
18744
- if (isMorphoType(lender))
18745
- return convertMarketsToMorphoResponse(data, chainId, additionalYields, list);
18746
- return {};
19315
+ `;
19316
+ var liteQuery = (chainId, limit) => `
19317
+ query GetSilosLite {
19318
+ silos(where: {chainId_in: [${chainId}]}, limit: ${limit}) {
19319
+ items {
19320
+ configAddress
19321
+ protocol { protocolVersion }
19322
+ market1 {
19323
+ index
19324
+ inputTokenId
19325
+ supply
19326
+ borrowed
19327
+ supplyUsd
19328
+ borrowedUsd
19329
+ solvencyOracleAddress
19330
+ solvencyOracle { quote quoteTokenId }
19331
+ }
19332
+ market2 {
19333
+ index
19334
+ inputTokenId
19335
+ supply
19336
+ borrowed
19337
+ supplyUsd
19338
+ borrowedUsd
19339
+ solvencyOracleAddress
19340
+ solvencyOracle { quote quoteTokenId }
19341
+ }
19342
+ }
19343
+ }
18747
19344
  }
18748
- var getLenderPublicDataViaApi = async (chainId, lenders, prices, additionalYields, tokenList = async () => {
18749
- return {};
18750
- }, includeUnlisted = false) => {
18751
- let promises = [];
18752
- for (const lender of lenders) {
18753
- promises.push(
18754
- getLenderDataFromApi(
18755
- lender,
18756
- chainId,
18757
- prices,
18758
- additionalYields,
18759
- includeUnlisted
18760
- )
19345
+ `;
19346
+ async function fetchSiloMarketsLite(chainId, options) {
19347
+ if (!SILO_API_SUPPORTED_CHAIN_IDS.has(chainId)) return [];
19348
+ const limit = options?.limit ?? 500;
19349
+ const response = await fetch(BASE_URL2, {
19350
+ method: "POST",
19351
+ headers: { "Content-Type": "application/json" },
19352
+ body: JSON.stringify({ query: liteQuery(chainId, limit) })
19353
+ });
19354
+ if (!response.ok) {
19355
+ throw new Error(
19356
+ `[silo-api] Network error: ${response.status} - ${response.statusText}`
18761
19357
  );
18762
19358
  }
18763
- const settled = await Promise.allSettled([tokenList(), ...promises]);
18764
- const listResult = settled[0];
18765
- const list = listResult.status === "fulfilled" ? listResult.value : {};
18766
- if (listResult.status === "rejected") {
18767
- console.warn(
18768
- `[lending] tokenList fetch failed on chain ${chainId}:`,
18769
- listResult.reason
19359
+ const payload = await response.json();
19360
+ if (payload?.errors?.length) {
19361
+ throw new Error(
19362
+ `[silo-api] GraphQL error: ${payload.errors.map((e) => e?.message).join("; ")}`
18770
19363
  );
18771
19364
  }
18772
- const lenderData = {};
18773
- for (let i = 0; i < lenders.length; i++) {
18774
- try {
18775
- const result = settled[i + 1];
18776
- if (result.status === "rejected") {
18777
- console.warn(
18778
- `[lending] API fetch failed for ${lenders[i]} on chain ${chainId}:`,
18779
- result.reason?.message ?? result.reason
18780
- );
18781
- continue;
18782
- }
18783
- const lender = lenders[i];
18784
- if (isMultiMarket(lender)) {
18785
- const dataObtained = result.value;
18786
- const converted = convertLenderDataFromApi(
18787
- lender,
18788
- chainId,
18789
- dataObtained,
19365
+ const items = payload?.data?.silos?.items ?? [];
19366
+ if (!options?.protocolVersion) return items;
19367
+ return items.filter(
19368
+ (s) => s.protocol?.protocolVersion === options.protocolVersion
19369
+ );
19370
+ }
19371
+ async function fetchSiloMarkets(chainId, options) {
19372
+ if (!SILO_API_SUPPORTED_CHAIN_IDS.has(chainId)) return [];
19373
+ const limit = options?.limit ?? 500;
19374
+ const response = await fetch(BASE_URL2, {
19375
+ method: "POST",
19376
+ headers: { "Content-Type": "application/json" },
19377
+ body: JSON.stringify({ query: query2(chainId, limit) })
19378
+ });
19379
+ if (!response.ok) {
19380
+ throw new Error(
19381
+ `[silo-api] Network error: ${response.status} - ${response.statusText}`
19382
+ );
19383
+ }
19384
+ const payload = await response.json();
19385
+ if (payload?.errors?.length) {
19386
+ throw new Error(
19387
+ `[silo-api] GraphQL error: ${payload.errors.map((e) => e?.message).join("; ")}`
19388
+ );
19389
+ }
19390
+ const items = payload?.data?.silos?.items ?? [];
19391
+ if (!options?.protocolVersion) return items;
19392
+ return items.filter(
19393
+ (s) => s.protocol?.protocolVersion === options.protocolVersion
19394
+ );
19395
+ }
19396
+
19397
+ // src/lending/public-data/silo-v2/convertPublic.ts
19398
+ function convertSiloMarketsToPublicResponse(apiItems, chainId, prices, additionalYields = {
19399
+ intrinsicYields: {},
19400
+ lenderRewards: {},
19401
+ loaded: true
19402
+ }, tokenList = {}) {
19403
+ const out = {};
19404
+ for (const item of apiItems) {
19405
+ if (item.protocol && item.protocol.protocolVersion !== "v2") continue;
19406
+ let lenderKey;
19407
+ try {
19408
+ lenderKey = siloV2LenderKey(item.configAddress);
19409
+ } catch {
19410
+ continue;
19411
+ }
19412
+ const registryEntry = getSiloV2MarketEntry(chainId, lenderKey);
19413
+ if (!registryEntry) continue;
19414
+ const [apiSide0, apiSide1] = item.market1.index === 0 ? [item.market1, item.market2] : [item.market2, item.market1];
19415
+ const sides = [
19416
+ { api: apiSide0, self: registryEntry.silo0, other: registryEntry.silo1 },
19417
+ { api: apiSide1, self: registryEntry.silo1, other: registryEntry.silo0 }
19418
+ ];
19419
+ const data = {};
19420
+ for (const { api, self, other } of sides) {
19421
+ const decimals = api.inputToken?.decimals ?? self.decimals;
19422
+ const tokenAddrLc = (api.inputTokenId ?? self.token).toLowerCase();
19423
+ const totalDeposits = safeNumber(api.supply);
19424
+ const totalDebt = safeNumber(api.borrowed);
19425
+ const totalLiquidity = totalDeposits - totalDebt;
19426
+ const utilization = totalDeposits > 0 ? totalDebt / totalDeposits : safeNumber(api.utilization);
19427
+ const variableBorrowRatePct = safeNumber(api.borrowRate) * 100;
19428
+ const depositRatePct = safeNumber(api.depositRate) * 100;
19429
+ const assetMeta = tokenList[tokenAddrLc];
19430
+ const oracleKey = toOracleKey(assetMeta?.assetGroup ?? null) || toGenericPriceKey(tokenAddrLc, chainId);
19431
+ const fallbackPrice = prices[oracleKey] ?? 0;
19432
+ const totalDepositsUSD = api.supplyUsd != null && api.supplyUsd > 0 ? api.supplyUsd : totalDeposits * fallbackPrice;
19433
+ const totalDebtUSD = api.borrowedUsd != null && api.borrowedUsd > 0 ? api.borrowedUsd : totalDebt * fallbackPrice;
19434
+ const totalLiquidityUSD = Math.max(totalDepositsUSD - totalDebtUSD, 0);
19435
+ const collateralLt = safeLtvOrFee(api, "lt", other.lt);
19436
+ const collateralMaxLtv = safeLtvOrFee(api, "maxLtv", other.maxLtv);
19437
+ const selfLt = bigintToLtv(api.lt ?? self.lt);
19438
+ const collateralLtFromApi = sides[0].api === api ? bigintToLtv(apiSide1.lt) : bigintToLtv(apiSide0.lt);
19439
+ const collateralMaxLtvFromApi = sides[0].api === api ? bigintToLtv(apiSide1.maxLtv) : bigintToLtv(apiSide0.maxLtv);
19440
+ const borrowingEnabled = (collateralLtFromApi || collateralLt) > 0;
19441
+ const collateralActive = selfLt > 0;
19442
+ const siloAddrLc = self.silo.toLowerCase();
19443
+ const marketUid = createMarketUid(chainId, lenderKey, siloAddrLc);
19444
+ data[marketUid] = {
19445
+ marketUid,
19446
+ name: item.name ? `Silo V2 ${item.name} ${assetMeta?.symbol ?? api.inputToken?.symbol ?? ""}` : `Silo V2 ${assetMeta?.symbol ?? api.inputToken?.symbol ?? ""}`,
19447
+ poolId: siloAddrLc,
19448
+ underlying: tokenAddrLc,
19449
+ asset: {
19450
+ ...assetMeta ?? {},
19451
+ chainId,
19452
+ decimals,
19453
+ address: tokenAddrLc,
19454
+ symbol: assetMeta?.symbol ?? api.inputToken?.symbol ?? self.symbol ?? "",
19455
+ name: assetMeta?.name ?? api.inputToken?.symbol ?? self.symbol ?? ""
19456
+ },
19457
+ // token amounts
19458
+ totalDeposits,
19459
+ totalDebt,
19460
+ totalDebtStable: 0,
19461
+ totalLiquidity,
19462
+ borrowLiquidity: totalLiquidity,
19463
+ // USD amounts
19464
+ totalDepositsUSD,
19465
+ totalDebtUSD,
19466
+ totalDebtStableUSD: 0,
19467
+ totalLiquidityUSD,
19468
+ borrowLiquidityUSD: totalLiquidityUSD,
19469
+ utilization,
19470
+ depositRate: depositRatePct,
19471
+ variableBorrowRate: variableBorrowRatePct,
19472
+ stableBorrowRate: 0,
19473
+ intrinsicYield: additionalYields?.intrinsicYields?.[assetMeta?.assetGroup] ?? 0,
19474
+ rewards: void 0,
19475
+ decimals,
19476
+ config: {
19477
+ 0: {
19478
+ category: 0,
19479
+ borrowCollateralFactor: collateralMaxLtvFromApi || collateralMaxLtv,
19480
+ collateralFactor: collateralLtFromApi || collateralLt,
19481
+ borrowFactor: 1,
19482
+ collateralDisabled: !borrowingEnabled,
19483
+ debtDisabled: !collateralActive
19484
+ }
19485
+ },
19486
+ collateralActive,
19487
+ borrowingEnabled,
19488
+ depositsEnabled: true,
19489
+ hasStable: false,
19490
+ isActive: true,
19491
+ isFrozen: false,
19492
+ params: {
19493
+ metadata: {
19494
+ silo: self.silo.toLowerCase(),
19495
+ counterpartySilo: other.silo.toLowerCase(),
19496
+ siloConfig: registryEntry.siloConfig.toLowerCase(),
19497
+ oracle: (api.solvencyOracleAddress ?? self.solvencyOracle).toLowerCase(),
19498
+ irm: (api.interestRateModelId ?? self.interestRateModel).toLowerCase(),
19499
+ shareTokens: {
19500
+ collateral: self.collateralShareToken,
19501
+ protected: self.protectedShareToken,
19502
+ debt: self.debtShareToken
19503
+ },
19504
+ fees: {
19505
+ dao: api.daoFee ?? self.daoFee,
19506
+ deployer: api.deployerFee ?? self.deployerFee,
19507
+ liquidation: api.liquidationFee ?? self.liquidationFee,
19508
+ flashloan: api.flashLoanFee ?? self.flashloanFee
19509
+ }
19510
+ }
19511
+ }
19512
+ };
19513
+ }
19514
+ out[lenderKey] = { data, chainId };
19515
+ }
19516
+ return out;
19517
+ }
19518
+ function safeNumber(v) {
19519
+ if (v == null) return 0;
19520
+ const n = typeof v === "number" ? v : Number(v);
19521
+ return Number.isFinite(n) ? n : 0;
19522
+ }
19523
+ function bigintToLtv(v) {
19524
+ if (!v) return 0;
19525
+ try {
19526
+ return Number(BigInt(v)) / 1e18;
19527
+ } catch {
19528
+ const n = Number(v);
19529
+ return Number.isFinite(n) ? n / 1e18 : 0;
19530
+ }
19531
+ }
19532
+ function safeLtvOrFee(api, field5, fallback) {
19533
+ return bigintToLtv(api[field5] ?? fallback);
19534
+ }
19535
+
19536
+ // src/lending/public-data/silo-v3/convertPublic.ts
19537
+ var ZERO_ADDRESS2 = "0x0000000000000000000000000000000000000000";
19538
+ function convertSiloV3MarketsToPublicResponse(apiItems, chainId, prices, additionalYields = {
19539
+ intrinsicYields: {},
19540
+ lenderRewards: {},
19541
+ loaded: true
19542
+ }, tokenList = {}) {
19543
+ const out = {};
19544
+ for (const item of apiItems) {
19545
+ if (item.protocol && item.protocol.protocolVersion !== "v3") continue;
19546
+ let lenderKey;
19547
+ try {
19548
+ lenderKey = siloV3LenderKey(item.configAddress);
19549
+ } catch {
19550
+ continue;
19551
+ }
19552
+ const registryEntry = getSiloV3MarketEntry(chainId, lenderKey);
19553
+ if (!registryEntry) continue;
19554
+ const [apiSide0, apiSide1] = item.market1.index === 0 ? [item.market1, item.market2] : [item.market2, item.market1];
19555
+ const sides = [
19556
+ { api: apiSide0, self: registryEntry.silo0, other: registryEntry.silo1 },
19557
+ { api: apiSide1, self: registryEntry.silo1, other: registryEntry.silo0 }
19558
+ ];
19559
+ const data = {};
19560
+ for (const { api, self, other } of sides) {
19561
+ const decimals = api.inputToken?.decimals ?? self.decimals;
19562
+ const tokenAddrLc = (api.inputTokenId ?? self.token).toLowerCase();
19563
+ const totalDeposits = safeNumber2(api.supply);
19564
+ const totalDebt = safeNumber2(api.borrowed);
19565
+ const totalLiquidity = totalDeposits - totalDebt;
19566
+ const utilization = totalDeposits > 0 ? totalDebt / totalDeposits : safeNumber2(api.utilization);
19567
+ const variableBorrowRatePct = safeNumber2(api.borrowRate) * 100;
19568
+ const depositRatePct = safeNumber2(api.depositRate) * 100;
19569
+ const assetMeta = tokenList[tokenAddrLc];
19570
+ const oracleKey = toOracleKey(assetMeta?.assetGroup ?? null) || toGenericPriceKey(tokenAddrLc, chainId);
19571
+ const fallbackPrice = prices[oracleKey] ?? 0;
19572
+ const totalDepositsUSD = api.supplyUsd != null && api.supplyUsd > 0 ? api.supplyUsd : totalDeposits * fallbackPrice;
19573
+ const totalDebtUSD = api.borrowedUsd != null && api.borrowedUsd > 0 ? api.borrowedUsd : totalDebt * fallbackPrice;
19574
+ const totalLiquidityUSD = Math.max(totalDepositsUSD - totalDebtUSD, 0);
19575
+ const collateralLt = safeLtvOrFee2(api, "lt", other.lt);
19576
+ const collateralMaxLtv = safeLtvOrFee2(api, "maxLtv", other.maxLtv);
19577
+ const selfLt = bigintToLtv2(api.lt ?? self.lt);
19578
+ const collateralLtFromApi = sides[0].api === api ? bigintToLtv2(apiSide1.lt) : bigintToLtv2(apiSide0.lt);
19579
+ const collateralMaxLtvFromApi = sides[0].api === api ? bigintToLtv2(apiSide1.maxLtv) : bigintToLtv2(apiSide0.maxLtv);
19580
+ const borrowingEnabled = (collateralLtFromApi || collateralLt) > 0;
19581
+ const collateralActive = selfLt > 0;
19582
+ const siloAddrLc = self.silo.toLowerCase();
19583
+ const marketUid = createMarketUid(chainId, lenderKey, siloAddrLc);
19584
+ data[marketUid] = {
19585
+ marketUid,
19586
+ name: item.name ? `Silo V3 ${item.name} ${assetMeta?.symbol ?? api.inputToken?.symbol ?? ""}` : `Silo V3 ${assetMeta?.symbol ?? api.inputToken?.symbol ?? ""}`,
19587
+ poolId: siloAddrLc,
19588
+ underlying: tokenAddrLc,
19589
+ asset: {
19590
+ ...assetMeta ?? {},
19591
+ chainId,
19592
+ decimals,
19593
+ address: tokenAddrLc,
19594
+ symbol: assetMeta?.symbol ?? api.inputToken?.symbol ?? self.symbol ?? "",
19595
+ name: assetMeta?.name ?? api.inputToken?.symbol ?? self.symbol ?? ""
19596
+ },
19597
+ totalDeposits,
19598
+ totalDebt,
19599
+ totalDebtStable: 0,
19600
+ totalLiquidity,
19601
+ borrowLiquidity: totalLiquidity,
19602
+ totalDepositsUSD,
19603
+ totalDebtUSD,
19604
+ totalDebtStableUSD: 0,
19605
+ totalLiquidityUSD,
19606
+ borrowLiquidityUSD: totalLiquidityUSD,
19607
+ utilization,
19608
+ depositRate: depositRatePct,
19609
+ variableBorrowRate: variableBorrowRatePct,
19610
+ stableBorrowRate: 0,
19611
+ intrinsicYield: additionalYields?.intrinsicYields?.[assetMeta?.assetGroup] ?? 0,
19612
+ rewards: void 0,
19613
+ decimals,
19614
+ config: {
19615
+ 0: {
19616
+ category: 0,
19617
+ borrowCollateralFactor: collateralMaxLtvFromApi || collateralMaxLtv,
19618
+ collateralFactor: collateralLtFromApi || collateralLt,
19619
+ borrowFactor: 1,
19620
+ collateralDisabled: !borrowingEnabled,
19621
+ debtDisabled: !collateralActive
19622
+ }
19623
+ },
19624
+ collateralActive,
19625
+ borrowingEnabled,
19626
+ depositsEnabled: true,
19627
+ hasStable: false,
19628
+ isActive: true,
19629
+ isFrozen: false,
19630
+ params: {
19631
+ metadata: {
19632
+ silo: self.silo.toLowerCase(),
19633
+ counterpartySilo: other.silo.toLowerCase(),
19634
+ siloConfig: registryEntry.siloConfig.toLowerCase(),
19635
+ oracle: (api.solvencyOracleAddress || self.solvencyOracle || ZERO_ADDRESS2).toLowerCase(),
19636
+ irm: (api.interestRateModelId || self.interestRateModel || ZERO_ADDRESS2).toLowerCase(),
19637
+ shareTokens: {
19638
+ collateral: self.collateralShareToken,
19639
+ protected: self.protectedShareToken,
19640
+ debt: self.debtShareToken
19641
+ },
19642
+ fees: {
19643
+ dao: api.daoFee ?? self.daoFee,
19644
+ deployer: api.deployerFee ?? self.deployerFee,
19645
+ liquidation: api.liquidationFee ?? self.liquidationFee,
19646
+ flashloan: api.flashLoanFee ?? self.flashloanFee
19647
+ }
19648
+ }
19649
+ }
19650
+ };
19651
+ }
19652
+ out[lenderKey] = { data, chainId };
19653
+ }
19654
+ return out;
19655
+ }
19656
+ function safeNumber2(v) {
19657
+ if (v == null) return 0;
19658
+ const n = typeof v === "number" ? v : Number(v);
19659
+ return Number.isFinite(n) ? n : 0;
19660
+ }
19661
+ function bigintToLtv2(v) {
19662
+ if (!v) return 0;
19663
+ try {
19664
+ return Number(BigInt(v)) / 1e18;
19665
+ } catch {
19666
+ const n = Number(v);
19667
+ return Number.isFinite(n) ? n / 1e18 : 0;
19668
+ }
19669
+ }
19670
+ function safeLtvOrFee2(api, field5, fallback) {
19671
+ return bigintToLtv2(api[field5] ?? fallback);
19672
+ }
19673
+
19674
+ // src/lending/public-data/fetchLenderExt.ts
19675
+ async function getLenderDataFromApi(lender, chainId, prices, additionalYields, includeUnlisted = false) {
19676
+ if (isMorphoType(lender))
19677
+ return await fetchMorphoMarkets(chainId, includeUnlisted);
19678
+ return {};
19679
+ }
19680
+ function convertLenderDataFromApi(lender, chainId, data, prices, additionalYields, list = {}) {
19681
+ if (isMorphoType(lender))
19682
+ return convertMarketsToMorphoResponse(data, chainId, additionalYields, list);
19683
+ return {};
19684
+ }
19685
+ var getLenderPublicDataViaApi = async (chainId, lenders, prices, additionalYields, tokenList = async () => {
19686
+ return {};
19687
+ }, includeUnlisted = false) => {
19688
+ const siloV2Lenders = lenders.filter((l) => isSiloV2Type(l));
19689
+ const siloV3Lenders = lenders.filter((l) => isSiloV3Type(l));
19690
+ const otherLenders = lenders.filter(
19691
+ (l) => !isSiloV2Type(l) && !isSiloV3Type(l)
19692
+ );
19693
+ const siloV2Promise = siloV2Lenders.length > 0 ? fetchSiloMarkets(chainId, { protocolVersion: "v2" }).then((items) => ({
19694
+ __silo_items__: items
19695
+ })) : Promise.resolve({});
19696
+ const siloV3Promise = siloV3Lenders.length > 0 ? fetchSiloMarkets(chainId, { protocolVersion: "v3" }).then((items) => ({
19697
+ __silo_items__: items
19698
+ })) : Promise.resolve({});
19699
+ let promises = [];
19700
+ for (const lender of otherLenders) {
19701
+ promises.push(
19702
+ getLenderDataFromApi(
19703
+ lender,
19704
+ chainId,
19705
+ prices,
19706
+ additionalYields,
19707
+ includeUnlisted
19708
+ )
19709
+ );
19710
+ }
19711
+ const settled = await Promise.allSettled([
19712
+ tokenList(),
19713
+ siloV2Promise,
19714
+ siloV3Promise,
19715
+ ...promises
19716
+ ]);
19717
+ const listResult = settled[0];
19718
+ const list = listResult.status === "fulfilled" ? listResult.value : {};
19719
+ if (listResult.status === "rejected") {
19720
+ console.warn(
19721
+ `[lending] tokenList fetch failed on chain ${chainId}:`,
19722
+ listResult.reason
19723
+ );
19724
+ }
19725
+ const lenderData = {};
19726
+ const siloV2Result = settled[1];
19727
+ if (siloV2Lenders.length > 0) {
19728
+ if (siloV2Result.status === "fulfilled") {
19729
+ const items = siloV2Result.value?.__silo_items__ ?? [];
19730
+ try {
19731
+ const converted = convertSiloMarketsToPublicResponse(
19732
+ items,
19733
+ chainId,
19734
+ prices,
19735
+ additionalYields,
19736
+ list
19737
+ );
19738
+ for (const lk of siloV2Lenders) {
19739
+ if (converted[lk]) lenderData[lk] = converted[lk];
19740
+ }
19741
+ } catch (e) {
19742
+ console.warn(
19743
+ `[lending] Silo v2 API convert failed on chain ${chainId}:`,
19744
+ e?.message ?? e
19745
+ );
19746
+ }
19747
+ } else {
19748
+ console.warn(
19749
+ `[lending] Silo v2 API fetch failed on chain ${chainId}:`,
19750
+ siloV2Result.reason?.message ?? siloV2Result.reason
19751
+ );
19752
+ }
19753
+ }
19754
+ const siloV3Result = settled[2];
19755
+ if (siloV3Lenders.length > 0) {
19756
+ if (siloV3Result.status === "fulfilled") {
19757
+ const items = siloV3Result.value?.__silo_items__ ?? [];
19758
+ try {
19759
+ const converted = convertSiloV3MarketsToPublicResponse(
19760
+ items,
19761
+ chainId,
19762
+ prices,
19763
+ additionalYields,
19764
+ list
19765
+ );
19766
+ for (const lk of siloV3Lenders) {
19767
+ if (converted[lk]) lenderData[lk] = converted[lk];
19768
+ }
19769
+ } catch (e) {
19770
+ console.warn(
19771
+ `[lending] Silo v3 API convert failed on chain ${chainId}:`,
19772
+ e?.message ?? e
19773
+ );
19774
+ }
19775
+ } else {
19776
+ console.warn(
19777
+ `[lending] Silo v3 API fetch failed on chain ${chainId}:`,
19778
+ siloV3Result.reason?.message ?? siloV3Result.reason
19779
+ );
19780
+ }
19781
+ }
19782
+ for (let i = 0; i < otherLenders.length; i++) {
19783
+ try {
19784
+ const result = settled[i + 3];
19785
+ if (result.status === "rejected") {
19786
+ console.warn(
19787
+ `[lending] API fetch failed for ${otherLenders[i]} on chain ${chainId}:`,
19788
+ result.reason?.message ?? result.reason
19789
+ );
19790
+ continue;
19791
+ }
19792
+ const lender = otherLenders[i];
19793
+ if (isMultiMarket(lender)) {
19794
+ const dataObtained = result.value;
19795
+ const converted = convertLenderDataFromApi(
19796
+ lender,
19797
+ chainId,
19798
+ dataObtained,
18790
19799
  prices,
18791
19800
  additionalYields,
18792
19801
  list
@@ -18808,7 +19817,7 @@ var getLenderPublicDataViaApi = async (chainId, lenders, prices, additionalYield
18808
19817
  }
18809
19818
  return lenderData;
18810
19819
  };
18811
- function lenderCanUseApi(lender, chainId) {
19820
+ function lenderApiOnly(lender, chainId) {
18812
19821
  if (lender === Lender.MORPHO_BLUE) {
18813
19822
  if (chainId === Chain.SONEIUM) return false;
18814
19823
  if (chainId === Chain.HEMI_NETWORK) return false;
@@ -18819,42 +19828,56 @@ function lenderCanUseApi(lender, chainId) {
18819
19828
  }
18820
19829
  return false;
18821
19830
  }
19831
+ function lenderApiWithOnChainFallback(lender, chainId) {
19832
+ if (isSiloV2Type(lender) || isSiloV3Type(lender)) {
19833
+ return SILO_API_SUPPORTED_CHAIN_IDS.has(chainId);
19834
+ }
19835
+ return false;
19836
+ }
18822
19837
  var getLenderPublicDataAll = async (chainId, lenders, prices, additionalYields, multicallRetry, tokenList, includeUnlistedMorphoMarkets = false) => {
18823
- const lendersApi = lenders.filter((l) => lenderCanUseApi(l, chainId));
18824
- const lendersOnChain = lenders.filter((l) => !lenderCanUseApi(l, chainId));
18825
- const onChain = getLenderPublicData(
18826
- chainId,
18827
- lendersOnChain,
18828
- prices,
18829
- additionalYields,
18830
- multicallRetry,
18831
- tokenList
18832
- );
18833
- const api = getLenderPublicDataViaApi(
18834
- chainId,
18835
- lendersApi,
18836
- prices,
18837
- additionalYields,
18838
- tokenList,
18839
- includeUnlistedMorphoMarkets
19838
+ const lendersApi = lenders.filter(
19839
+ (l) => lenderApiOnly(l, chainId) || lenderApiWithOnChainFallback(l, chainId)
18840
19840
  );
18841
- const [onChainResult, apiResult] = await Promise.allSettled([
18842
- onChain,
18843
- api
18844
- ]);
18845
- const onChainRes = onChainResult.status === "fulfilled" ? onChainResult.value : {};
18846
- const apiRes = apiResult.status === "fulfilled" ? apiResult.value : {};
18847
- if (onChainResult.status === "rejected") {
18848
- console.warn(
18849
- `[lending] on-chain fetch failed for chain ${chainId}:`,
18850
- onChainResult.reason?.message ?? onChainResult.reason
18851
- );
19841
+ let apiRes = {};
19842
+ if (lendersApi.length > 0) {
19843
+ try {
19844
+ apiRes = await getLenderPublicDataViaApi(
19845
+ chainId,
19846
+ lendersApi,
19847
+ prices,
19848
+ additionalYields,
19849
+ tokenList,
19850
+ includeUnlistedMorphoMarkets
19851
+ );
19852
+ } catch (e) {
19853
+ console.warn(
19854
+ `[lending] API fetch failed for chain ${chainId}:`,
19855
+ e?.message ?? e
19856
+ );
19857
+ }
18852
19858
  }
18853
- if (apiResult.status === "rejected") {
18854
- console.warn(
18855
- `[lending] API fetch failed for chain ${chainId}:`,
18856
- apiResult.reason?.message ?? apiResult.reason
18857
- );
19859
+ const lendersOnChain = lenders.filter((l) => {
19860
+ if (lenderApiOnly(l, chainId)) return false;
19861
+ if (lenderApiWithOnChainFallback(l, chainId) && apiRes[l]) return false;
19862
+ return true;
19863
+ });
19864
+ let onChainRes = {};
19865
+ if (lendersOnChain.length > 0) {
19866
+ try {
19867
+ onChainRes = await getLenderPublicData(
19868
+ chainId,
19869
+ lendersOnChain,
19870
+ prices,
19871
+ additionalYields,
19872
+ multicallRetry,
19873
+ tokenList
19874
+ );
19875
+ } catch (e) {
19876
+ console.warn(
19877
+ `[lending] on-chain fetch failed for chain ${chainId}:`,
19878
+ e?.message ?? e
19879
+ );
19880
+ }
18858
19881
  }
18859
19882
  return { ...onChainRes, ...apiRes };
18860
19883
  };
@@ -19134,7 +20157,7 @@ function fetchEulerSubAccountIndexes(chainId, owner) {
19134
20157
  async function fetchSubAccountsFromSubgraph(chainId, owner) {
19135
20158
  const url = EULER_SUBGRAPH_URLS[chainId];
19136
20159
  if (!url) return [0];
19137
- const query2 = `{
20160
+ const query3 = `{
19138
20161
  accounts(first: 100, where: { owner: "${owner.toLowerCase()}" }) {
19139
20162
  id
19140
20163
  subAccount
@@ -19143,7 +20166,7 @@ async function fetchSubAccountsFromSubgraph(chainId, owner) {
19143
20166
  const response = await fetch(url, {
19144
20167
  method: "POST",
19145
20168
  headers: { "Content-Type": "application/json" },
19146
- body: JSON.stringify({ query: query2 })
20169
+ body: JSON.stringify({ query: query3 })
19147
20170
  });
19148
20171
  if (!response.ok) return [0];
19149
20172
  const data = await response.json();
@@ -19246,6 +20269,55 @@ var buildAaveV4UserCall = (chainId, lender, account) => {
19246
20269
  return calls;
19247
20270
  };
19248
20271
 
20272
+ // src/lending/user-data/silo-v2/userCallBuild.ts
20273
+ var ASSET_TYPE_PROTECTED = 0;
20274
+ var ASSET_TYPE_COLLATERAL = 1;
20275
+ var SILO_V2_USER_CALLS_PER_SIDE = 5;
20276
+ var SILO_V2_USER_CALLS_PER_PAIR = SILO_V2_USER_CALLS_PER_SIDE * 2;
20277
+ var buildSiloV2UserCall = (chainId, lender, account) => {
20278
+ const market = getSiloV2MarketEntry(chainId, lender);
20279
+ if (!market) return [];
20280
+ const calls = [];
20281
+ for (const half of [market.silo0, market.silo1]) {
20282
+ const oneUnit = BigInt(10) ** BigInt(half.decimals);
20283
+ calls.push(
20284
+ // [0] collateral shares (silo IS the collateral share token)
20285
+ {
20286
+ address: half.silo,
20287
+ name: "balanceOf",
20288
+ params: [account]
20289
+ },
20290
+ // [1] protected shares (separate ERC-20)
20291
+ {
20292
+ address: half.protectedShareToken,
20293
+ name: "balanceOf",
20294
+ params: [account]
20295
+ },
20296
+ // [2] collateral rate: assets per unit of collateral shares
20297
+ {
20298
+ address: half.silo,
20299
+ name: "convertToAssets",
20300
+ params: [oneUnit, ASSET_TYPE_COLLATERAL],
20301
+ abi: SiloConvertToAssetsTypedAbi
20302
+ },
20303
+ // [3] protected rate: assets per unit of protected shares
20304
+ {
20305
+ address: half.silo,
20306
+ name: "convertToAssets",
20307
+ params: [oneUnit, ASSET_TYPE_PROTECTED],
20308
+ abi: SiloConvertToAssetsTypedAbi
20309
+ },
20310
+ // [4] debt position (already in assets, includes accrued interest)
20311
+ {
20312
+ address: half.silo,
20313
+ name: "maxRepay",
20314
+ params: [account]
20315
+ }
20316
+ );
20317
+ }
20318
+ return calls;
20319
+ };
20320
+
19249
20321
  // src/lending/user-data/fetch-balances/prepare.ts
19250
20322
  async function buildUserCall(chainId, lender, account, params) {
19251
20323
  if (isAaveV4Type(lender)) return buildAaveV4UserCall(chainId, lender, account);
@@ -19258,6 +20330,8 @@ async function buildUserCall(chainId, lender, account, params) {
19258
20330
  return buildCompoundV3UserCall(chainId, lender, account);
19259
20331
  if (isEulerType(lender))
19260
20332
  return buildEulerUserCall(chainId, lender, account, params?.subAccountIndexes);
20333
+ if (isSiloV2Type(lender))
20334
+ return buildSiloV2UserCall(chainId, lender, account);
19261
20335
  return buildCompoundV2UserCall(chainId, lender, account);
19262
20336
  }
19263
20337
  function organizeUserQueries(queries) {
@@ -20760,6 +21834,104 @@ function createAaveV4Entry(base, data, key, meta, spokeAddr) {
20760
21834
  };
20761
21835
  }
20762
21836
 
21837
+ // src/lending/user-data/silo-v2/userCallParse.ts
21838
+ var getSiloV2UserDataConverter = (lender, chainId, account, metaMap) => {
21839
+ const market = getSiloV2MarketEntry(chainId, lender);
21840
+ if (!market) return [() => void 0, 0];
21841
+ return [
21842
+ (data) => {
21843
+ if (!data || data.length !== SILO_V2_USER_CALLS_PER_PAIR)
21844
+ return void 0;
21845
+ const sides = [
21846
+ { self: market.silo0, other: market.silo1 },
21847
+ { self: market.silo1, other: market.silo0 }
21848
+ ];
21849
+ const lendingPositions = {};
21850
+ let addedDeposits = 0;
21851
+ let addedDebt = 0;
21852
+ let hasAnyPosition = false;
21853
+ for (let s = 0; s < 2; s++) {
21854
+ const { self } = sides[s];
21855
+ const slot = s * SILO_V2_USER_CALLS_PER_SIDE;
21856
+ const collateralShares = toBigInt5(data[slot]);
21857
+ const protectedShares = toBigInt5(data[slot + 1]);
21858
+ const collateralRate = toBigInt5(data[slot + 2]);
21859
+ const protectedRate = toBigInt5(data[slot + 3]);
21860
+ const repayRaw = toBigInt5(data[slot + 4]);
21861
+ const decimals = self.decimals;
21862
+ const oneUnit = BigInt(10) ** BigInt(decimals);
21863
+ const collateralAssets = oneUnit > 0n ? collateralShares * collateralRate / oneUnit : 0n;
21864
+ const protectedAssets = oneUnit > 0n ? protectedShares * protectedRate / oneUnit : 0n;
21865
+ const depositAssetsRaw = collateralAssets + protectedAssets;
21866
+ if (depositAssetsRaw === 0n && repayRaw === 0n) continue;
21867
+ hasAnyPosition = true;
21868
+ const marketUid = createMarketUid(chainId, lender, self.silo);
21869
+ const meta = metaMap?.[marketUid];
21870
+ const metaDecimals = meta?.asset?.decimals ?? decimals;
21871
+ const depositsStr = parseRawAmount(
21872
+ depositAssetsRaw.toString(),
21873
+ metaDecimals
21874
+ );
21875
+ const debtStr = parseRawAmount(repayRaw.toString(), metaDecimals);
21876
+ const depositsNum = Number(depositsStr);
21877
+ const debtNum = Number(debtStr);
21878
+ const displayPrice = meta ? getDisplayPrice(meta) : 0;
21879
+ const oraclePrice = meta ? getOraclePrice(meta) : 0;
21880
+ const priceHist = meta?.price?.priceUsd24h ?? displayPrice;
21881
+ const depositsUSD = depositsNum * displayPrice;
21882
+ const debtUSD = debtNum * displayPrice;
21883
+ const depositsUSDOracle = depositsNum * oraclePrice;
21884
+ const debtUSDOracle = debtNum * oraclePrice;
21885
+ addedDeposits += depositsNum * priceHist;
21886
+ addedDebt += debtNum * priceHist;
21887
+ const selfLt = Number(self.lt) / 1e18;
21888
+ const collateralEnabled = selfLt > 0 && depositAssetsRaw > 0n;
21889
+ lendingPositions[marketUid] = {
21890
+ marketUid,
21891
+ underlying: self.token.toLowerCase(),
21892
+ deposits: depositsStr,
21893
+ debt: debtStr,
21894
+ debtStable: "0",
21895
+ depositsUSD,
21896
+ debtUSD,
21897
+ debtStableUSD: 0,
21898
+ depositsUSDOracle,
21899
+ debtUSDOracle,
21900
+ debtStableUSDOracle: 0,
21901
+ stableBorrowRate: "0",
21902
+ collateralEnabled,
21903
+ claimableRewards: 0
21904
+ };
21905
+ }
21906
+ if (!hasAnyPosition) return void 0;
21907
+ const payload = {
21908
+ chainId,
21909
+ account,
21910
+ lendingPositions,
21911
+ rewards: [],
21912
+ userEMode: 0
21913
+ };
21914
+ return createBaseTypeUserState(
21915
+ payload,
21916
+ metaMap,
21917
+ addedDeposits,
21918
+ addedDebt,
21919
+ lender
21920
+ );
21921
+ },
21922
+ SILO_V2_USER_CALLS_PER_PAIR
21923
+ ];
21924
+ };
21925
+ function toBigInt5(v) {
21926
+ if (v === void 0 || v === null || v === "0x") return 0n;
21927
+ if (typeof v === "bigint") return v;
21928
+ try {
21929
+ return BigInt(v);
21930
+ } catch {
21931
+ return 0n;
21932
+ }
21933
+ }
21934
+
20763
21935
  // src/lending/user-data/fetch-balances/parse.ts
20764
21936
  function getUserDataConverter(lender, chainId, account, params, meta) {
20765
21937
  if (isAaveV4Type(lender))
@@ -20794,6 +21966,8 @@ function getUserDataConverter(lender, chainId, account, params, meta) {
20794
21966
  );
20795
21967
  if (isEulerType(lender))
20796
21968
  return getEulerUserDataConverter(lender, chainId, account, meta?.[lender], params?.subAccountIndexes);
21969
+ if (isSiloV2Type(lender))
21970
+ return getSiloV2UserDataConverter(lender, chainId, account, meta?.[lender]);
20797
21971
  return getCompoundV2UserDataConverter(
20798
21972
  lender,
20799
21973
  chainId,
@@ -20815,19 +21989,19 @@ var convertLenderUserDataResult = (chainId, queriesRaw, rawResults, lenderState)
20815
21989
  const queries = organizeUserQueries(queriesRaw);
20816
21990
  const lenderData = {};
20817
21991
  let currentSlice = 0;
20818
- for (const query2 of queries) {
21992
+ for (const query3 of queries) {
20819
21993
  const [converter, sliceLength] = getUserDataConverter(
20820
- query2.lender,
21994
+ query3.lender,
20821
21995
  chainId,
20822
- query2.account,
20823
- query2.params,
21996
+ query3.account,
21997
+ query3.params,
20824
21998
  lenderState
20825
21999
  );
20826
22000
  try {
20827
22001
  const data = rawResults.slice(currentSlice, currentSlice + sliceLength);
20828
22002
  const convertedData = converter(data);
20829
22003
  if (convertedData) {
20830
- if (isMultiMarket(query2.lender)) {
22004
+ if (isMultiMarket(query3.lender)) {
20831
22005
  Object.keys(convertedData).forEach((market) => {
20832
22006
  const filtered = filterEmptyUserData(convertedData[market]);
20833
22007
  if (filtered) {
@@ -20838,8 +22012,8 @@ var convertLenderUserDataResult = (chainId, queriesRaw, rawResults, lenderState)
20838
22012
  } else {
20839
22013
  const filtered = filterEmptyUserData(convertedData);
20840
22014
  if (filtered) {
20841
- filtered.lender = query2.lender;
20842
- lenderData[query2.lender] = filtered;
22015
+ filtered.lender = query3.lender;
22016
+ lenderData[query3.lender] = filtered;
20843
22017
  }
20844
22018
  }
20845
22019
  }
@@ -25473,6 +26647,7 @@ var getAbi2 = (lender) => {
25473
26647
  if (isEulerType(lender)) return accountLensAbi;
25474
26648
  if (isCompoundV2Type(lender))
25475
26649
  return [...ComptrollerAbi, ...CompoundV2CollateralToken];
26650
+ if (isSiloV2Type(lender)) return [...SiloAbi];
25476
26651
  return [];
25477
26652
  };
25478
26653
 
@@ -25579,15 +26754,15 @@ function unflattenLenderData(pools) {
25579
26754
  var getLenderUserDataResult = async (chainId, queriesRaw, getEvmClient3, allowFailure = true, batchSize = MULTICALL_DEFAULT_BATCH_SIZE, retries = 3, logs = false) => {
25580
26755
  const queries = organizeUserQueries(queriesRaw);
25581
26756
  const builtCalls = await Promise.all(
25582
- queries.map(async (query2) => {
25583
- const abi = getAbi2(query2.lender);
26757
+ queries.map(async (query3) => {
26758
+ const abi = getAbi2(query3.lender);
25584
26759
  const callData = await buildUserCall(
25585
26760
  chainId,
25586
- query2.lender,
25587
- query2.account,
25588
- query2.params
26761
+ query3.lender,
26762
+ query3.account,
26763
+ query3.params
25589
26764
  );
25590
- return callData.map((call) => ({ call, abi }));
26765
+ return callData.map((call) => ({ call, abi: call.abi ?? abi }));
25591
26766
  })
25592
26767
  );
25593
26768
  const calls = builtCalls.flat();
@@ -25608,15 +26783,15 @@ var prepareLenderUserDataRpcCalls = async (chainId, queriesRaw, batchSize = MULT
25608
26783
  const multicallAddress = getEvmChain(chainId).contracts?.multicall3?.address;
25609
26784
  const queries = organizeUserQueries(queriesRaw);
25610
26785
  const builtCalls = await Promise.all(
25611
- queries.map(async (query2) => {
25612
- const abi = getAbi2(query2.lender);
26786
+ queries.map(async (query3) => {
26787
+ const abi = getAbi2(query3.lender);
25613
26788
  const callData = await buildUserCall(
25614
26789
  chainId,
25615
- query2.lender,
25616
- query2.account,
25617
- query2.params
26790
+ query3.lender,
26791
+ query3.account,
26792
+ query3.params
25618
26793
  );
25619
- return callData.map((call) => ({ call, abi }));
26794
+ return callData.map((call) => ({ call, abi: call.abi ?? abi }));
25620
26795
  })
25621
26796
  );
25622
26797
  const calls = builtCalls.flat();
@@ -25725,13 +26900,13 @@ async function prepareMergedRpcCalls(chainId, balanceQueries, permissionParams,
25725
26900
  );
25726
26901
  let balanceCalls = [];
25727
26902
  const organizedQueries = organizeUserQueries(balanceQueries);
25728
- for (const query2 of organizedQueries) {
25729
- const abi = getAbi2(query2.lender);
26903
+ for (const query3 of organizedQueries) {
26904
+ const abi = getAbi2(query3.lender);
25730
26905
  const callData = await buildUserCall(
25731
26906
  chainId,
25732
- query2.lender,
25733
- query2.account,
25734
- query2.params
26907
+ query3.lender,
26908
+ query3.account,
26909
+ query3.params
25735
26910
  );
25736
26911
  const mappedCalls = callData.map((call) => ({ call, abi }));
25737
26912
  balanceCalls = [...balanceCalls, ...mappedCalls];
@@ -25790,13 +26965,13 @@ async function prepareMergedMulticallParams(chainId, balanceQueries, permissionP
25790
26965
  const permissionAbis = permissionCalls.map(() => permissionResult.abi);
25791
26966
  let balanceCalls = [];
25792
26967
  const organizedQueries = organizeUserQueries(balanceQueries);
25793
- for (const query2 of organizedQueries) {
25794
- const abi = getAbi2(query2.lender);
26968
+ for (const query3 of organizedQueries) {
26969
+ const abi = getAbi2(query3.lender);
25795
26970
  const callData = await buildUserCall(
25796
26971
  chainId,
25797
- query2.lender,
25798
- query2.account,
25799
- query2.params
26972
+ query3.lender,
26973
+ query3.account,
26974
+ query3.params
25800
26975
  );
25801
26976
  const mappedCalls = callData.map((call) => ({ call, abi }));
25802
26977
  balanceCalls = [...balanceCalls, ...mappedCalls];
@@ -28593,12 +29768,12 @@ function getMorphoCalls(chainId, context) {
28593
29768
  const queries = getMorphoMarketsForChain(chainId, context?.marketOverrides);
28594
29769
  if (queries.length === 0) return [];
28595
29770
  const oracleGroups = /* @__PURE__ */ new Map();
28596
- for (const query2 of queries) {
28597
- const oracleLc = query2.oracle.toLowerCase();
29771
+ for (const query3 of queries) {
29772
+ const oracleLc = query3.oracle.toLowerCase();
28598
29773
  if (!oracleGroups.has(oracleLc)) {
28599
29774
  oracleGroups.set(oracleLc, []);
28600
29775
  }
28601
- oracleGroups.get(oracleLc).push(query2);
29776
+ oracleGroups.get(oracleLc).push(query3);
28602
29777
  }
28603
29778
  return Array.from(oracleGroups.values()).map((markets) => {
28604
29779
  const call = {
@@ -29334,6 +30509,550 @@ var aaveV4Fetcher = {
29334
30509
  getAbi: getAaveV4Abi
29335
30510
  };
29336
30511
 
30512
+ // src/prices/oracle-prices/fetchers/siloV2.ts
30513
+ var SiloOracleAbi = [
30514
+ {
30515
+ inputs: [
30516
+ { name: "_baseAmount", type: "uint256" },
30517
+ { name: "_baseToken", type: "address" }
30518
+ ],
30519
+ name: "quote",
30520
+ outputs: [{ name: "quoteAmount", type: "uint256" }],
30521
+ stateMutability: "view",
30522
+ type: "function"
30523
+ },
30524
+ {
30525
+ inputs: [],
30526
+ name: "quoteToken",
30527
+ outputs: [{ name: "", type: "address" }],
30528
+ stateMutability: "view",
30529
+ type: "function"
30530
+ }
30531
+ ];
30532
+ var ZERO_ADDRESS3 = "0x0000000000000000000000000000000000000000";
30533
+ function lookupUSD(context, asset) {
30534
+ const lc = asset.toLowerCase();
30535
+ const groupKey = context.tokenList?.[lc]?.assetGroup ?? `${context.chainId}-${lc}`;
30536
+ return context.usdPrices[groupKey] ?? context.usdPrices[lc] ?? 0;
30537
+ }
30538
+ function getSiloV2Calls(chainId) {
30539
+ const allMarkets = siloMarkets()?.[chainId];
30540
+ if (!allMarkets || allMarkets.length === 0) return [];
30541
+ const tokensWithRealOracle = /* @__PURE__ */ new Set();
30542
+ for (const market of allMarkets) {
30543
+ for (const half of [market.silo0, market.silo1]) {
30544
+ if (half.solvencyOracle && half.solvencyOracle !== ZERO_ADDRESS3) {
30545
+ tokensWithRealOracle.add(half.token.toLowerCase());
30546
+ }
30547
+ }
30548
+ }
30549
+ const calls = [];
30550
+ const callIndexMap = {};
30551
+ const quoteTokenIndexMap = {};
30552
+ const entries = [];
30553
+ for (const market of allMarkets) {
30554
+ const lenderKey = siloV2LenderKey(market.siloConfig);
30555
+ const halves = [market.silo0, market.silo1];
30556
+ const isStatic = halves.map(
30557
+ (h) => !h.solvencyOracle || h.solvencyOracle === ZERO_ADDRESS3
30558
+ );
30559
+ if (isStatic[0] && isStatic[1]) {
30560
+ const t0 = halves[0].token.toLowerCase();
30561
+ const t1 = halves[1].token.toLowerCase();
30562
+ if (!tokensWithRealOracle.has(t0) && !tokensWithRealOracle.has(t1)) {
30563
+ continue;
30564
+ }
30565
+ }
30566
+ for (let i = 0; i < 2; i++) {
30567
+ const half = halves[i];
30568
+ const partner = halves[1 - i];
30569
+ const tokenLc = half.token.toLowerCase();
30570
+ const partnerLc = partner.token.toLowerCase();
30571
+ if (isStatic[i]) {
30572
+ entries.push({
30573
+ token: tokenLc,
30574
+ decimals: half.decimals,
30575
+ silo: half.silo.toLowerCase(),
30576
+ lenderKey,
30577
+ oracle: ZERO_ADDRESS3,
30578
+ partnerToken: partnerLc,
30579
+ isStatic: true
30580
+ });
30581
+ continue;
30582
+ }
30583
+ const oracleLc = half.solvencyOracle.toLowerCase();
30584
+ entries.push({
30585
+ token: tokenLc,
30586
+ decimals: half.decimals,
30587
+ silo: half.silo.toLowerCase(),
30588
+ lenderKey,
30589
+ oracle: oracleLc,
30590
+ partnerToken: partnerLc,
30591
+ isStatic: false
30592
+ });
30593
+ const quoteKey = `${oracleLc}:${tokenLc}`;
30594
+ if (!(quoteKey in callIndexMap)) {
30595
+ callIndexMap[quoteKey] = calls.length;
30596
+ calls.push({
30597
+ address: half.solvencyOracle,
30598
+ name: "quote",
30599
+ params: [BigInt(10) ** BigInt(half.decimals), half.token]
30600
+ });
30601
+ }
30602
+ if (!(oracleLc in quoteTokenIndexMap)) {
30603
+ quoteTokenIndexMap[oracleLc] = calls.length;
30604
+ calls.push({
30605
+ address: half.solvencyOracle,
30606
+ name: "quoteToken",
30607
+ params: []
30608
+ });
30609
+ }
30610
+ }
30611
+ }
30612
+ if (entries.length === 0) return [];
30613
+ return [
30614
+ {
30615
+ calls,
30616
+ meta: { entries, callIndexMap, quoteTokenIndexMap },
30617
+ lender: "SILO_V2"
30618
+ }
30619
+ ];
30620
+ }
30621
+ function parseSiloV2Results(data, meta, context) {
30622
+ const entries = [];
30623
+ const seen = /* @__PURE__ */ new Set();
30624
+ for (const entry of meta.entries) {
30625
+ const dedupKey = `${entry.lenderKey}:${entry.token}`;
30626
+ if (seen.has(dedupKey)) continue;
30627
+ try {
30628
+ let priceUSD = 0;
30629
+ let rawPrice = 1;
30630
+ if (entry.isStatic) {
30631
+ const ownUSD = lookupUSD(context, entry.token);
30632
+ const partnerUSD = lookupUSD(context, entry.partnerToken);
30633
+ priceUSD = ownUSD || partnerUSD;
30634
+ if (!priceUSD) continue;
30635
+ rawPrice = 1;
30636
+ } else {
30637
+ const quoteCallIdx = meta.callIndexMap[`${entry.oracle}:${entry.token}`];
30638
+ if (quoteCallIdx === void 0) continue;
30639
+ const rawQuote = data[quoteCallIdx];
30640
+ if (!rawQuote || rawQuote === "0x") continue;
30641
+ const quoteAmount = BigInt(rawQuote.toString());
30642
+ if (quoteAmount === 0n) continue;
30643
+ const qtIdx = meta.quoteTokenIndexMap[entry.oracle];
30644
+ if (qtIdx === void 0) continue;
30645
+ const rawQt = data[qtIdx];
30646
+ if (!rawQt || rawQt === "0x") continue;
30647
+ const quoteTokenAddr = rawQt.toLowerCase();
30648
+ const qtMeta = context.tokenList?.[quoteTokenAddr];
30649
+ const qtDecimals = qtMeta?.decimals ?? 18;
30650
+ const priceInQt = Number(quoteAmount) / Number(10n ** BigInt(qtDecimals));
30651
+ if (isNaN(priceInQt) || priceInQt === 0) continue;
30652
+ const qtUSD = lookupUSD(context, quoteTokenAddr);
30653
+ if (!qtUSD) continue;
30654
+ rawPrice = priceInQt;
30655
+ priceUSD = priceInQt * qtUSD;
30656
+ }
30657
+ if (isNaN(priceUSD) || priceUSD === 0) continue;
30658
+ entries.push({
30659
+ asset: entry.token,
30660
+ price: rawPrice,
30661
+ priceUSD,
30662
+ marketUid: createMarketUid(
30663
+ context.chainId,
30664
+ entry.lenderKey,
30665
+ entry.silo
30666
+ ),
30667
+ targetLender: entry.lenderKey,
30668
+ ...entry.isStatic ? { staticBase: true, baseAsset: entry.token } : {}
30669
+ });
30670
+ seen.add(dedupKey);
30671
+ } catch {
30672
+ }
30673
+ }
30674
+ return entries;
30675
+ }
30676
+ function getSiloV2Abi() {
30677
+ return SiloOracleAbi;
30678
+ }
30679
+ var siloV2Fetcher = {
30680
+ getCalls: getSiloV2Calls,
30681
+ parse: parseSiloV2Results,
30682
+ getAbi: getSiloV2Abi
30683
+ };
30684
+
30685
+ // src/prices/oracle-prices/fetchers/siloV3.ts
30686
+ var SiloOracleAbi2 = [
30687
+ {
30688
+ inputs: [
30689
+ { name: "_baseAmount", type: "uint256" },
30690
+ { name: "_baseToken", type: "address" }
30691
+ ],
30692
+ name: "quote",
30693
+ outputs: [{ name: "quoteAmount", type: "uint256" }],
30694
+ stateMutability: "view",
30695
+ type: "function"
30696
+ },
30697
+ {
30698
+ inputs: [],
30699
+ name: "quoteToken",
30700
+ outputs: [{ name: "", type: "address" }],
30701
+ stateMutability: "view",
30702
+ type: "function"
30703
+ }
30704
+ ];
30705
+ var ZERO_ADDRESS4 = "0x0000000000000000000000000000000000000000";
30706
+ function lookupUSD2(context, asset) {
30707
+ const lc = asset.toLowerCase();
30708
+ const groupKey = context.tokenList?.[lc]?.assetGroup ?? `${context.chainId}-${lc}`;
30709
+ return context.usdPrices[groupKey] ?? context.usdPrices[lc] ?? 0;
30710
+ }
30711
+ function getSiloV3Calls(chainId) {
30712
+ const allMarkets = siloMarketsV3()?.[chainId];
30713
+ if (!allMarkets || allMarkets.length === 0) return [];
30714
+ const tokensWithRealOracle = /* @__PURE__ */ new Set();
30715
+ for (const market of allMarkets) {
30716
+ for (const half of [market.silo0, market.silo1]) {
30717
+ if (half.solvencyOracle && half.solvencyOracle !== ZERO_ADDRESS4) {
30718
+ tokensWithRealOracle.add(half.token.toLowerCase());
30719
+ }
30720
+ }
30721
+ }
30722
+ const calls = [];
30723
+ const callIndexMap = {};
30724
+ const quoteTokenIndexMap = {};
30725
+ const entries = [];
30726
+ for (const market of allMarkets) {
30727
+ const lenderKey = siloV3LenderKey(market.siloConfig);
30728
+ const halves = [market.silo0, market.silo1];
30729
+ const isStatic = halves.map(
30730
+ (h) => !h.solvencyOracle || h.solvencyOracle === ZERO_ADDRESS4
30731
+ );
30732
+ if (isStatic[0] && isStatic[1]) {
30733
+ const t0 = halves[0].token.toLowerCase();
30734
+ const t1 = halves[1].token.toLowerCase();
30735
+ if (!tokensWithRealOracle.has(t0) && !tokensWithRealOracle.has(t1)) {
30736
+ continue;
30737
+ }
30738
+ }
30739
+ for (let i = 0; i < 2; i++) {
30740
+ const half = halves[i];
30741
+ const partner = halves[1 - i];
30742
+ const tokenLc = half.token.toLowerCase();
30743
+ const partnerLc = partner.token.toLowerCase();
30744
+ if (isStatic[i]) {
30745
+ entries.push({
30746
+ token: tokenLc,
30747
+ decimals: half.decimals,
30748
+ silo: half.silo.toLowerCase(),
30749
+ lenderKey,
30750
+ oracle: ZERO_ADDRESS4,
30751
+ partnerToken: partnerLc,
30752
+ isStatic: true
30753
+ });
30754
+ continue;
30755
+ }
30756
+ const oracleLc = half.solvencyOracle.toLowerCase();
30757
+ entries.push({
30758
+ token: tokenLc,
30759
+ decimals: half.decimals,
30760
+ silo: half.silo.toLowerCase(),
30761
+ lenderKey,
30762
+ oracle: oracleLc,
30763
+ partnerToken: partnerLc,
30764
+ isStatic: false
30765
+ });
30766
+ const quoteKey = `${oracleLc}:${tokenLc}`;
30767
+ if (!(quoteKey in callIndexMap)) {
30768
+ callIndexMap[quoteKey] = calls.length;
30769
+ calls.push({
30770
+ address: half.solvencyOracle,
30771
+ name: "quote",
30772
+ params: [BigInt(10) ** BigInt(half.decimals), half.token]
30773
+ });
30774
+ }
30775
+ if (!(oracleLc in quoteTokenIndexMap)) {
30776
+ quoteTokenIndexMap[oracleLc] = calls.length;
30777
+ calls.push({
30778
+ address: half.solvencyOracle,
30779
+ name: "quoteToken",
30780
+ params: []
30781
+ });
30782
+ }
30783
+ }
30784
+ }
30785
+ if (entries.length === 0) return [];
30786
+ return [
30787
+ {
30788
+ calls,
30789
+ meta: { entries, callIndexMap, quoteTokenIndexMap },
30790
+ lender: "SILO_V3"
30791
+ }
30792
+ ];
30793
+ }
30794
+ function parseSiloV3Results(data, meta, context) {
30795
+ const entries = [];
30796
+ const seen = /* @__PURE__ */ new Set();
30797
+ for (const entry of meta.entries) {
30798
+ const dedupKey = `${entry.lenderKey}:${entry.token}`;
30799
+ if (seen.has(dedupKey)) continue;
30800
+ try {
30801
+ let priceUSD = 0;
30802
+ let rawPrice = 1;
30803
+ if (entry.isStatic) {
30804
+ const ownUSD = lookupUSD2(context, entry.token);
30805
+ const partnerUSD = lookupUSD2(context, entry.partnerToken);
30806
+ priceUSD = ownUSD || partnerUSD;
30807
+ if (!priceUSD) continue;
30808
+ rawPrice = 1;
30809
+ } else {
30810
+ const quoteCallIdx = meta.callIndexMap[`${entry.oracle}:${entry.token}`];
30811
+ if (quoteCallIdx === void 0) continue;
30812
+ const rawQuote = data[quoteCallIdx];
30813
+ if (!rawQuote || rawQuote === "0x") continue;
30814
+ const quoteAmount = BigInt(rawQuote.toString());
30815
+ if (quoteAmount === 0n) continue;
30816
+ const qtIdx = meta.quoteTokenIndexMap[entry.oracle];
30817
+ if (qtIdx === void 0) continue;
30818
+ const rawQt = data[qtIdx];
30819
+ if (!rawQt || rawQt === "0x") continue;
30820
+ const quoteTokenAddr = rawQt.toLowerCase();
30821
+ const qtMeta = context.tokenList?.[quoteTokenAddr];
30822
+ const qtDecimals = qtMeta?.decimals ?? 18;
30823
+ const priceInQt = Number(quoteAmount) / Number(10n ** BigInt(qtDecimals));
30824
+ if (isNaN(priceInQt) || priceInQt === 0) continue;
30825
+ const qtUSD = lookupUSD2(context, quoteTokenAddr);
30826
+ if (!qtUSD) continue;
30827
+ rawPrice = priceInQt;
30828
+ priceUSD = priceInQt * qtUSD;
30829
+ }
30830
+ if (isNaN(priceUSD) || priceUSD === 0) continue;
30831
+ entries.push({
30832
+ asset: entry.token,
30833
+ price: rawPrice,
30834
+ priceUSD,
30835
+ marketUid: createMarketUid(
30836
+ context.chainId,
30837
+ entry.lenderKey,
30838
+ entry.silo
30839
+ ),
30840
+ targetLender: entry.lenderKey,
30841
+ ...entry.isStatic ? { staticBase: true, baseAsset: entry.token } : {}
30842
+ });
30843
+ seen.add(dedupKey);
30844
+ } catch {
30845
+ }
30846
+ }
30847
+ return entries;
30848
+ }
30849
+ function getSiloV3Abi() {
30850
+ return SiloOracleAbi2;
30851
+ }
30852
+ var siloV3Fetcher = {
30853
+ getCalls: getSiloV3Calls,
30854
+ parse: parseSiloV3Results,
30855
+ getAbi: getSiloV3Abi
30856
+ };
30857
+
30858
+ // src/prices/oracle-prices/fetchers/siloV2Graphql.ts
30859
+ async function fetchSiloV2GraphQLMarkets(chainId) {
30860
+ if (!SILO_API_SUPPORTED_CHAIN_IDS.has(chainId)) return null;
30861
+ try {
30862
+ const items = await fetchSiloMarketsLite(chainId, { protocolVersion: "v2" });
30863
+ return items;
30864
+ } catch (e) {
30865
+ console.warn(
30866
+ `[prices] Silo v2 GraphQL fetch failed on chain ${chainId}:`,
30867
+ e?.message ?? e
30868
+ );
30869
+ return null;
30870
+ }
30871
+ }
30872
+ function safeNumber3(v) {
30873
+ if (v == null) return 0;
30874
+ const n = typeof v === "number" ? v : Number(v);
30875
+ return Number.isFinite(n) ? n : 0;
30876
+ }
30877
+ function lookupUSD3(context, asset) {
30878
+ const lc = asset.toLowerCase();
30879
+ const groupKey = context.tokenList?.[lc]?.assetGroup ?? `${context.chainId}-${lc}`;
30880
+ return context.usdPrices[groupKey] ?? context.usdPrices[lc] ?? 0;
30881
+ }
30882
+ function parseSiloV2GraphQLResults(items, context) {
30883
+ const ZERO_ADDRESS5 = "0x0000000000000000000000000000000000000000";
30884
+ const out = [];
30885
+ const seen = /* @__PURE__ */ new Set();
30886
+ for (const item of items) {
30887
+ let lenderKey;
30888
+ try {
30889
+ lenderKey = siloV2LenderKey(item.configAddress);
30890
+ } catch {
30891
+ continue;
30892
+ }
30893
+ const registryEntry = getSiloV2MarketEntry(context.chainId, lenderKey);
30894
+ if (!registryEntry) continue;
30895
+ const [apiSide0, apiSide1] = item.market1.index === 0 ? [item.market1, item.market2] : [item.market2, item.market1];
30896
+ const sideTuples = [
30897
+ { api: apiSide0, self: registryEntry.silo0, other: registryEntry.silo1 },
30898
+ { api: apiSide1, self: registryEntry.silo1, other: registryEntry.silo0 }
30899
+ ];
30900
+ for (const { api: side, self, other } of sideTuples) {
30901
+ const tokenLc = (side.inputTokenId ?? side.inputToken?.id ?? self.token).toLowerCase();
30902
+ if (!tokenLc) continue;
30903
+ const partnerTokenLc = other.token.toLowerCase();
30904
+ const dedupKey = `${lenderKey}:${tokenLc}`;
30905
+ if (seen.has(dedupKey)) continue;
30906
+ const oracleAddr = (side.solvencyOracleAddress ?? side.solvencyOracle?.id ?? self.solvencyOracle ?? ZERO_ADDRESS5).toLowerCase();
30907
+ const isStatic = !oracleAddr || oracleAddr === ZERO_ADDRESS5;
30908
+ const siloAddrLc = self.silo.toLowerCase();
30909
+ try {
30910
+ let priceUSD = 0;
30911
+ let rawPrice = 1;
30912
+ const supplyNum = safeNumber3(side.supply);
30913
+ const supplyUsdNum = side.supplyUsd != null ? Number(side.supplyUsd) : 0;
30914
+ const borrowedNum = safeNumber3(side.borrowed);
30915
+ const borrowedUsdNum = side.borrowedUsd != null ? Number(side.borrowedUsd) : 0;
30916
+ if (supplyNum > 0 && supplyUsdNum > 0) {
30917
+ priceUSD = supplyUsdNum / supplyNum;
30918
+ rawPrice = isStatic ? 1 : priceUSD;
30919
+ } else if (borrowedNum > 0 && borrowedUsdNum > 0) {
30920
+ priceUSD = borrowedUsdNum / borrowedNum;
30921
+ rawPrice = isStatic ? 1 : priceUSD;
30922
+ } else if (isStatic) {
30923
+ const ownUSD = lookupUSD3(context, tokenLc);
30924
+ const partnerUSD = partnerTokenLc ? lookupUSD3(context, partnerTokenLc) : 0;
30925
+ priceUSD = ownUSD || partnerUSD;
30926
+ if (!priceUSD) continue;
30927
+ rawPrice = 1;
30928
+ } else {
30929
+ const quoteStr = side.solvencyOracle?.quote;
30930
+ if (!quoteStr) continue;
30931
+ const quoteNum = Number(quoteStr);
30932
+ if (!Number.isFinite(quoteNum) || quoteNum === 0) continue;
30933
+ const quoteTokenLc = (side.solvencyOracle?.quoteTokenId ?? "").toLowerCase();
30934
+ if (!quoteTokenLc) continue;
30935
+ const qtUSD = lookupUSD3(context, quoteTokenLc);
30936
+ if (!qtUSD) continue;
30937
+ rawPrice = quoteNum;
30938
+ priceUSD = quoteNum * qtUSD;
30939
+ }
30940
+ if (!Number.isFinite(priceUSD) || priceUSD === 0) continue;
30941
+ out.push({
30942
+ asset: tokenLc,
30943
+ price: rawPrice,
30944
+ priceUSD,
30945
+ marketUid: createMarketUid(context.chainId, lenderKey, siloAddrLc),
30946
+ targetLender: lenderKey,
30947
+ ...isStatic ? { staticBase: true, baseAsset: tokenLc } : {}
30948
+ });
30949
+ seen.add(dedupKey);
30950
+ } catch {
30951
+ }
30952
+ }
30953
+ }
30954
+ return out;
30955
+ }
30956
+
30957
+ // src/prices/oracle-prices/fetchers/siloV3Graphql.ts
30958
+ async function fetchSiloV3GraphQLMarkets(chainId) {
30959
+ if (!SILO_API_SUPPORTED_CHAIN_IDS.has(chainId)) return null;
30960
+ try {
30961
+ const items = await fetchSiloMarketsLite(chainId, { protocolVersion: "v3" });
30962
+ return items;
30963
+ } catch (e) {
30964
+ console.warn(
30965
+ `[prices] Silo v3 GraphQL fetch failed on chain ${chainId}:`,
30966
+ e?.message ?? e
30967
+ );
30968
+ return null;
30969
+ }
30970
+ }
30971
+ function safeNumber4(v) {
30972
+ if (v == null) return 0;
30973
+ const n = typeof v === "number" ? v : Number(v);
30974
+ return Number.isFinite(n) ? n : 0;
30975
+ }
30976
+ function lookupUSD4(context, asset) {
30977
+ const lc = asset.toLowerCase();
30978
+ const groupKey = context.tokenList?.[lc]?.assetGroup ?? `${context.chainId}-${lc}`;
30979
+ return context.usdPrices[groupKey] ?? context.usdPrices[lc] ?? 0;
30980
+ }
30981
+ function parseSiloV3GraphQLResults(items, context) {
30982
+ const ZERO_ADDRESS5 = "0x0000000000000000000000000000000000000000";
30983
+ const out = [];
30984
+ const seen = /* @__PURE__ */ new Set();
30985
+ for (const item of items) {
30986
+ let lenderKey;
30987
+ try {
30988
+ lenderKey = siloV3LenderKey(item.configAddress);
30989
+ } catch {
30990
+ continue;
30991
+ }
30992
+ const registryEntry = getSiloV3MarketEntry(context.chainId, lenderKey);
30993
+ if (!registryEntry) continue;
30994
+ const [apiSide0, apiSide1] = item.market1.index === 0 ? [item.market1, item.market2] : [item.market2, item.market1];
30995
+ const sideTuples = [
30996
+ { api: apiSide0, self: registryEntry.silo0, other: registryEntry.silo1 },
30997
+ { api: apiSide1, self: registryEntry.silo1, other: registryEntry.silo0 }
30998
+ ];
30999
+ for (const { api: side, self, other } of sideTuples) {
31000
+ const tokenLc = (side.inputTokenId ?? side.inputToken?.id ?? self.token).toLowerCase();
31001
+ if (!tokenLc) continue;
31002
+ const partnerTokenLc = other.token.toLowerCase();
31003
+ const dedupKey = `${lenderKey}:${tokenLc}`;
31004
+ if (seen.has(dedupKey)) continue;
31005
+ const oracleAddr = (side.solvencyOracleAddress ?? side.solvencyOracle?.id ?? self.solvencyOracle ?? ZERO_ADDRESS5).toLowerCase();
31006
+ const isStatic = !oracleAddr || oracleAddr === ZERO_ADDRESS5;
31007
+ const siloAddrLc = self.silo.toLowerCase();
31008
+ try {
31009
+ let priceUSD = 0;
31010
+ let rawPrice = 1;
31011
+ const supplyNum = safeNumber4(side.supply);
31012
+ const supplyUsdNum = side.supplyUsd != null ? Number(side.supplyUsd) : 0;
31013
+ const borrowedNum = safeNumber4(side.borrowed);
31014
+ const borrowedUsdNum = side.borrowedUsd != null ? Number(side.borrowedUsd) : 0;
31015
+ if (supplyNum > 0 && supplyUsdNum > 0) {
31016
+ priceUSD = supplyUsdNum / supplyNum;
31017
+ rawPrice = isStatic ? 1 : priceUSD;
31018
+ } else if (borrowedNum > 0 && borrowedUsdNum > 0) {
31019
+ priceUSD = borrowedUsdNum / borrowedNum;
31020
+ rawPrice = isStatic ? 1 : priceUSD;
31021
+ } else if (isStatic) {
31022
+ const ownUSD = lookupUSD4(context, tokenLc);
31023
+ const partnerUSD = partnerTokenLc ? lookupUSD4(context, partnerTokenLc) : 0;
31024
+ priceUSD = ownUSD || partnerUSD;
31025
+ if (!priceUSD) continue;
31026
+ rawPrice = 1;
31027
+ } else {
31028
+ const quoteStr = side.solvencyOracle?.quote;
31029
+ if (!quoteStr) continue;
31030
+ const quoteNum = Number(quoteStr);
31031
+ if (!Number.isFinite(quoteNum) || quoteNum === 0) continue;
31032
+ const quoteTokenLc = (side.solvencyOracle?.quoteTokenId ?? "").toLowerCase();
31033
+ if (!quoteTokenLc) continue;
31034
+ const qtUSD = lookupUSD4(context, quoteTokenLc);
31035
+ if (!qtUSD) continue;
31036
+ rawPrice = quoteNum;
31037
+ priceUSD = quoteNum * qtUSD;
31038
+ }
31039
+ if (!Number.isFinite(priceUSD) || priceUSD === 0) continue;
31040
+ out.push({
31041
+ asset: tokenLc,
31042
+ price: rawPrice,
31043
+ priceUSD,
31044
+ marketUid: createMarketUid(context.chainId, lenderKey, siloAddrLc),
31045
+ targetLender: lenderKey,
31046
+ ...isStatic ? { staticBase: true, baseAsset: tokenLc } : {}
31047
+ });
31048
+ seen.add(dedupKey);
31049
+ } catch {
31050
+ }
31051
+ }
31052
+ }
31053
+ return out;
31054
+ }
31055
+
29337
31056
  // src/prices/oracle-prices/fetchOraclePrices.ts
29338
31057
  function countFailures(data, offset, count) {
29339
31058
  let failures = 0;
@@ -29484,6 +31203,16 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
29484
31203
  }),
29485
31204
  getCallsErrors
29486
31205
  ) : [];
31206
+ const siloV2Results = isActive("silov2") ? safeGetCalls(
31207
+ "siloV2",
31208
+ () => siloV2Fetcher.getCalls(chainId),
31209
+ getCallsErrors
31210
+ ) : [];
31211
+ const siloV3Results = isActive("silov3") ? safeGetCalls(
31212
+ "siloV3",
31213
+ () => siloV3Fetcher.getCalls(chainId),
31214
+ getCallsErrors
31215
+ ) : [];
29487
31216
  const aaveGroup = buildGroup(
29488
31217
  "aave",
29489
31218
  aaveResults,
@@ -29526,6 +31255,18 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
29526
31255
  morphoFetcher.parse,
29527
31256
  ProxyOracleAbi
29528
31257
  );
31258
+ const siloV2Group = buildGroup(
31259
+ "siloV2",
31260
+ siloV2Results,
31261
+ siloV2Fetcher.parse,
31262
+ getSiloV2Abi()
31263
+ );
31264
+ const siloV3Group = buildGroup(
31265
+ "siloV3",
31266
+ siloV3Results,
31267
+ siloV3Fetcher.parse,
31268
+ getSiloV3Abi()
31269
+ );
29529
31270
  const allGroups = [
29530
31271
  aaveGroup,
29531
31272
  compoundV2Group,
@@ -29533,7 +31274,9 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
29533
31274
  listaGroup,
29534
31275
  eulerGroup,
29535
31276
  aaveV4Group,
29536
- morphoGroup
31277
+ morphoGroup,
31278
+ siloV2Group,
31279
+ siloV3Group
29537
31280
  ];
29538
31281
  const totalCalls = allGroups.reduce((s, g) => s + g.calls.length, 0);
29539
31282
  if (totalCalls === 0 && !isActive("morpho")) {
@@ -29552,6 +31295,8 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
29552
31295
  }
29553
31296
  const chainBatchSize = batchSize?.[chainId];
29554
31297
  const morphoGqlPromise = isActive("morpho") ? fetchMorphoGraphQLPrices(chainId) : Promise.resolve(null);
31298
+ const siloV2GqlPromise = fetchSiloV2GraphQLMarkets(chainId);
31299
+ const siloV3GqlPromise = fetchSiloV3GraphQLMarkets(chainId);
29555
31300
  const [
29556
31301
  aaveData,
29557
31302
  compoundV2Data,
@@ -29559,7 +31304,9 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
29559
31304
  listaData,
29560
31305
  eulerData,
29561
31306
  aaveV4Data,
29562
- morphoGqlEntries
31307
+ morphoGqlEntries,
31308
+ siloV2GqlItems,
31309
+ siloV3GqlItems
29563
31310
  ] = await Promise.all([
29564
31311
  executeGroup(
29565
31312
  aaveGroup,
@@ -29609,10 +31356,40 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
29609
31356
  allowFailure,
29610
31357
  rpcOverrides
29611
31358
  ),
29612
- morphoGqlPromise
31359
+ morphoGqlPromise,
31360
+ siloV2GqlPromise,
31361
+ siloV3GqlPromise
29613
31362
  ]);
31363
+ if (siloV2GqlItems == null && siloV2Group.calls.length > 0) {
31364
+ console.warn(
31365
+ `[prices] chain ${chainId}: Silo v2 GraphQL unavailable, falling back to on-chain (${siloV2Group.trackers.length} trackers)`
31366
+ );
31367
+ }
31368
+ const siloV2Data = siloV2GqlItems != null ? { results: [], error: void 0 } : await executeGroup(
31369
+ siloV2Group,
31370
+ chainId,
31371
+ chainBatchSize,
31372
+ retries,
31373
+ allowFailure,
31374
+ rpcOverrides
31375
+ );
31376
+ if (siloV3GqlItems == null && siloV3Group.calls.length > 0) {
31377
+ console.warn(
31378
+ `[prices] chain ${chainId}: Silo v3 GraphQL unavailable, falling back to on-chain (${siloV3Group.trackers.length} trackers)`
31379
+ );
31380
+ }
31381
+ const siloV3Data = siloV3GqlItems != null ? { results: [], error: void 0 } : await executeGroup(
31382
+ siloV3Group,
31383
+ chainId,
31384
+ chainBatchSize,
31385
+ retries,
31386
+ allowFailure,
31387
+ rpcOverrides
31388
+ );
29614
31389
  if (morphoGqlEntries == null && isActive("morpho")) {
29615
- console.warn(`[prices] chain ${chainId}: Morpho GraphQL returned null, falling back to on-chain (${morphoGroup.trackers.length} trackers)`);
31390
+ console.warn(
31391
+ `[prices] chain ${chainId}: Morpho GraphQL returned null, falling back to on-chain (${morphoGroup.trackers.length} trackers)`
31392
+ );
29616
31393
  }
29617
31394
  const morphoData = morphoGqlEntries != null ? { results: [], error: void 0 } : await executeGroup(
29618
31395
  morphoGroup,
@@ -29630,6 +31407,8 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
29630
31407
  { group: listaGroup, data: listaData },
29631
31408
  { group: eulerGroup, data: eulerData },
29632
31409
  { group: aaveV4Group, data: aaveV4Data },
31410
+ ...siloV2GqlItems != null ? [] : [{ group: siloV2Group, data: siloV2Data }],
31411
+ ...siloV3GqlItems != null ? [] : [{ group: siloV3Group, data: siloV3Data }],
29633
31412
  ...useMorphoGql ? [] : [{ group: morphoGroup, data: morphoData }]
29634
31413
  ];
29635
31414
  for (const { group, data } of groupResults) {
@@ -29714,6 +31493,48 @@ async function fetchOraclePrices(chainIds, rpcOverrides, lists = {}, retries = 3
29714
31493
  true,
29715
31494
  (t) => !!t.meta.baseAssetSource
29716
31495
  );
31496
+ if (siloV2GqlItems != null) {
31497
+ const context = { chainId, usdPrices, tokenList };
31498
+ const entries = parseSiloV2GraphQLResults(siloV2GqlItems, context);
31499
+ const diag2 = {
31500
+ lender: "SILO_V2 (GraphQL)",
31501
+ callCount: 0,
31502
+ failedCalls: 0,
31503
+ parsedEntries: entries.length
31504
+ };
31505
+ for (const entry of entries) {
31506
+ const lender = entry.targetLender ?? "SILO_V2";
31507
+ if (!chainResult[lender]) chainResult[lender] = [];
31508
+ chainResult[lender].push(entry);
31509
+ const oracleKey = tokenList[entry.asset]?.assetGroup ?? `${chainId}-${entry.asset}`;
31510
+ usdPrices[oracleKey] = entry.priceUSD;
31511
+ usdPrices[entry.asset] = entry.priceUSD;
31512
+ }
31513
+ trackerDiags.push(diag2);
31514
+ } else {
31515
+ parseTrackers(siloV2Group, siloV2Data.results);
31516
+ }
31517
+ if (siloV3GqlItems != null) {
31518
+ const context = { chainId, usdPrices, tokenList };
31519
+ const entries = parseSiloV3GraphQLResults(siloV3GqlItems, context);
31520
+ const diag2 = {
31521
+ lender: "SILO_V3 (GraphQL)",
31522
+ callCount: 0,
31523
+ failedCalls: 0,
31524
+ parsedEntries: entries.length
31525
+ };
31526
+ for (const entry of entries) {
31527
+ const lender = entry.targetLender ?? "SILO_V3";
31528
+ if (!chainResult[lender]) chainResult[lender] = [];
31529
+ chainResult[lender].push(entry);
31530
+ const oracleKey = tokenList[entry.asset]?.assetGroup ?? `${chainId}-${entry.asset}`;
31531
+ usdPrices[oracleKey] = entry.priceUSD;
31532
+ usdPrices[entry.asset] = entry.priceUSD;
31533
+ }
31534
+ trackerDiags.push(diag2);
31535
+ } else {
31536
+ parseTrackers(siloV3Group, siloV3Data.results);
31537
+ }
29717
31538
  if (useMorphoGql) {
29718
31539
  const morphoGqlDiag = {
29719
31540
  lender: "MORPHO_BLUE (GraphQL)",
@@ -30589,21 +32410,21 @@ function prepareTokenBalanceRpcCalls(chainId, account, tokens, blockTag = "lates
30589
32410
  encodedCalldata
30590
32411
  };
30591
32412
  }
30592
- function parseTokenBalanceResult(rawResult, query2) {
32413
+ function parseTokenBalanceResult(rawResult, query3) {
30593
32414
  if (!rawResult || rawResult === "0x") {
30594
32415
  return {};
30595
32416
  }
30596
32417
  const parsed = parseBalanceFetcherResult(
30597
32418
  rawResult,
30598
- [query2.account],
30599
- query2.tokens
32419
+ [query3.account],
32420
+ query3.tokens
30600
32421
  );
30601
32422
  if (parsed.balances.length === 0) {
30602
32423
  return {};
30603
32424
  }
30604
32425
  const result = {};
30605
32426
  const userBalances = parsed.balances[0].balances;
30606
- for (const token of query2.tokens) {
32427
+ for (const token of query3.tokens) {
30607
32428
  const balanceEntry = userBalances[token];
30608
32429
  if (balanceEntry) {
30609
32430
  result[token] = {