Commit 63978266 authored by Igor Stuev's avatar Igor Stuev Committed by GitHub

Support op stack operational transactions (#2743)

parent 982752aa
......@@ -63,3 +63,5 @@ NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED=true
NEXT_PUBLIC_VIEWS_TOKEN_SCAM_TOGGLE_ENABLED=true
NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com
NEXT_PUBLIC_XSTAR_SCORE_URL=https://docs.xname.app/the-solution-adaptive-proof-of-humanity-on-blockchain/xhs-scoring-algorithm?utm_source=blockscout&utm_medium=address
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_operational_txs']
NEXT_PUBLIC_HOMEPAGE_STATS=['latest_batch','average_block_time','total_operational_txs','wallet_addresses','gas_tracker']
\ No newline at end of file
......@@ -75,3 +75,5 @@ NEXT_PUBLIC_VIEWS_TOKEN_SCAM_TOGGLE_ENABLED=true
NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com
NEXT_PUBLIC_WEB3_WALLETS=['token_pocket', 'metamask']
NEXT_PUBLIC_XSTAR_SCORE_URL=https://docs.xname.app/the-solution-adaptive-proof-of-humanity-on-blockchain/xhs-scoring-algorithm?utm_source=blockscout&utm_medium=address
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_operational_txs']
NEXT_PUBLIC_HOMEPAGE_STATS=['latest_batch','average_block_time','total_operational_txs','wallet_addresses','gas_tracker']
\ No newline at end of file
......@@ -44,8 +44,8 @@
"dependencies": {
"@blockscout/bens-types": "1.4.1",
"@blockscout/points-types": "1.3.0-alpha.2",
"@blockscout/stats-types": "2.5.0-alpha",
"@blockscout/tac-operation-lifecycle-types": "0.0.1-alpha.6",
"@blockscout/stats-types": "^2.9.0",
"@blockscout/visualizer-types": "0.2.0",
"@chakra-ui/react": "3.15.0",
"@cloudnouns/kit": "1.1.6",
......@@ -191,5 +191,6 @@
"resolutions": {
"@types/react": "18.3.12",
"@types/react-dom": "18.3.1"
}
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}
......@@ -15,6 +15,8 @@ import type { Props as StatsWidgetProps } from 'ui/shared/stats/StatsWidget';
import StatsWidget from 'ui/shared/stats/StatsWidget';
const rollupFeature = config.features.rollup;
const isOptimisticRollup = rollupFeature.isEnabled && rollupFeature.type === 'optimistic';
const isArbitrumRollup = rollupFeature.isEnabled && rollupFeature.type === 'arbitrum';
const isStatsFeatureEnabled = config.features.stats.isEnabled;
const Stats = () => {
......@@ -150,7 +152,7 @@ const Stats = () => {
href: { pathname: '/txs' as const },
isLoading,
},
statsData?.total_operational_transactions?.value && {
(isArbitrumRollup && statsData?.total_operational_transactions?.value) && {
id: 'total_operational_txs' as const,
icon: 'transactions_slim' as const,
label: statsData?.total_operational_transactions?.title || 'Total operational transactions',
......@@ -158,6 +160,14 @@ const Stats = () => {
href: { pathname: '/txs' as const },
isLoading,
},
(isOptimisticRollup && statsData?.op_stack_total_operational_transactions?.value) && {
id: 'total_operational_txs' as const,
icon: 'transactions_slim' as const,
label: statsData?.op_stack_total_operational_transactions?.title || 'Total operational transactions',
value: Number(statsData?.op_stack_total_operational_transactions?.value).toLocaleString(),
href: { pathname: '/txs' as const },
isLoading,
},
apiData?.last_output_root_size && {
id: 'latest_l1_state_batch' as const,
icon: 'txn_batches_slim' as const,
......
......@@ -6,6 +6,10 @@ import useApiQuery from 'lib/api/useApiQuery';
import prepareChartItems from './utils/prepareChartItems';
const rollupFeature = config.features.rollup;
const isOptimisticRollup = rollupFeature.isEnabled && rollupFeature.type === 'optimistic';
const isArbitrumRollup = rollupFeature.isEnabled && rollupFeature.type === 'arbitrum';
const CHART_ITEMS: Record<ChainIndicatorId, Pick<TimeChartDataItem, 'name' | 'valueFormatter'>> = {
daily_txs: {
name: 'Tx/day',
......@@ -62,7 +66,14 @@ export default function useChartDataQuery(indicatorId: ChainIndicatorId): UseFet
queryOptions: {
refetchOnMount: false,
enabled: isStatsFeatureEnabled && indicatorId === 'daily_operational_txs',
select: (data) => data.daily_new_operational_transactions?.chart.map((item) => ({ date: new Date(item.date), value: Number(item.value) })) || [],
select: (data) => {
if (isArbitrumRollup) {
return data.daily_new_operational_transactions?.chart.map((item) => ({ date: new Date(item.date), value: Number(item.value) })) || [];
} else if (isOptimisticRollup) {
return data.op_stack_daily_new_operational_transactions?.chart.map((item) => ({ date: new Date(item.date), value: Number(item.value) })) || [];
}
return [];
},
},
});
......
......@@ -6,6 +6,10 @@ import config from 'configs/app';
import IconSvg from 'ui/shared/IconSvg';
import NativeTokenIcon from 'ui/shared/NativeTokenIcon';
const rollupFeature = config.features.rollup;
const isOptimisticRollup = rollupFeature.isEnabled && rollupFeature.type === 'optimistic';
const isArbitrumRollup = rollupFeature.isEnabled && rollupFeature.type === 'arbitrum';
const INDICATORS: Array<TChainIndicator> = [
{
id: 'daily_txs',
......@@ -24,11 +28,27 @@ const INDICATORS: Array<TChainIndicator> = [
{
id: 'daily_operational_txs',
title: 'Daily op txns',
titleMicroservice: (stats) => stats.daily_new_operational_transactions?.info?.title,
titleMicroservice: (stats) => {
if (isArbitrumRollup) {
return stats.daily_new_operational_transactions?.info?.title;
} else if (isOptimisticRollup) {
return stats.op_stack_daily_new_operational_transactions?.info?.title;
}
return '';
},
value: () => 'N/A',
valueMicroservice: (stats) => stats.yesterday_operational_transactions?.value === null ?
valueMicroservice: (stats) => {
if (isArbitrumRollup) {
return stats.yesterday_operational_transactions?.value === null ?
'N/A' :
Number(stats.yesterday_operational_transactions?.value).toLocaleString(undefined, { maximumFractionDigits: 2, notation: 'compact' }),
Number(stats.yesterday_operational_transactions?.value).toLocaleString(undefined, { maximumFractionDigits: 2, notation: 'compact' });
} else if (isOptimisticRollup) {
return stats.op_stack_yesterday_operational_transactions?.value === null ?
'N/A' :
Number(stats.op_stack_yesterday_operational_transactions?.value).toLocaleString(undefined, { maximumFractionDigits: 2, notation: 'compact' });
}
return;
},
icon: <IconSvg name="transactions" boxSize={ 6 } bgColor="#56ACD1" borderRadius="base" color="white"/>,
hint: `Number of operational transactions yesterday (0:00 - 23:59 UTC). The chart displays daily operational transactions for the past 30 days.`,
hintMicroservice: (stats) => stats.daily_new_operational_transactions?.info?.description,
......
......@@ -10,6 +10,9 @@ import { thinsp } from 'toolkit/utils/htmlEntities';
import StatsWidget from 'ui/shared/stats/StatsWidget';
const isStatsFeatureEnabled = config.features.stats.isEnabled;
const rollupFeature = config.features.rollup;
const isOptimisticRollup = rollupFeature.isEnabled && rollupFeature.type === 'optimistic';
const isArbitrumRollup = rollupFeature.isEnabled && rollupFeature.type === 'arbitrum';
const TxsStats = () => {
const txsStatsQuery = useApiQuery('stats:pages_transactions', {
......@@ -39,7 +42,8 @@ const TxsStats = () => {
const isLoading = isStatsFeatureEnabled ? txsStatsQuery.isPlaceholderData : txsStatsApiQuery.isPlaceholderData;
const txCount24h = isStatsFeatureEnabled ? txsStatsQuery.data?.transactions_24h?.value : txsStatsApiQuery.data?.transactions_count_24h;
const operationalTxns24h = isStatsFeatureEnabled ? txsStatsQuery.data?.operational_transactions_24h?.value : null;
const operationalTxns24hArbitrum = isArbitrumRollup && isStatsFeatureEnabled ? txsStatsQuery.data?.operational_transactions_24h?.value : null;
const operationalTxns24hOptimistic = isOptimisticRollup && isStatsFeatureEnabled ? txsStatsQuery.data?.op_stack_operational_transactions_24h?.value : null;
const pendingTxns = isStatsFeatureEnabled ? txsStatsQuery.data?.pending_transactions_30m?.value : txsStatsApiQuery.data?.pending_transactions_count;
......@@ -60,7 +64,8 @@ const TxsStats = () => {
const itemsCount = [
txCount24h,
operationalTxns24h,
operationalTxns24hArbitrum,
operationalTxns24hOptimistic,
pendingTxns,
txFeeSum24h,
txFeeAvg,
......@@ -85,12 +90,22 @@ const TxsStats = () => {
href={ config.features.stats.isEnabled ? { pathname: '/stats/[id]', query: { id: 'newTxns' } } : undefined }
/>
) }
{ operationalTxns24h && (
{ operationalTxns24hArbitrum && (
<StatsWidget
label={ txsStatsQuery.data?.operational_transactions_24h?.title ?
getLabelFromTitle(txsStatsQuery.data?.operational_transactions_24h?.title) :
'Daily op txns' }
value={ Number(operationalTxns24h).toLocaleString() }
value={ Number(operationalTxns24hArbitrum).toLocaleString() }
period="24h"
isLoading={ isLoading }
/>
) }
{ operationalTxns24hOptimistic && (
<StatsWidget
label={ txsStatsQuery.data?.op_stack_operational_transactions_24h?.title ?
getLabelFromTitle(txsStatsQuery.data?.op_stack_operational_transactions_24h?.title) :
'Daily op txns' }
value={ Number(operationalTxns24hOptimistic).toLocaleString() }
period="24h"
isLoading={ isLoading }
/>
......
......@@ -1573,10 +1573,10 @@
resolved "https://registry.yarnpkg.com/@blockscout/points-types/-/points-types-1.3.0-alpha.2.tgz#0308dcb4eef0dadf96f43b144835470e9f78f64f"
integrity sha512-tXCA51q3y08caCm7UhGyj+xsP0pd6yBhjElDHxEzM5SRop3culMiacaBXd0OPBszHjA0YdYgXFymuJhofB22ig==
"@blockscout/stats-types@2.5.0-alpha":
version "2.5.0-alpha"
resolved "https://registry.yarnpkg.com/@blockscout/stats-types/-/stats-types-2.5.0-alpha.tgz#e34698577a337ce08b176d8709f89f185d9d9359"
integrity sha512-B4IYeNt3pqIIJvcnkLIXm4LNN77VxTV1VYopJ8t6iFPT+JC3BSvRWSpMJMl7nV+WCLywcW27BKmYxdV9rR66bw==
"@blockscout/stats-types@^2.9.0":
version "2.9.0"
resolved "https://registry.yarnpkg.com/@blockscout/stats-types/-/stats-types-2.9.0.tgz#af8428ef7c89dbd2a74bc0d4bc2c3fd280ac5f20"
integrity sha512-/FIJAv/JyvHeG/gtFosNvunfRgts0BLggfliJKY84nuR0vWiXxD+FlyuvwPoHboC0QN/MkIkLId4BraCKReTUQ==
"@blockscout/tac-operation-lifecycle-types@0.0.1-alpha.6":
version "0.0.1-alpha.6"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment