@@ -43,9 +43,7 @@ function useChainStatswithRPC(_rpcUrl: string) {
4343 const latency = ( performance . now ( ) - startTimeStamp ) . toFixed ( 0 ) ;
4444
4545 const blockNumber = Number . parseInt ( json . result . number , 16 ) ;
46- const blockGasLimit = Number . parseInt ( json . result . gasLimit , 16 ) ;
4746 return {
48- blockGasLimit,
4947 blockNumber,
5048 latency,
5149 } ;
@@ -61,8 +59,70 @@ function useChainStatswithRPC(_rpcUrl: string) {
6159 } ) ;
6260}
6361
62+ function useEIP7702Support ( _rpcUrl : string ) {
63+ let rpcUrl = _rpcUrl . replace (
64+ // eslint-disable-next-line no-template-curly-in-string
65+ // biome-ignore lint/suspicious/noTemplateCurlyInString: this is expected in this case
66+ "${THIRDWEB_API_KEY}" ,
67+ NEXT_PUBLIC_DASHBOARD_CLIENT_ID ,
68+ ) ;
69+
70+ // based on the environment hit dev or production
71+ if ( hostnameEndsWith ( rpcUrl , "rpc.thirdweb.com" ) ) {
72+ if ( ! isProd ) {
73+ rpcUrl = rpcUrl . replace ( "rpc.thirdweb.com" , "rpc.thirdweb-dev.com" ) ;
74+ }
75+ }
76+
77+ return useQuery ( {
78+ enabled : ! ! rpcUrl ,
79+ queryFn : async ( ) => {
80+ try {
81+ const res = await fetch ( rpcUrl , {
82+ body : JSON . stringify ( {
83+ id : 1 ,
84+ jsonrpc : "2.0" ,
85+ method : "eth_estimateGas" ,
86+ params : [
87+ {
88+ from : "0xdeadbeef00000000000000000000000000000000" ,
89+ to : "0xdeadbeef00000000000000000000000000000000" ,
90+ data : "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" ,
91+ value : "0x0" ,
92+ } ,
93+ "latest" ,
94+ {
95+ "0xdeadbeef00000000000000000000000000000000" : {
96+ code : "0xef01000000000000000000000000000000000000000001" ,
97+ } ,
98+ } ,
99+ ] ,
100+ } ) ,
101+ method : "POST" ,
102+ } ) ;
103+
104+ const json = await res . json ( ) ;
105+
106+ // If the response has a valid result object, EIP-7702 is enabled
107+ return {
108+ isSupported : ! ! json . result ,
109+ } ;
110+ } catch {
111+ // If the request fails or errors, EIP-7702 is not supported
112+ return {
113+ isSupported : false ,
114+ } ;
115+ }
116+ } ,
117+ queryKey : [ "eip-7702-support" , { rpcUrl } ] ,
118+ refetchInterval : false , // Don't refetch this as it's unlikely to change
119+ refetchOnWindowFocus : false ,
120+ } ) ;
121+ }
122+
64123export function ChainLiveStats ( props : { rpc : string } ) {
65124 const stats = useChainStatswithRPC ( props . rpc ) ;
125+ const eip7702Support = useEIP7702Support ( props . rpc ) ;
66126
67127 return (
68128 < >
@@ -107,8 +167,8 @@ export function ChainLiveStats(props: { rpc: string }) {
107167 ) }
108168 </ PrimaryInfoItem >
109169
110- { /* Block Height */ }
111- < PrimaryInfoItem title = "Block Height " titleIcon = { < PulseDot /> } >
170+ { /* Latest Block */ }
171+ < PrimaryInfoItem title = "Latest Block " titleIcon = { < PulseDot /> } >
112172 { stats . isError ? (
113173 < p className = "fade-in-0 animate-in text-destructive-text" > N/A</ p >
114174 ) : stats . data ? (
@@ -120,16 +180,37 @@ export function ChainLiveStats(props: { rpc: string }) {
120180 ) }
121181 </ PrimaryInfoItem >
122182
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 >
183+ { /* EIP-7702 */ }
184+ < PrimaryInfoItem
185+ title = "EIP-7702"
186+ titleIcon = {
187+ eip7702Support . data ? (
188+ eip7702Support . data . isSupported ? (
189+ < ToolTipLabel label = "Enabled" >
190+ < CircleCheckIcon className = "size-4 text-success-text" />
191+ </ ToolTipLabel >
192+ ) : (
193+ < ToolTipLabel label = "Disabled" >
194+ < XIcon className = "size-4 text-destructive-text" />
195+ </ ToolTipLabel >
196+ )
197+ ) : eip7702Support . isError ? (
198+ < ToolTipLabel label = "Disabled" >
199+ < XIcon className = "size-4 text-destructive-text" />
200+ </ ToolTipLabel >
201+ ) : null
202+ }
203+ >
204+ { eip7702Support . data ? (
205+ eip7702Support . data . isSupported ? (
206+ "Enabled"
207+ ) : (
208+ "Disabled"
209+ )
210+ ) : eip7702Support . isError ? (
211+ "Disabled"
131212 ) : (
132- < div className = "flex h-[28px] w-[140px ] py-1" >
213+ < div className = "flex h-[28px] w-[80px ] py-1" >
133214 < Skeleton className = "h-full w-full" />
134215 </ div >
135216 ) }
0 commit comments