import { useEffect, useState } from "react"; import { JsonRpcProvider, JsonRpcBatchProvider, WebSocketProvider, } from "@ethersproject/providers"; import { ConnectionStatus } from "./types"; import { MIN_API_LEVEL } from "./params"; export const DEFAULT_ERIGON_URL = "http://127.0.0.1:8545"; export const useProvider = ( erigonURL?: string ): [ConnectionStatus, JsonRpcProvider | undefined] => { const [connStatus, setConnStatus] = useState( ConnectionStatus.CONNECTING ); if (erigonURL !== undefined) { if (erigonURL === "") { console.info(`Using default erigon URL: ${DEFAULT_ERIGON_URL}`); erigonURL = DEFAULT_ERIGON_URL; } else { console.log(`Using configured erigon URL: ${erigonURL}`); } } const [provider, setProvider] = useState(); useEffect(() => { if (erigonURL === undefined) { setConnStatus(ConnectionStatus.NOT_ETH_NODE); setProvider(undefined); return; } setConnStatus(ConnectionStatus.CONNECTING); const tryToConnect = async () => { let provider: JsonRpcProvider; if (erigonURL?.startsWith("ws://") || erigonURL?.startsWith("wss://")) { provider = new WebSocketProvider(erigonURL); } else { provider = new JsonRpcBatchProvider(erigonURL); } // Check if it is at least a regular ETH node let blockNumber: number = 0; try { blockNumber = await provider.getBlockNumber(); } catch (err) { console.log(err); setConnStatus(ConnectionStatus.NOT_ETH_NODE); setProvider(undefined); return; } // Check if it is an Erigon node by probing a lightweight method try { await provider.send("erigon_getHeaderByNumber", [blockNumber]); } catch (err) { console.log(err); setConnStatus(ConnectionStatus.NOT_ERIGON); setProvider(undefined); return; } // Check if it has Otterscan patches by probing a lightweight method try { const level = await provider.send("ots_getApiLevel", []); if (level < MIN_API_LEVEL) { setConnStatus(ConnectionStatus.NOT_OTTERSCAN_PATCHED); setProvider(undefined); } else { setConnStatus(ConnectionStatus.CONNECTED); setProvider(provider); } } catch (err) { console.log(err); setConnStatus(ConnectionStatus.NOT_OTTERSCAN_PATCHED); setProvider(undefined); } }; tryToConnect(); }, [erigonURL]); return [connStatus, provider]; };