+
+
- // Load the data from staking stats provider
- useEffect(() => {
- if (stakingStatsProvider.data) {
- setStakingStats(stakingStatsProvider.data);
- }
- setIsLoading(
- stakingStatsProvider.isLoading || Boolean(appState?.isLoading),
- );
- }, [stakingStatsProvider, appState?.isLoading]);
+
- const stakingCapText = useMemo(() => {
- if (!appState?.currentHeight) {
- return {
- title: "Staking TVL Cap",
- value: "-",
- };
- }
+
- const cap = buildStakingCapSection(
- coinName,
- appState.currentHeight,
- appState,
- );
+
- return (
- cap ?? {
- title: "Staking TVL Cap",
- value: "-",
- }
- );
- }, [coinName, appState]);
+
+
- const formatter = Intl.NumberFormat("en", {
- notation: "compact",
- maximumFractionDigits: 2,
- });
+
+
- const sections = [
- [
- {
- title: stakingCapText.title,
- value: stakingCapText.value,
- icon: stakingTvlCap,
- },
- {
- title: "Confirmed TVL",
- value: stakingStats?.activeTVLSat
- ? `${maxDecimals(satoshiToBtc(stakingStats.activeTVLSat), 8)} ${coinName}`
- : 0,
- icon: confirmedTvl,
- },
- {
- title: "Pending Stake",
- value: stakingStats?.unconfirmedTVLSat
- ? `${maxDecimals(satoshiToBtc(stakingStats.unconfirmedTVLSat - stakingStats.activeTVLSat), 8)} ${coinName}`
- : 0,
- icon: pendingStake,
- tooltip:
- stakingStats &&
- stakingStats.unconfirmedTVLSat - stakingStats.activeTVLSat < 0
- ? "Pending TVL can be negative when there are unbonding requests"
- : undefined,
- },
- ],
- [
- {
- title: "Delegations",
- value: stakingStats?.activeDelegations
- ? formatter.format(stakingStats.activeDelegations as number)
- : 0,
- icon: delegations,
- tooltip: "Total number of stake delegations",
- },
- {
- title: "Stakers",
- value: stakingStats?.totalStakers
- ? formatter.format(stakingStats.totalStakers as number)
- : 0,
- icon: stakers,
- },
- ],
- ];
+
- return (
-
- {sections.map((section, index) => (
-
- {section.map((subSection, subIndex) => (
-
-
-
-
-
-
- {subSection.title}
-
- {subSection.tooltip && (
- <>
-
-
-
-
- >
- )}
-
-
-
-
- {isLoading ? (
-
- ) : (
- {subSection.value}
- )}
-
-
-
- {subIndex !== section.length - 1 && (
-
- )}
-
- ))}
-
- ))}
+
+
);
-};
+});
+
+Stats.displayName = "Stats";
diff --git a/src/app/components/Stats/icons/confirmed-tvl.svg b/src/app/components/Stats/icons/confirmed-tvl.svg
deleted file mode 100644
index f12b9346..00000000
--- a/src/app/components/Stats/icons/confirmed-tvl.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/src/app/components/Stats/icons/delegations.svg b/src/app/components/Stats/icons/delegations.svg
deleted file mode 100644
index 8a851aa3..00000000
--- a/src/app/components/Stats/icons/delegations.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/src/app/components/Stats/icons/index.tsx b/src/app/components/Stats/icons/index.tsx
new file mode 100644
index 00000000..329e90f4
--- /dev/null
+++ b/src/app/components/Stats/icons/index.tsx
@@ -0,0 +1,89 @@
+export const confirmedTVL = (
+
+);
+
+export const delegations = (
+
+);
+
+export const pendingStake = (
+
+);
+
+export const stakers = (
+
+);
+
+export const stakingTvlCap = (
+
+);
diff --git a/src/app/components/Stats/icons/pending-stake.svg b/src/app/components/Stats/icons/pending-stake.svg
deleted file mode 100644
index f268679d..00000000
--- a/src/app/components/Stats/icons/pending-stake.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/src/app/components/Stats/icons/stakers.svg b/src/app/components/Stats/icons/stakers.svg
deleted file mode 100644
index 10eef4dd..00000000
--- a/src/app/components/Stats/icons/stakers.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
diff --git a/src/app/components/Stats/icons/staking-tvl-cap.svg b/src/app/components/Stats/icons/staking-tvl-cap.svg
deleted file mode 100644
index 065afdc4..00000000
--- a/src/app/components/Stats/icons/staking-tvl-cap.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/src/app/hooks/useApi.ts b/src/app/hooks/api/useApi.ts
similarity index 100%
rename from src/app/hooks/useApi.ts
rename to src/app/hooks/api/useApi.ts
diff --git a/src/app/hooks/useBTCTipHeight.ts b/src/app/hooks/api/useBTCTipHeight.ts
similarity index 81%
rename from src/app/hooks/useBTCTipHeight.ts
rename to src/app/hooks/api/useBTCTipHeight.ts
index ab952f39..7c5e30e1 100644
--- a/src/app/hooks/useBTCTipHeight.ts
+++ b/src/app/hooks/api/useBTCTipHeight.ts
@@ -1,4 +1,4 @@
-import { useAPIQuery } from "@/app/hooks/useApi";
+import { useAPIQuery } from "@/app/hooks/api/useApi";
import { getTipHeight } from "@/utils/mempool_api";
export const BTC_TIP_HEIGHT_KEY = "BTC_TIP_HEIGHT";
diff --git a/src/app/hooks/useDelegations.ts b/src/app/hooks/api/useDelegations.ts
similarity index 100%
rename from src/app/hooks/useDelegations.ts
rename to src/app/hooks/api/useDelegations.ts
diff --git a/src/app/hooks/useNetworkFees.ts b/src/app/hooks/api/useNetworkFees.ts
similarity index 85%
rename from src/app/hooks/useNetworkFees.ts
rename to src/app/hooks/api/useNetworkFees.ts
index 2a4840c5..8632af1a 100644
--- a/src/app/hooks/useNetworkFees.ts
+++ b/src/app/hooks/api/useNetworkFees.ts
@@ -1,4 +1,4 @@
-import { useAPIQuery } from "@/app/hooks/useApi";
+import { useAPIQuery } from "@/app/hooks/api/useApi";
import { getNetworkFees } from "@/utils/mempool_api";
export const NETWORK_FEES_KEY = "NETWORK_FEES";
diff --git a/src/app/hooks/api/useSystemStats.ts b/src/app/hooks/api/useSystemStats.ts
new file mode 100644
index 00000000..b2749736
--- /dev/null
+++ b/src/app/hooks/api/useSystemStats.ts
@@ -0,0 +1,11 @@
+import { getStats } from "@/app/api/getStats";
+import { useAPIQuery } from "@/app/hooks/api/useApi";
+
+export const BTC_TIP_HEIGHT_KEY = "API_STATS";
+
+export function useSystemStats() {
+ return useAPIQuery({
+ queryKey: ["API_STATS"],
+ queryFn: getStats,
+ });
+}
diff --git a/src/app/hooks/useUTXOs.ts b/src/app/hooks/api/useUTXOs.ts
similarity index 94%
rename from src/app/hooks/useUTXOs.ts
rename to src/app/hooks/api/useUTXOs.ts
index 99b880a6..c987eee0 100644
--- a/src/app/hooks/useUTXOs.ts
+++ b/src/app/hooks/api/useUTXOs.ts
@@ -1,6 +1,6 @@
import { ONE_MINUTE } from "@/app/constants";
import { useWallet } from "@/app/context/wallet/WalletProvider";
-import { useAPIQuery } from "@/app/hooks/useApi";
+import { useAPIQuery } from "@/app/hooks/api/useApi";
import { filterOrdinals } from "@/utils/utxo";
export const UTXO_KEY = "UTXO";
diff --git a/src/app/hooks/api/useVersions.ts b/src/app/hooks/api/useVersions.ts
new file mode 100644
index 00000000..3ea629a6
--- /dev/null
+++ b/src/app/hooks/api/useVersions.ts
@@ -0,0 +1,14 @@
+import { getGlobalParams } from "@/app/api/getGlobalParams";
+import { useAPIQuery } from "@/app/hooks/api/useApi";
+
+export const VERSIONS_KEY = "VERSIONS";
+
+export function useVersions({ enabled = true }: { enabled?: boolean } = {}) {
+ const data = useAPIQuery({
+ queryKey: [VERSIONS_KEY],
+ queryFn: getGlobalParams,
+ enabled,
+ });
+
+ return data;
+}
diff --git a/src/app/hooks/useVersionByHeight.ts b/src/app/hooks/useVersionByHeight.ts
new file mode 100644
index 00000000..05967a89
--- /dev/null
+++ b/src/app/hooks/useVersionByHeight.ts
@@ -0,0 +1,14 @@
+import { useMemo } from "react";
+
+import { getCurrentGlobalParamsVersion } from "@/utils/globalParams";
+
+import { useVersions } from "./api/useVersions";
+
+export function useVersionByHeight(height: number) {
+ const { data: versions } = useVersions();
+
+ return useMemo(
+ () => getCurrentGlobalParamsVersion(height, versions ?? []),
+ [versions, height],
+ );
+}
diff --git a/src/app/hooks/useVersions.ts b/src/app/hooks/useVersions.ts
deleted file mode 100644
index f1f812b3..00000000
--- a/src/app/hooks/useVersions.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { useMemo } from "react";
-
-import { getGlobalParams } from "@/app/api/getGlobalParams";
-import { useAPIQuery } from "@/app/hooks/useApi";
-import { getCurrentGlobalParamsVersion } from "@/utils/globalParams";
-
-export const VERSIONS_KEY = "VERSIONS";
-
-export function useVersions({ enabled = true }: { enabled?: boolean } = {}) {
- const data = useAPIQuery({
- queryKey: [VERSIONS_KEY],
- queryFn: getGlobalParams,
- enabled,
- });
-
- return data;
-}
-
-export function useVersionByHeight(height: number) {
- const { data: versions } = useVersions();
- return useMemo(
- () => getCurrentGlobalParamsVersion(height, versions ?? []),
- [versions, height],
- );
-}
diff --git a/src/app/state/DelegationState.tsx b/src/app/state/DelegationState.tsx
index 94dd9bf9..9b049837 100644
--- a/src/app/state/DelegationState.tsx
+++ b/src/app/state/DelegationState.tsx
@@ -2,7 +2,7 @@ import { useCallback, useEffect, useMemo, type PropsWithChildren } from "react";
import { useLocalStorage } from "usehooks-ts";
import { useWallet } from "@/app/context/wallet/WalletProvider";
-import { useDelegations } from "@/app/hooks/useDelegations";
+import { useDelegations } from "@/app/hooks/api/useDelegations";
import type { Delegation } from "@/app/types/delegations";
import { DelegationState as DelegationEnum } from "@/app/types/delegations";
import { createStateUtils } from "@/utils/createStateUtils";
diff --git a/src/app/state/index.tsx b/src/app/state/index.tsx
index deb79286..a3623270 100644
--- a/src/app/state/index.tsx
+++ b/src/app/state/index.tsx
@@ -1,8 +1,8 @@
import { useMemo, type PropsWithChildren } from "react";
-import { useBTCTipHeight } from "@/app/hooks/useBTCTipHeight";
-import { useUTXOs } from "@/app/hooks/useUTXOs";
-import { useVersions } from "@/app/hooks/useVersions";
+import { useBTCTipHeight } from "@/app/hooks/api/useBTCTipHeight";
+import { useUTXOs } from "@/app/hooks/api/useUTXOs";
+import { useVersions } from "@/app/hooks/api/useVersions";
import { GlobalParamsVersion } from "@/app/types/globalParams";
import { createStateUtils } from "@/utils/createStateUtils";
import { getCurrentGlobalParamsVersion } from "@/utils/globalParams";
@@ -12,7 +12,7 @@ import { DelegationState } from "./DelegationState";
const STATE_LIST = [DelegationState];
-interface AppState {
+export interface AppState {
availableUTXOs?: UTXO[];
totalBalance: number;
nextVersion?: GlobalParamsVersion;