diff --git a/apps/api/src/routes/v1/dashboardData.ts b/apps/api/src/routes/v1/dashboardData.ts index 6de202163..ee8e41946 100644 --- a/apps/api/src/routes/v1/dashboardData.ts +++ b/apps/api/src/routes/v1/dashboardData.ts @@ -144,22 +144,65 @@ const route = createRoute({ }); export default new OpenAPIHono().openapi(route, async c => { - const chainStatsQuery = await getChainStats(); - const dashboardData = await getDashboardData(); - const networkCapacity = await getNetworkCapacity(); - const networkCapacityStats = await getProviderGraphData("count"); - const latestBlocks = await getBlocks(5); - const latestTransactions = await getTransactions(5); - const chainStats = { - height: latestBlocks[0]?.height ?? null, - transactionCount: latestBlocks[0]?.totalTransactionCount ?? null, - ...chainStatsQuery, - }; + let chainStats; + let now; + let compare; + let networkCapacity; + let networkCapacityStats; + let latestBlocks; + let latestTransactions; + + try { + const chainStatsQuery = await getChainStats(); + chainStats = { ...chainStatsQuery }; + } catch (error) { + chainStats = {} + console.error("Failed to fetch getChainStats:", error); + } + + try { + const dashboardData = await getDashboardData(); + now = dashboardData.now; + compare = dashboardData.compare; + } catch (error) { + console.error("Failed to fetch dashboardData:", error); + } + + + try { + networkCapacity = await getNetworkCapacity(); + } catch (error) { + console.error("Failed to fetch networkCapacity:", error); + } + + try { + networkCapacityStats = await getProviderGraphData("count"); + } catch (error) { + console.error("Failed to fetch networkCapacityStats:", error); + } + + try { + latestBlocks = await getBlocks(5); + chainStats = { + ...chainStats, + height: latestBlocks[0]?.height ?? null, + transactionCount: latestBlocks[0]?.totalTransactionCount ?? null, + } + } catch (error) { + console.error("Failed to fetch latestBlocks:", error); + } + + try { + latestTransactions = await getTransactions(5); + } catch (error) { + console.error("Failed to fetch latestTransactions:", error); + } return c.json({ chainStats, - ...dashboardData, + now, + compare, networkCapacity, networkCapacityStats, latestBlocks, diff --git a/apps/stats-web/src/app/(home)/Dashboard.tsx b/apps/stats-web/src/app/(home)/Dashboard.tsx index 6e2f0d265..da04433fa 100644 --- a/apps/stats-web/src/app/(home)/Dashboard.tsx +++ b/apps/stats-web/src/app/(home)/Dashboard.tsx @@ -38,10 +38,28 @@ interface IDashboardProps { } export const Dashboard: React.FunctionComponent = ({ dashboardData }) => { - const memoryDiff = bytesToShrink(dashboardData.now.activeMemory - dashboardData.compare.activeMemory); - const storageDiff = bytesToShrink(dashboardData.now.activeStorage - dashboardData.compare.activeStorage); - const capacityMemoryDiff = bytesToShrink(dashboardData.networkCapacityStats.now.memory - dashboardData.networkCapacityStats.compare.memory); - const capacityStorageDiff = bytesToShrink(dashboardData.networkCapacityStats.now.storage - dashboardData.networkCapacityStats.compare.storage); + const memoryDiff = + dashboardData?.compare?.activeMemory !== undefined && + dashboardData?.now?.activeMemory !== undefined + ? bytesToShrink(dashboardData.now.activeMemory - dashboardData.compare.activeMemory) + : bytesToShrink(0); + + const storageDiff = + dashboardData?.compare?.activeStorage !== undefined && + dashboardData?.now?.activeStorage !== undefined + ? bytesToShrink(dashboardData.now.activeStorage - dashboardData.compare.activeStorage) + : bytesToShrink(0); + const capacityMemoryDiff = + dashboardData?.networkCapacityStats?.now?.memory !== undefined && + dashboardData?.networkCapacityStats?.compare?.memory !== undefined + ? bytesToShrink(dashboardData.networkCapacityStats.now.memory - dashboardData.networkCapacityStats.compare.memory) + : bytesToShrink(0); + const capacityStorageDiff = + dashboardData?.networkCapacityStats?.now?.storage !== undefined && + dashboardData?.networkCapacityStats?.compare?.storage !== undefined + ? bytesToShrink(dashboardData.networkCapacityStats.now.storage - dashboardData.networkCapacityStats.compare.storage) + : bytesToShrink(0); + return ( <> @@ -70,297 +88,347 @@ export const Dashboard: React.FunctionComponent = ({ dashboardD */} {/* */} - - Network Summary - - -
- - } - text="USD spent (24h)" - tooltip="Amount spent in the last 24h (USDC + AKT converted to USD)." - graphPath={UrlService.graph(SnapshotsUrlParam.dailyUsdSpent)} - diffNumber={udenomToDenom(dashboardData.now.dailyUUsdSpent - dashboardData.compare.dailyUUsdSpent)} - diffPercent={percIncrease(dashboardData.compare.dailyUUsdSpent, dashboardData.now.dailyUUsdSpent)} - /> - - - } - text="Total spent USD" - tooltip="This is the total amount spent (USDC + AKT converted to USD) to rent computing power on the akash network since the beginning of the network. (March 2021)" - graphPath={UrlService.graph(SnapshotsUrlParam.totalUSDSpent)} - diffNumber={udenomToDenom(dashboardData.now.totalUUsdSpent - dashboardData.compare.totalUUsdSpent)} - diffPercent={percIncrease(dashboardData.compare.totalUUsdSpent, dashboardData.now.totalUUsdSpent)} - /> - - - } - text="New leases (24h)" - tooltip="Last 24h" - graphPath={UrlService.graph(SnapshotsUrlParam.dailyDeploymentCount)} - diffNumber={dashboardData.now.dailyLeaseCount - dashboardData.compare.dailyLeaseCount} - diffPercent={percIncrease(dashboardData.compare.dailyLeaseCount, dashboardData.now.dailyLeaseCount)} - /> - - } - text="Total leases" - tooltip="The total lease count consists of all deployments that were live at some point and that someone paid for. This includes deployments that were deployed for testing or that were meant to be only temporary." - graphPath={UrlService.graph(SnapshotsUrlParam.allTimeDeploymentCount)} - diffNumber={dashboardData.now.totalLeaseCount - dashboardData.compare.totalLeaseCount} - diffPercent={percIncrease(dashboardData.compare.totalLeaseCount, dashboardData.now.totalLeaseCount)} - /> -
- - - - Resources leased - - -
- } - text="Active leases" - tooltip={ - <> -
This is the number of leases currently active on the network. A deployment can be anything.
-
For example: a simple website to a blockchain node or a video game server.
- - } - graphPath={UrlService.graph(SnapshotsUrlParam.activeLeases)} - diffNumber={dashboardData.now.activeLeaseCount - dashboardData.compare.activeLeaseCount} - diffPercent={percIncrease(dashboardData.compare.activeLeaseCount, dashboardData.now.activeLeaseCount)} - /> + {dashboardData.now && dashboardData.compare && + <> + + Network Summary + + +
+ {dashboardData.now.dailyUUsdSpent !== undefined && + dashboardData.compare.dailyUUsdSpent !== undefined && + + } + text="USD spent (24h)" + tooltip="Amount spent in the last 24h (USDC + AKT converted to USD)." + graphPath={UrlService.graph(SnapshotsUrlParam.dailyUsdSpent)} + diffNumber={udenomToDenom(dashboardData.now.dailyUUsdSpent - dashboardData.compare.dailyUUsdSpent)} + diffPercent={percIncrease(dashboardData.compare.dailyUUsdSpent, dashboardData.now.dailyUUsdSpent)} + />} + {dashboardData.now.totalUUsdSpent !== undefined && + dashboardData.compare.totalUUsdSpent !== undefined && + + } + text="Total spent USD" + tooltip="This is the total amount spent (USDC + AKT converted to USD) to rent computing power on the akash network since the beginning of the network. (March 2021)" + graphPath={UrlService.graph(SnapshotsUrlParam.totalUSDSpent)} + diffNumber={udenomToDenom(dashboardData.now.totalUUsdSpent - dashboardData.compare.totalUUsdSpent)} + diffPercent={percIncrease(dashboardData.compare.totalUUsdSpent, dashboardData.now.totalUUsdSpent)} + />} + {dashboardData.now.dailyLeaseCount !== undefined && + dashboardData.compare.dailyLeaseCount !== undefined && + + } + text="New leases (24h)" + tooltip="Last 24h" + graphPath={UrlService.graph(SnapshotsUrlParam.dailyDeploymentCount)} + diffNumber={dashboardData.now.dailyLeaseCount - dashboardData.compare.dailyLeaseCount} + diffPercent={percIncrease(dashboardData.compare.dailyLeaseCount, dashboardData.now.dailyLeaseCount)} + />} + + {dashboardData.now.totalLeaseCount !== undefined && + dashboardData.compare.totalLeaseCount !== undefined && + } + text="Total leases" + tooltip="The total lease count consists of all deployments that were live at some point and that someone paid for. This includes deployments that were deployed for testing or that were meant to be only temporary." + graphPath={UrlService.graph(SnapshotsUrlParam.allTimeDeploymentCount)} + diffNumber={dashboardData.now.totalLeaseCount - dashboardData.compare.totalLeaseCount} + diffPercent={percIncrease(dashboardData.compare.totalLeaseCount, dashboardData.now.totalLeaseCount)} + />} +
+ + + + Resources leased + + +
+ {dashboardData.now.activeLeaseCount !== undefined && + dashboardData.compare.activeLeaseCount !== undefined && + } + text="Active leases" + tooltip={ + <> +
This is the number of leases currently active on the network. A deployment can be anything.
+
For example: a simple website to a blockchain node or a video game server.
+ + } + graphPath={UrlService.graph(SnapshotsUrlParam.activeLeases)} + diffNumber={dashboardData.now.activeLeaseCount - dashboardData.compare.activeLeaseCount} + diffPercent={percIncrease(dashboardData.compare.activeLeaseCount, dashboardData.now.activeLeaseCount)} + />} + + {dashboardData.now.activeCPU !== undefined && + dashboardData.compare.activeCPU !== undefined && + + {" "} + CPU + + } + text="Compute" + graphPath={UrlService.graph(SnapshotsUrlParam.compute)} + diffNumber={(dashboardData.now.activeCPU - dashboardData.compare.activeCPU) / 1000} + diffPercent={percIncrease(dashboardData.compare.activeCPU, dashboardData.now.activeCPU)} + />} + + {dashboardData.now.activeGPU !== undefined && + dashboardData.compare.activeGPU !== undefined && + + {" "} + GPU + + } + text="Graphics" + graphPath={UrlService.graph(SnapshotsUrlParam.graphics)} + diffNumber={dashboardData.now.activeGPU - dashboardData.compare.activeGPU} + diffPercent={percIncrease(dashboardData.compare.activeGPU, dashboardData.now.activeGPU)} + />} + + {dashboardData.now.activeMemory !== undefined && + dashboardData.compare.activeMemory !== undefined && + } + text="Memory" + graphPath={UrlService.graph(SnapshotsUrlParam.memory)} + diffNumberUnit={memoryDiff.unit} + diffNumber={memoryDiff.value} + diffPercent={percIncrease(dashboardData.compare.activeMemory, dashboardData.now.activeMemory)} + />} + + {dashboardData.now.activeStorage !== undefined && + dashboardData.compare.activeStorage !== undefined && + } + text="Storage" + graphPath={UrlService.graph(SnapshotsUrlParam.storage)} + diffNumberUnit={storageDiff.unit} + diffNumber={storageDiff.value} + diffPercent={percIncrease(dashboardData.compare.activeStorage, dashboardData.now.activeStorage)} + />} +
+ } + + {dashboardData.networkCapacity && dashboardData.networkCapacity && + <> + + + Network Capacity + + +
+ {dashboardData.networkCapacity.activeProviderCount !== undefined && + dashboardData.networkCapacityStats.now.count !== undefined && + dashboardData.networkCapacityStats.compare.count !== undefined && + } + text="Active providers" + graphPath={UrlService.providerGraph(ProviderSnapshotsUrlParam.count)} + diffNumber={dashboardData.networkCapacityStats.now.count - dashboardData.networkCapacityStats.compare.count} + diffPercent={percIncrease(dashboardData.networkCapacityStats.compare.count, dashboardData.networkCapacityStats.now.count)} + tooltip={ + <> +
This is the number of providers currently active on the network.
+ + } + />} + + {dashboardData.networkCapacity.totalCPU !== undefined && + dashboardData.networkCapacityStats.now.cpu !== undefined && + dashboardData.networkCapacityStats.compare.cpu !== undefined && + + {" "} + CPU + + } + text="Compute" + graphPath={UrlService.providerGraph(ProviderSnapshotsUrlParam.cpu)} + diffNumber={(dashboardData.networkCapacityStats.now.cpu - dashboardData.networkCapacityStats.compare.cpu) / 1000} + diffPercent={percIncrease(dashboardData.networkCapacityStats.compare.cpu, dashboardData.networkCapacityStats.now.cpu)} + />} + {dashboardData.networkCapacity.totalGPU !== undefined && + dashboardData.networkCapacityStats.now.gpu !== undefined && + dashboardData.networkCapacityStats.compare.gpu !== undefined && + + {" "} + GPU + + } + text="Graphics" + graphPath={UrlService.providerGraph(ProviderSnapshotsUrlParam.gpu)} + diffNumber={dashboardData.networkCapacityStats.now.gpu - dashboardData.networkCapacityStats.compare.gpu} + diffPercent={percIncrease(dashboardData.networkCapacityStats.compare.gpu, dashboardData.networkCapacityStats.now.gpu)} + />} + + {dashboardData.networkCapacity.totalMemory !== undefined && + dashboardData.networkCapacityStats.now.memory !== undefined && + dashboardData.networkCapacityStats.compare.memory !== undefined && + } + text="Memory" + diffNumberUnit={capacityMemoryDiff.unit} + diffNumber={capacityMemoryDiff.value} + diffPercent={percIncrease(dashboardData.networkCapacityStats.compare.memory, dashboardData.networkCapacityStats.now.memory)} + graphPath={UrlService.providerGraph(ProviderSnapshotsUrlParam.memory)} + />} + + {dashboardData.networkCapacity.totalStorage !== undefined && + dashboardData.networkCapacityStats.now.storage !== undefined && + dashboardData.networkCapacityStats.compare.storage !== undefined && + } + text="Storage" + graphPath={UrlService.providerGraph(ProviderSnapshotsUrlParam.storage)} + diffNumberUnit={capacityStorageDiff.unit} + diffNumber={capacityStorageDiff.value} + diffPercent={percIncrease(dashboardData.networkCapacityStats.compare.storage, dashboardData.networkCapacityStats.now.storage)} + />} +
+ } + {dashboardData.now && dashboardData.compare && + <> + + + Spent Assets + + +
+ {dashboardData.now.dailyUAktSpent !== undefined && + dashboardData.compare.dailyUAktSpent !== undefined && + + + + + } + text="AKT spent (24h)" + tooltip="Last 24h" + graphPath={UrlService.graph(SnapshotsUrlParam.dailyAktSpent)} + diffNumber={udenomToDenom(dashboardData.now.dailyUAktSpent - dashboardData.compare.dailyUAktSpent)} + diffPercent={percIncrease(dashboardData.compare.dailyUAktSpent, dashboardData.now.dailyUAktSpent)} + />} + + {dashboardData.now.totalUAktSpent !== undefined && + dashboardData.compare.totalUAktSpent !== undefined && + + + + + } + text="Total spent AKT" + tooltip="This is the total amount of akt spent to rent computing power on the akash network since the beginning of the network. (March 2021)" + graphPath={UrlService.graph(SnapshotsUrlParam.totalAKTSpent)} + diffNumber={udenomToDenom(dashboardData.now.totalUAktSpent - dashboardData.compare.totalUAktSpent)} + diffPercent={percIncrease(dashboardData.compare.totalUAktSpent, dashboardData.now.totalUAktSpent)} + />} + + {dashboardData.now.dailyUUsdcSpent !== undefined && + dashboardData.compare.dailyUUsdcSpent !== undefined && + + + + + } + text="USDC spent (24h)" + tooltip="Last 24h" + graphPath={UrlService.graph(SnapshotsUrlParam.dailyUsdcSpent)} + diffNumber={udenomToDenom(dashboardData.now.dailyUUsdcSpent - dashboardData.compare.dailyUUsdcSpent)} + diffPercent={percIncrease(dashboardData.compare.dailyUUsdcSpent, dashboardData.now.dailyUUsdcSpent)} + />} + + {dashboardData.now.totalUUsdcSpent !== undefined && + dashboardData.compare.totalUUsdcSpent !== undefined && + + + + + } + text="Total spent USDC" + tooltip="This is the total amount of usdc spent to rent computing power on the akash network since the Mainnet 6 upgrade that added usdc support. (August 2023)" + graphPath={UrlService.graph(SnapshotsUrlParam.totalUSDCSpent)} + diffNumber={udenomToDenom(dashboardData.now.totalUUsdcSpent - dashboardData.compare.totalUUsdcSpent)} + diffPercent={percIncrease(dashboardData.compare.totalUUsdcSpent, dashboardData.now.totalUUsdcSpent)} + />} +
+ } + {dashboardData.chainStats && <> + + + Blockchain + + +
+ {dashboardData.chainStats.height !== undefined && } text="Height" />} + + {dashboardData.chainStats.transactionCount !== undefined && } text="Transactions" />} + + {dashboardData.chainStats.communityPool !== undefined && } text="Community pool" />} + + {dashboardData.chainStats.bondedTokens !== undefined && dashboardData.chainStats.totalSupply !== undefined && + /{" "} + + + + + + } + text="Bonded tokens" + />} + + {dashboardData.chainStats.inflation !== undefined && } + text="Inflation" + />} + + {dashboardData.chainStats.stakingAPR !== undefined && } + text="Staking APR" + />} +
+ } - - {" "} - CPU - - } - text="Compute" - graphPath={UrlService.graph(SnapshotsUrlParam.compute)} - diffNumber={(dashboardData.now.activeCPU - dashboardData.compare.activeCPU) / 1000} - diffPercent={percIncrease(dashboardData.compare.activeCPU, dashboardData.now.activeCPU)} - /> - - - {" "} - GPU - - } - text="Graphics" - graphPath={UrlService.graph(SnapshotsUrlParam.graphics)} - diffNumber={dashboardData.now.activeGPU - dashboardData.compare.activeGPU} - diffPercent={percIncrease(dashboardData.compare.activeGPU, dashboardData.now.activeGPU)} - /> - - } - text="Memory" - graphPath={UrlService.graph(SnapshotsUrlParam.memory)} - diffNumberUnit={memoryDiff.unit} - diffNumber={memoryDiff.value} - diffPercent={percIncrease(dashboardData.compare.activeMemory, dashboardData.now.activeMemory)} - /> - - } - text="Storage" - graphPath={UrlService.graph(SnapshotsUrlParam.storage)} - diffNumberUnit={storageDiff.unit} - diffNumber={storageDiff.value} - diffPercent={percIncrease(dashboardData.compare.activeStorage, dashboardData.now.activeStorage)} - /> -
- - - - Network Capacity - - -
- } - text="Active providers" - graphPath={UrlService.providerGraph(ProviderSnapshotsUrlParam.count)} - diffNumber={dashboardData.networkCapacityStats.now.count - dashboardData.networkCapacityStats.compare.count} - diffPercent={percIncrease(dashboardData.networkCapacityStats.compare.count, dashboardData.networkCapacityStats.now.count)} - tooltip={ - <> -
This is the number of providers currently active on the network.
- - } - /> - - - {" "} - CPU - - } - text="Compute" - graphPath={UrlService.providerGraph(ProviderSnapshotsUrlParam.cpu)} - diffNumber={(dashboardData.networkCapacityStats.now.cpu - dashboardData.networkCapacityStats.compare.cpu) / 1000} - diffPercent={percIncrease(dashboardData.networkCapacityStats.compare.cpu, dashboardData.networkCapacityStats.now.cpu)} - /> - - {" "} - GPU - - } - text="Graphics" - graphPath={UrlService.providerGraph(ProviderSnapshotsUrlParam.gpu)} - diffNumber={dashboardData.networkCapacityStats.now.gpu - dashboardData.networkCapacityStats.compare.gpu} - diffPercent={percIncrease(dashboardData.networkCapacityStats.compare.gpu, dashboardData.networkCapacityStats.now.gpu)} - /> - - } - text="Memory" - diffNumberUnit={capacityMemoryDiff.unit} - diffNumber={capacityMemoryDiff.value} - diffPercent={percIncrease(dashboardData.networkCapacityStats.compare.memory, dashboardData.networkCapacityStats.now.memory)} - graphPath={UrlService.providerGraph(ProviderSnapshotsUrlParam.memory)} - /> - - } - text="Storage" - graphPath={UrlService.providerGraph(ProviderSnapshotsUrlParam.storage)} - diffNumberUnit={capacityStorageDiff.unit} - diffNumber={capacityStorageDiff.value} - diffPercent={percIncrease(dashboardData.networkCapacityStats.compare.storage, dashboardData.networkCapacityStats.now.storage)} - /> -
- - - - Spent Assets - - -
- - - - - } - text="AKT spent (24h)" - tooltip="Last 24h" - graphPath={UrlService.graph(SnapshotsUrlParam.dailyAktSpent)} - diffNumber={udenomToDenom(dashboardData.now.dailyUAktSpent - dashboardData.compare.dailyUAktSpent)} - diffPercent={percIncrease(dashboardData.compare.dailyUAktSpent, dashboardData.now.dailyUAktSpent)} - /> - - - - - } - text="Total spent AKT" - tooltip="This is the total amount of akt spent to rent computing power on the akash network since the beginning of the network. (March 2021)" - graphPath={UrlService.graph(SnapshotsUrlParam.totalAKTSpent)} - diffNumber={udenomToDenom(dashboardData.now.totalUAktSpent - dashboardData.compare.totalUAktSpent)} - diffPercent={percIncrease(dashboardData.compare.totalUAktSpent, dashboardData.now.totalUAktSpent)} - /> - - - - - - } - text="USDC spent (24h)" - tooltip="Last 24h" - graphPath={UrlService.graph(SnapshotsUrlParam.dailyUsdcSpent)} - diffNumber={udenomToDenom(dashboardData.now.dailyUUsdcSpent - dashboardData.compare.dailyUUsdcSpent)} - diffPercent={percIncrease(dashboardData.compare.dailyUUsdcSpent, dashboardData.now.dailyUUsdcSpent)} - /> - - - - - - } - text="Total spent USDC" - tooltip="This is the total amount of usdc spent to rent computing power on the akash network since the Mainnet 6 upgrade that added usdc support. (August 2023)" - graphPath={UrlService.graph(SnapshotsUrlParam.totalUSDCSpent)} - diffNumber={udenomToDenom(dashboardData.now.totalUUsdcSpent - dashboardData.compare.totalUUsdcSpent)} - diffPercent={percIncrease(dashboardData.compare.totalUUsdcSpent, dashboardData.now.totalUUsdcSpent)} - /> -
- - - - Blockchain - - -
- } text="Height" /> - - } text="Transactions" /> - - } text="Community pool" /> - - - /{" "} - - - - - - } - text="Bonded tokens" - /> - - } - text="Inflation" - /> - - } - text="Staking APR" - /> -
@@ -383,7 +451,7 @@ export const Dashboard: React.FunctionComponent = ({ dashboardD - {dashboardData.latestBlocks.map(block => ( + {dashboardData.latestBlocks && dashboardData.latestBlocks.map(block => ( ))} @@ -414,7 +482,7 @@ export const Dashboard: React.FunctionComponent = ({ dashboardD - {dashboardData.latestTransactions.map(tx => ( + {dashboardData.latestTransactions && dashboardData.latestTransactions.map(tx => ( ))} diff --git a/apps/stats-web/src/app/(home)/DashboardContainer.tsx b/apps/stats-web/src/app/(home)/DashboardContainer.tsx index e8a318256..576e02689 100644 --- a/apps/stats-web/src/app/(home)/DashboardContainer.tsx +++ b/apps/stats-web/src/app/(home)/DashboardContainer.tsx @@ -23,7 +23,7 @@ export const DashboardContainer: React.FunctionComponent = () => {

- Last updated: + Last updated: {dashboardData?.now?.date !== undefined && } {dashboardData?.now?.date !== undefined && }