11"use client" ;
22
3- import { CommandIcon , CornerDownLeft , LoaderIcon , PauseIcon , PlayIcon } from "lucide-react" ;
3+ import { ClockIcon , CommandIcon , CornerDownLeft , LoaderIcon , PauseIcon , PlayIcon } from "lucide-react" ;
44import { KeyCode , KeyMod , editor } from "monaco-editor/esm/vs/editor/editor.api" ;
5+ import { useQueryState } from "nuqs" ;
6+ import { useConfig } from "wagmi" ;
7+ import { getBlock } from "wagmi/actions" ;
58import { useEffect , useRef , useState } from "react" ;
69import { useForm } from "react-hook-form" ;
710import { Table } from "@latticexyz/config" ;
811import Editor from "@monaco-editor/react" ;
912import { Tooltip } from "../../../../../../components/Tooltip" ;
1013import { Button } from "../../../../../../components/ui/Button" ;
1114import { Form , FormField } from "../../../../../../components/ui/Form" ;
15+ import { Input } from "../../../../../../components/ui/Input" ;
1216import { cn } from "../../../../../../utils" ;
17+ import { useChain } from "../../../../hooks/useChain" ;
1318import { useTableDataQuery } from "../../../../queries/useTableDataQuery" ;
1419import { PAGE_SIZE_OPTIONS , monacoOptions } from "./consts" ;
1520import { usePaginationState } from "./hooks/usePaginationState" ;
@@ -31,6 +36,12 @@ export function SQLEditor({ table, isLiveQuery, setIsLiveQuery }: Props) {
3136 const [ isUserTriggeredRefetch , setIsUserTriggeredRefetch ] = useState ( false ) ;
3237 const [ pagination , setPagination ] = usePaginationState ( ) ;
3338 const [ query , setQuery ] = useSQLQueryState ( ) ;
39+ const [ blockHeight , setBlockHeight ] = useQueryState ( "blockHeight" ) ;
40+ const [ blockTimestamp , setBlockTimestamp ] = useState < number | null > ( null ) ;
41+ const [ isLoadingBlock , setIsLoadingBlock ] = useState ( false ) ;
42+
43+ const wagmiConfig = useConfig ( ) ;
44+ const { id : chainId } = useChain ( ) ;
3445
3546 const validateQuery = useQueryValidator ( table ) ;
3647 const { data : tableData , refetch, isRefetching : isTableDataRefetching } = useTableDataQuery ( { table, isLiveQuery } ) ;
@@ -76,6 +87,32 @@ export function SQLEditor({ table, isLiveQuery, setIsLiveQuery }: Props) {
7687 form . reset ( { query } ) ;
7788 } , [ query , form ] ) ;
7889
90+ // Fetch block timestamp when blockHeight changes
91+ useEffect ( ( ) => {
92+ const fetchBlockTimestamp = async ( ) => {
93+ if ( ! blockHeight || ! wagmiConfig || ! chainId ) {
94+ setBlockTimestamp ( null ) ;
95+ return ;
96+ }
97+
98+ setIsLoadingBlock ( true ) ;
99+ try {
100+ const block = await getBlock ( wagmiConfig , {
101+ chainId,
102+ blockNumber : BigInt ( blockHeight ) ,
103+ } ) ;
104+ setBlockTimestamp ( Number ( block . timestamp ) ) ;
105+ } catch ( error ) {
106+ console . error ( "Failed to fetch block timestamp:" , error ) ;
107+ setBlockTimestamp ( null ) ;
108+ } finally {
109+ setIsLoadingBlock ( false ) ;
110+ }
111+ } ;
112+
113+ fetchBlockTimestamp ( ) ;
114+ } , [ blockHeight , wagmiConfig , chainId ] ) ;
115+
79116 const updateHeight = ( ) => {
80117 if ( editorRef . current ) {
81118 const contentHeight = Math . min ( 200 , editorRef . current . getContentHeight ( ) ) ;
@@ -182,6 +219,29 @@ export function SQLEditor({ table, isLiveQuery, setIsLiveQuery }: Props) {
182219 </ >
183220 ) : null }
184221
222+ < Input
223+ type = "number"
224+ step = "1000"
225+ className = "w-[120px]"
226+ value = { blockHeight ?? "" }
227+ onChange = { ( e ) => setBlockHeight ( e . target . value ) }
228+ />
229+
230+ { blockHeight && (
231+ < div className = "flex items-center gap-2 text-xs text-white/60" >
232+ < ClockIcon className = "h-3 w-3" />
233+ { isLoadingBlock ? (
234+ < span > Loading...</ span >
235+ ) : blockTimestamp ? (
236+ < Tooltip text = { new Date ( blockTimestamp * 1000 ) . toISOString ( ) } >
237+ < span > { new Date ( blockTimestamp * 1000 ) . toLocaleString ( ) } </ span >
238+ </ Tooltip >
239+ ) : (
240+ < span > Invalid block</ span >
241+ ) }
242+ </ div >
243+ ) }
244+
185245 < Button className = "group relative flex gap-2 pl-4 pr-3" type = "submit" disabled = { isRefetching } >
186246 Run
187247 < span className = "relative flex items-center gap-0.5 text-white/60" >
0 commit comments