diff --git a/.commitlintrc.json b/.commitlintrc.json index 3004716bc..dd240a528 100644 --- a/.commitlintrc.json +++ b/.commitlintrc.json @@ -13,7 +13,8 @@ "billing", "provider", "deployment", - "dx" + "dx", + "stats" ] ] } diff --git a/apps/api/src/routes/v1/dashboardData.ts b/apps/api/src/routes/v1/dashboardData.ts index d050a3ea0..89af9d8db 100644 --- a/apps/api/src/routes/v1/dashboardData.ts +++ b/apps/api/src/routes/v1/dashboardData.ts @@ -1,10 +1,16 @@ import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi"; +import { LoggerService } from "@src/core/services/logger/logger.service"; import { getBlocks } from "@src/services/db/blocksService"; import { getNetworkCapacity } from "@src/services/db/providerStatusService"; import { getDashboardData, getProviderGraphData } from "@src/services/db/statsService"; import { getTransactions } from "@src/services/db/transactionsService"; import { getChainStats } from "@src/services/external/apiNodeService"; +import { createLoggingExecutor } from "@src/utils/logging"; + + +const logger = new LoggerService({ context: "Dashboard" }); +const runOrLog = createLoggingExecutor(logger) const route = createRoute({ method: "get", @@ -144,25 +150,33 @@ 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 [{ now, compare }, chainStatsQuery, networkCapacity, networkCapacityStats, latestBlocks, latestTransactions] = await Promise.all([ + runOrLog(getDashboardData), + runOrLog(getChainStats, { + bondedTokens: undefined, + totalSupply: undefined, + communityPool: undefined, + inflation: undefined, + stakingAPR: undefined + }), + runOrLog(getNetworkCapacity), + runOrLog(() => getProviderGraphData("count")), + runOrLog(() => getBlocks(5)), + runOrLog(() => getTransactions(5)) + ]); const chainStats = { - height: latestBlocks[0].height, - transactionCount: latestBlocks[0].totalTransactionCount, - ...chainStatsQuery - }; + ...chainStatsQuery, + height: latestBlocks && latestBlocks.length > 0 ? latestBlocks[0].height : undefined, + transactionCount: latestBlocks && latestBlocks.length > 0 ? latestBlocks[0].totalTransactionCount : undefined, + } return c.json({ chainStats, - ...dashboardData, + now, + compare, networkCapacity, networkCapacityStats, latestBlocks, latestTransactions }); -}); +}); \ No newline at end of file diff --git a/apps/api/src/services/external/apiNodeService.ts b/apps/api/src/services/external/apiNodeService.ts index 91f642efc..e5e193130 100644 --- a/apps/api/src/services/external/apiNodeService.ts +++ b/apps/api/src/services/external/apiNodeService.ts @@ -6,6 +6,7 @@ import fetch from "node-fetch"; import { Op } from "sequelize"; import { cacheKeys, cacheResponse } from "@src/caching/helpers"; +import { LoggerService } from "@src/core/services/logger/logger.service"; import { getTransactionByAddress } from "@src/services/db/transactionsService"; import { CosmosGovProposalResponse, @@ -28,45 +29,87 @@ import { CosmosMintInflationResponse } from "@src/types/rest/cosmosMintInflation import { CosmosStakingPoolResponse } from "@src/types/rest/cosmosStakingPoolResponse"; import { coinToAsset } from "@src/utils/coin"; import { apiNodeUrl, averageBlockCountInAMonth, betaTypeVersion, betaTypeVersionMarket } from "@src/utils/constants"; +import { createLoggingExecutor } from "@src/utils/logging"; import { getDeploymentRelatedMessages } from "../db/deploymentService"; import { getProviderList } from "../db/providerStatusService"; export async function getChainStats() { + const logger = new LoggerService({ context: "ApiNode" }) + const runOrLog = createLoggingExecutor(logger) + const result = await cacheResponse( 60 * 5, // 5 minutes cacheKeys.getChainStats, async () => { - const bondedTokensQuery = axios.get(`${apiNodeUrl}/cosmos/staking/v1beta1/pool`); - const supplyQuery = axios.get(`${apiNodeUrl}/cosmos/bank/v1beta1/supply?pagination.limit=1000`); - const communityPoolQuery = axios.get(`${apiNodeUrl}/cosmos/distribution/v1beta1/community_pool`); - const inflationQuery = axios.get(`${apiNodeUrl}/cosmos/mint/v1beta1/inflation`); - const distributionQuery = axios.get(`${apiNodeUrl}/cosmos/distribution/v1beta1/params`); - - const [bondedTokensResponse, supplyResponse, communityPoolResponse, inflationResponse, distributionResponse] = await Promise.all([ - bondedTokensQuery, - supplyQuery, - communityPoolQuery, - inflationQuery, - distributionQuery + const bondedTokensAsPromised = await runOrLog(async () => { + const bondedTokensQuery = await axios.get( + `${apiNodeUrl}/cosmos/staking/v1beta1/pool` + ); + return parseInt(bondedTokensQuery.data.pool.bonded_tokens); + }); + + const totalSupplyAsPromised = await runOrLog(async () => { + const supplyQuery = await axios.get( + `${apiNodeUrl}/cosmos/bank/v1beta1/supply?pagination.limit=1000` + ); + return parseInt( + supplyQuery.data.supply.find((x) => x.denom === "uakt")?.amount || "0" + ); + }); + + const communityPoolAsPromised = await runOrLog(async () => { + const communityPoolQuery = await axios.get( + `${apiNodeUrl}/cosmos/distribution/v1beta1/community_pool` + ); + return parseFloat( + communityPoolQuery.data.pool.find((x) => x.denom === "uakt")?.amount || "0" + ); + }); + + const inflationAsPromised = await runOrLog(async () => { + const inflationQuery = await axios.get( + `${apiNodeUrl}/cosmos/mint/v1beta1/inflation` + ); + return parseFloat(inflationQuery.data.inflation || "0"); + }); + + const communityTaxAsPromised = await runOrLog(async () => { + const distributionQuery = await axios.get( + `${apiNodeUrl}/cosmos/distribution/v1beta1/params` + ); + return parseFloat(distributionQuery.data.params.community_tax || "0"); + }); + + const [bondedTokens, totalSupply, communityPool, inflation, communityTax] = await Promise.all([ + bondedTokensAsPromised, + totalSupplyAsPromised, + communityPoolAsPromised, + inflationAsPromised, + communityTaxAsPromised ]); return { - communityPool: parseFloat(communityPoolResponse.data.pool.find(x => x.denom === "uakt").amount), - inflation: parseFloat(inflationResponse.data.inflation), - communityTax: parseFloat(distributionResponse.data.params.community_tax), - bondedTokens: parseInt(bondedTokensResponse.data.pool.bonded_tokens), - totalSupply: parseInt(supplyResponse.data.supply.find(x => x.denom === "uakt").amount) + communityPool, + inflation, + communityTax, + bondedTokens, + totalSupply, }; }, true ); + let stakingAPR: number | undefined; + if (result.bondedTokens && result.bondedTokens > 0 && result.inflation && result.communityTax && result.totalSupply) { + stakingAPR = result.inflation * (1 - result.communityTax) * result.totalSupply / result.bondedTokens + } + return { bondedTokens: result.bondedTokens, totalSupply: result.totalSupply, communityPool: result.communityPool, inflation: result.inflation, - stakingAPR: (result.inflation * (1 - result.communityTax)) / (result.bondedTokens / result.totalSupply) + stakingAPR, }; } diff --git a/apps/api/src/utils/logging.ts b/apps/api/src/utils/logging.ts new file mode 100644 index 000000000..7ccef6e91 --- /dev/null +++ b/apps/api/src/utils/logging.ts @@ -0,0 +1,12 @@ +import { getSentry } from "@src/core/providers/sentry.provider"; +import { LoggerService } from "@src/core/services/logger/logger.service"; + +export const createLoggingExecutor = (logger: LoggerService) => async (cb: () => Promise, defaultValue?: T): Promise => { + try { + return await cb(); + } catch (error) { + logger.error({ event: `Failed to fetch ${cb.name}`, error }); + getSentry().captureException(error); + return defaultValue; + } +} \ No newline at end of file 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..9d374e93d 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 && } {!!dashboardData?.now?.date && }