import { useEffect, useRef, useState } from "react"; import TooltipInfo from "../TooltipInfo"; import { usePublicClient } from "wagmi"; import { useScaffoldReadContract } from "~~/hooks/scaffold-eth"; export const BucketCountdown = () => { const publicClient = usePublicClient(); const { data: bucketWindow } = useScaffoldReadContract({ contractName: "StakingOracle", functionName: "BUCKET_WINDOW", }) as { data: bigint | undefined }; const [remainingSec, setRemainingSec] = useState(null); const [currentBucketNum, setCurrentBucketNum] = useState(null); const lastBucketCheckTime = useRef(0); // Poll getCurrentBucketNumber every second for accuracy const { data: contractBucketNum } = useScaffoldReadContract({ contractName: "StakingOracle", functionName: "getCurrentBucketNumber", watch: true, }) as { data: bigint | undefined }; useEffect(() => { if (contractBucketNum !== undefined) { setCurrentBucketNum(contractBucketNum); lastBucketCheckTime.current = Date.now(); } }, [contractBucketNum]); useEffect(() => { if (!bucketWindow || !publicClient || !currentBucketNum) return; let mounted = true; const update = async () => { try { const block = await publicClient.getBlock(); const blockNum = Number(block.number); const w = Number(bucketWindow); if (w <= 0) { setRemainingSec(null); return; } // Calculate blocks remaining in current bucket // Bucket number = (block.number / BUCKET_WINDOW) + 1 // So current bucket started at: (currentBucketNum - 1) * BUCKET_WINDOW const bucketStartBlock = (Number(currentBucketNum) - 1) * w; const nextBucketBlock = bucketStartBlock + w; const blocksRemaining = nextBucketBlock - blockNum; // Add 2 second offset since node is ahead of system time const estimatedSecondsRemaining = Math.max(0, blocksRemaining + 2); if (mounted) setRemainingSec(estimatedSecondsRemaining > 24 ? 24 : estimatedSecondsRemaining); // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (e) { // ignore } }; update(); const id = setInterval(update, 1000); return () => { mounted = false; clearInterval(id); }; }, [bucketWindow, publicClient, currentBucketNum]); return (

Bucket Countdown

Bucket #{currentBucketNum?.toString() ?? "..."}
{remainingSec !== null ? `${remainingSec}s` : "..."}
until next bucket
); };