import { MaintenanceBanner } from './components/MaintenanceBanner' import { MaintenanceWarningMessage } from './components/MaintenanceWarningMessage' import { useEventCountdownProgressBar } from './components/EventCountdownProgressBar' import { useBridgeState } from '@/slices/bridge/hooks' import { useSwapState } from '@/slices/swap/hooks' import { useMaintenanceState } from '@/slices/maintenance/hooks' import { isChainIncluded } from '@/utils/isChainIncluded' import { BridgeModuleName, isValidBridgeModule, } from './functions/isValidBridgeModule' import { getFurthestFutureDate } from './functions/getFurthestFutureDate' import { useTranslations } from 'next-intl' interface ChainPause { id: string pausedFromChains: number[] pausedToChains: number[] pauseBridge: boolean pauseSwap: boolean startTimePauseChain: Date endTimePauseChain: Date | null // If null, pause chain indefinitely. startTimeBanner: Date endTimeBanner: Date | null // If null, persist banner indefinitely. inputWarningMessage: string bannerMessage: JSX.Element progressBarMessage: string disableBanner: boolean disableWarning: boolean disableCountdown: boolean } export interface BridgeModulePause { chainId?: number // Origin chain ID. If undefined, match any origin chain. toChainId?: number // Destination chain ID. If undefined, match any destination chain. bridgeModuleName: BridgeModuleName } const useMaintenanceData = () => { const { pausedChainsData, pausedModulesData } = useMaintenanceState() const pausedChainsList: ChainPause[] = pausedChainsData ? pausedChainsData?.map((pause: ChainPause) => { return { ...pause, startTimeBanner: new Date(pause.startTimeBanner), endTimeBanner: pause.endTimeBanner ? new Date(pause.endTimeBanner) : null, startTimePauseChain: new Date(pause.startTimePauseChain), endTimePauseChain: pause.endTimePauseChain ? new Date(pause.endTimePauseChain) : null, bannerMessage:

{pause.bannerMessage}

, inputWarningMessage: pause.inputWarningMessage, progressBarMessage: pause.progressBarMessage, } }) : [] const pausedModulesList: BridgeModulePause[] = pausedModulesData ? pausedModulesData?.map((route: BridgeModulePause) => { if (!isValidBridgeModule(route.bridgeModuleName)) { throw new Error(`Invalid module type: ${route.bridgeModuleName}`) } return { ...route, } }) : [] return { pausedChainsList, pausedModulesList, } } export const MaintenanceBanners = () => { const { pausedChainsList, pausedModulesList } = useMaintenanceData() const { fromChainId: bridgeFromChainId, toChainId: bridgeToChainId } = useBridgeState() const { swapChainId } = useSwapState() const t = useTranslations('Bridge') const activeBanner = pausedChainsList.find( (pausedChain) => isChainIncluded(pausedChain?.pausedFromChains, [bridgeFromChainId]) || isChainIncluded(pausedChain?.pausedToChains, [bridgeToChainId]) || isChainIncluded(pausedChain?.pausedFromChains, [swapChainId]) || isChainIncluded(pausedChain?.pausedToChains, [swapChainId]) ) const isGlobalBridgeModulePause = pausedModulesList.some( (module) => !module.chainId && module.bridgeModuleName === 'ALL' ) if (activeBanner || isGlobalBridgeModulePause) { return ( <> {activeBanner ? ( ) : null} {isGlobalBridgeModulePause ? (
{t('Bridge paused')}

} startDate={new Date('2020-01-01T00:00:00Z')} endDate={null} />
) : null} ) } } export const useMaintenance = () => { const { pausedChainsList, pausedModulesList } = useMaintenanceData() const { fromChainId: bridgeFromChainId, toChainId: bridgeToChainId } = useBridgeState() const { swapChainId } = useSwapState() const activeBridgePause = pausedChainsList .filter( (pausedChain) => isChainIncluded(pausedChain?.pausedFromChains, [bridgeFromChainId]) || isChainIncluded(pausedChain?.pausedToChains, [bridgeToChainId]) ) .reduce((furthestPauseChain, currentChain) => { const furthestDate = furthestPauseChain?.endTimePauseChain ?? null const currentDate = currentChain.endTimePauseChain ?? null const furthestFutureDate = getFurthestFutureDate( furthestDate, currentDate ) if (!furthestDate) return currentChain return furthestFutureDate === furthestDate ? furthestPauseChain : currentChain }, null) const activeSwapPause = pausedChainsList.find( (pausedChain) => isChainIncluded(pausedChain?.pausedFromChains, [swapChainId]) || isChainIncluded(pausedChain?.pausedToChains, [swapChainId]) ) const { isPending: isBridgePaused, EventCountdownProgressBar: BridgeEventCountdownProgressBar, } = useEventCountdownProgressBar( activeBridgePause?.progressBarMessage, activeBridgePause?.startTimePauseChain, activeBridgePause?.endTimePauseChain, activeBridgePause?.disableCountdown ) const { isPending: isSwapPaused, EventCountdownProgressBar: SwapEventCountdownProgressBar, } = useEventCountdownProgressBar( activeSwapPause?.progressBarMessage, activeSwapPause?.startTimePauseChain, activeSwapPause?.endTimePauseChain, activeSwapPause?.disableCountdown ) const BridgeMaintenanceProgressBar = () => BridgeEventCountdownProgressBar const SwapMaintenanceProgressBar = () => SwapEventCountdownProgressBar const BridgeMaintenanceWarningMessage = () => ( ) const SwapMaintenanceWarningMessage = () => ( ) return { isBridgePaused, isSwapPaused, pausedChainsList, pausedModulesList, BridgeMaintenanceProgressBar, BridgeMaintenanceWarningMessage, SwapMaintenanceProgressBar, SwapMaintenanceWarningMessage, } }