@1delta/margin-fetcher 5.0.101 → 5.0.102

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.
package/dist/index.js CHANGED
@@ -10729,11 +10729,11 @@ async function resolveListaBrokers(chainId, marketKeys, getClient = getEvmClient
10729
10729
  const moolah = morphoPools()?.LISTA_DAO?.[chainId];
10730
10730
  const out = {};
10731
10731
  if (!moolah || marketKeys.length === 0) return out;
10732
- const cache6 = BROKER_CACHE[chainId] ??= {};
10732
+ const cache7 = BROKER_CACHE[chainId] ??= {};
10733
10733
  const missing = [];
10734
10734
  for (const key3 of marketKeys) {
10735
10735
  const id = toBytes32MarketId(key3);
10736
- if (cache6[id] === void 0) missing.push(id);
10736
+ if (cache7[id] === void 0) missing.push(id);
10737
10737
  }
10738
10738
  if (missing.length > 0) {
10739
10739
  try {
@@ -10749,7 +10749,7 @@ async function resolveListaBrokers(chainId, marketKeys, getClient = getEvmClient
10749
10749
  );
10750
10750
  results.forEach((addr4, i) => {
10751
10751
  if (addr4 === void 0) return;
10752
- cache6[missing[i]] = addr4.toLowerCase();
10752
+ cache7[missing[i]] = addr4.toLowerCase();
10753
10753
  });
10754
10754
  } catch (e) {
10755
10755
  console.warn(
@@ -10760,7 +10760,7 @@ async function resolveListaBrokers(chainId, marketKeys, getClient = getEvmClient
10760
10760
  }
10761
10761
  for (const key3 of marketKeys) {
10762
10762
  const id = toBytes32MarketId(key3);
10763
- const broker = cache6[id];
10763
+ const broker = cache7[id];
10764
10764
  if (broker && broker !== zeroAddress) out[id] = broker;
10765
10765
  }
10766
10766
  return out;
@@ -10788,7 +10788,7 @@ async function fetchListaFixedTerms(chainId, marketKeys, multicallRetry) {
10788
10788
  })),
10789
10789
  multicallRetry
10790
10790
  );
10791
- const cache6 = FIXED_TERMS_CACHE[chainId] ??= {};
10791
+ const cache7 = FIXED_TERMS_CACHE[chainId] ??= {};
10792
10792
  results.forEach((raw, i) => {
10793
10793
  if (!raw) return;
10794
10794
  const id = ids[i];
@@ -10802,7 +10802,7 @@ async function fetchListaFixedTerms(chainId, marketKeys, multicallRetry) {
10802
10802
  };
10803
10803
  });
10804
10804
  out[id] = terms;
10805
- cache6[id] = terms;
10805
+ cache7[id] = terms;
10806
10806
  });
10807
10807
  } catch (e) {
10808
10808
  console.warn(
@@ -12307,6 +12307,39 @@ function formatNr(n, d) {
12307
12307
  return Number(formatUnits(BigInt(n ?? 0), d));
12308
12308
  }
12309
12309
 
12310
+ // src/lending/public-data/morpho/unlisted.ts
12311
+ var MORPHO_UNLISTED_CHAINS = /* @__PURE__ */ new Set([
12312
+ // Robinhood Chain. 189 of its 194 markets are unlisted and essentially all of
12313
+ // them are Longbow — a curated Morpho Blue deployment (tokenized equities and
12314
+ // RWAs against USDG) that Morpho's own frontend does not carry, so `listed`
12315
+ // here says nothing about the market's quality. Enabled 2026-09-08 together
12316
+ // with the three things a chain needs before it can be:
12317
+ // 1. its collateral tokens in `token-lists` (wsNET was the last gap — the
12318
+ // collateral of the chain's LARGEST market), or the rows price at $0,
12319
+ // 2. `lender-metadata`'s `SERVES_UNLISTED_CHAINS` carrying the same chain
12320
+ // id, so the markets get a NAME and an oracle roster (5 -> 188 rows),
12321
+ // 3. a look at what the unlisted book actually holds — here 56 real
12322
+ // markets, $524k supplied / $351k borrowed, no runaway rates (the
12323
+ // highest borrow APR on the chain is 21.9 %).
12324
+ // See LONGBOW.md.
12325
+ "4663",
12326
+ // World Chain. blue-api indexes it, but 0 of its 30 markets are listed —
12327
+ // Morpho's frontend simply does not carry the chain, so `listed` says
12328
+ // nothing about the book (the Longbow shape again). Looked at 2026-09-16:
12329
+ // $59.5M supplied / $45.0M borrowed, of which the real two-sided markets are
12330
+ // USDC/WBTC $3.9M, USDC/WETH $3.6M, WETH/WBTC $2.1M, USDC/WLD $1.6M and
12331
+ // WETH/ezETH $1.1M at 0.1–4.6 % borrow APY; the $35.8M USDC/sdeUSD market is
12332
+ // pinned at 100 % utilization (297,994 % APY, $0 liquid) and is exactly what
12333
+ // `earn/rateSanity.ts` exists to drop. Token-list gaps on 480 at enablement:
12334
+ // sdeUSD and ezETH (collateral of two markets) — those rows price at $0 with
12335
+ // a blank LTV until token-lists carries them. `lender-metadata`'s
12336
+ // `SERVES_UNLISTED_CHAINS` was updated in the same change.
12337
+ "480"
12338
+ ]);
12339
+ function morphoIncludesUnlisted(chainId) {
12340
+ return MORPHO_UNLISTED_CHAINS.has(chainId);
12341
+ }
12342
+
12310
12343
  // src/lending/public-data/morpho/convertPublic.ts
12311
12344
  function convertMarketsToMorphoResponse(response, chainId, additionalYields = {
12312
12345
  intrinsicYields: {},
@@ -12316,6 +12349,7 @@ function convertMarketsToMorphoResponse(response, chainId, additionalYields = {
12316
12349
  const data = {};
12317
12350
  const items = response?.markets?.items;
12318
12351
  if (!items) return data;
12352
+ const listedFlagMeaningful = !morphoIncludesUnlisted(chainId);
12319
12353
  items.forEach((market) => {
12320
12354
  const {
12321
12355
  uniqueKey,
@@ -12480,7 +12514,7 @@ function convertMarketsToMorphoResponse(response, chainId, additionalYields = {
12480
12514
  irm: irmAddress,
12481
12515
  collateralAddress: collateralAssetAddress,
12482
12516
  loanAddress: loanAssetAddress,
12483
- isListed: whitelisted,
12517
+ isListed: whitelisted || listedFlagMeaningful ? whitelisted : void 0,
12484
12518
  fee: state.fee,
12485
12519
  rateAtTarget: state?.rateAtTarget?.toString()
12486
12520
  }
@@ -12490,18 +12524,220 @@ function convertMarketsToMorphoResponse(response, chainId, additionalYields = {
12490
12524
  });
12491
12525
  return data;
12492
12526
  }
12493
- var query = (first, skip, chainId, includeUnlisted = false) => `
12527
+
12528
+ // src/lending/public-data/morpho/vaultFunded.ts
12529
+ var MORPHO_VAULT_FUNDED_MIN_USD = 1e4;
12530
+ var MORPHO_VAULT_FUNDED_MIN_VAULT_USD = 1e3;
12531
+ var BASE_URL = "https://blue-api.morpho.org/graphql";
12532
+ var V1_PAGE = 100;
12533
+ var V2_PAGE = 50;
12534
+ var MAX_PAGES = 20;
12535
+ var CACHE_TTL_MS = 15 * 6e4;
12536
+ var FAIL_TTL_MS = 6e4;
12537
+ var V1_VAULT_ALLOCATIONS_QUERY = (first, skip, chainId) => `
12538
+ query VaultFundedV1 {
12539
+ vaults(first: ${first}, skip: ${skip}, where: {
12540
+ chainId_in: [${chainId}],
12541
+ totalAssetsUsd_gte: ${MORPHO_VAULT_FUNDED_MIN_VAULT_USD}
12542
+ }) {
12543
+ items {
12544
+ address
12545
+ state {
12546
+ allocation {
12547
+ supplyAssetsUsd
12548
+ market { marketId listed collateralAsset { address } }
12549
+ }
12550
+ }
12551
+ }
12552
+ }
12553
+ }
12554
+ `;
12555
+ var V2_VAULT_CAPS_QUERY = (first, skip, chainId) => `
12556
+ query VaultFundedV2 {
12557
+ vaultV2s(first: ${first}, skip: ${skip}, where: {
12558
+ chainId_in: [${chainId}],
12559
+ totalAssetsUsd_gte: ${MORPHO_VAULT_FUNDED_MIN_VAULT_USD}
12560
+ }) {
12561
+ items {
12562
+ address
12563
+ totalAssets
12564
+ totalAssetsUsd
12565
+ asset { decimals price { usd } }
12566
+ caps {
12567
+ items {
12568
+ type
12569
+ allocation
12570
+ data {
12571
+ __typename
12572
+ ... on MarketV1CapData {
12573
+ market { marketId listed collateralAsset { address } }
12574
+ }
12575
+ }
12576
+ }
12577
+ }
12578
+ }
12579
+ }
12580
+ }
12581
+ `;
12582
+ var ZERO = "0x0000000000000000000000000000000000000000";
12583
+ var isUnlistedLendable = (m) => {
12584
+ if (m?.listed !== false) return false;
12585
+ const coll = m.collateralAsset?.address?.toLowerCase();
12586
+ return !!coll && coll !== ZERO;
12587
+ };
12588
+ function sumVaultFundedUnlisted(v1Vaults, v2Vaults, minUsd = MORPHO_VAULT_FUNDED_MIN_USD) {
12589
+ const byMarket = /* @__PURE__ */ new Map();
12590
+ const add = (marketId, usd) => {
12591
+ if (!marketId || usd == null || !Number.isFinite(usd) || usd <= 0) return;
12592
+ const k = marketId.toLowerCase();
12593
+ byMarket.set(k, (byMarket.get(k) ?? 0) + usd);
12594
+ };
12595
+ for (const v of v1Vaults) {
12596
+ for (const a of v?.state?.allocation ?? []) {
12597
+ if (!isUnlistedLendable(a?.market)) continue;
12598
+ add(a.market.marketId, typeof a.supplyAssetsUsd === "number" ? a.supplyAssetsUsd : null);
12599
+ }
12600
+ }
12601
+ for (const v of v2Vaults) {
12602
+ const decimals = typeof v?.asset?.decimals === "number" ? v.asset.decimals : null;
12603
+ let price2 = typeof v?.asset?.price?.usd === "number" ? v.asset.price.usd : null;
12604
+ const total = Number(v?.totalAssets ?? 0);
12605
+ if (price2 == null && decimals != null && total > 0 && typeof v?.totalAssetsUsd === "number")
12606
+ price2 = v.totalAssetsUsd / (total / 10 ** decimals);
12607
+ for (const c of v?.caps?.items ?? []) {
12608
+ if (c?.type !== "MarketV1") continue;
12609
+ const m = c.data?.market;
12610
+ if (!isUnlistedLendable(m)) continue;
12611
+ const raw = Number(c.allocation ?? 0);
12612
+ add(m.marketId, price2 != null && decimals != null ? raw / 10 ** decimals * price2 : null);
12613
+ }
12614
+ }
12615
+ return [...byMarket].filter(([, usd]) => usd >= minUsd).map(([marketId, vaultUsd]) => ({ marketId, vaultUsd })).sort((a, b) => b.vaultUsd - a.vaultUsd || a.marketId.localeCompare(b.marketId));
12616
+ }
12617
+ async function post(query3) {
12618
+ const res = await fetch(BASE_URL, {
12619
+ method: "POST",
12620
+ headers: { "Content-Type": "application/json" },
12621
+ body: JSON.stringify({ query: query3 })
12622
+ });
12623
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
12624
+ const json = await res.json();
12625
+ if (json?.errors?.length)
12626
+ throw new Error(json.errors.map((e) => e?.message).join("; "));
12627
+ return json.data;
12628
+ }
12629
+ async function pageAll(build6, field13, pageSize) {
12630
+ const out = [];
12631
+ for (let page = 0; page < MAX_PAGES; page++) {
12632
+ const items = (await post(build6(pageSize, page * pageSize)))?.[field13]?.items;
12633
+ if (!Array.isArray(items)) throw new Error(`unexpected ${field13} shape`);
12634
+ out.push(...items);
12635
+ if (items.length < pageSize) return out;
12636
+ }
12637
+ console.warn(`[morpho-vault-funded] ${field13}: hit MAX_PAGES, result truncated`);
12638
+ return out;
12639
+ }
12640
+ async function discover(chainId) {
12641
+ const [v1, v2] = await Promise.all([
12642
+ pageAll((f, s) => V1_VAULT_ALLOCATIONS_QUERY(f, s, chainId), "vaults", V1_PAGE),
12643
+ pageAll((f, s) => V2_VAULT_CAPS_QUERY(f, s, chainId), "vaultV2s", V2_PAGE)
12644
+ ]);
12645
+ return sumVaultFundedUnlisted(v1, v2);
12646
+ }
12647
+ var cache = /* @__PURE__ */ new Map();
12648
+ function morphoVaultFundedUnlistedMarkets(chainId) {
12649
+ if (morphoIncludesUnlisted(chainId)) return Promise.resolve([]);
12650
+ const now = Date.now();
12651
+ const hit = cache.get(chainId);
12652
+ if (hit && now - hit.at < hit.ttl) return hit.promise;
12653
+ const entry = { at: now, ttl: CACHE_TTL_MS, promise: Promise.resolve([]) };
12654
+ entry.promise = discover(chainId).catch((e) => {
12655
+ entry.ttl = FAIL_TTL_MS;
12656
+ console.warn(
12657
+ `[morpho-vault-funded] chain ${chainId}: discovery failed, serving listed markets only:`,
12658
+ e?.message ?? e
12659
+ );
12660
+ return [];
12661
+ });
12662
+ cache.set(chainId, entry);
12663
+ return entry.promise;
12664
+ }
12665
+ async function morphoVaultFundedUnlistedMarketIds(chainId) {
12666
+ return (await morphoVaultFundedUnlistedMarkets(chainId)).map((m) => m.marketId);
12667
+ }
12668
+ var uniqueKeyInFilter = (keys) => `uniqueKey_in: [${keys.map((k) => JSON.stringify(k.toLowerCase())).join(", ")}]`;
12669
+ function mergeMarketItemsByKey(base, extra) {
12670
+ const have = new Set(base.map((m) => m?.uniqueKey?.toLowerCase()));
12671
+ const out = [...base];
12672
+ for (const m of extra) {
12673
+ const k = m?.uniqueKey?.toLowerCase();
12674
+ if (!k || have.has(k)) continue;
12675
+ have.add(k);
12676
+ out.push(m);
12677
+ }
12678
+ return out;
12679
+ }
12680
+ var BY_KEY_CHUNK = 100;
12681
+ async function appendVaultFundedMarkets(chainId, base, buildByKeys) {
12682
+ const ids = await morphoVaultFundedUnlistedMarketIds(chainId);
12683
+ if (ids.length === 0) return base;
12684
+ const have = new Set(base.map((m) => m?.uniqueKey?.toLowerCase()));
12685
+ const missing = ids.filter((id) => !have.has(id));
12686
+ if (missing.length === 0) return base;
12687
+ try {
12688
+ const extra = [];
12689
+ for (let i = 0; i < missing.length; i += BY_KEY_CHUNK) {
12690
+ const items = (await post(buildByKeys(missing.slice(i, i + BY_KEY_CHUNK))))?.markets?.items;
12691
+ if (!Array.isArray(items)) throw new Error("unexpected markets shape");
12692
+ extra.push(...items);
12693
+ }
12694
+ return mergeMarketItemsByKey(base, extra);
12695
+ } catch (e) {
12696
+ console.warn(
12697
+ `[morpho-vault-funded] chain ${chainId}: by-key fetch of ${missing.length} markets failed:`,
12698
+ e?.message ?? e
12699
+ );
12700
+ return base;
12701
+ }
12702
+ }
12703
+
12704
+ // src/lending/public-data/morpho/apiFields.ts
12705
+ function normalizeMorphoApiMarket(item) {
12706
+ if (!item || typeof item !== "object") return item;
12707
+ const out = { ...item };
12708
+ if ("oracle" in out) {
12709
+ out.oracleAddress = out.oracle?.address ?? void 0;
12710
+ delete out.oracle;
12711
+ }
12712
+ for (const side of ["loanAsset", "collateralAsset"]) {
12713
+ const a = out[side];
12714
+ if (a && typeof a === "object" && "price" in a) {
12715
+ const { price: price2, ...rest } = a;
12716
+ out[side] = { ...rest, priceUsd: price2?.usd ?? null };
12717
+ }
12718
+ }
12719
+ return out;
12720
+ }
12721
+ function normalizeMorphoApiMarkets(items) {
12722
+ return items.map(normalizeMorphoApiMarket);
12723
+ }
12724
+
12725
+ // src/lending/public-data/morpho/fetchPublic.ts
12726
+ var query = (first, skip, chainId, includeUnlisted = false, uniqueKeys) => `
12494
12727
  query GetMarkets {
12495
12728
  markets(first: ${first}, skip: ${skip}, where: {
12496
- chainId_in: [${chainId}]${includeUnlisted ? "" : ",\n listed: true"}
12729
+ chainId_in: [${chainId}]${uniqueKeys ? `,
12730
+ ${uniqueKeyInFilter(uniqueKeys)}` : includeUnlisted ? "" : ",\n listed: true"}
12497
12731
  },
12498
- orderBy: SupplyAssetsUsd,
12732
+ orderBy: ${uniqueKeys ? "UniqueKey" : "SupplyAssetsUsd"},
12499
12733
  orderDirection: Desc
12500
12734
  ) {
12501
12735
  items {
12502
12736
  uniqueKey: marketId
12503
12737
  irmAddress
12504
- oracleAddress
12738
+ oracle {
12739
+ address
12740
+ }
12505
12741
  lltv
12506
12742
  whitelisted: listed
12507
12743
  loanAsset {
@@ -12509,14 +12745,18 @@ query GetMarkets {
12509
12745
  name
12510
12746
  symbol
12511
12747
  decimals
12512
- priceUsd
12748
+ price {
12749
+ usd
12750
+ }
12513
12751
  }
12514
12752
  collateralAsset {
12515
12753
  address
12516
12754
  name
12517
12755
  symbol
12518
12756
  decimals
12519
- priceUsd
12757
+ price {
12758
+ usd
12759
+ }
12520
12760
  }
12521
12761
  state {
12522
12762
  borrowApy
@@ -12544,7 +12784,7 @@ query GetMarkets {
12544
12784
  }
12545
12785
  }
12546
12786
  `;
12547
- var BASE_URL = "https://blue-api.morpho.org/graphql";
12787
+ var BASE_URL2 = "https://blue-api.morpho.org/graphql";
12548
12788
  function assertNoGraphQLErrors(json) {
12549
12789
  if (json?.errors?.length) {
12550
12790
  throw new Error(
@@ -12553,12 +12793,25 @@ function assertNoGraphQLErrors(json) {
12553
12793
  }
12554
12794
  }
12555
12795
  async function fetchMorphoMarkets(chainId, includeUnlisted = false) {
12796
+ const data = await fetchMorphoMarketsBase(chainId, includeUnlisted);
12797
+ if (!Array.isArray(data?.markets?.items)) return data;
12798
+ const items = includeUnlisted ? data.markets.items : await appendVaultFundedMarkets(
12799
+ chainId,
12800
+ data.markets.items,
12801
+ (keys) => query(keys.length, 0, chainId, false, keys)
12802
+ );
12803
+ return {
12804
+ ...data,
12805
+ markets: { ...data.markets, items: normalizeMorphoApiMarkets(items) }
12806
+ };
12807
+ }
12808
+ async function fetchMorphoMarketsBase(chainId, includeUnlisted) {
12556
12809
  if (chainId !== Chain.ETHEREUM_MAINNET) {
12557
12810
  const requestBody = {
12558
12811
  query: query(200, 0, chainId, includeUnlisted),
12559
12812
  variables: {}
12560
12813
  };
12561
- const response = await fetch(BASE_URL, {
12814
+ const response = await fetch(BASE_URL2, {
12562
12815
  method: "POST",
12563
12816
  headers: {
12564
12817
  "Content-Type": "application/json"
@@ -12583,14 +12836,14 @@ async function fetchMorphoMarkets(chainId, includeUnlisted = false) {
12583
12836
  variables: {}
12584
12837
  };
12585
12838
  const [data0, data1] = await Promise.all([
12586
- fetch(BASE_URL, {
12839
+ fetch(BASE_URL2, {
12587
12840
  method: "POST",
12588
12841
  headers: {
12589
12842
  "Content-Type": "application/json"
12590
12843
  },
12591
12844
  body: JSON.stringify(requestBody0)
12592
12845
  }).then((x) => x.json()),
12593
- fetch(BASE_URL, {
12846
+ fetch(BASE_URL2, {
12594
12847
  method: "POST",
12595
12848
  headers: {
12596
12849
  "Content-Type": "application/json"
@@ -20181,7 +20434,7 @@ var FLUID_API_BASE = "https://api.fluid.instadapp.io/v2";
20181
20434
  var SUPPORTED_CHAINS = /* @__PURE__ */ new Set(["1", "56", "137", "8453", "9745", "42161"]);
20182
20435
  var TTL_MS2 = 6e4;
20183
20436
  var ZERO_ADDRESS4 = "0x0000000000000000000000000000000000000000";
20184
- var cache = {};
20437
+ var cache2 = {};
20185
20438
  var inflight = /* @__PURE__ */ new Map();
20186
20439
  var isRealDex = (d) => !!d && String(d.id ?? "0") !== "0" && String(d.address ?? ZERO_ADDRESS4).toLowerCase() !== ZERO_ADDRESS4;
20187
20440
  var toBigInt7 = (v) => {
@@ -20226,7 +20479,7 @@ var parseChainPayload = (raw) => {
20226
20479
  };
20227
20480
  var fetchFluidApiData = async (chainId) => {
20228
20481
  if (!SUPPORTED_CHAINS.has(chainId)) return void 0;
20229
- const hit = cache[chainId];
20482
+ const hit = cache2[chainId];
20230
20483
  if (hit && Date.now() - hit.at < TTL_MS2) return hit.data;
20231
20484
  const pending = inflight.get(chainId);
20232
20485
  if (pending) return pending;
@@ -20237,11 +20490,11 @@ var fetchFluidApiData = async (chainId) => {
20237
20490
  const json = await res.json();
20238
20491
  if (!Array.isArray(json)) throw new Error("unexpected payload");
20239
20492
  const data = parseChainPayload(json);
20240
- cache[chainId] = { at: Date.now(), data };
20493
+ cache2[chainId] = { at: Date.now(), data };
20241
20494
  return data;
20242
20495
  } catch {
20243
- const prev = cache[chainId]?.data;
20244
- cache[chainId] = { at: Date.now(), data: prev };
20496
+ const prev = cache2[chainId]?.data;
20497
+ cache2[chainId] = { at: Date.now(), data: prev };
20245
20498
  return prev;
20246
20499
  } finally {
20247
20500
  inflight.delete(chainId);
@@ -20250,7 +20503,7 @@ var fetchFluidApiData = async (chainId) => {
20250
20503
  inflight.set(chainId, run);
20251
20504
  return run;
20252
20505
  };
20253
- var getCachedFluidApiData = (chainId) => cache[chainId]?.data;
20506
+ var getCachedFluidApiData = (chainId) => cache2[chainId]?.data;
20254
20507
  var DEX_RESOLVER_FALLBACK = {
20255
20508
  "1": "0x11D80CfF056Cef4F9E6d23da8672fE9873e5cC07",
20256
20509
  "137": "0x11D80CfF056Cef4F9E6d23da8672fE9873e5cC07",
@@ -20262,12 +20515,12 @@ var DEX_RESOLVER_FALLBACK = {
20262
20515
  var dexResolverFor = (chainId) => fluidResolvers()?.[chainId]?.dexResolver ?? DEX_RESOLVER_FALLBACK[chainId];
20263
20516
  var ZERO_ADDRESS5 = "0x0000000000000000000000000000000000000000";
20264
20517
  var TTL_MS3 = 6e4;
20265
- var cache2 = {};
20518
+ var cache3 = {};
20266
20519
  var inflight2 = /* @__PURE__ */ new Map();
20267
20520
  var fetchFluidDexState = async (chainId, multicallRetry, extraDexAddresses = []) => {
20268
20521
  const resolver = dexResolverFor(chainId);
20269
20522
  if (!resolver) return void 0;
20270
- const hit = cache2[chainId];
20523
+ const hit = cache3[chainId];
20271
20524
  if (hit && Date.now() - hit.at < TTL_MS3) return hit.data;
20272
20525
  const pending = inflight2.get(chainId);
20273
20526
  if (pending) return pending;
@@ -20307,11 +20560,11 @@ var fetchFluidDexState = async (chainId, multicallRetry, extraDexAddresses = [])
20307
20560
  totalBorrowShares: BigInt(s.totalBorrowShares ?? 0)
20308
20561
  };
20309
20562
  }
20310
- cache2[chainId] = { at: Date.now(), data };
20563
+ cache3[chainId] = { at: Date.now(), data };
20311
20564
  return data;
20312
20565
  } catch {
20313
- const prev = cache2[chainId]?.data;
20314
- cache2[chainId] = { at: Date.now(), data: prev };
20566
+ const prev = cache3[chainId]?.data;
20567
+ cache3[chainId] = { at: Date.now(), data: prev };
20315
20568
  return prev;
20316
20569
  } finally {
20317
20570
  inflight2.delete(chainId);
@@ -20320,7 +20573,7 @@ var fetchFluidDexState = async (chainId, multicallRetry, extraDexAddresses = [])
20320
20573
  inflight2.set(chainId, run);
20321
20574
  return run;
20322
20575
  };
20323
- var getCachedFluidDexState = (chainId) => cache2[chainId]?.data;
20576
+ var getCachedFluidDexState = (chainId) => cache3[chainId]?.data;
20324
20577
 
20325
20578
  // src/lending/public-data/fluid/publicCallParse.ts
20326
20579
  var FLUID_EEE_LOWER = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
@@ -25517,7 +25770,7 @@ var LLAMALEND_READ_ABI = [
25517
25770
  ...LlamaLendAmmAbi,
25518
25771
  ...Erc20Abi
25519
25772
  ];
25520
- var ZERO = "0x0000000000000000000000000000000000000000";
25773
+ var ZERO2 = "0x0000000000000000000000000000000000000000";
25521
25774
  var WAD8 = 10n ** 18n;
25522
25775
  var CALLS_PER_MARKET = 6;
25523
25776
  var fetchJson2 = async (url, timeoutMs = 8e3) => {
@@ -25566,7 +25819,7 @@ async function fetchChainExtras(chainId, markets) {
25566
25819
  { address: m.amm, name: "price_oracle", params: [] },
25567
25820
  { address: m.amm, name: "active_band", params: [] },
25568
25821
  { address: m.controller, name: "n_loans", params: [] },
25569
- { address: m.vault, name: "maxDeposit", params: [ZERO] },
25822
+ { address: m.vault, name: "maxDeposit", params: [ZERO2] },
25570
25823
  // v1 controllers have no `borrow_cap`; allowFailure turns that into a
25571
25824
  // null rather than sinking the whole batch.
25572
25825
  { address: m.controller, name: "borrow_cap", params: [] },
@@ -29339,7 +29592,7 @@ function convertFrankencoinMarketsToResponse(raw, chainId, prices = {}, _additio
29339
29592
  }
29340
29593
 
29341
29594
  // src/lending/public-data/silo-v2/fetchPublic.ts
29342
- var BASE_URL2 = "https://api-v3.silo.finance";
29595
+ var BASE_URL3 = "https://api-v3.silo.finance";
29343
29596
  var SILO_API_SUPPORTED_CHAIN_IDS = /* @__PURE__ */ new Set([
29344
29597
  "1",
29345
29598
  // Ethereum
@@ -29482,7 +29735,7 @@ query GetSilosLite {
29482
29735
  async function fetchSiloMarketsLite(chainId, options) {
29483
29736
  if (!SILO_API_SUPPORTED_CHAIN_IDS.has(chainId)) return [];
29484
29737
  const limit = options?.limit ?? 500;
29485
- const response = await fetch(BASE_URL2, {
29738
+ const response = await fetch(BASE_URL3, {
29486
29739
  method: "POST",
29487
29740
  headers: { "Content-Type": "application/json" },
29488
29741
  body: JSON.stringify({ query: liteQuery(chainId, limit) })
@@ -29507,7 +29760,7 @@ async function fetchSiloMarketsLite(chainId, options) {
29507
29760
  async function fetchSiloMarkets(chainId, options) {
29508
29761
  if (!SILO_API_SUPPORTED_CHAIN_IDS.has(chainId)) return [];
29509
29762
  const limit = options?.limit ?? 500;
29510
- const response = await fetch(BASE_URL2, {
29763
+ const response = await fetch(BASE_URL3, {
29511
29764
  method: "POST",
29512
29765
  headers: { "Content-Type": "application/json" },
29513
29766
  body: JSON.stringify({ query: query2(chainId, limit) })
@@ -30288,39 +30541,6 @@ var getLenderPublicDataViaApi = async (chainId, lenders, prices, additionalYield
30288
30541
  }
30289
30542
  return lenderData;
30290
30543
  };
30291
-
30292
- // src/lending/public-data/morpho/unlisted.ts
30293
- var MORPHO_UNLISTED_CHAINS = /* @__PURE__ */ new Set([
30294
- // Robinhood Chain. 189 of its 194 markets are unlisted and essentially all of
30295
- // them are Longbow — a curated Morpho Blue deployment (tokenized equities and
30296
- // RWAs against USDG) that Morpho's own frontend does not carry, so `listed`
30297
- // here says nothing about the market's quality. Enabled 2026-09-08 together
30298
- // with the three things a chain needs before it can be:
30299
- // 1. its collateral tokens in `token-lists` (wsNET was the last gap — the
30300
- // collateral of the chain's LARGEST market), or the rows price at $0,
30301
- // 2. `lender-metadata`'s `SERVES_UNLISTED_CHAINS` carrying the same chain
30302
- // id, so the markets get a NAME and an oracle roster (5 -> 188 rows),
30303
- // 3. a look at what the unlisted book actually holds — here 56 real
30304
- // markets, $524k supplied / $351k borrowed, no runaway rates (the
30305
- // highest borrow APR on the chain is 21.9 %).
30306
- // See LONGBOW.md.
30307
- "4663",
30308
- // World Chain. blue-api indexes it, but 0 of its 30 markets are listed —
30309
- // Morpho's frontend simply does not carry the chain, so `listed` says
30310
- // nothing about the book (the Longbow shape again). Looked at 2026-09-16:
30311
- // $59.5M supplied / $45.0M borrowed, of which the real two-sided markets are
30312
- // USDC/WBTC $3.9M, USDC/WETH $3.6M, WETH/WBTC $2.1M, USDC/WLD $1.6M and
30313
- // WETH/ezETH $1.1M at 0.1–4.6 % borrow APY; the $35.8M USDC/sdeUSD market is
30314
- // pinned at 100 % utilization (297,994 % APY, $0 liquid) and is exactly what
30315
- // `earn/rateSanity.ts` exists to drop. Token-list gaps on 480 at enablement:
30316
- // sdeUSD and ezETH (collateral of two markets) — those rows price at $0 with
30317
- // a blank LTV until token-lists carries them. `lender-metadata`'s
30318
- // `SERVES_UNLISTED_CHAINS` was updated in the same change.
30319
- "480"
30320
- ]);
30321
- function morphoIncludesUnlisted(chainId) {
30322
- return MORPHO_UNLISTED_CHAINS.has(chainId);
30323
- }
30324
30544
  var ERC20_BALANCE_OF_ABI2 = [
30325
30545
  {
30326
30546
  inputs: [{ name: "account", type: "address" }],
@@ -30943,7 +31163,7 @@ function decodeVariableLensRows(blob, fixedWords, headerBytes = 0) {
30943
31163
  }
30944
31164
 
30945
31165
  // src/lending/user-data/aave-v3-type/lens.ts
30946
- var ZERO2 = "0x0000000000000000000000000000000000000000";
31166
+ var ZERO3 = "0x0000000000000000000000000000000000000000";
30947
31167
  var AAVE_LENS_HEADER_BYTES = 3;
30948
31168
  var HEADER_EMODE_OK = 1;
30949
31169
  var HEADER_CONFIG_OK = 2;
@@ -30951,7 +31171,7 @@ var AAVE_LENS_WORDS = 7;
30951
31171
  var reserveTuple = (tokens, asset) => {
30952
31172
  const t = tokens?.[asset.toLowerCase()];
30953
31173
  if (!t?.aToken || !t?.vToken) return void 0;
30954
- return [asset, t.aToken, t.vToken, t.sToken ?? ZERO2];
31174
+ return [asset, t.aToken, t.vToken, t.sToken ?? ZERO3];
30955
31175
  };
30956
31176
  var usesAaveLens = (chainId, lender) => {
30957
31177
  if (getPositionLensFor(chainId, LENS_FAMILY.AAVE) === void 0) return false;
@@ -30981,7 +31201,7 @@ var buildAaveLensCall = (chainId, lender, account, assetsToQuery, withEMode) =>
30981
31201
  getAaveTypePoolDataProviderAddress(chainId, lender),
30982
31202
  // A zero pool disables the e-mode read, which is exactly what YLDR wants:
30983
31203
  // it has no `getUserEMode` and the walk omits that call for it too.
30984
- withEMode ? getAaveTypePoolAddress(chainId, lender) : ZERO2
31204
+ withEMode ? getAaveTypePoolAddress(chainId, lender) : ZERO3
30985
31205
  ]
30986
31206
  );
30987
31207
  return [
@@ -32061,7 +32281,7 @@ var buildExactlyUserCall = (chainId, _lender, account) => {
32061
32281
  return [{ address: cfg.previewer, name: "exactly", params: [account] }];
32062
32282
  };
32063
32283
  var OWNER_INDEX_PROBE_COUNT = 8;
32064
- var CACHE_TTL_MS = 5 * 6e4;
32284
+ var CACHE_TTL_MS2 = 5 * 6e4;
32065
32285
  var discoveryCache = /* @__PURE__ */ new Map();
32066
32286
  async function discoverViaLens(chainId, branches, zappers, account, opts) {
32067
32287
  const lens = getPositionLensFor(chainId, LENS_FAMILY.LIQUITY);
@@ -32130,7 +32350,7 @@ var getCachedLiquityTroves = (chainId, lender, account, opts) => {
32130
32350
  const hit = discoveryCache.get(
32131
32351
  cacheKey(chainId, lender, account, blockKey(opts))
32132
32352
  );
32133
- if (!hit || Date.now() - hit.at > CACHE_TTL_MS) return void 0;
32353
+ if (!hit || Date.now() - hit.at > CACHE_TTL_MS2) return void 0;
32134
32354
  return hit;
32135
32355
  };
32136
32356
  var ADDRESS_ADDRESS_UINT = [
@@ -32350,7 +32570,7 @@ var buildRiverUserCall = (chainId, lender, account) => {
32350
32570
  });
32351
32571
  return calls;
32352
32572
  };
32353
- var ZERO3 = "0x0000000000000000000000000000000000000000";
32573
+ var ZERO4 = "0x0000000000000000000000000000000000000000";
32354
32574
  var LLAMALEND_LENS_WORDS = 12;
32355
32575
  var LLAMALEND_CALLS_PER_MARKET = 8;
32356
32576
  var usesLlamaLendLens = (chainId) => getPositionLensFor(chainId, LENS_FAMILY.LLAMALEND) !== void 0;
@@ -32364,7 +32584,7 @@ var buildLlamaLendLensCall = (chainId, markets, account, delegate) => {
32364
32584
  m.controller,
32365
32585
  m.amm,
32366
32586
  m.vault,
32367
- m.gauge ?? ZERO3
32587
+ m.gauge ?? ZERO4
32368
32588
  ]),
32369
32589
  delegate
32370
32590
  ]
@@ -32913,7 +33133,7 @@ function getCachedTwyneDiscovery(chainId, lender, account, opts) {
32913
33133
  }
32914
33134
  var lower2 = (a) => String(a).toLowerCase();
32915
33135
  var isAddress4 = (v) => typeof v === "string" && /^0x[0-9a-fA-F]{40}$/.test(v);
32916
- async function discover(chainId, lender, account, opts) {
33136
+ async function discover2(chainId, lender, account, opts) {
32917
33137
  const key3 = discoveryKey3(chainId, lender, account, blockKey(opts));
32918
33138
  const cached = discoveryCache4.get(key3);
32919
33139
  if (cached && Date.now() - cached.at < DISCOVERY_TTL_MS3) return cached;
@@ -33015,7 +33235,7 @@ async function discover(chainId, lender, account, opts) {
33015
33235
  return result;
33016
33236
  }
33017
33237
  async function buildTwyneUserCall(chainId, lender, account, opts) {
33018
- const { vaults } = await discover(chainId, lender, account, opts);
33238
+ const { vaults } = await discover2(chainId, lender, account, opts);
33019
33239
  if (vaults.length === 0) return [];
33020
33240
  return vaults.flatMap(({ vault }) => [
33021
33241
  { address: vault, name: "totalAssetsDepositedOrReserved", args: [] },
@@ -33029,14 +33249,14 @@ async function buildTwyneUserCall(chainId, lender, account, opts) {
33029
33249
  }
33030
33250
  var DSS_CALLS_PER_CDP = 1;
33031
33251
  var MAX_CDP_WALK = 64;
33032
- var CACHE_TTL_MS2 = 5 * 6e4;
33252
+ var CACHE_TTL_MS3 = 5 * 6e4;
33033
33253
  var discoveryCache5 = /* @__PURE__ */ new Map();
33034
33254
  var cacheKey2 = (lender, chainId, account, block = "head") => `${lender}:${chainId}:${account.toLowerCase()}:${block}`;
33035
33255
  var getCachedDssCdps = (lender, chainId, account, opts) => {
33036
33256
  const hit = discoveryCache5.get(
33037
33257
  cacheKey2(lender, chainId, account, blockKey(opts))
33038
33258
  );
33039
- if (!hit || Date.now() - hit.at > CACHE_TTL_MS2) return void 0;
33259
+ if (!hit || Date.now() - hit.at > CACHE_TTL_MS3) return void 0;
33040
33260
  return hit;
33041
33261
  };
33042
33262
  var big7 = (v) => {
@@ -33279,12 +33499,12 @@ async function discoverTellerBidsViaLens(chainId, tellerV2, account, opts) {
33279
33499
 
33280
33500
  // src/lending/user-data/teller/userCallBuild.ts
33281
33501
  var TELLER_CALLS_PER_BID = 4;
33282
- var CACHE_TTL_MS3 = 5 * 6e4;
33502
+ var CACHE_TTL_MS4 = 5 * 6e4;
33283
33503
  var discoveryCache7 = /* @__PURE__ */ new Map();
33284
33504
  var cacheKey4 = (chainId, account, block = "head") => `${chainId}:${account.toLowerCase()}:${block}`;
33285
33505
  var getCachedTellerBids = (chainId, account, opts) => {
33286
33506
  const hit = discoveryCache7.get(cacheKey4(chainId, account, blockKey(opts)));
33287
- if (!hit || Date.now() - hit.at > CACHE_TTL_MS3) return void 0;
33507
+ if (!hit || Date.now() - hit.at > CACHE_TTL_MS4) return void 0;
33288
33508
  return hit;
33289
33509
  };
33290
33510
  var nowSec5 = () => Math.floor(Date.now() / 1e3);
@@ -33421,12 +33641,12 @@ var buildFlyingTulipUserCall = (chainId, lender, account) => {
33421
33641
  ];
33422
33642
  };
33423
33643
  var TERMMAX_MARKETS_PER_CALL = 180;
33424
- var CACHE_TTL_MS4 = 5 * 6e4;
33644
+ var CACHE_TTL_MS5 = 5 * 6e4;
33425
33645
  var discoveryCache8 = /* @__PURE__ */ new Map();
33426
33646
  var cacheKey5 = (chainId, account) => `${chainId}:${account.toLowerCase()}`;
33427
33647
  var getCachedTermMaxDiscovery = (chainId, account) => {
33428
33648
  const hit = discoveryCache8.get(cacheKey5(chainId, account));
33429
- if (!hit || Date.now() - hit.at > CACHE_TTL_MS4) return void 0;
33649
+ if (!hit || Date.now() - hit.at > CACHE_TTL_MS5) return void 0;
33430
33650
  return hit;
33431
33651
  };
33432
33652
  var buildTermMaxUserCall = async (chainId, _lender, account) => {
@@ -43706,7 +43926,7 @@ var MORPHO_API_CHAIN_IDS = {
43706
43926
  [Chain.UNICHAIN]: 130
43707
43927
  };
43708
43928
  var FETCH_TIMEOUT_MS = 3e3;
43709
- var CACHE_TTL_MS5 = 2e3;
43929
+ var CACHE_TTL_MS6 = 2e3;
43710
43930
  var buildSubgraphQuery = (account) => `
43711
43931
  {
43712
43932
  account(id: "${account.toLowerCase()}") {
@@ -43774,7 +43994,7 @@ async function dedupedFetch(chainId, account, loader) {
43774
43994
  const existing = inflight3.get(key3);
43775
43995
  if (existing) return existing;
43776
43996
  const promise = loader().then((value) => {
43777
- resolved.set(key3, { value, expiresAt: Date.now() + CACHE_TTL_MS5 });
43997
+ resolved.set(key3, { value, expiresAt: Date.now() + CACHE_TTL_MS6 });
43778
43998
  return value;
43779
43999
  }).finally(() => {
43780
44000
  inflight3.delete(key3);
@@ -56751,7 +56971,7 @@ var dtrinityRebateRewardFetcher = {
56751
56971
  };
56752
56972
  var SECONDS_PER_YEAR15 = 31536e3;
56753
56973
  var WAD16 = 10n ** 18n;
56754
- var ZERO4 = "0x0000000000000000000000000000000000000000";
56974
+ var ZERO5 = "0x0000000000000000000000000000000000000000";
56755
56975
  var UNBOOSTED_FACTOR = 0.4;
56756
56976
  var MAX_BOOST = 2.5;
56757
56977
  var GAUGE_CONTROLLER = "0x2F50D538606Fa9EDD2B11E2446BEb18C9D5846bB";
@@ -56947,7 +57167,7 @@ async function fetchPrices(keys) {
56947
57167
  var priceOf = (prices, chainId, address) => prices[`${LLAMA_CHAIN_SLUG[chainId]}:${address.toLowerCase()}`] ?? 0;
56948
57168
  function rosterFor(chainId) {
56949
57169
  const markets = llamaLendChainData(Lender.LLAMALEND, chainId)?.markets ?? [];
56950
- return markets.filter((m) => m.gauge && m.gauge !== ZERO4).map((m) => ({
57170
+ return markets.filter((m) => m.gauge && m.gauge !== ZERO5).map((m) => ({
56951
57171
  controller: m.controller,
56952
57172
  vault: m.vault,
56953
57173
  gauge: m.gauge,
@@ -57024,7 +57244,7 @@ async function fetchForChain(chainId, nowSeconds) {
57024
57244
  }) : [];
57025
57245
  let cursor = 0;
57026
57246
  const withTokens = state.map((s) => {
57027
- const tokens = r2.slice(cursor, cursor + s.rewardCount).filter((t) => typeof t === "string" && t !== ZERO4);
57247
+ const tokens = r2.slice(cursor, cursor + s.rewardCount).filter((t) => typeof t === "string" && t !== ZERO5);
57028
57248
  cursor += s.rewardCount;
57029
57249
  return { ...s, tokens };
57030
57250
  });
@@ -57619,26 +57839,32 @@ function getMorphoAbi() {
57619
57839
  var MORPHO_GRAPHQL_URL = "https://blue-api.morpho.org/graphql";
57620
57840
  var MAX_UNLISTED_PRICE_PAGES = 10;
57621
57841
  var PRICE_PAGE_SIZE = 200;
57622
- var PRICE_QUERY = (first, skip, chainId, includeUnlisted) => `
57842
+ var PRICE_QUERY = (first, skip, chainId, includeUnlisted, uniqueKeys) => `
57623
57843
  query GetMarketPrices {
57624
57844
  markets(first: ${first}, skip: ${skip}, where: {
57625
- chainId_in: [${chainId}]${!includeUnlisted && chainId != Chain.ETHEREUM_MAINNET ? `,listed: true` : ""}
57845
+ chainId_in: [${chainId}]${uniqueKeys ? `,${uniqueKeyInFilter(uniqueKeys)}` : !includeUnlisted && chainId != Chain.ETHEREUM_MAINNET ? `,listed: true` : ""}
57626
57846
  },
57627
- orderBy: SupplyAssetsUsd,
57847
+ orderBy: ${uniqueKeys ? "UniqueKey" : "SupplyAssetsUsd"},
57628
57848
  orderDirection: Desc
57629
57849
  ) {
57630
57850
  items {
57631
57851
  uniqueKey: marketId
57632
- oracleAddress
57852
+ oracle {
57853
+ address
57854
+ }
57633
57855
  loanAsset {
57634
57856
  address
57635
57857
  decimals
57636
- priceUsd
57858
+ price {
57859
+ usd
57860
+ }
57637
57861
  }
57638
57862
  collateralAsset {
57639
57863
  address
57640
57864
  decimals
57641
- priceUsd
57865
+ price {
57866
+ usd
57867
+ }
57642
57868
  }
57643
57869
  state {
57644
57870
  price
@@ -57649,7 +57875,7 @@ query GetMarketPrices {
57649
57875
  `;
57650
57876
  async function fetchMorphoGraphQLPrices(chainId, includeUnlisted = false) {
57651
57877
  if (!morphoApiAvailable(chainId)) return null;
57652
- const post = (skip) => fetch(MORPHO_GRAPHQL_URL, {
57878
+ const post2 = (skip) => fetch(MORPHO_GRAPHQL_URL, {
57653
57879
  method: "POST",
57654
57880
  headers: { "Content-Type": "application/json" },
57655
57881
  body: JSON.stringify({
@@ -57670,7 +57896,7 @@ async function fetchMorphoGraphQLPrices(chainId, includeUnlisted = false) {
57670
57896
  const allMarkets = [];
57671
57897
  if (includeUnlisted) {
57672
57898
  for (let page = 0; page < MAX_UNLISTED_PRICE_PAGES; page++) {
57673
- const items = readItems(await post(page * PRICE_PAGE_SIZE));
57899
+ const items = readItems(await post2(page * PRICE_PAGE_SIZE));
57674
57900
  if (!items) return null;
57675
57901
  allMarkets.push(...items);
57676
57902
  if (items.length < PRICE_PAGE_SIZE) break;
@@ -57682,14 +57908,23 @@ async function fetchMorphoGraphQLPrices(chainId, includeUnlisted = false) {
57682
57908
  }
57683
57909
  } else {
57684
57910
  const skips = chainId === Chain.ETHEREUM_MAINNET ? [0, PRICE_PAGE_SIZE] : [0];
57685
- const results = await Promise.all(skips.map(post));
57911
+ const results = await Promise.all(skips.map(post2));
57686
57912
  for (const result of results) {
57687
57913
  const items = readItems(result);
57688
57914
  if (!items) return null;
57689
57915
  allMarkets.push(...items);
57690
57916
  }
57691
57917
  }
57692
- return processMarketsToEntries(chainId, allMarkets, "morpho-gql");
57918
+ const priced = includeUnlisted ? allMarkets : await appendVaultFundedMarkets(
57919
+ chainId,
57920
+ allMarkets,
57921
+ (keys) => PRICE_QUERY(keys.length, 0, chainId, false, keys)
57922
+ );
57923
+ return processMarketsToEntries(
57924
+ chainId,
57925
+ normalizeMorphoApiMarkets(priced),
57926
+ "morpho-gql"
57927
+ );
57693
57928
  } catch (err) {
57694
57929
  console.warn(
57695
57930
  `[morpho-gql] chain ${chainId}: API error, falling back to on-chain`,
@@ -64294,7 +64529,7 @@ var fetchSiloVaults = async (chainId, prices = {}, tokenList = {}, options) => {
64294
64529
  // src/vaults/euler-earn/entityLabels.ts
64295
64530
  var LABELS_BASE = "https://raw.githubusercontent.com/euler-xyz/euler-labels/master";
64296
64531
  var TTL_MS4 = 30 * 60 * 1e3;
64297
- var cache3 = /* @__PURE__ */ new Map();
64532
+ var cache4 = /* @__PURE__ */ new Map();
64298
64533
  var inflight4 = /* @__PURE__ */ new Map();
64299
64534
  async function fetchChainEntities(chainId) {
64300
64535
  const res = await fetch(`${LABELS_BASE}/${chainId}/entities.json`);
@@ -64318,12 +64553,12 @@ async function fetchChainEntities(chainId) {
64318
64553
  return map;
64319
64554
  }
64320
64555
  async function fetchEulerEntityNames(chainId) {
64321
- const hit = cache3.get(chainId);
64556
+ const hit = cache4.get(chainId);
64322
64557
  if (hit && Date.now() - hit.at <= TTL_MS4) return hit.map;
64323
64558
  const running = inflight4.get(chainId);
64324
64559
  if (running) return running;
64325
64560
  const p = fetchChainEntities(chainId).then((map) => {
64326
- cache3.set(chainId, { at: Date.now(), map });
64561
+ cache4.set(chainId, { at: Date.now(), map });
64327
64562
  return map;
64328
64563
  }).catch(() => {
64329
64564
  return hit?.map ?? /* @__PURE__ */ new Map();
@@ -64420,7 +64655,7 @@ query EvkByAssets($assets: [Bytes!]!) {
64420
64655
  }
64421
64656
  }
64422
64657
  `;
64423
- var ZERO5 = 0n;
64658
+ var ZERO6 = 0n;
64424
64659
  var RAY_TO_PERCENT3 = 1e25;
64425
64660
  function readAddress2(field13) {
64426
64661
  if (!field13) return void 0;
@@ -64435,28 +64670,28 @@ function parseVaultFee(v) {
64435
64670
  return n;
64436
64671
  }
64437
64672
  function safeBigInt(v) {
64438
- if (v == null || v === "") return ZERO5;
64673
+ if (v == null || v === "") return ZERO6;
64439
64674
  try {
64440
64675
  return BigInt(v);
64441
64676
  } catch {
64442
- return ZERO5;
64677
+ return ZERO6;
64443
64678
  }
64444
64679
  }
64445
64680
  function computeWeightedSupplyApy(strategies, totalAssetsRaw, feePercent2, evkIndex) {
64446
64681
  if (!strategies?.length) return 0;
64447
64682
  const totalAssets = safeBigInt(totalAssetsRaw);
64448
- if (totalAssets === ZERO5) return 0;
64449
- let weightedRay = ZERO5;
64683
+ if (totalAssets === ZERO6) return 0;
64684
+ let weightedRay = ZERO6;
64450
64685
  for (const s of strategies) {
64451
64686
  const evk = s.strategy?.toLowerCase();
64452
64687
  if (!evk) continue;
64453
64688
  const apyRay = evkIndex.bySupplyApyRay.get(evk);
64454
64689
  if (apyRay == null) continue;
64455
64690
  const allocated = safeBigInt(s.allocatedAssets);
64456
- if (allocated === ZERO5) continue;
64691
+ if (allocated === ZERO6) continue;
64457
64692
  weightedRay += allocated * apyRay;
64458
64693
  }
64459
- if (weightedRay === ZERO5) return 0;
64694
+ if (weightedRay === ZERO6) return 0;
64460
64695
  const apyRayPerAsset = weightedRay / totalAssets;
64461
64696
  const grossPercent = apyToAprPercent(Number(apyRayPerAsset) / RAY_TO_PERCENT3);
64462
64697
  const netPercent = grossPercent * (1 - feePercent2 / 100);
@@ -64464,24 +64699,24 @@ function computeWeightedSupplyApy(strategies, totalAssetsRaw, feePercent2, evkIn
64464
64699
  }
64465
64700
  function computeRealLiquidity(strategies, totalAssetsRaw, evkIndex) {
64466
64701
  const totalAssets = safeBigInt(totalAssetsRaw);
64467
- if (totalAssets === ZERO5) return ZERO5;
64702
+ if (totalAssets === ZERO6) return ZERO6;
64468
64703
  if (evkIndex.byCash.size === 0 && evkIndex.bySupplyApyRay.size === 0) {
64469
64704
  return totalAssets;
64470
64705
  }
64471
64706
  if (!strategies?.length) {
64472
64707
  return totalAssets;
64473
64708
  }
64474
- let allocSum = ZERO5;
64475
- let withdrawable = ZERO5;
64709
+ let allocSum = ZERO6;
64710
+ let withdrawable = ZERO6;
64476
64711
  for (const s of strategies) {
64477
64712
  const alloc = safeBigInt(s.allocatedAssets);
64478
- if (alloc === ZERO5) continue;
64713
+ if (alloc === ZERO6) continue;
64479
64714
  allocSum += alloc;
64480
64715
  const evk = s.strategy?.toLowerCase();
64481
64716
  const cash = evk ? evkIndex.byCash.get(evk) : void 0;
64482
64717
  withdrawable += cash == null ? alloc : alloc < cash ? alloc : cash;
64483
64718
  }
64484
- const idle = totalAssets > allocSum ? totalAssets - allocSum : ZERO5;
64719
+ const idle = totalAssets > allocSum ? totalAssets - allocSum : ZERO6;
64485
64720
  const result = idle + withdrawable;
64486
64721
  return result > totalAssets ? totalAssets : result;
64487
64722
  }
@@ -75058,7 +75293,7 @@ function isLiveMarket(market, nowSecs = Math.floor(Date.now() / 1e3)) {
75058
75293
  if (expiry === void 0) return false;
75059
75294
  return expiry > nowSecs;
75060
75295
  }
75061
- var CACHE_TTL_MS6 = 6e4;
75296
+ var CACHE_TTL_MS7 = 6e4;
75062
75297
  var marketsCache;
75063
75298
  var assetsCache;
75064
75299
  function clearPendleMarketsCache() {
@@ -75074,9 +75309,9 @@ async function getJson4(url, label) {
75074
75309
  }
75075
75310
  return response.json();
75076
75311
  }
75077
- function cache4(slot, build6, store) {
75312
+ function cache5(slot, build6, store) {
75078
75313
  const now = Date.now();
75079
- if (slot && now - slot.at < CACHE_TTL_MS6) return slot.promise;
75314
+ if (slot && now - slot.at < CACHE_TTL_MS7) return slot.promise;
75080
75315
  const promise = build6();
75081
75316
  const entry = { at: now, promise };
75082
75317
  store(entry);
@@ -75084,7 +75319,7 @@ function cache4(slot, build6, store) {
75084
75319
  return promise;
75085
75320
  }
75086
75321
  function fetchPendleApiMarkets() {
75087
- return cache4(
75322
+ return cache5(
75088
75323
  marketsCache,
75089
75324
  async () => (await getJson4(PENDLE_MARKETS_URL, "markets"))?.markets ?? [],
75090
75325
  (c) => {
@@ -75094,7 +75329,7 @@ function fetchPendleApiMarkets() {
75094
75329
  }
75095
75330
  var assetKey = (chainId, address) => `${chainId}-${address.toLowerCase()}`;
75096
75331
  function fetchPendleApiAssets() {
75097
- return cache4(
75332
+ return cache5(
75098
75333
  assetsCache,
75099
75334
  async () => {
75100
75335
  const json = await getJson4(PENDLE_ASSETS_URL, "assets");
@@ -75345,17 +75580,17 @@ function parsePtRate(raw) {
75345
75580
  if (!Number.isFinite(n) || n < 0 || n > 1.000001) return void 0;
75346
75581
  return n;
75347
75582
  }
75348
- var CACHE_TTL_MS7 = 6e4;
75349
- var cache5 = /* @__PURE__ */ new Map();
75583
+ var CACHE_TTL_MS8 = 6e4;
75584
+ var cache6 = /* @__PURE__ */ new Map();
75350
75585
  function clearSpectraMarketsCache() {
75351
- cache5.clear();
75586
+ cache6.clear();
75352
75587
  }
75353
75588
  function fetchSpectraApiMarkets(chainId) {
75354
75589
  const network = spectraNetwork(chainId);
75355
75590
  if (!network) return Promise.resolve([]);
75356
75591
  const now = Date.now();
75357
- const hit = cache5.get(network);
75358
- if (hit && now - hit.at < CACHE_TTL_MS7) return hit.promise;
75592
+ const hit = cache6.get(network);
75593
+ if (hit && now - hit.at < CACHE_TTL_MS8) return hit.promise;
75359
75594
  const promise = (async () => {
75360
75595
  const response = await fetch(spectraPoolsUrl(network), {
75361
75596
  headers: { Accept: "application/json" }
@@ -75368,9 +75603,9 @@ function fetchSpectraApiMarkets(chainId) {
75368
75603
  const json = await response.json();
75369
75604
  return Array.isArray(json) ? json : [];
75370
75605
  })();
75371
- cache5.set(network, { at: now, promise });
75606
+ cache6.set(network, { at: now, promise });
75372
75607
  promise.catch(() => {
75373
- if (cache5.get(network)?.promise === promise) cache5.delete(network);
75608
+ if (cache6.get(network)?.promise === promise) cache6.delete(network);
75374
75609
  });
75375
75610
  return promise;
75376
75611
  }