zframes 0.5.2 → 0.6.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.
- package/NOTICE +6 -2
- package/dist/index.js +614 -10
- package/package.json +2 -2
- package/runtime/assets/{bitcoin-dominance-CtnczH5N.js → bitcoin-dominance-CweHlZx7.js} +1 -1
- package/runtime/assets/{breakeven-zbCEQ5ag.js → breakeven-CG9rKwgE.js} +1 -1
- package/runtime/assets/{breathing-6Wmy_hqF.js → breathing-cDundHq6.js} +1 -1
- package/runtime/assets/{btc-blocks-D1xOLm2L.js → btc-blocks-Do_nySHd.js} +1 -1
- package/runtime/assets/{btc-difficulty-BTbKIqrl.js → btc-difficulty-vNbz5uRo.js} +1 -1
- package/runtime/assets/{btc-fees-5Geh2TSa.js → btc-fees-BmADLsmK.js} +1 -1
- package/runtime/assets/{btc-hashrate-DZfnxUsi.js → btc-hashrate-Wx2RAG-5.js} +1 -1
- package/runtime/assets/{btc-mempool-8oOMDiaW.js → btc-mempool-CTwbkMUR.js} +1 -1
- package/runtime/assets/{calculator-D91iI7KM.js → calculator-mvv6XpQC.js} +1 -1
- package/runtime/assets/{checklist-DNrOJw0w.js → checklist-CuEw3GpE.js} +1 -1
- package/runtime/assets/{clock-BzAIAbhU.js → clock-Cjnwi03W.js} +1 -1
- package/runtime/assets/{coin-movers-99W2EABZ.js → coin-movers-Bcx1XR0F.js} +1 -1
- package/runtime/assets/{countdown-ZAJmbykg.js → countdown-Cdi5gSSu.js} +1 -1
- package/runtime/assets/cycle-shared-BOGcJDzT.js +1 -0
- package/runtime/assets/cycle-signals-CS629ZDc.js +1 -0
- package/runtime/assets/{daily-analysis-CS5MqofA.js → daily-analysis-DX8bVq85.js} +1 -1
- package/runtime/assets/{day-meter-DzBvLcpd.js → day-meter-DDfTuhms.js} +1 -1
- package/runtime/assets/defi-revenue-CpeAGwhb.js +1 -0
- package/runtime/assets/{dex-volume-chart-BfnczfAT.js → dex-volume-chart-sHIuJACJ.js} +1 -1
- package/runtime/assets/{dex-volume-treemap-CLyIrkgU.js → dex-volume-treemap-rSTrzz7O.js} +1 -1
- package/runtime/assets/{dice-CAvRf0md.js → dice-BrFORdjN.js} +1 -1
- package/runtime/assets/{dino-game-gsyCpJ-0.js → dino-game-BOV8mV1d.js} +1 -1
- package/runtime/assets/{divider-DCTu-qNh.js → divider-C33tH1RU.js} +1 -1
- package/runtime/assets/{drawdy-CZWCFtog.js → drawdy-BIb36JN9.js} +1 -1
- package/runtime/assets/dxy-CRifEdp_.js +1 -0
- package/runtime/assets/editor-CZoWRTJC.css +1 -0
- package/runtime/assets/editor-Dnp1eXvY.js +68 -0
- package/runtime/assets/etf-flows-BV10E2R-.js +1 -0
- package/runtime/assets/etf-flows-chart-DHu8mkXm.js +1 -0
- package/runtime/assets/eth-staking-BqWeJq6F.js +1 -0
- package/runtime/assets/eth-supply-CF-MgHjn.js +1 -0
- package/runtime/assets/{fear-greed-DOcPswrx.js → fear-greed-DuDR56h2.js} +1 -1
- package/runtime/assets/{filings-feed-Cs--DpYl.js → filings-feed-BpfO2yF6.js} +1 -1
- package/runtime/assets/{financial-stress-BqnxLk2O.js → financial-stress-BfYJdlry.js} +1 -1
- package/runtime/assets/{flappy-bird-DaasqVGg.js → flappy-bird-Dbb2UQBv.js} +1 -1
- package/runtime/assets/{fundamentals-GseULnsD.js → fundamentals-CUnqjF--.js} +1 -1
- package/runtime/assets/funding-comparison-CMKxW1n-.js +1 -0
- package/runtime/assets/{funding-heatmap-2RvVLTPN.js → funding-heatmap-CZWnYF8Y.js} +1 -1
- package/runtime/assets/{funding-rate-chart-DCRKHp6g.js → funding-rate-chart-C-tpwid_.js} +1 -1
- package/runtime/assets/{fx-board-CVW6VmbY.js → fx-board-YAy44m5d.js} +1 -1
- package/runtime/assets/{heading-BaRMJq2t.js → heading-uIVBEE7K.js} +1 -1
- package/runtime/assets/{holiday-calendar-2OBfwbh-.js → holiday-calendar-DCj83hi2.js} +1 -1
- package/runtime/assets/{image-CuTXEV7Q.js → image-CITPAmp0.js} +1 -1
- package/runtime/assets/index-Bx7RmzY8.js +1 -0
- package/runtime/assets/index-CrmTiZaB.css +1 -0
- package/runtime/assets/index-DyvZokhk.js +1097 -0
- package/runtime/assets/indicators-CogwjDn9.js +1 -0
- package/runtime/assets/{inflation-pulse-B8E9uzQB.js → inflation-pulse-Bqa3-cuC.js} +1 -1
- package/runtime/assets/{journal-log-7APM_99k.js → journal-log-Bgjia8cQ.js} +1 -1
- package/runtime/assets/{journal-open-CcdGuysA.js → journal-open-Bm5gwWXz.js} +1 -1
- package/runtime/assets/{journal-results-CUTn4-kq.js → journal-results-cEWe2pbe.js} +1 -1
- package/runtime/assets/{journal-score-C31dg2yL.js → journal-score-vmfF-9bK.js} +1 -1
- package/runtime/assets/{journal-ui-C5ueSjZx.js → journal-ui-ApBNIq5_.js} +1 -1
- package/runtime/assets/{labor-market-DgvDQtFo.js → labor-market-azDXD-dR.js} +1 -1
- package/runtime/assets/{lightning-stats-CiUlm-e_.js → lightning-stats-nkyh2dOX.js} +1 -1
- package/runtime/assets/{link-grid-DlsY59eq.js → link-grid-BEo4b54T.js} +1 -1
- package/runtime/assets/ma-multiplier-BllDQMF5.js +1 -0
- package/runtime/assets/macro-calendar-Ck0dJk4p.js +1 -0
- package/runtime/assets/{market-cap-treemap-6vqLUgVk.js → market-cap-treemap-AxE2EYPO.js} +1 -1
- package/runtime/assets/{market-hours-BArlXOQB.js → market-hours-BSwXtU8c.js} +1 -1
- package/runtime/assets/{marquee-2Di2SqI2.js → marquee-1Zr5qDJP.js} +1 -1
- package/runtime/assets/mayer-multiple-DpBJNd4d.js +1 -0
- package/runtime/assets/{mining-pools-Bg02wm2V.js → mining-pools-B-jxdTot.js} +1 -1
- package/runtime/assets/{mover-row-C8040L85.js → mover-row-Dg96EIqq.js} +1 -1
- package/runtime/assets/mvrv-Dx_S0TwE.js +1 -0
- package/runtime/assets/{national-debt-BS57WjA3.js → national-debt-BKVBHaqm.js} +1 -1
- package/runtime/assets/{news-feed-oBCTiuoo.js → news-feed-C9itZmyp.js} +1 -1
- package/runtime/assets/{note-BLWlz52v.js → note-BtCnmuMo.js} +1 -1
- package/runtime/assets/nupl-aIjkc57m.js +1 -0
- package/runtime/assets/{open-interest-DxMqZcmu.js → open-interest-C0ulogv6.js} +1 -1
- package/runtime/assets/{options-iv-CgIIFdpN.js → options-iv-CdUder3x.js} +1 -1
- package/runtime/assets/{options-oi-strike-blRp4kmB.js → options-oi-strike-CvCZnMCR.js} +1 -1
- package/runtime/assets/{options-put-call-CyOwXBVQ.js → options-put-call-FuaDHJ-S.js} +1 -1
- package/runtime/assets/pi-cycle-BuCnLnIJ.js +1 -0
- package/runtime/assets/{pomodoro-BKJlh-bz.js → pomodoro-DDBVVcSR.js} +1 -1
- package/runtime/assets/{portfolio-allocation-Cat1vq2_.js → portfolio-allocation-DAnQk_h_.js} +1 -1
- package/runtime/assets/{portfolio-common-DeyRfuNV.js → portfolio-common-Bi16i0aA.js} +1 -1
- package/runtime/assets/{portfolio-holdings-DDDhMMFL.js → portfolio-holdings-MyAinCzt.js} +1 -1
- package/runtime/assets/{portfolio-value-D9qrGeZp.js → portfolio-value-BPURwKf8.js} +1 -1
- package/runtime/assets/prediction-markets-Bzy51qnV.js +1 -0
- package/runtime/assets/{price-chart-CQJNOBtu.js → price-chart-BOCD8ka3.js} +1 -1
- package/runtime/assets/{price-compare-DqBiHd7S.js → price-compare-DZlF-qhZ.js} +1 -1
- package/runtime/assets/{price-liveline-BlVGC2-R.js → price-liveline-Bl7qCd5-.js} +1 -1
- package/runtime/assets/{price-ticker-QdVoVaQh.js → price-ticker-D2W4T02y.js} +1 -1
- package/runtime/assets/{protocol-fees-treemap-39F-aE33.js → protocol-fees-treemap-DiIt4bfo.js} +1 -1
- package/runtime/assets/{protocol-tvl-chart-DZOgbMZu.js → protocol-tvl-chart-CmzANiR7.js} +1 -1
- package/runtime/assets/{protocol-tvl-treemap-DusQ6xL2.js → protocol-tvl-treemap-BjNPrrtL.js} +1 -1
- package/runtime/assets/puell-multiple-BGrJX43r.js +1 -0
- package/runtime/assets/{quote-Di049ggj.js → quote-CRM3bfI7.js} +1 -1
- package/runtime/assets/{rates-board-Dm3tb6-P.js → rates-board-Cb9rV0_-.js} +1 -1
- package/runtime/assets/realized-price-CYlrFa0m.js +1 -0
- package/runtime/assets/reserve-risk-Be98XUsD.js +1 -0
- package/runtime/assets/{returns-projector-BiMx_kSw.js → returns-projector-D67a_yvC.js} +1 -1
- package/runtime/assets/{risk-reward-1Q_Kt75s.js → risk-reward-C7WMz2od.js} +1 -1
- package/runtime/assets/rsi-momentum-IglnulkJ.js +1 -0
- package/runtime/assets/{rules-card-BkAX9PEq.js → rules-card-DJs3fDVN.js} +1 -1
- package/runtime/assets/scene-uwfOGek1.js +1 -0
- package/runtime/assets/sector-performance-DVMaleLY.js +1 -0
- package/runtime/assets/sector-treemap-B681nSi6.js +1 -0
- package/runtime/assets/{session-progress-D_1dzPzM.js → session-progress-CZO3LqUi.js} +1 -1
- package/runtime/assets/{short-volume-U-uFonb2.js → short-volume-l8_9Yoh3.js} +1 -1
- package/runtime/assets/{snake-Dp4E3Dcv.js → snake-CifbTGlZ.js} +1 -1
- package/runtime/assets/sopr-Dw_oz-mC.js +1 -0
- package/runtime/assets/{spotify-embed-Cw95WZjV.js → spotify-embed-BA0m1IRb.js} +1 -1
- package/runtime/assets/stablecoin-chains-Dd2LqqqY.js +1 -0
- package/runtime/assets/stablecoin-supply-DM4ogL4V.js +1 -0
- package/runtime/assets/{stopwatch-B2_iDkKK.js → stopwatch-Co72v-7u.js} +1 -1
- package/runtime/assets/{top-movers--vCUiTII.js → top-movers-CLmC2TNu.js} +1 -1
- package/runtime/assets/{treasury-auctions-BpzYivLg.js → treasury-auctions-Dl9fiRgf.js} +1 -1
- package/runtime/assets/{treemap-leaf-DNIoJEK-.js → treemap-leaf-Dn31k9S9.js} +1 -1
- package/runtime/assets/trending-coins-Cpx9T6cG.js +1 -0
- package/runtime/assets/{tvl-treemap-BYgD9bNy.js → tvl-treemap-e610jE8k.js} +1 -1
- package/runtime/assets/{video-D-nBm697.js → video-CeKjM-cE.js} +1 -1
- package/runtime/assets/volume-profile-CiMFsIBu.js +1 -0
- package/runtime/assets/{yield-curve-8IsrMS_9.js → yield-curve-DkB0u2_Q.js} +1 -1
- package/runtime/assets/yield-scanner-BP90untT.js +1 -0
- package/runtime/index.html +2 -2
- package/runtime/assets/editor-BMMobjrE.css +0 -1
- package/runtime/assets/editor-Ckt9OQ98.js +0 -68
- package/runtime/assets/index-BqHx9BjX.css +0 -1
- package/runtime/assets/index-CH54P4Cn.js +0 -936
- package/runtime/assets/index-DK7jWlTL.js +0 -1
- package/runtime/assets/unicorn-scene-DcohHRPZ.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,12 @@ 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" }
|
|
430
439
|
};
|
|
431
440
|
var clockMeta = defineFrameMeta({
|
|
432
441
|
name: "clock",
|
|
@@ -772,7 +781,7 @@ var fundamentalsMeta = defineFrameMeta({
|
|
|
772
781
|
label: "Fundamentals",
|
|
773
782
|
category: "equities",
|
|
774
783
|
iconUrl: widgetIcon("fundamentals"),
|
|
775
|
-
layout: { w: 4, h:
|
|
784
|
+
layout: { w: 4, h: 4, minW: 3, minH: 3 },
|
|
776
785
|
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
786
|
capabilities: ["fundamentals"],
|
|
778
787
|
source: SOURCES.secEdgar,
|
|
@@ -916,7 +925,7 @@ var journalScoreMeta = defineFrameMeta({
|
|
|
916
925
|
label: "Journal \xB7 Scoreboard",
|
|
917
926
|
category: "journal",
|
|
918
927
|
iconUrl: widgetIcon("journal-score"),
|
|
919
|
-
layout: { w: 4, h:
|
|
928
|
+
layout: { w: 4, h: 3, minW: 3, minH: 3 },
|
|
920
929
|
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
930
|
capabilities: [],
|
|
922
931
|
schema: z3.object({})
|
|
@@ -1503,7 +1512,7 @@ var btcFeesMeta = defineFrameMeta({
|
|
|
1503
1512
|
label: "BTC Fees",
|
|
1504
1513
|
category: "bitcoin",
|
|
1505
1514
|
iconUrl: widgetIcon("btc-fees"),
|
|
1506
|
-
layout: { w: 3, h:
|
|
1515
|
+
layout: { w: 3, h: 3, minW: 2, minH: 3 },
|
|
1507
1516
|
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
1517
|
capabilities: ["btc-fees"],
|
|
1509
1518
|
source: SOURCES.mempool,
|
|
@@ -1667,6 +1676,377 @@ var coinMoversMeta = defineFrameMeta({
|
|
|
1667
1676
|
)
|
|
1668
1677
|
})
|
|
1669
1678
|
});
|
|
1679
|
+
var mvrvMeta = defineFrameMeta({
|
|
1680
|
+
name: "mvrv",
|
|
1681
|
+
label: "MVRV Ratio",
|
|
1682
|
+
category: "onchain",
|
|
1683
|
+
iconUrl: widgetIcon("mvrv"),
|
|
1684
|
+
layout: { w: 3, h: 3, minW: 2, minH: 2 },
|
|
1685
|
+
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.",
|
|
1686
|
+
capabilities: ["onchain-valuation"],
|
|
1687
|
+
source: SOURCES.coinMetrics,
|
|
1688
|
+
schema: z3.object({
|
|
1689
|
+
window: z3.enum(["1Y", "2Y", "4Y", "all"]).default("all").describe("How much history the sparkline shows.")
|
|
1690
|
+
})
|
|
1691
|
+
});
|
|
1692
|
+
var nuplMeta = defineFrameMeta({
|
|
1693
|
+
name: "nupl",
|
|
1694
|
+
label: "NUPL",
|
|
1695
|
+
category: "onchain",
|
|
1696
|
+
iconUrl: widgetIcon("nupl"),
|
|
1697
|
+
layout: { w: 3, h: 3, minW: 2, minH: 2 },
|
|
1698
|
+
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.",
|
|
1699
|
+
capabilities: ["onchain-valuation"],
|
|
1700
|
+
source: SOURCES.coinMetrics,
|
|
1701
|
+
schema: z3.object({
|
|
1702
|
+
window: z3.enum(["1Y", "2Y", "4Y", "all"]).default("all").describe("How much history the sparkline shows.")
|
|
1703
|
+
})
|
|
1704
|
+
});
|
|
1705
|
+
var soprMeta = defineFrameMeta({
|
|
1706
|
+
name: "sopr",
|
|
1707
|
+
label: "SOPR",
|
|
1708
|
+
category: "onchain",
|
|
1709
|
+
iconUrl: widgetIcon("sopr"),
|
|
1710
|
+
layout: { w: 3, h: 3, minW: 2, minH: 2 },
|
|
1711
|
+
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).",
|
|
1712
|
+
capabilities: ["onchain-cycle-extras"],
|
|
1713
|
+
source: SOURCES.bitcoinData,
|
|
1714
|
+
schema: z3.object({
|
|
1715
|
+
window: z3.enum(["90D", "180D", "1Y"]).default("1Y").describe("How much history the sparkline shows.")
|
|
1716
|
+
})
|
|
1717
|
+
});
|
|
1718
|
+
var puellMultipleMeta = defineFrameMeta({
|
|
1719
|
+
name: "puell-multiple",
|
|
1720
|
+
label: "Puell Multiple",
|
|
1721
|
+
category: "onchain",
|
|
1722
|
+
iconUrl: widgetIcon("puell-multiple"),
|
|
1723
|
+
layout: { w: 3, h: 3, minW: 2, minH: 2 },
|
|
1724
|
+
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).",
|
|
1725
|
+
capabilities: ["onchain-cycle-extras"],
|
|
1726
|
+
source: SOURCES.bitcoinData,
|
|
1727
|
+
schema: z3.object({
|
|
1728
|
+
window: z3.enum(["90D", "180D", "1Y"]).default("1Y").describe("How much history the sparkline shows.")
|
|
1729
|
+
})
|
|
1730
|
+
});
|
|
1731
|
+
var mayerMultipleMeta = defineFrameMeta({
|
|
1732
|
+
name: "mayer-multiple",
|
|
1733
|
+
label: "Mayer Multiple",
|
|
1734
|
+
category: "onchain",
|
|
1735
|
+
iconUrl: widgetIcon("mayer-multiple"),
|
|
1736
|
+
layout: { w: 3, h: 3, minW: 2, minH: 2 },
|
|
1737
|
+
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).",
|
|
1738
|
+
capabilities: ["price-history-daily"],
|
|
1739
|
+
source: SOURCES.coinMetrics,
|
|
1740
|
+
schema: z3.object({
|
|
1741
|
+
window: z3.enum(["1Y", "2Y", "4Y", "all"]).default("2Y").describe("How much history the sparkline shows.")
|
|
1742
|
+
})
|
|
1743
|
+
});
|
|
1744
|
+
var piCycleMeta = defineFrameMeta({
|
|
1745
|
+
name: "pi-cycle",
|
|
1746
|
+
label: "Pi Cycle Top",
|
|
1747
|
+
category: "onchain",
|
|
1748
|
+
iconUrl: widgetIcon("pi-cycle"),
|
|
1749
|
+
layout: { w: 3, h: 3, minW: 2, minH: 2 },
|
|
1750
|
+
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).",
|
|
1751
|
+
capabilities: ["price-history-daily"],
|
|
1752
|
+
source: SOURCES.coinMetrics,
|
|
1753
|
+
schema: z3.object({
|
|
1754
|
+
window: z3.enum(["1Y", "2Y", "4Y", "all"]).default("2Y").describe("How much history the sparkline shows.")
|
|
1755
|
+
})
|
|
1756
|
+
});
|
|
1757
|
+
var maMultiplierMeta = defineFrameMeta({
|
|
1758
|
+
name: "ma-multiplier",
|
|
1759
|
+
label: "MA Multiplier",
|
|
1760
|
+
category: "onchain",
|
|
1761
|
+
iconUrl: widgetIcon("ma-multiplier"),
|
|
1762
|
+
layout: { w: 3, h: 3, minW: 2, minH: 2 },
|
|
1763
|
+
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).",
|
|
1764
|
+
capabilities: ["price-history-daily"],
|
|
1765
|
+
source: SOURCES.coinMetrics,
|
|
1766
|
+
schema: z3.object({
|
|
1767
|
+
years: z3.enum(["2", "4"]).default("2").describe("Moving-average window in years."),
|
|
1768
|
+
window: z3.enum(["2Y", "4Y", "all"]).default("all").describe("How much history the sparkline shows.")
|
|
1769
|
+
})
|
|
1770
|
+
});
|
|
1771
|
+
var rsiMomentumMeta = defineFrameMeta({
|
|
1772
|
+
name: "rsi-momentum",
|
|
1773
|
+
label: "RSI Momentum",
|
|
1774
|
+
category: "markets",
|
|
1775
|
+
iconUrl: widgetIcon("rsi-momentum"),
|
|
1776
|
+
layout: { w: 3, h: 3, minW: 2, minH: 2 },
|
|
1777
|
+
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).",
|
|
1778
|
+
capabilities: ["price-history-daily"],
|
|
1779
|
+
source: SOURCES.coinMetrics,
|
|
1780
|
+
schema: z3.object({
|
|
1781
|
+
period: z3.number().int().min(2).max(50).default(14).describe("RSI lookback period in days."),
|
|
1782
|
+
window: z3.enum(["90D", "180D", "1Y", "2Y"]).default("180D").describe("How much history the sparkline shows.")
|
|
1783
|
+
})
|
|
1784
|
+
});
|
|
1785
|
+
var volumeProfileMeta = defineFrameMeta({
|
|
1786
|
+
name: "volume-profile",
|
|
1787
|
+
label: "Volume Profile",
|
|
1788
|
+
category: "markets",
|
|
1789
|
+
iconUrl: widgetIcon("volume-profile"),
|
|
1790
|
+
layout: { w: 4, h: 4, minW: 3, minH: 3 },
|
|
1791
|
+
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').",
|
|
1792
|
+
capabilities: ["ohlcv"],
|
|
1793
|
+
source: SOURCES.hyperliquid,
|
|
1794
|
+
schema: z3.object({
|
|
1795
|
+
symbol: z3.string().default("BTC").describe(
|
|
1796
|
+
"Symbol to profile, e.g. 'BTC', 'ETH', or a HIP-3 equity 'xyz:TSLA'."
|
|
1797
|
+
),
|
|
1798
|
+
interval: z3.enum(["1h", "4h", "1d"]).default("1d").describe("Candle interval."),
|
|
1799
|
+
lookbackDays: z3.number().int().min(7).max(365).default(90).describe("How many days of candles to build the profile from."),
|
|
1800
|
+
bins: z3.number().int().min(8).max(48).default(24).describe("Number of price buckets in the histogram.")
|
|
1801
|
+
})
|
|
1802
|
+
});
|
|
1803
|
+
var dxyMeta = defineFrameMeta({
|
|
1804
|
+
name: "dxy",
|
|
1805
|
+
label: "Dollar Index (DXY)",
|
|
1806
|
+
category: "macro",
|
|
1807
|
+
iconUrl: widgetIcon("dxy"),
|
|
1808
|
+
layout: { w: 3, h: 3, minW: 2, minH: 2 },
|
|
1809
|
+
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).",
|
|
1810
|
+
capabilities: ["dollar-index"],
|
|
1811
|
+
source: SOURCES.frankfurter,
|
|
1812
|
+
schema: z3.object({})
|
|
1813
|
+
});
|
|
1814
|
+
var cycleSignalsMeta = defineFrameMeta({
|
|
1815
|
+
name: "cycle-signals",
|
|
1816
|
+
label: "Cycle Signals",
|
|
1817
|
+
category: "onchain",
|
|
1818
|
+
iconUrl: widgetIcon("cycle-signals"),
|
|
1819
|
+
layout: { w: 4, h: 5, minW: 3, minH: 3 },
|
|
1820
|
+
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).",
|
|
1821
|
+
capabilities: [
|
|
1822
|
+
"onchain-valuation",
|
|
1823
|
+
"onchain-cycle-extras",
|
|
1824
|
+
"price-history-daily"
|
|
1825
|
+
],
|
|
1826
|
+
source: [SOURCES.coinMetrics, SOURCES.bitcoinData],
|
|
1827
|
+
schema: z3.object({
|
|
1828
|
+
mode: z3.enum(["peak", "bottom"]).default("peak").describe(
|
|
1829
|
+
"Which checklist to show: cycle-top ('peak') or cycle-bottom ('bottom') signals."
|
|
1830
|
+
)
|
|
1831
|
+
})
|
|
1832
|
+
});
|
|
1833
|
+
var stablecoinSupplyMeta = defineFrameMeta({
|
|
1834
|
+
name: "stablecoin-supply",
|
|
1835
|
+
label: "Stablecoin Supply",
|
|
1836
|
+
category: "crypto",
|
|
1837
|
+
iconUrl: widgetIcon("stablecoin-supply"),
|
|
1838
|
+
layout: { w: 3, h: 3, minW: 2, minH: 2 },
|
|
1839
|
+
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).",
|
|
1840
|
+
capabilities: ["stablecoins"],
|
|
1841
|
+
source: SOURCES.defillama,
|
|
1842
|
+
schema: z3.object({})
|
|
1843
|
+
});
|
|
1844
|
+
var yieldScannerMeta = defineFrameMeta({
|
|
1845
|
+
name: "yield-scanner",
|
|
1846
|
+
label: "Yield Scanner",
|
|
1847
|
+
category: "crypto",
|
|
1848
|
+
iconUrl: widgetIcon("yield-scanner"),
|
|
1849
|
+
layout: { w: 5, h: 4, minW: 3, minH: 3 },
|
|
1850
|
+
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).",
|
|
1851
|
+
capabilities: ["yields"],
|
|
1852
|
+
source: SOURCES.defillama,
|
|
1853
|
+
schema: z3.object({
|
|
1854
|
+
limit: z3.number().int().min(3).max(20).default(8).describe("How many pools to list."),
|
|
1855
|
+
stablecoinOnly: z3.boolean().default(false).describe("Only show stablecoin pools (lower impermanent-loss risk)."),
|
|
1856
|
+
minTvlUsd: z3.number().min(0).default(1e6).describe("Minimum pool TVL in USD \u2014 a liquidity floor to hide dust.")
|
|
1857
|
+
})
|
|
1858
|
+
});
|
|
1859
|
+
var defiRevenueMeta = defineFrameMeta({
|
|
1860
|
+
name: "defi-revenue",
|
|
1861
|
+
label: "DeFi Fees & Revenue",
|
|
1862
|
+
category: "crypto",
|
|
1863
|
+
iconUrl: widgetIcon("defi-revenue"),
|
|
1864
|
+
layout: { w: 3, h: 3, minW: 2, minH: 2 },
|
|
1865
|
+
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).",
|
|
1866
|
+
capabilities: ["fees-overview"],
|
|
1867
|
+
source: SOURCES.defillama,
|
|
1868
|
+
schema: z3.object({})
|
|
1869
|
+
});
|
|
1870
|
+
var fundingComparisonMeta = defineFrameMeta({
|
|
1871
|
+
name: "funding-comparison",
|
|
1872
|
+
label: "Cross-Venue Funding",
|
|
1873
|
+
category: "derivatives",
|
|
1874
|
+
iconUrl: widgetIcon("funding-comparison"),
|
|
1875
|
+
layout: { w: 5, h: 4, minW: 3, minH: 3 },
|
|
1876
|
+
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).",
|
|
1877
|
+
capabilities: ["funding-comparison"],
|
|
1878
|
+
source: SOURCES.hyperliquid,
|
|
1879
|
+
schema: z3.object({
|
|
1880
|
+
limit: z3.number().int().min(3).max(20).default(8).describe("How many coins (by funding spread) to show.")
|
|
1881
|
+
})
|
|
1882
|
+
});
|
|
1883
|
+
var ethSupplyMeta = defineFrameMeta({
|
|
1884
|
+
name: "eth-supply",
|
|
1885
|
+
label: "ETH Ultrasound",
|
|
1886
|
+
category: "crypto",
|
|
1887
|
+
iconUrl: widgetIcon("eth-supply"),
|
|
1888
|
+
layout: { w: 4, h: 3, minW: 2, minH: 2 },
|
|
1889
|
+
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).",
|
|
1890
|
+
capabilities: ["eth-supply"],
|
|
1891
|
+
source: SOURCES.ultrasound,
|
|
1892
|
+
schema: z3.object({})
|
|
1893
|
+
});
|
|
1894
|
+
var ethStakingMeta = defineFrameMeta({
|
|
1895
|
+
name: "eth-staking",
|
|
1896
|
+
label: "ETH Staking APR",
|
|
1897
|
+
category: "crypto",
|
|
1898
|
+
iconUrl: widgetIcon("eth-staking"),
|
|
1899
|
+
layout: { w: 3, h: 3, minW: 2, minH: 2 },
|
|
1900
|
+
description: "Ethereum staking yield \u2014 total validator APR broken into consensus issuance, MEV, and priority tips. The 'risk-free' ETH rate. Keyless (ultrasound.money).",
|
|
1901
|
+
capabilities: ["eth-supply"],
|
|
1902
|
+
source: SOURCES.ultrasound,
|
|
1903
|
+
schema: z3.object({})
|
|
1904
|
+
});
|
|
1905
|
+
var predictionMarketsMeta = defineFrameMeta({
|
|
1906
|
+
name: "prediction-markets",
|
|
1907
|
+
label: "Prediction Markets",
|
|
1908
|
+
category: "sentiment",
|
|
1909
|
+
iconUrl: widgetIcon("prediction-markets"),
|
|
1910
|
+
layout: { w: 4, h: 4, minW: 3, minH: 3 },
|
|
1911
|
+
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).",
|
|
1912
|
+
capabilities: ["prediction-markets"],
|
|
1913
|
+
source: SOURCES.polymarket,
|
|
1914
|
+
schema: z3.object({
|
|
1915
|
+
limit: z3.number().int().min(3).max(20).default(6).describe("How many markets (by volume) to show.")
|
|
1916
|
+
})
|
|
1917
|
+
});
|
|
1918
|
+
var etfFlowsMeta = defineFrameMeta({
|
|
1919
|
+
name: "etf-flows",
|
|
1920
|
+
label: "Spot ETF Flows",
|
|
1921
|
+
category: "crypto",
|
|
1922
|
+
iconUrl: widgetIcon("etf-flows"),
|
|
1923
|
+
layout: { w: 4, h: 4, minW: 3, minH: 3 },
|
|
1924
|
+
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.",
|
|
1925
|
+
capabilities: ["etf-flows"],
|
|
1926
|
+
source: SOURCES.sosovalue,
|
|
1927
|
+
schema: z3.object({
|
|
1928
|
+
asset: z3.enum(["btc", "eth"]).default("btc").describe("Which spot-ETF complex to show."),
|
|
1929
|
+
limit: z3.number().int().min(3).max(15).default(8).describe("How many issuers to list.")
|
|
1930
|
+
})
|
|
1931
|
+
});
|
|
1932
|
+
var trendingCoinsMeta = defineFrameMeta({
|
|
1933
|
+
name: "trending-coins",
|
|
1934
|
+
label: "Trending Coins",
|
|
1935
|
+
category: "crypto",
|
|
1936
|
+
iconUrl: widgetIcon("trending-coins"),
|
|
1937
|
+
layout: { w: 3, h: 4, minW: 2, minH: 3 },
|
|
1938
|
+
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).",
|
|
1939
|
+
capabilities: ["trending-coins"],
|
|
1940
|
+
source: SOURCES.coingecko,
|
|
1941
|
+
schema: z3.object({
|
|
1942
|
+
limit: z3.number().int().min(3).max(15).default(7).describe("How many trending coins to show.")
|
|
1943
|
+
})
|
|
1944
|
+
});
|
|
1945
|
+
var sectorPerformanceMeta = defineFrameMeta({
|
|
1946
|
+
name: "sector-performance",
|
|
1947
|
+
label: "Sector Performance",
|
|
1948
|
+
category: "crypto",
|
|
1949
|
+
iconUrl: widgetIcon("sector-performance"),
|
|
1950
|
+
layout: { w: 4, h: 4, minW: 3, minH: 3 },
|
|
1951
|
+
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).",
|
|
1952
|
+
capabilities: ["sector-performance"],
|
|
1953
|
+
source: SOURCES.coingecko,
|
|
1954
|
+
schema: z3.object({
|
|
1955
|
+
limit: z3.number().int().min(4).max(30).default(10).describe("How many sectors to show.")
|
|
1956
|
+
})
|
|
1957
|
+
});
|
|
1958
|
+
var macroCalendarMeta = defineFrameMeta({
|
|
1959
|
+
name: "macro-calendar",
|
|
1960
|
+
label: "Macro Calendar",
|
|
1961
|
+
category: "macro",
|
|
1962
|
+
iconUrl: widgetIcon("macro-calendar"),
|
|
1963
|
+
layout: { w: 4, h: 4, minW: 3, minH: 2 },
|
|
1964
|
+
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.",
|
|
1965
|
+
capabilities: [],
|
|
1966
|
+
schema: z3.object({
|
|
1967
|
+
limit: z3.number().int().min(1).max(12).default(5).describe("How many upcoming events to show."),
|
|
1968
|
+
events: z3.array(
|
|
1969
|
+
z3.object({
|
|
1970
|
+
date: z3.string().describe("Event date, ISO YYYY-MM-DD."),
|
|
1971
|
+
label: z3.string().describe("Event name, e.g. 'FOMC decision'.")
|
|
1972
|
+
})
|
|
1973
|
+
).default([
|
|
1974
|
+
{ date: "2026-07-29", label: "FOMC decision" },
|
|
1975
|
+
{ date: "2026-09-16", label: "FOMC decision" },
|
|
1976
|
+
{ date: "2026-10-28", label: "FOMC decision" },
|
|
1977
|
+
{ date: "2026-12-09", label: "FOMC decision" },
|
|
1978
|
+
{ date: "2027-01-27", label: "FOMC decision" }
|
|
1979
|
+
]).describe(
|
|
1980
|
+
"Scheduled events (date + label). Defaults to the 2026 FOMC meetings; edit to add CPI/NFP/earnings dates."
|
|
1981
|
+
)
|
|
1982
|
+
})
|
|
1983
|
+
});
|
|
1984
|
+
var stablecoinChainsMeta = defineFrameMeta({
|
|
1985
|
+
name: "stablecoin-chains",
|
|
1986
|
+
label: "Stablecoin Chains",
|
|
1987
|
+
category: "crypto",
|
|
1988
|
+
iconUrl: widgetIcon("stablecoin-chains"),
|
|
1989
|
+
layout: { w: 5, h: 4, minW: 4, minH: 3 },
|
|
1990
|
+
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).",
|
|
1991
|
+
capabilities: ["stablecoins"],
|
|
1992
|
+
source: SOURCES.defillama,
|
|
1993
|
+
schema: z3.object({
|
|
1994
|
+
limit: z3.number().int().min(4).max(16).default(12).describe("How many chains to show in the treemap.")
|
|
1995
|
+
})
|
|
1996
|
+
});
|
|
1997
|
+
var sectorTreemapMeta = defineFrameMeta({
|
|
1998
|
+
name: "sector-treemap",
|
|
1999
|
+
label: "Sector Treemap",
|
|
2000
|
+
category: "crypto",
|
|
2001
|
+
iconUrl: widgetIcon("sector-treemap"),
|
|
2002
|
+
layout: { w: 6, h: 4, minW: 4, minH: 3 },
|
|
2003
|
+
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).",
|
|
2004
|
+
capabilities: ["sector-performance"],
|
|
2005
|
+
source: SOURCES.coingecko,
|
|
2006
|
+
schema: z3.object({
|
|
2007
|
+
limit: z3.number().int().min(6).max(30).default(16).describe("How many sectors to show.")
|
|
2008
|
+
})
|
|
2009
|
+
});
|
|
2010
|
+
var etfFlowsChartMeta = defineFrameMeta({
|
|
2011
|
+
name: "etf-flows-chart",
|
|
2012
|
+
label: "ETF Flows Chart",
|
|
2013
|
+
category: "crypto",
|
|
2014
|
+
iconUrl: widgetIcon("etf-flows-chart"),
|
|
2015
|
+
layout: { w: 6, h: 3, minW: 3, minH: 3 },
|
|
2016
|
+
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.",
|
|
2017
|
+
capabilities: ["etf-flows"],
|
|
2018
|
+
source: SOURCES.sosovalue,
|
|
2019
|
+
schema: z3.object({
|
|
2020
|
+
asset: z3.enum(["btc", "eth"]).default("btc").describe("Which spot-ETF complex to chart."),
|
|
2021
|
+
lookback: z3.enum(["1M", "3M", "6M"]).default("3M").describe("History window for the flow chart.")
|
|
2022
|
+
})
|
|
2023
|
+
});
|
|
2024
|
+
var realizedPriceMeta = defineFrameMeta({
|
|
2025
|
+
name: "realized-price",
|
|
2026
|
+
label: "Realized Price",
|
|
2027
|
+
category: "onchain",
|
|
2028
|
+
iconUrl: widgetIcon("realized-price"),
|
|
2029
|
+
layout: { w: 6, h: 3, minW: 4, minH: 3 },
|
|
2030
|
+
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).",
|
|
2031
|
+
capabilities: ["onchain-valuation"],
|
|
2032
|
+
source: SOURCES.coinMetrics,
|
|
2033
|
+
schema: z3.object({
|
|
2034
|
+
window: z3.enum(["1Y", "2Y", "4Y", "all"]).default("2Y").describe("How much history the chart shows.")
|
|
2035
|
+
})
|
|
2036
|
+
});
|
|
2037
|
+
var reserveRiskMeta = defineFrameMeta({
|
|
2038
|
+
name: "reserve-risk",
|
|
2039
|
+
label: "Reserve Risk",
|
|
2040
|
+
category: "onchain",
|
|
2041
|
+
iconUrl: widgetIcon("reserve-risk"),
|
|
2042
|
+
layout: { w: 3, h: 3, minW: 2, minH: 2 },
|
|
2043
|
+
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).",
|
|
2044
|
+
capabilities: ["onchain-cycle-extras"],
|
|
2045
|
+
source: SOURCES.bitcoinData,
|
|
2046
|
+
schema: z3.object({
|
|
2047
|
+
window: z3.enum(["90D", "180D", "1Y"]).default("1Y").describe("How much history the sparkline shows.")
|
|
2048
|
+
})
|
|
2049
|
+
});
|
|
1670
2050
|
var frameMetas = [
|
|
1671
2051
|
newsFeedMeta,
|
|
1672
2052
|
portfolioValueMeta,
|
|
@@ -1726,7 +2106,34 @@ var frameMetas = [
|
|
|
1726
2106
|
optionsPutCallMeta,
|
|
1727
2107
|
optionsIvMeta,
|
|
1728
2108
|
optionsOiStrikeMeta,
|
|
1729
|
-
coinMoversMeta
|
|
2109
|
+
coinMoversMeta,
|
|
2110
|
+
mvrvMeta,
|
|
2111
|
+
nuplMeta,
|
|
2112
|
+
soprMeta,
|
|
2113
|
+
puellMultipleMeta,
|
|
2114
|
+
mayerMultipleMeta,
|
|
2115
|
+
piCycleMeta,
|
|
2116
|
+
maMultiplierMeta,
|
|
2117
|
+
rsiMomentumMeta,
|
|
2118
|
+
volumeProfileMeta,
|
|
2119
|
+
dxyMeta,
|
|
2120
|
+
cycleSignalsMeta,
|
|
2121
|
+
stablecoinSupplyMeta,
|
|
2122
|
+
yieldScannerMeta,
|
|
2123
|
+
defiRevenueMeta,
|
|
2124
|
+
fundingComparisonMeta,
|
|
2125
|
+
ethSupplyMeta,
|
|
2126
|
+
ethStakingMeta,
|
|
2127
|
+
predictionMarketsMeta,
|
|
2128
|
+
etfFlowsMeta,
|
|
2129
|
+
trendingCoinsMeta,
|
|
2130
|
+
sectorPerformanceMeta,
|
|
2131
|
+
macroCalendarMeta,
|
|
2132
|
+
stablecoinChainsMeta,
|
|
2133
|
+
sectorTreemapMeta,
|
|
2134
|
+
etfFlowsChartMeta,
|
|
2135
|
+
realizedPriceMeta,
|
|
2136
|
+
reserveRiskMeta
|
|
1730
2137
|
];
|
|
1731
2138
|
var allFrameMetas = [
|
|
1732
2139
|
...frameMetas,
|
|
@@ -1803,6 +2210,11 @@ function use(args) {
|
|
|
1803
2210
|
// src/init.ts
|
|
1804
2211
|
import { existsSync as existsSync2, mkdirSync as mkdirSync2, statSync as statSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
1805
2212
|
import { dirname, resolve as resolve2 } from "path";
|
|
2213
|
+
|
|
2214
|
+
// ../spec/src/presets.ts
|
|
2215
|
+
var SCENE_DEFAULT_PROJECT_ID = "YrTzGatwjK7EoFpCSfgZ";
|
|
2216
|
+
|
|
2217
|
+
// src/init.ts
|
|
1806
2218
|
function parseArgs(args) {
|
|
1807
2219
|
let target = "dashboard.json";
|
|
1808
2220
|
let title = "my dashboard";
|
|
@@ -1847,7 +2259,7 @@ function skeleton(title, author) {
|
|
|
1847
2259
|
grid: { columns: 12, rowHeight: 96, gap: 12 },
|
|
1848
2260
|
background: {
|
|
1849
2261
|
type: "unicorn",
|
|
1850
|
-
projectId:
|
|
2262
|
+
projectId: SCENE_DEFAULT_PROJECT_ID,
|
|
1851
2263
|
opacity: 1
|
|
1852
2264
|
},
|
|
1853
2265
|
theme: {
|
|
@@ -3115,6 +3527,8 @@ var AlternativeMeProvider = class {
|
|
|
3115
3527
|
// ../provider-coingecko/src/index.ts
|
|
3116
3528
|
var GLOBAL_URL = "https://api.coingecko.com/api/v3/global";
|
|
3117
3529
|
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";
|
|
3530
|
+
var TRENDING_URL = "https://api.coingecko.com/api/v3/search/trending";
|
|
3531
|
+
var CATEGORIES_URL = "https://api.coingecko.com/api/v3/coins/categories";
|
|
3118
3532
|
var globalCache = new TtlCache({
|
|
3119
3533
|
namespace: "zframes:coingecko:global",
|
|
3120
3534
|
ttlMs: 12 * 6e4,
|
|
@@ -3125,12 +3539,55 @@ var marketsCache = new TtlCache({
|
|
|
3125
3539
|
ttlMs: 10 * 6e4,
|
|
3126
3540
|
persist: true
|
|
3127
3541
|
});
|
|
3542
|
+
var trendingCache = new TtlCache({
|
|
3543
|
+
namespace: "zframes:coingecko:trending",
|
|
3544
|
+
ttlMs: 10 * 6e4,
|
|
3545
|
+
persist: true
|
|
3546
|
+
});
|
|
3547
|
+
var categoriesCache = new TtlCache({
|
|
3548
|
+
namespace: "zframes:coingecko:categories",
|
|
3549
|
+
ttlMs: 12 * 6e4,
|
|
3550
|
+
persist: true
|
|
3551
|
+
});
|
|
3128
3552
|
var CoinGeckoProvider = class {
|
|
3129
3553
|
name = "coingecko";
|
|
3130
3554
|
capabilities = [
|
|
3131
3555
|
"global-market",
|
|
3132
|
-
"coin-markets"
|
|
3556
|
+
"coin-markets",
|
|
3557
|
+
"trending-coins",
|
|
3558
|
+
"sector-performance"
|
|
3133
3559
|
];
|
|
3560
|
+
async getTrendingCoins() {
|
|
3561
|
+
return trendingCache.get("trending", async () => {
|
|
3562
|
+
const body = await fetchJson(TRENDING_URL);
|
|
3563
|
+
if (!Array.isArray(body?.coins))
|
|
3564
|
+
throw new Error("coingecko trending: unexpected response shape");
|
|
3565
|
+
return body.coins.map(({ item }) => {
|
|
3566
|
+
const price = Number(item.data?.price);
|
|
3567
|
+
const chg = Number(item.data?.price_change_percentage_24h?.usd);
|
|
3568
|
+
return {
|
|
3569
|
+
id: item.id,
|
|
3570
|
+
name: item.name,
|
|
3571
|
+
symbol: (item.symbol ?? "").toUpperCase(),
|
|
3572
|
+
rank: Number.isFinite(item.market_cap_rank) ? item.market_cap_rank : null,
|
|
3573
|
+
price: Number.isFinite(price) ? price : null,
|
|
3574
|
+
changePct24h: Number.isFinite(chg) ? chg : null
|
|
3575
|
+
};
|
|
3576
|
+
});
|
|
3577
|
+
});
|
|
3578
|
+
}
|
|
3579
|
+
async getSectorPerformance() {
|
|
3580
|
+
return categoriesCache.get("categories", async () => {
|
|
3581
|
+
const body = await fetchJson(CATEGORIES_URL);
|
|
3582
|
+
if (!Array.isArray(body))
|
|
3583
|
+
throw new Error("coingecko categories: unexpected response shape");
|
|
3584
|
+
return body.filter((c) => Number.isFinite(c.market_cap) && (c.market_cap ?? 0) > 0).map((c) => ({
|
|
3585
|
+
name: c.name,
|
|
3586
|
+
marketCap: c.market_cap,
|
|
3587
|
+
changePct24h: Number.isFinite(c.market_cap_change_24h) ? c.market_cap_change_24h : 0
|
|
3588
|
+
})).sort((a, b) => b.marketCap - a.marketCap).slice(0, 30);
|
|
3589
|
+
});
|
|
3590
|
+
}
|
|
3134
3591
|
async getGlobalMarket() {
|
|
3135
3592
|
return globalCache.get("global", async () => {
|
|
3136
3593
|
const body = await fetchJson(GLOBAL_URL);
|
|
@@ -3164,6 +3621,9 @@ var CHAINS_URL = "https://api.llama.fi/v2/chains";
|
|
|
3164
3621
|
var DEXS_URL = "https://api.llama.fi/overview/dexs";
|
|
3165
3622
|
var FEES_URL = "https://api.llama.fi/overview/fees";
|
|
3166
3623
|
var PROTOCOLS_URL = "https://api.llama.fi/protocols";
|
|
3624
|
+
var STABLES_URL = "https://stablecoins.llama.fi/stablecoins?includePrices=true";
|
|
3625
|
+
var STABLECHAINS_URL = "https://stablecoins.llama.fi/stablecoinchains";
|
|
3626
|
+
var YIELDS_URL = "https://yields.llama.fi/pools";
|
|
3167
3627
|
var SNAPSHOT_TTL_MS = 8 * 6e4;
|
|
3168
3628
|
var HISTORY_TTL_MS = 30 * 6e4;
|
|
3169
3629
|
var tvlCache = new TtlCache({
|
|
@@ -3190,6 +3650,19 @@ var protocolHistoryCache = new TtlCache({
|
|
|
3190
3650
|
namespace: "zframes:defillama:protocol-history",
|
|
3191
3651
|
ttlMs: HISTORY_TTL_MS
|
|
3192
3652
|
});
|
|
3653
|
+
var stablecoinsCache = new TtlCache({
|
|
3654
|
+
namespace: "zframes:defillama:stablecoins",
|
|
3655
|
+
ttlMs: 30 * 6e4,
|
|
3656
|
+
persist: true
|
|
3657
|
+
});
|
|
3658
|
+
var yieldsCache = new TtlCache({
|
|
3659
|
+
namespace: "zframes:defillama:yields",
|
|
3660
|
+
ttlMs: 12 * 6e4
|
|
3661
|
+
});
|
|
3662
|
+
var feesOverviewCache = new TtlCache({
|
|
3663
|
+
namespace: "zframes:defillama:fees-overview",
|
|
3664
|
+
ttlMs: SNAPSHOT_TTL_MS
|
|
3665
|
+
});
|
|
3193
3666
|
var slugKey = (slugs) => [...slugs].sort().join(",");
|
|
3194
3667
|
function toSeries(chart) {
|
|
3195
3668
|
if (!Array.isArray(chart)) return [];
|
|
@@ -3202,7 +3675,10 @@ var DefiLlamaProvider = class {
|
|
|
3202
3675
|
"tvl",
|
|
3203
3676
|
"dex-volume",
|
|
3204
3677
|
"protocol-tvl",
|
|
3205
|
-
"protocol-fees"
|
|
3678
|
+
"protocol-fees",
|
|
3679
|
+
"stablecoins",
|
|
3680
|
+
"yields",
|
|
3681
|
+
"fees-overview"
|
|
3206
3682
|
];
|
|
3207
3683
|
async getTvlByChain() {
|
|
3208
3684
|
return tvlCache.get("chains", async () => {
|
|
@@ -3287,11 +3763,95 @@ var DefiLlamaProvider = class {
|
|
|
3287
3763
|
})).sort((a, b) => b.fees24h - a.fees24h);
|
|
3288
3764
|
});
|
|
3289
3765
|
}
|
|
3766
|
+
async getStablecoinSupply() {
|
|
3767
|
+
return stablecoinsCache.get("supply", async () => {
|
|
3768
|
+
const [assetsBody, chains] = await Promise.all([
|
|
3769
|
+
fetchJson(STABLES_URL),
|
|
3770
|
+
fetchJson(STABLECHAINS_URL).catch(() => [])
|
|
3771
|
+
]);
|
|
3772
|
+
const assets = assetsBody?.peggedAssets;
|
|
3773
|
+
if (!Array.isArray(assets))
|
|
3774
|
+
throw new Error("defillama stablecoins: unexpected response shape");
|
|
3775
|
+
let now = 0;
|
|
3776
|
+
let d1 = 0;
|
|
3777
|
+
let d7 = 0;
|
|
3778
|
+
let d30 = 0;
|
|
3779
|
+
for (const a of assets) {
|
|
3780
|
+
if (a.pegType && a.pegType !== "peggedUSD") continue;
|
|
3781
|
+
now += a.circulating?.peggedUSD ?? 0;
|
|
3782
|
+
d1 += a.circulatingPrevDay?.peggedUSD ?? 0;
|
|
3783
|
+
d7 += a.circulatingPrevWeek?.peggedUSD ?? 0;
|
|
3784
|
+
d30 += a.circulatingPrevMonth?.peggedUSD ?? 0;
|
|
3785
|
+
}
|
|
3786
|
+
if (now <= 0) throw new Error("defillama stablecoins: empty aggregate");
|
|
3787
|
+
const pct = (prev) => prev > 0 ? (now - prev) / prev * 100 : 0;
|
|
3788
|
+
const nowMs = Date.now();
|
|
3789
|
+
const history = [
|
|
3790
|
+
{ time: nowMs - 30 * 864e5, value: d30 },
|
|
3791
|
+
{ time: nowMs - 7 * 864e5, value: d7 },
|
|
3792
|
+
{ time: nowMs - 864e5, value: d1 },
|
|
3793
|
+
{ time: nowMs, value: now }
|
|
3794
|
+
].filter((p) => p.value > 0);
|
|
3795
|
+
const topChains = (Array.isArray(chains) ? chains : []).map((c) => ({
|
|
3796
|
+
name: c.name,
|
|
3797
|
+
usd: c.totalCirculatingUSD?.peggedUSD ?? 0
|
|
3798
|
+
})).filter((c) => c.usd > 0).sort((a, b) => b.usd - a.usd).slice(0, 12);
|
|
3799
|
+
return {
|
|
3800
|
+
totalUsd: now,
|
|
3801
|
+
changePct1d: pct(d1),
|
|
3802
|
+
changePct7d: pct(d7),
|
|
3803
|
+
changePct30d: pct(d30),
|
|
3804
|
+
history,
|
|
3805
|
+
topChains
|
|
3806
|
+
};
|
|
3807
|
+
});
|
|
3808
|
+
}
|
|
3809
|
+
async getYieldPools() {
|
|
3810
|
+
return yieldsCache.get("pools", async () => {
|
|
3811
|
+
const body = await fetchJson(YIELDS_URL);
|
|
3812
|
+
const data = body?.data;
|
|
3813
|
+
if (!Array.isArray(data))
|
|
3814
|
+
throw new Error("defillama yields: unexpected response shape");
|
|
3815
|
+
return data.filter(
|
|
3816
|
+
(p) => Number.isFinite(p.tvlUsd) && (p.tvlUsd ?? 0) > 0 && Number.isFinite(p.apy)
|
|
3817
|
+
).map((p) => ({
|
|
3818
|
+
pool: p.pool,
|
|
3819
|
+
chain: p.chain,
|
|
3820
|
+
project: p.project,
|
|
3821
|
+
symbol: p.symbol,
|
|
3822
|
+
tvlUsd: p.tvlUsd,
|
|
3823
|
+
apy: p.apy,
|
|
3824
|
+
apyBase: Number.isFinite(p.apyBase) ? p.apyBase : null,
|
|
3825
|
+
apyReward: Number.isFinite(p.apyReward) ? p.apyReward : null,
|
|
3826
|
+
apyPct7D: Number.isFinite(p.apyPct7D) ? p.apyPct7D : null,
|
|
3827
|
+
stablecoin: !!p.stablecoin,
|
|
3828
|
+
ilRisk: p.ilRisk ?? "unknown"
|
|
3829
|
+
})).sort((a, b) => b.tvlUsd - a.tvlUsd).slice(0, 250);
|
|
3830
|
+
});
|
|
3831
|
+
}
|
|
3832
|
+
async getFeesOverview() {
|
|
3833
|
+
return feesOverviewCache.get("overview", async () => {
|
|
3834
|
+
const body = await fetchJson(FEES_URL);
|
|
3835
|
+
if (!body || !Number.isFinite(body.total24h))
|
|
3836
|
+
throw new Error("defillama fees-overview: unexpected response shape");
|
|
3837
|
+
return {
|
|
3838
|
+
total24h: body.total24h,
|
|
3839
|
+
total7d: Number.isFinite(body.total7d) ? body.total7d : null,
|
|
3840
|
+
changePct: Number.isFinite(body.change_1d) ? body.change_1d : null,
|
|
3841
|
+
history: toSeries(body.totalDataChart)
|
|
3842
|
+
};
|
|
3843
|
+
});
|
|
3844
|
+
}
|
|
3290
3845
|
};
|
|
3291
3846
|
|
|
3292
3847
|
// ../provider-hyperliquid/src/index.ts
|
|
3293
3848
|
var WS_URL = "wss://api.hyperliquid.xyz/ws";
|
|
3294
3849
|
var INFO_URL = "https://api.hyperliquid.xyz/info";
|
|
3850
|
+
var VENUE_LABELS = {
|
|
3851
|
+
HlPerp: "Hyperliquid",
|
|
3852
|
+
BinPerp: "Binance",
|
|
3853
|
+
BybitPerp: "Bybit"
|
|
3854
|
+
};
|
|
3295
3855
|
var dexOf = (symbol) => symbol.includes(":") ? symbol.split(":")[0] : "";
|
|
3296
3856
|
async function info(body) {
|
|
3297
3857
|
return fetchJson(INFO_URL, void 0, {
|
|
@@ -3320,6 +3880,10 @@ var fundingCache = new TtlCache({
|
|
|
3320
3880
|
ttlMs: 4.5 * 6e4,
|
|
3321
3881
|
persist: true
|
|
3322
3882
|
});
|
|
3883
|
+
var fundingComparisonCache = new TtlCache({
|
|
3884
|
+
namespace: "zframes:hyperliquid:funding-comparison",
|
|
3885
|
+
ttlMs: 5 * 6e4
|
|
3886
|
+
});
|
|
3323
3887
|
var sortedKey = (symbols) => symbols ? [...symbols].sort().join(",") : "*";
|
|
3324
3888
|
var HyperliquidProvider = class {
|
|
3325
3889
|
name = "hyperliquid";
|
|
@@ -3328,8 +3892,48 @@ var HyperliquidProvider = class {
|
|
|
3328
3892
|
"day-stats",
|
|
3329
3893
|
"funding-history",
|
|
3330
3894
|
"ohlcv",
|
|
3331
|
-
"open-interest"
|
|
3895
|
+
"open-interest",
|
|
3896
|
+
"funding-comparison"
|
|
3332
3897
|
];
|
|
3898
|
+
async getFundingComparison() {
|
|
3899
|
+
return fundingComparisonCache.get("all", async () => {
|
|
3900
|
+
const resp = await info({
|
|
3901
|
+
type: "predictedFundings"
|
|
3902
|
+
});
|
|
3903
|
+
if (!Array.isArray(resp))
|
|
3904
|
+
throw new Error("hyperliquid predictedFundings: unexpected shape");
|
|
3905
|
+
const out = [];
|
|
3906
|
+
for (const entry of resp) {
|
|
3907
|
+
if (!Array.isArray(entry) || entry.length < 2) continue;
|
|
3908
|
+
const [coin, venueList] = entry;
|
|
3909
|
+
if (typeof coin !== "string" || !Array.isArray(venueList)) continue;
|
|
3910
|
+
const venues = [];
|
|
3911
|
+
for (const vEntry of venueList) {
|
|
3912
|
+
if (!Array.isArray(vEntry) || vEntry.length < 2) continue;
|
|
3913
|
+
const [venue, meta] = vEntry;
|
|
3914
|
+
if (!meta) continue;
|
|
3915
|
+
const rawRate = parseFloat(meta.fundingRate);
|
|
3916
|
+
if (!Number.isFinite(rawRate)) continue;
|
|
3917
|
+
const reported = Number(meta.fundingIntervalHours);
|
|
3918
|
+
const intervalHours = Number.isFinite(reported) && reported > 0 ? reported : venue === "HlPerp" ? 1 : 8;
|
|
3919
|
+
venues.push({
|
|
3920
|
+
venue: VENUE_LABELS[venue] ?? venue,
|
|
3921
|
+
rawRate,
|
|
3922
|
+
intervalHours,
|
|
3923
|
+
annualizedPct: rawRate * (8760 / intervalHours) * 100
|
|
3924
|
+
});
|
|
3925
|
+
}
|
|
3926
|
+
if (venues.length < 2) continue;
|
|
3927
|
+
const rates = venues.map((v) => v.annualizedPct);
|
|
3928
|
+
out.push({
|
|
3929
|
+
coin,
|
|
3930
|
+
venues,
|
|
3931
|
+
spreadPct: Math.max(...rates) - Math.min(...rates)
|
|
3932
|
+
});
|
|
3933
|
+
}
|
|
3934
|
+
return out.sort((a, b) => Math.abs(b.spreadPct) - Math.abs(a.spreadPct)).slice(0, 80);
|
|
3935
|
+
});
|
|
3936
|
+
}
|
|
3333
3937
|
ws = null;
|
|
3334
3938
|
listeners = /* @__PURE__ */ new Set();
|
|
3335
3939
|
reconnectTimer = null;
|