22
33import { useQuery } from "@tanstack/react-query" ;
44import { CircleCheckIcon , XIcon } from "lucide-react" ;
5+ import { Badge } from "@/components/ui/badge" ;
56import { CopyTextButton } from "@/components/ui/CopyTextButton" ;
67import { Skeleton } from "@/components/ui/skeleton" ;
78import { ToolTipLabel } from "@/components/ui/tooltip" ;
@@ -43,9 +44,7 @@ function useChainStatswithRPC(_rpcUrl: string) {
4344 const latency = ( performance . now ( ) - startTimeStamp ) . toFixed ( 0 ) ;
4445
4546 const blockNumber = Number . parseInt ( json . result . number , 16 ) ;
46- const blockGasLimit = Number . parseInt ( json . result . gasLimit , 16 ) ;
4747 return {
48- blockGasLimit,
4948 blockNumber,
5049 latency,
5150 } ;
@@ -61,8 +60,70 @@ function useChainStatswithRPC(_rpcUrl: string) {
6160 } ) ;
6261}
6362
63+ function useEIP7702Support ( _rpcUrl : string ) {
64+ let rpcUrl = _rpcUrl . replace (
65+ // eslint-disable-next-line no-template-curly-in-string
66+ // biome-ignore lint/suspicious/noTemplateCurlyInString: this is expected in this case
67+ "${THIRDWEB_API_KEY}" ,
68+ NEXT_PUBLIC_DASHBOARD_CLIENT_ID ,
69+ ) ;
70+
71+ // based on the environment hit dev or production
72+ if ( hostnameEndsWith ( rpcUrl , "rpc.thirdweb.com" ) ) {
73+ if ( ! isProd ) {
74+ rpcUrl = rpcUrl . replace ( "rpc.thirdweb.com" , "rpc.thirdweb-dev.com" ) ;
75+ }
76+ }
77+
78+ return useQuery ( {
79+ enabled : ! ! rpcUrl ,
80+ queryFn : async ( ) => {
81+ try {
82+ const res = await fetch ( rpcUrl , {
83+ body : JSON . stringify ( {
84+ id : 1 ,
85+ jsonrpc : "2.0" ,
86+ method : "eth_estimateGas" ,
87+ params : [
88+ {
89+ from : "0xdeadbeef00000000000000000000000000000000" ,
90+ to : "0xdeadbeef00000000000000000000000000000000" ,
91+ data : "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" ,
92+ value : "0x0"
93+ } ,
94+ "latest" ,
95+ {
96+ "0xdeadbeef00000000000000000000000000000000" : {
97+ code : "0xef01000000000000000000000000000000000000000001"
98+ }
99+ }
100+ ] ,
101+ } ) ,
102+ method : "POST" ,
103+ } ) ;
104+
105+ const json = await res . json ( ) ;
106+
107+ // If the response has a valid result object, EIP-7702 is enabled
108+ return {
109+ isSupported : ! ! json . result ,
110+ } ;
111+ } catch {
112+ // If the request fails or errors, EIP-7702 is not supported
113+ return {
114+ isSupported : false ,
115+ } ;
116+ }
117+ } ,
118+ queryKey : [ "eip-7702-support" , { rpcUrl } ] ,
119+ refetchInterval : false , // Don't refetch this as it's unlikely to change
120+ refetchOnWindowFocus : false ,
121+ } ) ;
122+ }
123+
64124export function ChainLiveStats ( props : { rpc : string } ) {
65125 const stats = useChainStatswithRPC ( props . rpc ) ;
126+ const eip7702Support = useEIP7702Support ( props . rpc ) ;
66127
67128 return (
68129 < >
@@ -120,16 +181,16 @@ export function ChainLiveStats(props: { rpc: string }) {
120181 ) }
121182 </ PrimaryInfoItem >
122183
123- { /* Block Gas Limit */ }
124- < PrimaryInfoItem title = "Block Gas Limit" titleIcon = { < PulseDot /> } >
125- { stats . isError ? (
126- < p className = "fade-in-0 animate-in text- destructive-text" > N/A </ p >
127- ) : stats . data ? (
128- < p className = "fade-in-0 animate-in" >
129- { stats . data . blockGasLimit ?? "N/A "}
130- </ p >
184+ { /* EIP-7702 Support */ }
185+ < PrimaryInfoItem title = "EIP-7702 Support" >
186+ { eip7702Support . isError ? (
187+ < Badge variant = " destructive" > Disabled </ Badge >
188+ ) : eip7702Support . data ? (
189+ < Badge variant = { eip7702Support . data . isSupported ? "success" : "destructive" } >
190+ { eip7702Support . data . isSupported ? "Enabled" : "Disabled "}
191+ </ Badge >
131192 ) : (
132- < div className = "flex h-[28px] w-[140px ] py-1" >
193+ < div className = "flex h-[28px] w-[80px ] py-1" >
133194 < Skeleton className = "h-full w-full" />
134195 </ div >
135196 ) }
0 commit comments