Files
explorer-monorepo/frontend/src/pages/index.tsx

104 lines
4.2 KiB
TypeScript

import type { GetServerSideProps } from 'next'
import HomePage from '@/components/home/HomePage'
import { normalizeBlock } from '@/services/api/blockscout'
import {
normalizeExplorerStats,
normalizeTransactionTrend,
summarizeRecentTransactions,
type ExplorerRecentActivitySnapshot,
type ExplorerStats,
type ExplorerTransactionTrendPoint,
} from '@/services/api/stats'
import {
summarizeMissionControlRelay,
type MissionControlBridgeStatusResponse,
type MissionControlRelaySummary,
} from '@/services/api/missionControl'
import type { Block } from '@/services/api/blocks'
import type { Transaction } from '@/services/api/transactions'
import { fetchPublicJson } from '@/utils/publicExplorer'
import { normalizeTransaction } from '@/services/api/blockscout'
interface IndexPageProps {
initialStats: ExplorerStats | null
initialRecentBlocks: Block[]
initialRecentTransactions: Transaction[]
initialTransactionTrend: ExplorerTransactionTrendPoint[]
initialActivitySnapshot: ExplorerRecentActivitySnapshot | null
initialBridgeStatus: MissionControlBridgeStatusResponse | null
initialRelaySummary: MissionControlRelaySummary | null
}
export default function IndexPage(props: IndexPageProps) {
return <HomePage {...props} />
}
function serializeTransactions(transactions: Transaction[]): Transaction[] {
return JSON.parse(
JSON.stringify(
transactions.map((transaction) => ({
hash: transaction.hash,
block_number: transaction.block_number,
from_address: transaction.from_address,
to_address: transaction.to_address ?? null,
value: transaction.value,
status: transaction.status ?? null,
contract_address: transaction.contract_address ?? null,
fee: transaction.fee ?? null,
created_at: transaction.created_at,
})),
),
) as Transaction[]
}
export const getServerSideProps: GetServerSideProps<IndexPageProps> = async () => {
const chainId = Number(process.env.NEXT_PUBLIC_CHAIN_ID || '138')
const [statsResult, blocksResult, transactionsResult, trendResult, activityResult, bridgeResult] = await Promise.allSettled([
fetchPublicJson<{
total_blocks?: number | string | null
total_transactions?: number | string | null
total_addresses?: number | string | null
latest_block?: number | string | null
}>('/api/v2/stats'),
fetchPublicJson<{ items?: unknown[] }>('/api/v2/blocks?page=1&page_size=10'),
fetchPublicJson<{ items?: unknown[] }>('/api/v2/transactions?page=1&page_size=5'),
fetchPublicJson<{ chart_data?: Array<{ date?: string | null; transaction_count?: number | string | null }> }>(
'/api/v2/stats/charts/transactions'
),
fetchPublicJson<
Array<{
status?: string | null
transaction_types?: string[] | null
gas_used?: number | string | null
fee?: { value?: string | number | null } | string | null
}>
>('/api/v2/main-page/transactions'),
fetchPublicJson('/explorer-api/v1/track1/bridge/status'),
])
return {
props: {
initialStats: statsResult.status === 'fulfilled' ? normalizeExplorerStats(statsResult.value) : null,
initialRecentBlocks:
blocksResult.status === 'fulfilled' && Array.isArray(blocksResult.value?.items)
? blocksResult.value.items.map((item) => normalizeBlock(item as never, chainId))
: [],
initialRecentTransactions:
transactionsResult.status === 'fulfilled' && Array.isArray(transactionsResult.value?.items)
? serializeTransactions(
transactionsResult.value.items.map((item) => normalizeTransaction(item as never, chainId)),
)
: [],
initialTransactionTrend:
trendResult.status === 'fulfilled' ? normalizeTransactionTrend(trendResult.value) : [],
initialActivitySnapshot:
activityResult.status === 'fulfilled' ? summarizeRecentTransactions(activityResult.value) : null,
initialBridgeStatus:
bridgeResult.status === 'fulfilled' ? (bridgeResult.value as MissionControlBridgeStatusResponse) : null,
initialRelaySummary:
bridgeResult.status === 'fulfilled' ? summarizeMissionControlRelay(bridgeResult.value as never) : null,
},
}
}