MDK Logo

Data hooks

Adapter hooks that fetch and shape site, pool, dashboard, and chart data

@tetherto/mdk-react-adapter

TanStack Query–backed hooks that fetch live data from the MDK backend and project it into view-model shapes ready for MDK foundation components. These hooks sit in the adapter layer so that tag names, aggregate field keys, and unit conversions stay out of the devkit component layer.

All hooks require <MdkProvider> to be mounted in the tree.

At a glance

Sub-groupHooks
AlertsuseCurrentAlertDevices, useHistoricalAlerts
Auth and tokenuseAuthToken, useTokenPolling
Chart datauseConsumptionChartData, useHashrateChartData, usePowerModeTimelineData
DashboarduseDashboardDateRange, useDashboardExport, useDashboardTimeRange
IncidentsuseActiveIncidents
Pool datausePoolRows, usePoolStats
Site datauseSiteConsumption, useSiteConsumptionChartData, useSiteContainerCapacity, useSiteEfficiency, useSiteHashrate, useSiteMinerCounts, useSiteMinerStats, useSitePowerMeter, useSitesOverviewData

Prerequisites

Import

import {
  useActiveIncidents,
  useAuthToken,
  useConsumptionChartData,
  useCurrentAlertDevices,
  useDashboardDateRange,
  useDashboardExport,
  useDashboardTimeRange,
  useHashrateChartData,
  useHistoricalAlerts,
  usePoolRows,
  usePoolStats,
  usePowerModeTimelineData,
  useSiteConsumption,
  useSiteConsumptionChartData,
  useSiteContainerCapacity,
  useSiteEfficiency,
  useSiteHashrate,
  useSiteMinerCounts,
  useSiteMinerStats,
  useSitePowerMeter,
  useSitesOverviewData,
  useTokenPolling,
} from '@tetherto/mdk-react-adapter'

Site data

useSitesOverviewData

Projects raw site-overview container rows and pool stats into a <PoolManagerSitesOverview />-ready shape. Each container receives its per-container hashrate in MH/s, an attached pool-stats row, and a mining / offline status derived from the underlying snapshot.

import { useSitesOverviewData } from '@tetherto/mdk-react-adapter'

Options

OptionStatusTypeDefaultDescription
unitsRequiredContainerUnit[]noneRequired. Raw container rows from the site overview query.
poolStatsRequiredContainerPoolStat[]noneRequired. Per-container pool stat rows keyed by container id.
isLoadingRequiredbooleannoneRequired. Combined loading state from the upstream queries.
tailLogItemRequiredSitesOverviewTailLogItemnoneRequired. Latest tail-log row from a stat-1m miner query; pass _head(_head(rawResponse)).

Returns

MemberTypeDescription
unitsProcessedContainerUnit[]Processed containers with hashrateMhs, status, and poolStats attached.
isLoadingbooleanPasses through the combined loading state from the options.

Example

import { useSitesOverviewData } from '@tetherto/mdk-react-adapter'
import { PoolManagerSitesOverview } from '@tetherto/mdk-react-devkit/foundation'

function SiteOverview({ rawUnits, rawPoolStats, loading, latestTailLog }) {
  const { units, isLoading } = useSitesOverviewData({
    units: rawUnits,
    poolStats: rawPoolStats,
    isLoading: loading,
    tailLogItem: latestTailLog,
  })
  return <PoolManagerSitesOverview units={units} isLoading={isLoading} />
}

useSiteConsumption

Projects the freshest power sample from the dashboard's existing tail-log query into a scalar MW value for the header stats strip (<HeaderConsumptionBox />). Delegates fetching to useSiteConsumptionChartData.

import { useSiteConsumption } from '@tetherto/mdk-react-adapter'

Options

Accepts the same UseConsumptionChartDataParams object as useSiteConsumptionChartData.

OptionStatusTypeDefaultDescription
timelineRequiredstringnoneRequired. Stat key suffix, e.g. '5m'.
startOptionalnumbernoneLower time bound (ms epoch).
endOptionalnumbernoneUpper time bound (ms epoch).
tagOptionalstring't-miner'Thing tag. Use 't-powermeter' for transformer-level readings.
powerAttributeOptionalstring'power_w_sum_aggr'Aggregate field name to read from the tail-log row.
refetchIntervalOptionalnumber60000Polling interval in ms. Pass 0 to disable.

Returns

MemberTypeDescription
valueMwnumber | undefinedLatest aggregate value in MW; undefined while loading or with no data.
valueWnumber | undefinedRaw backend value in watts.
isLoadingbooleanLoading state from the upstream query.

useSiteConsumptionChartData

TanStack Query hook that fetches site consumption tail-log samples and returns a <LineChartCard>-ready ChartCardData payload. Applies site-powermeter defaults and converts watts to MW.

import { useSiteConsumptionChartData } from '@tetherto/mdk-react-adapter'

Options

Same UseConsumptionChartDataParams as useSiteConsumption.

Returns

A TanStack UseQueryResult whose data field is ChartCardData — the object accepted by <LineChartCard data={...} />.

Example

import { useSiteConsumptionChartData } from '@tetherto/mdk-react-adapter'
import { LineChartCard } from '@tetherto/mdk-react-devkit/foundation'

function ConsumptionChart() {
  const { data, isLoading } = useSiteConsumptionChartData({ timeline: '5m' })
  return <LineChartCard data={data} isLoading={isLoading} />
}

useSiteContainerCapacity

Reads the aggregated nominal miner capacity across all site containers from the 5-minute tail-log aggregate, giving the denominator shown in the header (e.g. the "2,188" in "MOS / 2,188").

import { useSiteContainerCapacity } from '@tetherto/mdk-react-adapter'

Options

OptionStatusTypeDefaultDescription
refetchIntervalOptionalnumber300000Polling interval in ms. Pass 0 to disable.

Returns

MemberTypeDescription
valuenumber | undefinedTotal nominal miner slots across all site containers; undefined while loading.
isLoadingbooleanLoading state.

useSiteEfficiency

Derives site efficiency in W/TH/s by dividing the latest site consumption by the latest hashrate. Both upstream hooks are called internally; pass powerW to override the consumption source (e.g. to use a power-meter reading instead).

import { useSiteEfficiency } from '@tetherto/mdk-react-adapter'

Options

OptionStatusTypeDefaultDescription
timelineRequiredstringnoneRequired. Stat key suffix forwarded to both upstream hooks.
startOptionalnumbernoneLower time bound (ms epoch).
endOptionalnumbernoneUpper time bound (ms epoch).
tagOptionalstringnoneThing tag override forwarded to the consumption hook.
powerAttributeOptionalstringnoneAggregate field override forwarded to the consumption hook.
refetchIntervalOptionalnumbernonePolling interval in ms forwarded to both upstream hooks.
powerWOptionalnumbernoneWhen provided, skips the internal useSiteConsumption call and uses this watts value as the numerator directly. Pair with useSitePowerMeter().valueW for meter-level efficiency.

Returns

MemberTypeDescription
valueWthSnumber | undefinedWatts per TH/s; undefined while loading or when hashrate is zero.
isLoadingbooleantrue while either upstream hook is loading.

useSiteHashrate

TanStack Query hook that reads the latest aggregate hashrate from the site tail-log and returns both a PH/s display value and the raw MH/s backend value.

import { useSiteHashrate } from '@tetherto/mdk-react-adapter'

Options

OptionStatusTypeDefaultDescription
timelineRequiredstringnoneRequired. Stat key suffix, e.g. '5m'.
startOptionalnumbernoneLower time bound (ms epoch).
endOptionalnumbernoneUpper time bound (ms epoch).
refetchIntervalOptionalnumber60000Polling interval in ms. Pass 0 to disable.

Returns

MemberTypeDescription
valuePhsnumber | undefinedLatest aggregate value in PH/s; undefined while loading or with no data.
valueMhsnumber | undefinedLatest aggregate value in MH/s (raw backend unit).
isLoadingbooleanLoading state.

useSiteMinerCounts

Polls the device list for miners and aggregates them into online / offline / error counts. Uses the last.status field on each device row.

import { useSiteMinerCounts } from '@tetherto/mdk-react-adapter'

Options

OptionStatusTypeDefaultDescription
refetchIntervalOptionalnumbernonePolling interval in ms.

Returns

MemberTypeDescription
totalnumberTotal miner device count.
onlinenumberMiners with status online or on.
offlinenumberMiners not online and not in error.
errornumberMiners with status error or alert.

useSiteMinerStats

Polls the stat-rtd realtime aggregate for the live miner stat summary — the MOS total, online/offline breakdown, and active pool worker count shown in the header.

import { useSiteMinerStats } from '@tetherto/mdk-react-adapter'

Options

OptionStatusTypeDefaultDescription
refetchIntervalOptionalnumbernonePolling interval in ms.

Returns

MemberTypeDescription
mosTotalnumberCount of miners that reported hashrate in the last minute (the MOS denominator).
onlinenumberMiners online or with minor errors (green column).
offlinenumberOffline or sleeping miners.
notMiningnumberMiners not currently mining.
isLoadingbooleanLoading state.

useSitePowerMeter

Reads the current power-meter reading in watts from the site-level device tagged t-powermeter. Returns a MW conversion alongside the raw watts value.

import { useSitePowerMeter } from '@tetherto/mdk-react-adapter'

Options

OptionStatusTypeDefaultDescription
tagOptionalstring't-powermeter'Device tag to filter by.
refetchIntervalOptionalnumbernonePolling interval in ms.

Returns

MemberTypeDescription
valueMwnumber | undefinedLatest power-meter reading in MW; undefined when no device or no data.
valueWnumber | undefinedRaw value in watts.
isLoadingbooleanLoading state.

Pool data

usePoolRows

TanStack Query hook that fetches per-pool stats and transforms them into PoolRow[] objects shaped for the pool manager table. Hashrate is normalised from raw H/s to PH/s.

import { usePoolRows } from '@tetherto/mdk-react-adapter'

Options

OptionStatusTypeDefaultDescription
refetchIntervalOptionalnumber120000Polling interval in ms. Pass 0 to disable.

Returns

A TanStack UseQueryResult whose data is PoolRow[].

MemberTypeDescription
idstringStable React key derived from poolType.
namestringDisplay name in Moria style — minerpool-{poolType}-shelf-0.
poolTypestringRaw pool type string, e.g. 'f2pool', 'ocean'.
revenue24hBtcnumber | undefined24 h revenue in BTC if reported.
hashrateHsnumber | undefinedHashrate in raw H/s.
hashratePhsDisplaynumber | undefinedHashrate in PH/s for display.
detailsPoolDetail[]Array of label/value pairs for the expanded row.

usePoolStats

TanStack Query hook that fetches per-pool stats and aggregates them into site-level totals — total workers, online workers, mismatch count, and aggregate hashrate in PH/s.

import { usePoolStats } from '@tetherto/mdk-react-adapter'

Options

OptionStatusTypeDefaultDescription
refetchIntervalOptionalnumber120000Polling interval in ms. Pass 0 to disable.

Returns

MemberTypeDescription
totalnumberTotal miners reported across all configured pools.
onlinenumberPool-reported active workers.
mismatchnumberDifference between configured and active workers.
hashratePhsnumber | undefinedAggregate pool hashrate in PH/s; undefined while loading or with no data.
hashrateHsnumber | undefinedAggregate pool hashrate in raw H/s.
isLoadingbooleanLoading state.

Dashboard

useDashboardDateRange

Owns the single source of truth for the dashboard's date-range picker: a start / end ms-epoch pair with setters and a reset helper that restores the default 24-hour window.

import { useDashboardDateRange } from '@tetherto/mdk-react-adapter'

Options

OptionStatusTypeDefaultDescription
initialOptional{ start: number; end: number }last 24 hInitial date range. Defaults to the last 24 hours ending now.

Returns

MemberTypeDescription
startnumberLower bound (ms epoch).
endnumberUpper bound (ms epoch).
setRangefunctionReplace the current range.
resetfunctionConvenience: restore the default 24-hour window ending now.

Example

import { useDashboardDateRange } from '@tetherto/mdk-react-adapter'
import { DateRangePicker } from '@tetherto/mdk-react-devkit/foundation'

function DashboardHeader() {
  const { start, end, setRange, reset } = useDashboardDateRange()
  return <DateRangePicker start={start} end={end} onChange={setRange} onReset={reset} />
}

useDashboardExport

Reads cached query data for hashrate, consumption, incidents, and pool stats from the TanStack Query client and exposes exportCsv, exportJson, and a unified export(format) callable. Does not trigger refetches — the export represents exactly what is currently displayed.

import { useDashboardExport } from '@tetherto/mdk-react-adapter'

Options

Accepts a UseDashboardExportOptions object containing DashboardQueryRange fields (timeline, start, end, tag) needed to reconstruct the query keys.

OptionStatusTypeDefaultDescription
timelineRequiredstringnoneRequired. Stat key suffix used to locate the cached chart queries.
startOptionalnumbernoneLower time bound (ms epoch).
endOptionalnumbernoneUpper time bound (ms epoch).
tagOptionalstringnoneThing tag override.

Returns

MemberTypeDescription
exportCsvfunctionTriggers a browser file-download of the dashboard data as CSV.
exportJsonfunctionTriggers a browser file-download as JSON.
exportfunctionUnified callable — export('csv') or export('json').

useDashboardTimeRange

Tiny piece of scoped state for the dashboard's timeline selector. Owns the current timeline string and the canonical option list. Chart hooks (useHashrateChartData, useSiteConsumptionChartData, etc.) consume timeline as a prop.

import { useDashboardTimeRange } from '@tetherto/mdk-react-adapter'

Options

OptionStatusTypeDefaultDescription
initialOptionalstring'5m'Initial timeline value.
optionsOptionalTimelineOption[]canonical listCustom option list; defaults to the canonical set from getTimelineOptions.

Returns

MemberTypeDescription
timelinestringCurrently selected timeline string, e.g. '5m'.
optionsTimelineOption[]Available options, ready for <TimelineSelector options={...} />.
setTimelinefunctionSetter for the current timeline.

Example

import { useDashboardTimeRange, useSiteHashrate } from '@tetherto/mdk-react-adapter'
import { TimelineSelector } from '@tetherto/mdk-react-devkit/foundation'

function DashboardControls() {
  const { timeline, options, setTimeline } = useDashboardTimeRange()
  const { valuePhs } = useSiteHashrate({ timeline })
  return (
    <>
      <TimelineSelector options={options} value={timeline} onChange={setTimeline} />
      <span>{valuePhs?.toFixed(2)} PH/s</span>
    </>
  )
}

Chart data

useConsumptionChartData

TanStack Query hook returning raw consumption tail-log samples. Most dashboards should use the higher-level useSiteConsumptionChartData, which wraps this hook and returns a <LineChartCard>-ready payload.

import { useConsumptionChartData } from '@tetherto/mdk-react-adapter'

Options

OptionStatusTypeDefaultDescription
timelineRequiredstringnoneRequired. Stat key suffix, e.g. '1m', '5m'.
startOptionalnumbernoneLower time bound (ms epoch).
endOptionalnumbernoneUpper time bound (ms epoch).
tagOptionalstring't-miner'Thing tag. Use 't-powermeter' for transformer-level consumption.
powerAttributeOptionalstring'power_w_sum_aggr'Aggregate field name to read.
refetchIntervalOptionalnumber60000Polling interval in ms. Pass 0 to disable.

Returns

A TanStack UseQueryResult<TailLogEntry[][], Error> — raw tail-log matrix before projection.


useHashrateChartData

TanStack Query hook combining the site tail-log hashrate series with the per-pool hashrate history into a single ChartCardData payload for <LineChartCard />. Handles unit conversion from both MH/s (tail-log) and raw H/s (pool API) into PH/s for display.

import { useHashrateChartData } from '@tetherto/mdk-react-adapter'

Options

OptionStatusTypeDefaultDescription
timelineRequiredstringnoneRequired. Stat key suffix, e.g. '5m'.
startOptionalnumbernoneLower time bound (ms epoch).
endOptionalnumbernoneUpper time bound (ms epoch).
refetchIntervalOptionalnumbernonePolling interval in ms.

Returns

A TanStack UseQueryResult whose data is ChartCardData — ready for <LineChartCard data={...} />.


usePowerModeTimelineData

TanStack Query hook returning power-mode and status samples shaped for <PowerModeTimelineChart data={...} />.

import { usePowerModeTimelineData } from '@tetherto/mdk-react-adapter'

Options

OptionStatusTypeDefaultDescription
timelineRequiredstringnoneRequired. Stat key suffix, e.g. '1m'.
startOptionalnumbernoneLower time bound (ms epoch).
endOptionalnumbernoneUpper time bound (ms epoch).
tagOptionalstringnoneThing tag override.
refetchIntervalOptionalnumbernonePolling interval in ms.

Returns

A TanStack UseQueryResult<PowerModeTimelineEntry[], Error>.


Auth and token

useAuthToken

Reads ?authToken=… from window.location.search, persists it into the headless authStore, and strips the parameter from the URL via history.replaceState so the token never lingers in the address bar. Router-agnostic by design. Returns the current token from the store so callers can gate navigation on authentication.

import { useAuthToken } from '@tetherto/mdk-react-adapter'

Returns

TypeDescription
string | nullCurrent auth token from the authStore, or null when no token is present.

Example

import { useAuthToken } from '@tetherto/mdk-react-adapter'
import { Navigate, Outlet } from 'react-router-dom'

function ProtectedRoute() {
  const token = useAuthToken()
  return token ? <Outlet /> : <Navigate to="/signin" replace />
}

useTokenPolling

Polls the backend token-refresh endpoint at a fixed interval (default 250 s) and writes the new token back into the authStore. Fires the optional onSessionEnded callback on a 401 or 500, which MDK UI Shell uses to redirect back to /signin.

import { useTokenPolling } from '@tetherto/mdk-react-adapter'

Options

OptionStatusTypeDefaultDescription
intervalMsOptionalnumber250000Polling interval in ms. Backend token TTL defaults to 5 min (300 s); 250 s gives comfortable headroom.
enabledOptionalbooleantrue when token presentPass false to pause polling (e.g. on the sign-in page).
onSessionEndedOptionalfunctionnoneCalled on 401 or 500; use to navigate to the sign-in page.

Example

import { useTokenPolling } from '@tetherto/mdk-react-adapter'
import { useNavigate } from 'react-router-dom'

function App() {
  const navigate = useNavigate()
  useTokenPolling({ onSessionEnded: () => navigate('/signin') })
  return <Outlet />
}

Incidents

useActiveIncidents

TanStack Query hook returning the list of currently-firing alerts, shaped for <ActiveIncidentsCard items={...} />. Queries devices that have a non-null last.alerts field and maps them via the mapDevicesToIncidents utility.

import { useActiveIncidents } from '@tetherto/mdk-react-adapter'

Options

OptionStatusTypeDefaultDescription
refetchIntervalOptionalnumber20000Polling interval in ms. Matches Moria's production cadence. Pass 0 to disable.
formatDateOptionalfunctionISO stringDate formatter applied to the row body timestamp.

Returns

A TanStack UseQueryResult<IncidentRow[], Error>.

Example

import { useActiveIncidents } from '@tetherto/mdk-react-adapter'
import { ActiveIncidentsCard } from '@tetherto/mdk-react-devkit/foundation'

function IncidentsFeed() {
  const { data: items = [], isLoading } = useActiveIncidents({ refetchInterval: 20_000 })
  return <ActiveIncidentsCard items={items} isLoading={isLoading} />
}

Alerts

Data hooks that back the full alerts surface: useCurrentAlertDevices feeds the <CurrentAlerts> / <Alerts> table with raw device rows; useHistoricalAlerts fetches and shapes the historical-alerts log for <HistoricalAlerts>. Both require <MdkProvider> in the tree.

See also useActiveIncidents in the Incidents section, which hits the same list-things endpoint but maps results to the dashboard card's IncidentRow[] shape.

useCurrentAlertDevices

TanStack Query hook returning the raw devices that currently carry one or more alerts, as the nested ListThingsDevice[][] envelope the devkit <Alerts> / <CurrentAlerts> table expects. Unlike useActiveIncidents, this hook leaves the payload unshaped so the table can derive its own filter tokens and per-row status. Both hit /auth/list-things; this hook requests a wider field set and uses a distinct cache key.

import { useCurrentAlertDevices } from '@tetherto/mdk-react-adapter'
import type { UseCurrentAlertDevicesOptions } from '@tetherto/mdk-react-adapter'

Options

OptionStatusTypeDefaultDescription
refetchIntervalOptionalnumber20000Polling interval in ms. Matches the default production polling cadence. Pass 0 to disable.
filterTagsOptionalstring[]noneAlerts search chips. Folded into the backend list-things selector — triggers a re-fetch that narrows the dataset server-side.

Returns

A TanStack UseQueryResult<ListThingsDevice[][], Error>.

Example

import { useCurrentAlertDevices } from '@tetherto/mdk-react-adapter'
import { CurrentAlerts } from '@tetherto/mdk-react-devkit/foundation'

function AlertsTable({ filterTags }) {
  const { data, isLoading } = useCurrentAlertDevices({ filterTags })
  return <CurrentAlerts devices={data ?? []} isLoading={isLoading} filterTags={filterTags} />
}

useHistoricalAlerts

TanStack Query hook for the historical-alerts log. Fetches the [start, end] range as successive history-log windows, merges results by uuid, and shapes rows for the devkit <HistoricalAlerts> table via mapHistoryLogToAlerts. Range changes abort the in-flight chunk loop through the query's AbortSignal.

By default the entire range is fetched in a single request. Pass a smaller intervalMs (e.g. ONE_DAY_MS) only for wide ranges where the backend would otherwise cap or slow a single query — that splits the fetch into sequential 24-hour windows.

import { useHistoricalAlerts } from '@tetherto/mdk-react-adapter'
import type { UseHistoricalAlertsOptions } from '@tetherto/mdk-react-adapter'

Options

OptionStatusTypeDefaultDescription
startRequirednumbernoneLower bound of the look-back window (ms epoch).
endRequirednumbernoneUpper bound of the look-back window (ms epoch).
intervalMsOptionalnumberwhole rangePer-request window size in ms. Defaults to the whole range in one request; set a smaller value to chunk wide ranges into sequential fetches.
enabledOptionalbooleantrue when range validPass false to force-disable the query. Defaults to enabled when start and end are finite and end > start.

Returns

A TanStack UseQueryResult<HistoricalAlert[], Error>.

Example

import { useHistoricalAlerts } from '@tetherto/mdk-react-adapter'
import { HistoricalAlerts } from '@tetherto/mdk-react-devkit/foundation'

function AlertHistory({ start, end, filterTags, localFilters, onDateRangeChange }) {
  const { data: alerts = [], isLoading } = useHistoricalAlerts({ start, end })
  return (
    <HistoricalAlerts
      alerts={alerts}
      isLoading={isLoading}
      filterTags={filterTags}
      localFilters={localFilters}
      dateRange={{ start, end }}
      onDateRangeChange={onDateRangeChange}
    />
  )
}

Behaviour notes

  • Wide ranges fan out into many requests. The MDK UI Shell page caps the default window at 14 days; pass a tighter [start, end] or set intervalMs to limit per-request payload size.
  • The hook removes duplicate rows by uuid after merging chunks, before passing them to mapHistoryLogToAlerts.

On this page