zframes 0.5.3 → 0.7.0

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 (134) hide show
  1. package/dist/index.js +735 -9
  2. package/package.json +5 -5
  3. package/runtime/assets/{bitcoin-dominance-CxfMBVwW.js → bitcoin-dominance-rskkp4h2.js} +1 -1
  4. package/runtime/assets/{breakeven-BrpmE2y2.js → breakeven-DyCA3ya5.js} +1 -1
  5. package/runtime/assets/{breathing-Bjv7D86F.js → breathing-C8Y-Izs8.js} +1 -1
  6. package/runtime/assets/{btc-blocks-Cy-YFeqC.js → btc-blocks-BxS4aEAB.js} +1 -1
  7. package/runtime/assets/{btc-difficulty-CQ_30M6B.js → btc-difficulty-CNFxEiPh.js} +1 -1
  8. package/runtime/assets/{btc-fees-DsYgskwn.js → btc-fees-Db-5JKh9.js} +1 -1
  9. package/runtime/assets/{btc-hashrate-C0dYT_WJ.js → btc-hashrate-Dy2c30Gb.js} +1 -1
  10. package/runtime/assets/{btc-mempool-DipekM7O.js → btc-mempool-DFgUVk8y.js} +1 -1
  11. package/runtime/assets/{calculator-zC8onHXp.js → calculator-v01_FkZv.js} +1 -1
  12. package/runtime/assets/chain-activity-CuA1eiPY.js +1 -0
  13. package/runtime/assets/{chart-utils-BYIZMM9J.js → chart-utils-Ct7WziT9.js} +1 -1
  14. package/runtime/assets/{checklist-baxMKxEm.js → checklist-Be_y1aTE.js} +1 -1
  15. package/runtime/assets/{clock-x9v1tYQm.js → clock-BWFux5om.js} +1 -1
  16. package/runtime/assets/{coin-movers-fIxzBuhy.js → coin-movers-BcXfoFc6.js} +1 -1
  17. package/runtime/assets/{countdown-BlyeM771.js → countdown-CXSOeUWD.js} +1 -1
  18. package/runtime/assets/cycle-shared-pyXzkgt1.js +1 -0
  19. package/runtime/assets/cycle-signals-BrKJX2c6.js +1 -0
  20. package/runtime/assets/{d3-xK4fOkBU.js → d3-Dr3MHXm3.js} +1 -1
  21. package/runtime/assets/{daily-analysis-DxjxE53t.js → daily-analysis-CWluVygw.js} +1 -1
  22. package/runtime/assets/{day-meter-9YEIbKbk.js → day-meter-Bi5OZCC4.js} +1 -1
  23. package/runtime/assets/defi-revenue-CFNSNfG7.js +1 -0
  24. package/runtime/assets/dex-hot-pools-C4TrRB17.js +1 -0
  25. package/runtime/assets/dex-pool-treemap-DqvlN1Jo.js +1 -0
  26. package/runtime/assets/{dex-volume-chart-CIN2oKpJ.js → dex-volume-chart-BLR-L_B0.js} +1 -1
  27. package/runtime/assets/{dex-volume-treemap-CqHdMsnd.js → dex-volume-treemap-qyEBx4ll.js} +1 -1
  28. package/runtime/assets/{dice-DnddcY-J.js → dice-CuzcQipj.js} +1 -1
  29. package/runtime/assets/{dino-game-D6AH1SSj.js → dino-game-CiGWzsag.js} +1 -1
  30. package/runtime/assets/{divider-Bu8aGlm1.js → divider-DvK5oM9v.js} +1 -1
  31. package/runtime/assets/{drawdy-BhOQeakE.js → drawdy-Bxr7eJ-7.js} +1 -1
  32. package/runtime/assets/dxy-CVbZmRsT.js +1 -0
  33. package/runtime/assets/editor-CQM8mtD8.css +1 -0
  34. package/runtime/assets/editor-EOEtB4_n.js +68 -0
  35. package/runtime/assets/etf-flows-Cl1WliDl.js +1 -0
  36. package/runtime/assets/etf-flows-chart-B4Im9TVy.js +1 -0
  37. package/runtime/assets/eth-staking-_q2b8DEx.js +1 -0
  38. package/runtime/assets/eth-supply-55OpYYBL.js +1 -0
  39. package/runtime/assets/{fear-greed-i87oWLnT.js → fear-greed-CywOCckQ.js} +1 -1
  40. package/runtime/assets/{filings-feed-Cxg9eG9S.js → filings-feed-CosEi4NL.js} +1 -1
  41. package/runtime/assets/{financial-stress-Bv_reW65.js → financial-stress-DBCae4TA.js} +1 -1
  42. package/runtime/assets/{flappy-bird-BENHBDEL.js → flappy-bird-CBVgwfgX.js} +1 -1
  43. package/runtime/assets/{fundamentals-AlhngJ8G.js → fundamentals-zRwGUcmb.js} +1 -1
  44. package/runtime/assets/funding-comparison-wCNoCb1H.js +1 -0
  45. package/runtime/assets/{funding-heatmap-B4RGXX4K.js → funding-heatmap-a4zdnKi9.js} +1 -1
  46. package/runtime/assets/{funding-rate-chart-Cg6gi0YC.js → funding-rate-chart-Da9WMKyJ.js} +1 -1
  47. package/runtime/assets/{fx-board-BqGsP0Xx.js → fx-board-CxhwDBHO.js} +1 -1
  48. package/runtime/assets/{heading-Dr7Q6vy_.js → heading-b5H33lig.js} +1 -1
  49. package/runtime/assets/{holiday-calendar-C1fruUVL.js → holiday-calendar-C77t3m6c.js} +1 -1
  50. package/runtime/assets/{image-BulRsYTV.js → image-C8ZSUHEx.js} +1 -1
  51. package/runtime/assets/{index-XGtH5pVY.css → index-BXLwJuoo.css} +1 -1
  52. package/runtime/assets/index-C-VdMqKb.css +1 -0
  53. package/runtime/assets/index-DKixdHYB.js +1 -0
  54. package/runtime/assets/index-kB-TyxKi.js +1073 -0
  55. package/runtime/assets/indicators-CogwjDn9.js +1 -0
  56. package/runtime/assets/{inflation-pulse-Q-3bZn55.js → inflation-pulse-CoXcuabd.js} +1 -1
  57. package/runtime/assets/{journal-log-FuAPC6JH.js → journal-log-BDu39CBE.js} +1 -1
  58. package/runtime/assets/{journal-open-BREaG6Cs.js → journal-open-FejLOzlA.js} +1 -1
  59. package/runtime/assets/{journal-results-Y_pKQcgg.js → journal-results-CtKy6MZM.js} +1 -1
  60. package/runtime/assets/{journal-score-ZATtCKrj.js → journal-score-Bd7IDYl4.js} +1 -1
  61. package/runtime/assets/{journal-ui-C_1ADbUX.js → journal-ui-C_htu3aM.js} +1 -1
  62. package/runtime/assets/{labor-market-DVybIeSN.js → labor-market-DR0j05Gy.js} +1 -1
  63. package/runtime/assets/{lightning-stats-ByvWkKyP.js → lightning-stats-botYMCIX.js} +1 -1
  64. package/runtime/assets/{link-grid-CJC48i5r.js → link-grid-DFuD6XVK.js} +1 -1
  65. package/runtime/assets/ma-multiplier-s6ix-kL8.js +1 -0
  66. package/runtime/assets/macro-calendar-Dhnx2n5Q.js +1 -0
  67. package/runtime/assets/{market-cap-treemap-CpnOP_gY.js → market-cap-treemap-BWtivvac.js} +1 -1
  68. package/runtime/assets/{market-hours-B9zPCvQk.js → market-hours-wSrW5Elv.js} +1 -1
  69. package/runtime/assets/{marquee-D8GTgVmy.js → marquee-NHBiLJUk.js} +1 -1
  70. package/runtime/assets/mayer-multiple-CZC5q6ra.js +1 -0
  71. package/runtime/assets/{mini-line-chart-CHM5UBjJ.js → mini-line-chart-QWeuTPfP.js} +1 -1
  72. package/runtime/assets/{mining-pools-DiyEBr6a.js → mining-pools-BxipfJmv.js} +1 -1
  73. package/runtime/assets/{mover-row-CO2STKkw.js → mover-row-CUd1i2yt.js} +1 -1
  74. package/runtime/assets/mvrv-BIwCiyRN.js +1 -0
  75. package/runtime/assets/{national-debt-CcTydivP.js → national-debt-DwC5azy3.js} +1 -1
  76. package/runtime/assets/{news-feed-D4xS-sLD.js → news-feed-BhAsJ6gt.js} +1 -1
  77. package/runtime/assets/nft-collections-sD-yDfKU.js +1 -0
  78. package/runtime/assets/nft-treemap-Bqhk41Of.js +1 -0
  79. package/runtime/assets/{note-BXsj5NlE.js → note-C1-RPOvR.js} +1 -1
  80. package/runtime/assets/nupl-U-WHVDJ0.js +1 -0
  81. package/runtime/assets/{open-interest-DaFRJd2O.js → open-interest-C0_M6MkH.js} +1 -1
  82. package/runtime/assets/{options-iv-MpSqgS3E.js → options-iv-CIHzBULM.js} +1 -1
  83. package/runtime/assets/{options-oi-strike-BHF28ASR.js → options-oi-strike-Db8lP27S.js} +1 -1
  84. package/runtime/assets/{options-put-call-_ZFaepBW.js → options-put-call-5ex7Ablt.js} +1 -1
  85. package/runtime/assets/pi-cycle-eACZGQhd.js +1 -0
  86. package/runtime/assets/{pomodoro-CxHVmgqp.js → pomodoro-CaS6y-eQ.js} +1 -1
  87. package/runtime/assets/portfolio-allocation-NR-4wbGL.js +1 -0
  88. package/runtime/assets/{portfolio-common-DnESc3oR.js → portfolio-common-Cfpnudvk.js} +1 -1
  89. package/runtime/assets/{portfolio-holdings-2vYKEk7f.js → portfolio-holdings-D-SG9B5X.js} +1 -1
  90. package/runtime/assets/{portfolio-value-B-7uIpG4.js → portfolio-value-DPKyirHc.js} +1 -1
  91. package/runtime/assets/prediction-markets-Cnf0KZba.js +1 -0
  92. package/runtime/assets/{price-chart-Cx_2scgb.js → price-chart-BEnpZLyb.js} +1 -1
  93. package/runtime/assets/{price-compare-DQcEOpnr.js → price-compare-8LvkF-xq.js} +1 -1
  94. package/runtime/assets/{price-liveline-TTo-aOFd.js → price-liveline-DkTeXuC2.js} +1 -1
  95. package/runtime/assets/{price-ticker-Cp7yYsNm.js → price-ticker-DgDJ3k4b.js} +1 -1
  96. package/runtime/assets/{protocol-fees-treemap-D-koQrKr.js → protocol-fees-treemap-fvVOfUFt.js} +1 -1
  97. package/runtime/assets/{protocol-tvl-chart-CDZkrQuF.js → protocol-tvl-chart-BfrszRqq.js} +1 -1
  98. package/runtime/assets/{protocol-tvl-treemap-I8fjLZU7.js → protocol-tvl-treemap-v5kaQdP4.js} +1 -1
  99. package/runtime/assets/puell-multiple-BdOLF9Wh.js +1 -0
  100. package/runtime/assets/{quote-CKEEp9tF.js → quote-slpulzHo.js} +1 -1
  101. package/runtime/assets/{rates-board-BElUHlYN.js → rates-board-B6hHyiDM.js} +1 -1
  102. package/runtime/assets/realized-price-dn6bApj-.js +1 -0
  103. package/runtime/assets/reserve-risk-_07r_h5w.js +1 -0
  104. package/runtime/assets/{returns-projector-DjIbvas1.js → returns-projector-NBs7iGAV.js} +1 -1
  105. package/runtime/assets/{risk-reward-pVHqmm_g.js → risk-reward-Baq_TRho.js} +1 -1
  106. package/runtime/assets/rsi-momentum-B6oTu5W6.js +1 -0
  107. package/runtime/assets/{rules-card-uMZQ6oP0.js → rules-card-D98hKEwY.js} +1 -1
  108. package/runtime/assets/sector-performance-DlnYIM-L.js +1 -0
  109. package/runtime/assets/sector-treemap-C3sX3Q9o.js +1 -0
  110. package/runtime/assets/{session-progress-Djhvb1G5.js → session-progress-BYwNuuP-.js} +1 -1
  111. package/runtime/assets/{short-volume-CiBfmCKw.js → short-volume-CxBDSjP6.js} +1 -1
  112. package/runtime/assets/{snake-CYXVjy8d.js → snake-CGV0Kg4z.js} +1 -1
  113. package/runtime/assets/sopr-DAn99w9D.js +1 -0
  114. package/runtime/assets/{spotify-embed-CGYKFOmX.js → spotify-embed-BBfim9vk.js} +1 -1
  115. package/runtime/assets/stablecoin-chains-D4EKi_YR.js +1 -0
  116. package/runtime/assets/stablecoin-supply-1m6FGR7-.js +1 -0
  117. package/runtime/assets/{stopwatch-Cl10sfaX.js → stopwatch-CCqsSaII.js} +1 -1
  118. package/runtime/assets/{top-movers-vvOomk6S.js → top-movers-CAqBZOUL.js} +1 -1
  119. package/runtime/assets/{treasury-auctions-JMoATy9T.js → treasury-auctions-Bl19yaM_.js} +1 -1
  120. package/runtime/assets/{treemap-leaf-DNIoJEK-.js → treemap-leaf-A45Ge4-e.js} +1 -1
  121. package/runtime/assets/trending-coins-Dm9R9zGQ.js +1 -0
  122. package/runtime/assets/{tvl-treemap-B28_19EZ.js → tvl-treemap-CSM9ioUr.js} +1 -1
  123. package/runtime/assets/{utils-DaT-yT0k.js → utils-DxneYyA_.js} +1 -1
  124. package/runtime/assets/{video-DjiOnvMm.js → video-CkvIGlHg.js} +1 -1
  125. package/runtime/assets/volume-profile-UJPTgNwV.js +1 -0
  126. package/runtime/assets/{yield-curve-Dj5vJwI4.js → yield-curve-DlXQg4sl.js} +1 -1
  127. package/runtime/assets/yield-scanner-Qm88hZuv.js +1 -0
  128. package/runtime/index.html +2 -2
  129. package/runtime/assets/editor-BMMobjrE.css +0 -1
  130. package/runtime/assets/editor-Ca-voh3h.js +0 -68
  131. package/runtime/assets/index-BgSQpj_B.js +0 -936
  132. package/runtime/assets/index-BqHx9BjX.css +0 -1
  133. package/runtime/assets/index-DK7jWlTL.js +0 -1
  134. package/runtime/assets/portfolio-allocation-Cf251dcH.js +0 -1
package/dist/index.js CHANGED
@@ -192,13 +192,17 @@ var DashboardSpecSchema = z2.preprocess(
192
192
  ),
193
193
  gap: z2.number().min(0).default(12).describe(
194
194
  "Pixels of space between frames (the grid gutter). 0 makes the cards flush; the editor's Layout rail exposes this as a slider."
195
+ ),
196
+ paddingX: z2.number().min(0).default(0).describe(
197
+ "Horizontal padding (px) inside the dashboard grid \u2014 the left/right gutter between the frames and the viewport edges (the x-axis inset). 0 (default) keeps the board flush to the edges; the editor's Layout rail exposes this as a slider."
195
198
  )
196
199
  }).default({
197
200
  mode: "flow-vertical",
198
201
  columns: 12,
199
202
  rowHeight: 96,
200
203
  rows: 6,
201
- gap: 12
204
+ gap: 12,
205
+ paddingX: 0
202
206
  }),
203
207
  background: BackgroundSchema.default({
204
208
  type: "none",
@@ -426,7 +430,17 @@ var SOURCES = {
426
430
  mempool: { name: "mempool.space", url: "https://mempool.space" },
427
431
  deribit: { name: "Deribit", url: "https://www.deribit.com" },
428
432
  coinpaprika: { name: "Coinpaprika", url: "https://coinpaprika.com" },
429
- frankfurter: { name: "Frankfurter (ECB)", url: "https://frankfurter.dev" }
433
+ frankfurter: { name: "Frankfurter (ECB)", url: "https://frankfurter.dev" },
434
+ coinMetrics: { name: "Coin Metrics", url: "https://coinmetrics.io" },
435
+ bitcoinData: { name: "bitcoin-data.com", url: "https://bitcoin-data.com" },
436
+ ultrasound: { name: "ultrasound.money", url: "https://ultrasound.money" },
437
+ polymarket: { name: "Polymarket", url: "https://polymarket.com" },
438
+ sosovalue: { name: "SoSoValue", url: "https://sosovalue.com" },
439
+ geckoterminal: {
440
+ name: "GeckoTerminal",
441
+ url: "https://www.geckoterminal.com"
442
+ },
443
+ blockchair: { name: "Blockchair", url: "https://blockchair.com" }
430
444
  };
431
445
  var clockMeta = defineFrameMeta({
432
446
  name: "clock",
@@ -772,7 +786,7 @@ var fundamentalsMeta = defineFrameMeta({
772
786
  label: "Fundamentals",
773
787
  category: "equities",
774
788
  iconUrl: widgetIcon("fundamentals"),
775
- layout: { w: 4, h: 3, minW: 3, minH: 3 },
789
+ layout: { w: 4, h: 4, minW: 3, minH: 3 },
776
790
  description: "Headline financials for one US-listed company from SEC EDGAR XBRL company facts \u2014 revenue, net income, total assets, shareholders' equity, diluted EPS, and shares outstanding, each labelled with its fiscal period. Income-statement figures are the latest full fiscal year; balance-sheet figures are the latest reported quarter. Keyless official data that updates only when the company files (annual/quarterly), not a live feed. Requires the zframes runtime's data proxy (it ships with `zframes serve` / `vite dev`); resolve by ticker (bundled top-500 map) or raw SEC CIK.",
777
791
  capabilities: ["fundamentals"],
778
792
  source: SOURCES.secEdgar,
@@ -916,7 +930,7 @@ var journalScoreMeta = defineFrameMeta({
916
930
  label: "Journal \xB7 Scoreboard",
917
931
  category: "journal",
918
932
  iconUrl: widgetIcon("journal-score"),
919
- layout: { w: 4, h: 2, minW: 3, minH: 2 },
933
+ layout: { w: 4, h: 3, minW: 3, minH: 3 },
920
934
  description: "The decision-journal scoreboard \u2014 a story, not a spreadsheet: where your judgment has an edge, where it leaks, and how calibrated your confidence is, plus a one-line read from zAI. Aggregates the calls logged via Journal \xB7 Log.",
921
935
  capabilities: [],
922
936
  schema: z3.object({})
@@ -1503,7 +1517,7 @@ var btcFeesMeta = defineFrameMeta({
1503
1517
  label: "BTC Fees",
1504
1518
  category: "bitcoin",
1505
1519
  iconUrl: widgetIcon("btc-fees"),
1506
- layout: { w: 3, h: 2, minW: 2, minH: 2 },
1520
+ layout: { w: 3, h: 3, minW: 2, minH: 3 },
1507
1521
  description: "Recommended Bitcoin on-chain fee rates (sat/vB) from mempool.space \u2014 the next-block ('fastest'), ~30-minute, ~1-hour, economy, and minimum tiers, as a compact gauge. Live mempool data, keyless; updates every ~30s.",
1508
1522
  capabilities: ["btc-fees"],
1509
1523
  source: SOURCES.mempool,
@@ -1667,6 +1681,442 @@ var coinMoversMeta = defineFrameMeta({
1667
1681
  )
1668
1682
  })
1669
1683
  });
1684
+ var mvrvMeta = defineFrameMeta({
1685
+ name: "mvrv",
1686
+ label: "MVRV Ratio",
1687
+ category: "onchain",
1688
+ iconUrl: widgetIcon("mvrv"),
1689
+ layout: { w: 3, h: 3, minW: 2, minH: 2 },
1690
+ description: "Bitcoin MVRV ratio \u2014 market cap \xF7 realized cap. Above ~3 historically marks cycle tops (overvalued); below ~1 marks deep value near bottoms. Shows the current ratio, its valuation zone, the MVRV Z-score, and a history sparkline. Keyless on-chain data from Coin Metrics.",
1691
+ capabilities: ["onchain-valuation"],
1692
+ source: SOURCES.coinMetrics,
1693
+ schema: z3.object({
1694
+ window: z3.enum(["1Y", "2Y", "4Y", "all"]).default("all").describe("How much history the sparkline shows.")
1695
+ })
1696
+ });
1697
+ var nuplMeta = defineFrameMeta({
1698
+ name: "nupl",
1699
+ label: "NUPL",
1700
+ category: "onchain",
1701
+ iconUrl: widgetIcon("nupl"),
1702
+ layout: { w: 3, h: 3, minW: 2, minH: 2 },
1703
+ description: "Net Unrealized Profit/Loss \u2014 the share of Bitcoin's market cap held in unrealized profit. Maps to cycle sentiment phases: Capitulation (<0), Hope/Fear (0\u201325%), Optimism (25\u201350%), Belief (50\u201375%), Euphoria/Greed (>75%). Derived from MVRV; keyless Coin Metrics data.",
1704
+ capabilities: ["onchain-valuation"],
1705
+ source: SOURCES.coinMetrics,
1706
+ schema: z3.object({
1707
+ window: z3.enum(["1Y", "2Y", "4Y", "all"]).default("all").describe("How much history the sparkline shows.")
1708
+ })
1709
+ });
1710
+ var soprMeta = defineFrameMeta({
1711
+ name: "sopr",
1712
+ label: "SOPR",
1713
+ category: "onchain",
1714
+ iconUrl: widgetIcon("sopr"),
1715
+ layout: { w: 3, h: 3, minW: 2, minH: 2 },
1716
+ description: "Spent Output Profit Ratio \u2014 whether coins moving on-chain are, on average, being sold in profit (>1) or loss (<1). Sustained dips below 1 mark capitulation; resets to ~1 in bull markets are healthy. Keyless full-history data from bitcoin-data.com (polled once daily).",
1717
+ capabilities: ["onchain-cycle-extras"],
1718
+ source: SOURCES.bitcoinData,
1719
+ schema: z3.object({
1720
+ window: z3.enum(["90D", "180D", "1Y"]).default("1Y").describe("How much history the sparkline shows.")
1721
+ })
1722
+ });
1723
+ var puellMultipleMeta = defineFrameMeta({
1724
+ name: "puell-multiple",
1725
+ label: "Puell Multiple",
1726
+ category: "onchain",
1727
+ iconUrl: widgetIcon("puell-multiple"),
1728
+ layout: { w: 3, h: 3, minW: 2, minH: 2 },
1729
+ description: "Puell Multiple \u2014 daily miner issuance in USD \xF7 its 365-day average. High values (>4) mark cycle tops where miner revenue is stretched; low values (\u22640.5) mark miner capitulation near bottoms. Keyless data from bitcoin-data.com (polled once daily).",
1730
+ capabilities: ["onchain-cycle-extras"],
1731
+ source: SOURCES.bitcoinData,
1732
+ schema: z3.object({
1733
+ window: z3.enum(["90D", "180D", "1Y"]).default("1Y").describe("How much history the sparkline shows.")
1734
+ })
1735
+ });
1736
+ var mayerMultipleMeta = defineFrameMeta({
1737
+ name: "mayer-multiple",
1738
+ label: "Mayer Multiple",
1739
+ category: "onchain",
1740
+ iconUrl: widgetIcon("mayer-multiple"),
1741
+ layout: { w: 3, h: 3, minW: 2, minH: 2 },
1742
+ description: "Mayer Multiple \u2014 BTC price \xF7 its 200-day moving average. Above ~2.4 has historically been overheated; below ~0.8 marks value zones. Computed in-browser from a keyless long daily price series (Coin Metrics).",
1743
+ capabilities: ["price-history-daily"],
1744
+ source: SOURCES.coinMetrics,
1745
+ schema: z3.object({
1746
+ window: z3.enum(["1Y", "2Y", "4Y", "all"]).default("2Y").describe("How much history the sparkline shows.")
1747
+ })
1748
+ });
1749
+ var piCycleMeta = defineFrameMeta({
1750
+ name: "pi-cycle",
1751
+ label: "Pi Cycle Top",
1752
+ category: "onchain",
1753
+ iconUrl: widgetIcon("pi-cycle"),
1754
+ layout: { w: 3, h: 3, minW: 2, minH: 2 },
1755
+ description: "Pi Cycle Top indicator \u2014 the ratio of the 111-day MA to 2\xD7 the 350-day MA. When it crosses 1 (the 111DMA overtakes 2\xD7350DMA) it has historically pinpointed cycle tops within days. Computed in-browser from a keyless long daily price series (Coin Metrics).",
1756
+ capabilities: ["price-history-daily"],
1757
+ source: SOURCES.coinMetrics,
1758
+ schema: z3.object({
1759
+ window: z3.enum(["1Y", "2Y", "4Y", "all"]).default("2Y").describe("How much history the sparkline shows.")
1760
+ })
1761
+ });
1762
+ var maMultiplierMeta = defineFrameMeta({
1763
+ name: "ma-multiplier",
1764
+ label: "MA Multiplier",
1765
+ category: "onchain",
1766
+ iconUrl: widgetIcon("ma-multiplier"),
1767
+ layout: { w: 3, h: 3, minW: 2, minH: 2 },
1768
+ description: "Long moving-average multiplier \u2014 BTC price \xF7 its multi-year moving average (2-year or 4-year). The 2Y band flags a buy zone below \xF71.5 and sell tiers at \xD72\u2013\xD75; the 4Y multiple marks tops above ~3.5\xD7. Computed in-browser from a keyless long daily price series (Coin Metrics).",
1769
+ capabilities: ["price-history-daily"],
1770
+ source: SOURCES.coinMetrics,
1771
+ schema: z3.object({
1772
+ years: z3.enum(["2", "4"]).default("2").describe("Moving-average window in years."),
1773
+ window: z3.enum(["2Y", "4Y", "all"]).default("all").describe("How much history the sparkline shows.")
1774
+ })
1775
+ });
1776
+ var rsiMomentumMeta = defineFrameMeta({
1777
+ name: "rsi-momentum",
1778
+ label: "RSI Momentum",
1779
+ category: "markets",
1780
+ iconUrl: widgetIcon("rsi-momentum"),
1781
+ layout: { w: 3, h: 3, minW: 2, minH: 2 },
1782
+ description: "Wilder RSI on BTC daily closes with a 55/45 momentum regime: above 55 = risk-on, below 45 = risk-off, in between = neutral. Also flags classic overbought (\u226580) / oversold (\u226430) extremes. Computed in-browser from a keyless long daily price series (Coin Metrics).",
1783
+ capabilities: ["price-history-daily"],
1784
+ source: SOURCES.coinMetrics,
1785
+ schema: z3.object({
1786
+ period: z3.number().int().min(2).max(50).default(14).describe("RSI lookback period in days."),
1787
+ window: z3.enum(["90D", "180D", "1Y", "2Y"]).default("180D").describe("How much history the sparkline shows.")
1788
+ })
1789
+ });
1790
+ var volumeProfileMeta = defineFrameMeta({
1791
+ name: "volume-profile",
1792
+ label: "Volume Profile",
1793
+ category: "markets",
1794
+ iconUrl: widgetIcon("volume-profile"),
1795
+ layout: { w: 4, h: 4, minW: 3, minH: 3 },
1796
+ description: "Volume-by-price histogram over a lookback window \u2014 the Point of Control (POC, highest-volume price) and the 70% Value Area (VAH/VAL) that frame support/resistance. Computed in-browser from OHLCV candles. Pass any tradable symbol (crypto or a HIP-3 equity like 'xyz:TSLA').",
1797
+ capabilities: ["ohlcv"],
1798
+ source: SOURCES.hyperliquid,
1799
+ schema: z3.object({
1800
+ symbol: z3.string().default("BTC").describe(
1801
+ "Symbol to profile, e.g. 'BTC', 'ETH', or a HIP-3 equity 'xyz:TSLA'."
1802
+ ),
1803
+ interval: z3.enum(["1h", "4h", "1d"]).default("1d").describe("Candle interval."),
1804
+ lookbackDays: z3.number().int().min(7).max(365).default(90).describe("How many days of candles to build the profile from."),
1805
+ bins: z3.number().int().min(8).max(48).default(24).describe("Number of price buckets in the histogram.")
1806
+ })
1807
+ });
1808
+ var dxyMeta = defineFrameMeta({
1809
+ name: "dxy",
1810
+ label: "Dollar Index (DXY)",
1811
+ category: "macro",
1812
+ iconUrl: widgetIcon("dxy"),
1813
+ layout: { w: 3, h: 3, minW: 2, minH: 2 },
1814
+ description: "US Dollar Index (DXY) \u2014 the dollar's strength vs a basket of six major currencies. A rising DXY is a macro headwind for risk assets (incl. BTC); a falling DXY a tailwind. Computed as the ICE-weighted geometric mean of keyless ECB reference rates (daily granularity).",
1815
+ capabilities: ["dollar-index"],
1816
+ source: SOURCES.frankfurter,
1817
+ schema: z3.object({})
1818
+ });
1819
+ var cycleSignalsMeta = defineFrameMeta({
1820
+ name: "cycle-signals",
1821
+ label: "Cycle Signals",
1822
+ category: "onchain",
1823
+ iconUrl: widgetIcon("cycle-signals"),
1824
+ layout: { w: 4, h: 5, minW: 3, minH: 3 },
1825
+ description: "A cycle top- or bottom-signal checklist \u2014 MVRV, MVRV Z-score, NUPL, Mayer Multiple, Puell, RSI, and Pi Cycle each checked against its historical extreme, with a live 'X of N firing' tally. A capstone that aggregates the on-chain and cycle metrics into one 'how late in the cycle are we' read. Keyless (Coin Metrics + bitcoin-data.com).",
1826
+ capabilities: [
1827
+ "onchain-valuation",
1828
+ "onchain-cycle-extras",
1829
+ "price-history-daily"
1830
+ ],
1831
+ source: [SOURCES.coinMetrics, SOURCES.bitcoinData],
1832
+ schema: z3.object({
1833
+ mode: z3.enum(["peak", "bottom"]).default("peak").describe(
1834
+ "Which checklist to show: cycle-top ('peak') or cycle-bottom ('bottom') signals."
1835
+ )
1836
+ })
1837
+ });
1838
+ var stablecoinSupplyMeta = defineFrameMeta({
1839
+ name: "stablecoin-supply",
1840
+ label: "Stablecoin Supply",
1841
+ category: "crypto",
1842
+ iconUrl: widgetIcon("stablecoin-supply"),
1843
+ layout: { w: 3, h: 3, minW: 2, minH: 2 },
1844
+ description: "Total USD-stablecoin circulating supply \u2014 a market-wide liquidity gauge. Rising supply = fresh capital entering crypto (risk-on dry powder); contraction = risk-off. Shows the total, 1d/7d/30d change, and the largest chains. Keyless (DeFiLlama).",
1845
+ capabilities: ["stablecoins"],
1846
+ source: SOURCES.defillama,
1847
+ schema: z3.object({})
1848
+ });
1849
+ var yieldScannerMeta = defineFrameMeta({
1850
+ name: "yield-scanner",
1851
+ label: "Yield Scanner",
1852
+ category: "crypto",
1853
+ iconUrl: widgetIcon("yield-scanner"),
1854
+ layout: { w: 5, h: 4, minW: 3, minH: 3 },
1855
+ description: "Top DeFi yield pools ranked by APY, across every chain and protocol \u2014 the 'where's the yield' board. Filter to stablecoin pools or a TVL floor. Shows APY (base + reward), TVL, chain, and IL risk. Keyless (DeFiLlama yields).",
1856
+ capabilities: ["yields"],
1857
+ source: SOURCES.defillama,
1858
+ schema: z3.object({
1859
+ limit: z3.number().int().min(3).max(20).default(8).describe("How many pools to list."),
1860
+ stablecoinOnly: z3.boolean().default(false).describe("Only show stablecoin pools (lower impermanent-loss risk)."),
1861
+ minTvlUsd: z3.number().min(0).default(1e6).describe("Minimum pool TVL in USD \u2014 a liquidity floor to hide dust.")
1862
+ })
1863
+ });
1864
+ var defiRevenueMeta = defineFrameMeta({
1865
+ name: "defi-revenue",
1866
+ label: "DeFi Fees & Revenue",
1867
+ category: "crypto",
1868
+ iconUrl: widgetIcon("defi-revenue"),
1869
+ layout: { w: 3, h: 3, minW: 2, minH: 2 },
1870
+ description: "Aggregate DeFi protocol fees across all of crypto \u2014 trailing-24h total with a daily trend. A read on real on-chain economic activity. Keyless (DeFiLlama).",
1871
+ capabilities: ["fees-overview"],
1872
+ source: SOURCES.defillama,
1873
+ schema: z3.object({})
1874
+ });
1875
+ var fundingComparisonMeta = defineFrameMeta({
1876
+ name: "funding-comparison",
1877
+ label: "Cross-Venue Funding",
1878
+ category: "derivatives",
1879
+ iconUrl: widgetIcon("funding-comparison"),
1880
+ layout: { w: 5, h: 4, minW: 3, minH: 3 },
1881
+ description: "Predicted perpetual funding rates compared across venues (Hyperliquid vs Binance vs Bybit), annualized, per coin \u2014 ranked by the cross-venue spread. A large spread flags a funding-arbitrage or crowded-positioning signal. Keyless (Hyperliquid predicted fundings).",
1882
+ capabilities: ["funding-comparison"],
1883
+ source: SOURCES.hyperliquid,
1884
+ schema: z3.object({
1885
+ limit: z3.number().int().min(3).max(20).default(8).describe("How many coins (by funding spread) to show.")
1886
+ })
1887
+ });
1888
+ var ethSupplyMeta = defineFrameMeta({
1889
+ name: "eth-supply",
1890
+ label: "ETH Ultrasound",
1891
+ category: "crypto",
1892
+ iconUrl: widgetIcon("eth-supply"),
1893
+ layout: { w: 4, h: 3, minW: 2, minH: 2 },
1894
+ description: "Ethereum supply economics \u2014 EIP-1559 burn vs PoS issuance and the resulting net annual supply growth. Negative growth = deflationary ('ultrasound money'). Shows the net rate, burn/issuance, and vs the counterfactual PoW issuance. Keyless (ultrasound.money).",
1895
+ capabilities: ["eth-supply"],
1896
+ source: SOURCES.ultrasound,
1897
+ schema: z3.object({})
1898
+ });
1899
+ var ethStakingMeta = defineFrameMeta({
1900
+ name: "eth-staking",
1901
+ label: "ETH Staking APR",
1902
+ category: "crypto",
1903
+ iconUrl: widgetIcon("eth-staking"),
1904
+ layout: { w: 3, h: 3, minW: 2, minH: 2 },
1905
+ description: "Ethereum staking yield \u2014 total validator APR broken into consensus issuance, MEV, and priority tips. The 'risk-free' ETH rate. Keyless (ultrasound.money).",
1906
+ capabilities: ["eth-supply"],
1907
+ source: SOURCES.ultrasound,
1908
+ schema: z3.object({})
1909
+ });
1910
+ var predictionMarketsMeta = defineFrameMeta({
1911
+ name: "prediction-markets",
1912
+ label: "Prediction Markets",
1913
+ category: "sentiment",
1914
+ iconUrl: widgetIcon("prediction-markets"),
1915
+ layout: { w: 4, h: 4, minW: 3, minH: 3 },
1916
+ description: "Live Polymarket odds \u2014 the highest-volume open prediction markets with their market-implied probabilities (macro, rates, crypto, politics). A real-money sentiment gauge. Keyless (Polymarket Gamma API).",
1917
+ capabilities: ["prediction-markets"],
1918
+ source: SOURCES.polymarket,
1919
+ schema: z3.object({
1920
+ limit: z3.number().int().min(3).max(20).default(6).describe("How many markets (by volume) to show.")
1921
+ })
1922
+ });
1923
+ var etfFlowsMeta = defineFrameMeta({
1924
+ name: "etf-flows",
1925
+ label: "Spot ETF Flows",
1926
+ category: "crypto",
1927
+ iconUrl: widgetIcon("etf-flows"),
1928
+ layout: { w: 4, h: 4, minW: 3, minH: 3 },
1929
+ description: "Spot Bitcoin or Ethereum ETF daily net flows \u2014 per-issuer (IBIT, FBTC, GBTC, \u2026) plus the total, with a recent trend. The biggest institutional-demand signal. Keyless (SoSoValue); best-effort, may show empty if the source is unavailable.",
1930
+ capabilities: ["etf-flows"],
1931
+ source: SOURCES.sosovalue,
1932
+ schema: z3.object({
1933
+ asset: z3.enum(["btc", "eth"]).default("btc").describe("Which spot-ETF complex to show."),
1934
+ limit: z3.number().int().min(3).max(15).default(8).describe("How many issuers to list.")
1935
+ })
1936
+ });
1937
+ var trendingCoinsMeta = defineFrameMeta({
1938
+ name: "trending-coins",
1939
+ label: "Trending Coins",
1940
+ category: "crypto",
1941
+ iconUrl: widgetIcon("trending-coins"),
1942
+ layout: { w: 3, h: 4, minW: 2, minH: 3 },
1943
+ description: "The coins with the most search interest right now on CoinGecko \u2014 a retail-attention gauge. Shows rank, price, and 24h change. Keyless (CoinGecko).",
1944
+ capabilities: ["trending-coins"],
1945
+ source: SOURCES.coingecko,
1946
+ schema: z3.object({
1947
+ limit: z3.number().int().min(3).max(15).default(7).describe("How many trending coins to show.")
1948
+ })
1949
+ });
1950
+ var sectorPerformanceMeta = defineFrameMeta({
1951
+ name: "sector-performance",
1952
+ label: "Sector Performance",
1953
+ category: "crypto",
1954
+ iconUrl: widgetIcon("sector-performance"),
1955
+ layout: { w: 4, h: 4, minW: 3, minH: 3 },
1956
+ description: "Crypto sector rotation \u2014 market categories (L1s, DeFi, AI, memes, RWA, \u2026) ranked by 24h market-cap change. Shows where capital is rotating. Keyless (CoinGecko categories).",
1957
+ capabilities: ["sector-performance"],
1958
+ source: SOURCES.coingecko,
1959
+ schema: z3.object({
1960
+ limit: z3.number().int().min(4).max(30).default(10).describe("How many sectors to show.")
1961
+ })
1962
+ });
1963
+ var macroCalendarMeta = defineFrameMeta({
1964
+ name: "macro-calendar",
1965
+ label: "Macro Calendar",
1966
+ category: "macro",
1967
+ iconUrl: widgetIcon("macro-calendar"),
1968
+ layout: { w: 4, h: 4, minW: 3, minH: 2 },
1969
+ description: "Countdown to upcoming scheduled macro events \u2014 defaults to the 2026 FOMC rate decisions, fully editable. No data feed; the dates are known in advance.",
1970
+ capabilities: [],
1971
+ schema: z3.object({
1972
+ limit: z3.number().int().min(1).max(12).default(5).describe("How many upcoming events to show."),
1973
+ events: z3.array(
1974
+ z3.object({
1975
+ date: z3.string().describe("Event date, ISO YYYY-MM-DD."),
1976
+ label: z3.string().describe("Event name, e.g. 'FOMC decision'.")
1977
+ })
1978
+ ).default([
1979
+ { date: "2026-07-29", label: "FOMC decision" },
1980
+ { date: "2026-09-16", label: "FOMC decision" },
1981
+ { date: "2026-10-28", label: "FOMC decision" },
1982
+ { date: "2026-12-09", label: "FOMC decision" },
1983
+ { date: "2027-01-27", label: "FOMC decision" }
1984
+ ]).describe(
1985
+ "Scheduled events (date + label). Defaults to the 2026 FOMC meetings; edit to add CPI/NFP/earnings dates."
1986
+ )
1987
+ })
1988
+ });
1989
+ var stablecoinChainsMeta = defineFrameMeta({
1990
+ name: "stablecoin-chains",
1991
+ label: "Stablecoin Chains",
1992
+ category: "crypto",
1993
+ iconUrl: widgetIcon("stablecoin-chains"),
1994
+ layout: { w: 5, h: 4, minW: 4, minH: 3 },
1995
+ description: "Where stablecoin liquidity sits \u2014 a treemap of the largest chains by stablecoin circulating supply. Complements the Stablecoin Supply total with the cross-chain distribution. Keyless (DeFiLlama).",
1996
+ capabilities: ["stablecoins"],
1997
+ source: SOURCES.defillama,
1998
+ schema: z3.object({
1999
+ limit: z3.number().int().min(4).max(16).default(12).describe("How many chains to show in the treemap.")
2000
+ })
2001
+ });
2002
+ var sectorTreemapMeta = defineFrameMeta({
2003
+ name: "sector-treemap",
2004
+ label: "Sector Treemap",
2005
+ category: "crypto",
2006
+ iconUrl: widgetIcon("sector-treemap"),
2007
+ layout: { w: 6, h: 4, minW: 4, minH: 3 },
2008
+ description: "Crypto sector rotation as a treemap \u2014 each category sized by market cap and colored by 24h change (green up / red down). The at-a-glance view of where capital is flowing. Keyless (CoinGecko categories).",
2009
+ capabilities: ["sector-performance"],
2010
+ source: SOURCES.coingecko,
2011
+ schema: z3.object({
2012
+ limit: z3.number().int().min(6).max(30).default(16).describe("How many sectors to show.")
2013
+ })
2014
+ });
2015
+ var etfFlowsChartMeta = defineFrameMeta({
2016
+ name: "etf-flows-chart",
2017
+ label: "ETF Flows Chart",
2018
+ category: "crypto",
2019
+ iconUrl: widgetIcon("etf-flows-chart"),
2020
+ layout: { w: 6, h: 3, minW: 3, minH: 3 },
2021
+ description: "Spot BTC or ETH ETF daily net flows over time \u2014 the inflow/outflow trend as a line, complementing the per-issuer snapshot. Keyless (SoSoValue); best-effort, may be empty if the source is unavailable.",
2022
+ capabilities: ["etf-flows"],
2023
+ source: SOURCES.sosovalue,
2024
+ schema: z3.object({
2025
+ asset: z3.enum(["btc", "eth"]).default("btc").describe("Which spot-ETF complex to chart."),
2026
+ lookback: z3.enum(["1M", "3M", "6M"]).default("3M").describe("History window for the flow chart.")
2027
+ })
2028
+ });
2029
+ var realizedPriceMeta = defineFrameMeta({
2030
+ name: "realized-price",
2031
+ label: "Realized Price",
2032
+ category: "onchain",
2033
+ iconUrl: widgetIcon("realized-price"),
2034
+ layout: { w: 6, h: 3, minW: 4, minH: 3 },
2035
+ description: "Bitcoin market price vs realized price \u2014 the on-chain cost basis of all coins. Market above realized = aggregate profit; crossing below realized has marked cycle bottoms. Keyless (Coin Metrics).",
2036
+ capabilities: ["onchain-valuation"],
2037
+ source: SOURCES.coinMetrics,
2038
+ schema: z3.object({
2039
+ window: z3.enum(["1Y", "2Y", "4Y", "all"]).default("2Y").describe("How much history the chart shows.")
2040
+ })
2041
+ });
2042
+ var reserveRiskMeta = defineFrameMeta({
2043
+ name: "reserve-risk",
2044
+ label: "Reserve Risk",
2045
+ category: "onchain",
2046
+ iconUrl: widgetIcon("reserve-risk"),
2047
+ layout: { w: 3, h: 3, minW: 2, minH: 2 },
2048
+ description: "Reserve Risk \u2014 long-term-holder conviction relative to price. Low values = strong conviction at a low price (attractive risk/reward, cycle-bottom territory); high values = conviction spent into a high price. Keyless (bitcoin-data.com).",
2049
+ capabilities: ["onchain-cycle-extras"],
2050
+ source: SOURCES.bitcoinData,
2051
+ schema: z3.object({
2052
+ window: z3.enum(["90D", "180D", "1Y"]).default("1Y").describe("How much history the sparkline shows.")
2053
+ })
2054
+ });
2055
+ var nftCollectionsMeta = defineFrameMeta({
2056
+ name: "nft-collections",
2057
+ label: "NFT Collections",
2058
+ category: "crypto",
2059
+ iconUrl: widgetIcon("nft-collections"),
2060
+ layout: { w: 3, h: 4, minW: 2, minH: 3 },
2061
+ description: "Blue-chip NFT collections ranked by 24h trading volume \u2014 floor price (USD), 24h floor change, and volume, for a hand-picked set of majors (Bored Ape, Pudgy Penguins, CryptoPunks, Azuki, \u2026). Keyless (CoinGecko free tier). A quick read on where the top NFT market is trading.",
2062
+ capabilities: ["nft-market"],
2063
+ source: SOURCES.coingecko,
2064
+ schema: z3.object({
2065
+ topN: z3.number().int().min(4).max(10).default(8).describe("How many collections to show (up to 10 curated majors).")
2066
+ })
2067
+ });
2068
+ var dexHotPoolsMeta = defineFrameMeta({
2069
+ name: "dex-hot-pools",
2070
+ label: "Hot DEX Pools",
2071
+ category: "onchain",
2072
+ iconUrl: widgetIcon("dex-hot-pools"),
2073
+ layout: { w: 3, h: 4, minW: 2, minH: 3 },
2074
+ description: "Trending DEX liquidity pools on a chain, ranked by 24h volume \u2014 each pool's pair, base-token price, 24h price change, and 24h volume. Surfaces what's hot on-chain (new listings, momentum pairs) across Ethereum, Solana, Base and more. Keyless (GeckoTerminal free tier).",
2075
+ capabilities: ["dex-pools"],
2076
+ source: SOURCES.geckoterminal,
2077
+ schema: z3.object({
2078
+ network: z3.enum(["eth", "solana", "base", "arbitrum", "bsc", "polygon_pos"]).default("eth").describe("Which chain's trending pools to show."),
2079
+ count: z3.number().int().min(5).max(15).default(10).describe("How many trending pools to list (up to 15).")
2080
+ })
2081
+ });
2082
+ var chainActivityMeta = defineFrameMeta({
2083
+ name: "chain-activity",
2084
+ label: "Chain Activity",
2085
+ category: "onchain",
2086
+ iconUrl: widgetIcon("chain-activity"),
2087
+ layout: { w: 3, h: 4, minW: 2, minH: 3 },
2088
+ description: "Cross-chain network activity for major layer-1s (Bitcoin, Ethereum, Litecoin, \u2026), ranked by 24h transaction count \u2014 with blocks mined and mempool backlog per chain. A side-by-side pulse of which chains are busiest right now. Keyless (Blockchair).",
2089
+ capabilities: ["chain-activity"],
2090
+ source: SOURCES.blockchair,
2091
+ schema: z3.object({})
2092
+ });
2093
+ var nftTreemapMeta = defineFrameMeta({
2094
+ name: "nft-treemap",
2095
+ label: "NFT Treemap",
2096
+ category: "crypto",
2097
+ iconUrl: widgetIcon("nft-treemap"),
2098
+ layout: { w: 4, h: 4, minW: 3, minH: 3 },
2099
+ description: "Treemap of blue-chip NFT collections sized by market capitalisation, tiles colored green/red by 24h floor-price change. A heat-map of the top NFT market at a glance. Keyless (CoinGecko free tier).",
2100
+ capabilities: ["nft-market"],
2101
+ source: SOURCES.coingecko,
2102
+ schema: z3.object({
2103
+ topN: z3.number().int().min(4).max(10).default(8).describe("How many collections to show (up to 10 curated majors).")
2104
+ })
2105
+ });
2106
+ var dexPoolTreemapMeta = defineFrameMeta({
2107
+ name: "dex-pool-treemap",
2108
+ label: "DEX Pool Treemap",
2109
+ category: "onchain",
2110
+ iconUrl: widgetIcon("dex-pool-treemap"),
2111
+ layout: { w: 4, h: 4, minW: 3, minH: 3 },
2112
+ description: "Treemap of trending DEX pools on a chain sized by 24h trading volume, tiles colored green/red by 24h price change. Shows at a glance which pairs are pulling the most on-chain volume. Keyless (GeckoTerminal free tier).",
2113
+ capabilities: ["dex-pools"],
2114
+ source: SOURCES.geckoterminal,
2115
+ schema: z3.object({
2116
+ network: z3.enum(["eth", "solana", "base", "arbitrum", "bsc", "polygon_pos"]).default("eth").describe("Which chain's trending pools to show."),
2117
+ count: z3.number().int().min(5).max(15).default(12).describe("How many trending pools to include (up to 15).")
2118
+ })
2119
+ });
1670
2120
  var frameMetas = [
1671
2121
  newsFeedMeta,
1672
2122
  portfolioValueMeta,
@@ -1726,7 +2176,39 @@ var frameMetas = [
1726
2176
  optionsPutCallMeta,
1727
2177
  optionsIvMeta,
1728
2178
  optionsOiStrikeMeta,
1729
- coinMoversMeta
2179
+ coinMoversMeta,
2180
+ mvrvMeta,
2181
+ nuplMeta,
2182
+ soprMeta,
2183
+ puellMultipleMeta,
2184
+ mayerMultipleMeta,
2185
+ piCycleMeta,
2186
+ maMultiplierMeta,
2187
+ rsiMomentumMeta,
2188
+ volumeProfileMeta,
2189
+ dxyMeta,
2190
+ cycleSignalsMeta,
2191
+ stablecoinSupplyMeta,
2192
+ yieldScannerMeta,
2193
+ defiRevenueMeta,
2194
+ fundingComparisonMeta,
2195
+ ethSupplyMeta,
2196
+ ethStakingMeta,
2197
+ predictionMarketsMeta,
2198
+ etfFlowsMeta,
2199
+ trendingCoinsMeta,
2200
+ sectorPerformanceMeta,
2201
+ macroCalendarMeta,
2202
+ stablecoinChainsMeta,
2203
+ sectorTreemapMeta,
2204
+ etfFlowsChartMeta,
2205
+ realizedPriceMeta,
2206
+ reserveRiskMeta,
2207
+ nftCollectionsMeta,
2208
+ dexHotPoolsMeta,
2209
+ chainActivityMeta,
2210
+ nftTreemapMeta,
2211
+ dexPoolTreemapMeta
1730
2212
  ];
1731
2213
  var allFrameMetas = [
1732
2214
  ...frameMetas,
@@ -3120,6 +3602,21 @@ var AlternativeMeProvider = class {
3120
3602
  // ../provider-coingecko/src/index.ts
3121
3603
  var GLOBAL_URL = "https://api.coingecko.com/api/v3/global";
3122
3604
  var MARKETS_URL = "https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=50&page=1&sparkline=false&price_change_percentage=24h";
3605
+ var TRENDING_URL = "https://api.coingecko.com/api/v3/search/trending";
3606
+ var CATEGORIES_URL = "https://api.coingecko.com/api/v3/coins/categories";
3607
+ var NFT_URL = "https://api.coingecko.com/api/v3/nfts";
3608
+ var NFT_IDS = [
3609
+ "bored-ape-yacht-club",
3610
+ "pudgy-penguins",
3611
+ "mutant-ape-yacht-club",
3612
+ "cryptopunks",
3613
+ "azuki",
3614
+ "milady",
3615
+ "doodles-official",
3616
+ "moonbirds",
3617
+ "lil-pudgys",
3618
+ "degods"
3619
+ ];
3123
3620
  var globalCache = new TtlCache({
3124
3621
  namespace: "zframes:coingecko:global",
3125
3622
  ttlMs: 12 * 6e4,
@@ -3130,12 +3627,94 @@ var marketsCache = new TtlCache({
3130
3627
  ttlMs: 10 * 6e4,
3131
3628
  persist: true
3132
3629
  });
3630
+ var trendingCache = new TtlCache({
3631
+ namespace: "zframes:coingecko:trending",
3632
+ ttlMs: 10 * 6e4,
3633
+ persist: true
3634
+ });
3635
+ var categoriesCache = new TtlCache({
3636
+ namespace: "zframes:coingecko:categories",
3637
+ ttlMs: 12 * 6e4,
3638
+ persist: true
3639
+ });
3640
+ var nftCache = new TtlCache({
3641
+ namespace: "zframes:coingecko:nft",
3642
+ ttlMs: 45 * 6e4,
3643
+ persist: true
3644
+ });
3645
+ function numberOr(value, fallback) {
3646
+ const n = Number(value);
3647
+ return Number.isFinite(n) ? n : fallback;
3648
+ }
3133
3649
  var CoinGeckoProvider = class {
3134
3650
  name = "coingecko";
3135
3651
  capabilities = [
3136
3652
  "global-market",
3137
- "coin-markets"
3653
+ "coin-markets",
3654
+ "trending-coins",
3655
+ "sector-performance",
3656
+ "nft-market"
3138
3657
  ];
3658
+ async getTrendingCoins() {
3659
+ return trendingCache.get("trending", async () => {
3660
+ const body = await fetchJson(TRENDING_URL);
3661
+ if (!Array.isArray(body?.coins))
3662
+ throw new Error("coingecko trending: unexpected response shape");
3663
+ return body.coins.map(({ item }) => {
3664
+ const price = Number(item.data?.price);
3665
+ const chg = Number(item.data?.price_change_percentage_24h?.usd);
3666
+ return {
3667
+ id: item.id,
3668
+ name: item.name,
3669
+ symbol: (item.symbol ?? "").toUpperCase(),
3670
+ rank: Number.isFinite(item.market_cap_rank) ? item.market_cap_rank : null,
3671
+ price: Number.isFinite(price) ? price : null,
3672
+ changePct24h: Number.isFinite(chg) ? chg : null
3673
+ };
3674
+ });
3675
+ });
3676
+ }
3677
+ async getSectorPerformance() {
3678
+ return categoriesCache.get("categories", async () => {
3679
+ const body = await fetchJson(CATEGORIES_URL);
3680
+ if (!Array.isArray(body))
3681
+ throw new Error("coingecko categories: unexpected response shape");
3682
+ return body.filter((c) => Number.isFinite(c.market_cap) && (c.market_cap ?? 0) > 0).map((c) => ({
3683
+ name: c.name,
3684
+ marketCap: c.market_cap,
3685
+ changePct24h: Number.isFinite(c.market_cap_change_24h) ? c.market_cap_change_24h : 0
3686
+ })).sort((a, b) => b.marketCap - a.marketCap).slice(0, 30);
3687
+ });
3688
+ }
3689
+ async getNftMarket() {
3690
+ return nftCache.get("nft", async () => {
3691
+ const collections = [];
3692
+ for (const id of NFT_IDS) {
3693
+ try {
3694
+ const body = await fetchJson(`${NFT_URL}/${id}`);
3695
+ const floorUsd = Number(body?.floor_price?.usd);
3696
+ if (!body?.id || !Number.isFinite(floorUsd)) continue;
3697
+ collections.push({
3698
+ id: body.id,
3699
+ name: body.name ?? body.id,
3700
+ floorNative: numberOr(body.floor_price?.native_currency, 0),
3701
+ floorUsd,
3702
+ floorChangePct24h: numberOr(
3703
+ body.floor_price_24h_percentage_change?.usd,
3704
+ 0
3705
+ ),
3706
+ marketCapUsd: numberOr(body.market_cap?.usd, 0),
3707
+ volume24hUsd: numberOr(body.volume_24h?.usd, 0),
3708
+ sales24h: numberOr(body.one_day_sales, 0)
3709
+ });
3710
+ } catch {
3711
+ }
3712
+ }
3713
+ if (collections.length === 0)
3714
+ throw new Error("coingecko nfts: no collections resolved");
3715
+ return collections.sort((a, b) => b.volume24hUsd - a.volume24hUsd);
3716
+ });
3717
+ }
3139
3718
  async getGlobalMarket() {
3140
3719
  return globalCache.get("global", async () => {
3141
3720
  const body = await fetchJson(GLOBAL_URL);
@@ -3169,6 +3748,9 @@ var CHAINS_URL = "https://api.llama.fi/v2/chains";
3169
3748
  var DEXS_URL = "https://api.llama.fi/overview/dexs";
3170
3749
  var FEES_URL = "https://api.llama.fi/overview/fees";
3171
3750
  var PROTOCOLS_URL = "https://api.llama.fi/protocols";
3751
+ var STABLES_URL = "https://stablecoins.llama.fi/stablecoins?includePrices=true";
3752
+ var STABLECHAINS_URL = "https://stablecoins.llama.fi/stablecoinchains";
3753
+ var YIELDS_URL = "https://yields.llama.fi/pools";
3172
3754
  var SNAPSHOT_TTL_MS = 8 * 6e4;
3173
3755
  var HISTORY_TTL_MS = 30 * 6e4;
3174
3756
  var tvlCache = new TtlCache({
@@ -3195,6 +3777,19 @@ var protocolHistoryCache = new TtlCache({
3195
3777
  namespace: "zframes:defillama:protocol-history",
3196
3778
  ttlMs: HISTORY_TTL_MS
3197
3779
  });
3780
+ var stablecoinsCache = new TtlCache({
3781
+ namespace: "zframes:defillama:stablecoins",
3782
+ ttlMs: 30 * 6e4,
3783
+ persist: true
3784
+ });
3785
+ var yieldsCache = new TtlCache({
3786
+ namespace: "zframes:defillama:yields",
3787
+ ttlMs: 12 * 6e4
3788
+ });
3789
+ var feesOverviewCache = new TtlCache({
3790
+ namespace: "zframes:defillama:fees-overview",
3791
+ ttlMs: SNAPSHOT_TTL_MS
3792
+ });
3198
3793
  var slugKey = (slugs) => [...slugs].sort().join(",");
3199
3794
  function toSeries(chart) {
3200
3795
  if (!Array.isArray(chart)) return [];
@@ -3207,7 +3802,10 @@ var DefiLlamaProvider = class {
3207
3802
  "tvl",
3208
3803
  "dex-volume",
3209
3804
  "protocol-tvl",
3210
- "protocol-fees"
3805
+ "protocol-fees",
3806
+ "stablecoins",
3807
+ "yields",
3808
+ "fees-overview"
3211
3809
  ];
3212
3810
  async getTvlByChain() {
3213
3811
  return tvlCache.get("chains", async () => {
@@ -3292,11 +3890,95 @@ var DefiLlamaProvider = class {
3292
3890
  })).sort((a, b) => b.fees24h - a.fees24h);
3293
3891
  });
3294
3892
  }
3893
+ async getStablecoinSupply() {
3894
+ return stablecoinsCache.get("supply", async () => {
3895
+ const [assetsBody, chains] = await Promise.all([
3896
+ fetchJson(STABLES_URL),
3897
+ fetchJson(STABLECHAINS_URL).catch(() => [])
3898
+ ]);
3899
+ const assets = assetsBody?.peggedAssets;
3900
+ if (!Array.isArray(assets))
3901
+ throw new Error("defillama stablecoins: unexpected response shape");
3902
+ let now = 0;
3903
+ let d1 = 0;
3904
+ let d7 = 0;
3905
+ let d30 = 0;
3906
+ for (const a of assets) {
3907
+ if (a.pegType && a.pegType !== "peggedUSD") continue;
3908
+ now += a.circulating?.peggedUSD ?? 0;
3909
+ d1 += a.circulatingPrevDay?.peggedUSD ?? 0;
3910
+ d7 += a.circulatingPrevWeek?.peggedUSD ?? 0;
3911
+ d30 += a.circulatingPrevMonth?.peggedUSD ?? 0;
3912
+ }
3913
+ if (now <= 0) throw new Error("defillama stablecoins: empty aggregate");
3914
+ const pct = (prev) => prev > 0 ? (now - prev) / prev * 100 : 0;
3915
+ const nowMs = Date.now();
3916
+ const history = [
3917
+ { time: nowMs - 30 * 864e5, value: d30 },
3918
+ { time: nowMs - 7 * 864e5, value: d7 },
3919
+ { time: nowMs - 864e5, value: d1 },
3920
+ { time: nowMs, value: now }
3921
+ ].filter((p) => p.value > 0);
3922
+ const topChains = (Array.isArray(chains) ? chains : []).map((c) => ({
3923
+ name: c.name,
3924
+ usd: c.totalCirculatingUSD?.peggedUSD ?? 0
3925
+ })).filter((c) => c.usd > 0).sort((a, b) => b.usd - a.usd).slice(0, 12);
3926
+ return {
3927
+ totalUsd: now,
3928
+ changePct1d: pct(d1),
3929
+ changePct7d: pct(d7),
3930
+ changePct30d: pct(d30),
3931
+ history,
3932
+ topChains
3933
+ };
3934
+ });
3935
+ }
3936
+ async getYieldPools() {
3937
+ return yieldsCache.get("pools", async () => {
3938
+ const body = await fetchJson(YIELDS_URL);
3939
+ const data = body?.data;
3940
+ if (!Array.isArray(data))
3941
+ throw new Error("defillama yields: unexpected response shape");
3942
+ return data.filter(
3943
+ (p) => Number.isFinite(p.tvlUsd) && (p.tvlUsd ?? 0) > 0 && Number.isFinite(p.apy)
3944
+ ).map((p) => ({
3945
+ pool: p.pool,
3946
+ chain: p.chain,
3947
+ project: p.project,
3948
+ symbol: p.symbol,
3949
+ tvlUsd: p.tvlUsd,
3950
+ apy: p.apy,
3951
+ apyBase: Number.isFinite(p.apyBase) ? p.apyBase : null,
3952
+ apyReward: Number.isFinite(p.apyReward) ? p.apyReward : null,
3953
+ apyPct7D: Number.isFinite(p.apyPct7D) ? p.apyPct7D : null,
3954
+ stablecoin: !!p.stablecoin,
3955
+ ilRisk: p.ilRisk ?? "unknown"
3956
+ })).sort((a, b) => b.tvlUsd - a.tvlUsd).slice(0, 250);
3957
+ });
3958
+ }
3959
+ async getFeesOverview() {
3960
+ return feesOverviewCache.get("overview", async () => {
3961
+ const body = await fetchJson(FEES_URL);
3962
+ if (!body || !Number.isFinite(body.total24h))
3963
+ throw new Error("defillama fees-overview: unexpected response shape");
3964
+ return {
3965
+ total24h: body.total24h,
3966
+ total7d: Number.isFinite(body.total7d) ? body.total7d : null,
3967
+ changePct: Number.isFinite(body.change_1d) ? body.change_1d : null,
3968
+ history: toSeries(body.totalDataChart)
3969
+ };
3970
+ });
3971
+ }
3295
3972
  };
3296
3973
 
3297
3974
  // ../provider-hyperliquid/src/index.ts
3298
3975
  var WS_URL = "wss://api.hyperliquid.xyz/ws";
3299
3976
  var INFO_URL = "https://api.hyperliquid.xyz/info";
3977
+ var VENUE_LABELS = {
3978
+ HlPerp: "Hyperliquid",
3979
+ BinPerp: "Binance",
3980
+ BybitPerp: "Bybit"
3981
+ };
3300
3982
  var dexOf = (symbol) => symbol.includes(":") ? symbol.split(":")[0] : "";
3301
3983
  async function info(body) {
3302
3984
  return fetchJson(INFO_URL, void 0, {
@@ -3325,6 +4007,10 @@ var fundingCache = new TtlCache({
3325
4007
  ttlMs: 4.5 * 6e4,
3326
4008
  persist: true
3327
4009
  });
4010
+ var fundingComparisonCache = new TtlCache({
4011
+ namespace: "zframes:hyperliquid:funding-comparison",
4012
+ ttlMs: 5 * 6e4
4013
+ });
3328
4014
  var sortedKey = (symbols) => symbols ? [...symbols].sort().join(",") : "*";
3329
4015
  var HyperliquidProvider = class {
3330
4016
  name = "hyperliquid";
@@ -3333,8 +4019,48 @@ var HyperliquidProvider = class {
3333
4019
  "day-stats",
3334
4020
  "funding-history",
3335
4021
  "ohlcv",
3336
- "open-interest"
4022
+ "open-interest",
4023
+ "funding-comparison"
3337
4024
  ];
4025
+ async getFundingComparison() {
4026
+ return fundingComparisonCache.get("all", async () => {
4027
+ const resp = await info({
4028
+ type: "predictedFundings"
4029
+ });
4030
+ if (!Array.isArray(resp))
4031
+ throw new Error("hyperliquid predictedFundings: unexpected shape");
4032
+ const out = [];
4033
+ for (const entry of resp) {
4034
+ if (!Array.isArray(entry) || entry.length < 2) continue;
4035
+ const [coin, venueList] = entry;
4036
+ if (typeof coin !== "string" || !Array.isArray(venueList)) continue;
4037
+ const venues = [];
4038
+ for (const vEntry of venueList) {
4039
+ if (!Array.isArray(vEntry) || vEntry.length < 2) continue;
4040
+ const [venue, meta] = vEntry;
4041
+ if (!meta) continue;
4042
+ const rawRate = parseFloat(meta.fundingRate);
4043
+ if (!Number.isFinite(rawRate)) continue;
4044
+ const reported = Number(meta.fundingIntervalHours);
4045
+ const intervalHours = Number.isFinite(reported) && reported > 0 ? reported : venue === "HlPerp" ? 1 : 8;
4046
+ venues.push({
4047
+ venue: VENUE_LABELS[venue] ?? venue,
4048
+ rawRate,
4049
+ intervalHours,
4050
+ annualizedPct: rawRate * (8760 / intervalHours) * 100
4051
+ });
4052
+ }
4053
+ if (venues.length < 2) continue;
4054
+ const rates = venues.map((v) => v.annualizedPct);
4055
+ out.push({
4056
+ coin,
4057
+ venues,
4058
+ spreadPct: Math.max(...rates) - Math.min(...rates)
4059
+ });
4060
+ }
4061
+ return out.sort((a, b) => Math.abs(b.spreadPct) - Math.abs(a.spreadPct)).slice(0, 80);
4062
+ });
4063
+ }
3338
4064
  ws = null;
3339
4065
  listeners = /* @__PURE__ */ new Set();
3340
4066
  reconnectTimer = null;