diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/live-stats.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/live-stats.tsx index 7199c3145ff..ef969f1f6aa 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/live-stats.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/live-stats.tsx @@ -43,9 +43,7 @@ function useChainStatswithRPC(_rpcUrl: string) { const latency = (performance.now() - startTimeStamp).toFixed(0); const blockNumber = Number.parseInt(json.result.number, 16); - const blockGasLimit = Number.parseInt(json.result.gasLimit, 16); return { - blockGasLimit, blockNumber, latency, }; @@ -61,8 +59,70 @@ function useChainStatswithRPC(_rpcUrl: string) { }); } +function useEIP7702Support(_rpcUrl: string) { + let rpcUrl = _rpcUrl.replace( + // eslint-disable-next-line no-template-curly-in-string + // biome-ignore lint/suspicious/noTemplateCurlyInString: this is expected in this case + "${THIRDWEB_API_KEY}", + NEXT_PUBLIC_DASHBOARD_CLIENT_ID, + ); + + // based on the environment hit dev or production + if (hostnameEndsWith(rpcUrl, "rpc.thirdweb.com")) { + if (!isProd) { + rpcUrl = rpcUrl.replace("rpc.thirdweb.com", "rpc.thirdweb-dev.com"); + } + } + + return useQuery({ + enabled: !!rpcUrl, + queryFn: async () => { + try { + const res = await fetch(rpcUrl, { + body: JSON.stringify({ + id: 1, + jsonrpc: "2.0", + method: "eth_estimateGas", + params: [ + { + from: "0xdeadbeef00000000000000000000000000000000", + to: "0xdeadbeef00000000000000000000000000000000", + data: "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + value: "0x0", + }, + "latest", + { + "0xdeadbeef00000000000000000000000000000000": { + code: "0xef01000000000000000000000000000000000000000001", + }, + }, + ], + }), + method: "POST", + }); + + const json = await res.json(); + + // If the response has a valid result object, EIP-7702 is enabled + return { + isSupported: !!json.result, + }; + } catch { + // If the request fails or errors, EIP-7702 is not supported + return { + isSupported: false, + }; + } + }, + queryKey: ["eip-7702-support", { rpcUrl }], + refetchInterval: false, // Don't refetch this as it's unlikely to change + refetchOnWindowFocus: false, + }); +} + export function ChainLiveStats(props: { rpc: string }) { const stats = useChainStatswithRPC(props.rpc); + const eip7702Support = useEIP7702Support(props.rpc); return ( <> @@ -107,8 +167,8 @@ export function ChainLiveStats(props: { rpc: string }) { )} - {/* Block Height */} - }> + {/* Latest Block */} + }> {stats.isError ? (

N/A

) : stats.data ? ( @@ -120,16 +180,37 @@ export function ChainLiveStats(props: { rpc: string }) { )}
- {/* Block Gas Limit */} - }> - {stats.isError ? ( -

N/A

- ) : stats.data ? ( -

- {stats.data.blockGasLimit ?? "N/A"} -

+ {/* EIP-7702 */} + + + + ) : ( + + + + ) + ) : eip7702Support.isError ? ( + + + + ) : null + } + > + {eip7702Support.data ? ( + eip7702Support.data.isSupported ? ( + "Enabled" + ) : ( + "Disabled" + ) + ) : eip7702Support.isError ? ( + "Disabled" ) : ( -
+
)}