Parameterize erigon node url
This commit is contained in:
parent
3e58030a43
commit
da16ce8ad6
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"erigonURL": "http://localhost:8545"
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useState, useEffect, useMemo } from "react";
|
||||
import React, { useState, useEffect, useMemo, useContext } from "react";
|
||||
import { useParams, useLocation, useHistory } from "react-router-dom";
|
||||
import { ethers } from "ethers";
|
||||
import queryString from "query-string";
|
||||
|
@ -12,9 +12,9 @@ import ResultHeader from "./search/ResultHeader";
|
|||
import PendingResults from "./search/PendingResults";
|
||||
import TransactionItem from "./search/TransactionItem";
|
||||
import { SearchController } from "./search/search";
|
||||
import { ProviderContext } from "./useProvider";
|
||||
import { useENSCache } from "./useReverseCache";
|
||||
import { useFeeToggler } from "./search/useFeeToggler";
|
||||
import { provider } from "./ethersconfig";
|
||||
|
||||
type BlockParams = {
|
||||
addressOrName: string;
|
||||
|
@ -26,6 +26,7 @@ type PageParams = {
|
|||
};
|
||||
|
||||
const AddressTransactions: React.FC = () => {
|
||||
const provider = useContext(ProviderContext);
|
||||
const params = useParams<BlockParams>();
|
||||
const location = useLocation<PageParams>();
|
||||
const history = useHistory();
|
||||
|
@ -59,6 +60,9 @@ const AddressTransactions: React.FC = () => {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!provider) {
|
||||
return;
|
||||
}
|
||||
const resolveName = async () => {
|
||||
const resolvedAddress = await provider.resolveName(params.addressOrName);
|
||||
if (resolvedAddress !== null) {
|
||||
|
@ -72,20 +76,30 @@ const AddressTransactions: React.FC = () => {
|
|||
}
|
||||
};
|
||||
resolveName();
|
||||
}, [params.addressOrName, history, params.direction, location.search]);
|
||||
}, [
|
||||
provider,
|
||||
params.addressOrName,
|
||||
history,
|
||||
params.direction,
|
||||
location.search,
|
||||
]);
|
||||
|
||||
const [controller, setController] = useState<SearchController>();
|
||||
useEffect(() => {
|
||||
if (!checksummedAddress) {
|
||||
if (!provider || !checksummedAddress) {
|
||||
return;
|
||||
}
|
||||
|
||||
const readFirstPage = async () => {
|
||||
const _controller = await SearchController.firstPage(checksummedAddress);
|
||||
const _controller = await SearchController.firstPage(
|
||||
provider,
|
||||
checksummedAddress
|
||||
);
|
||||
setController(_controller);
|
||||
};
|
||||
const readMiddlePage = async (next: boolean) => {
|
||||
const _controller = await SearchController.middlePage(
|
||||
provider,
|
||||
checksummedAddress,
|
||||
hash!,
|
||||
next
|
||||
|
@ -93,15 +107,18 @@ const AddressTransactions: React.FC = () => {
|
|||
setController(_controller);
|
||||
};
|
||||
const readLastPage = async () => {
|
||||
const _controller = await SearchController.lastPage(checksummedAddress);
|
||||
const _controller = await SearchController.lastPage(
|
||||
provider,
|
||||
checksummedAddress
|
||||
);
|
||||
setController(_controller);
|
||||
};
|
||||
const prevPage = async () => {
|
||||
const _controller = await controller!.prevPage(hash!);
|
||||
const _controller = await controller!.prevPage(provider, hash!);
|
||||
setController(_controller);
|
||||
};
|
||||
const nextPage = async () => {
|
||||
const _controller = await controller!.nextPage(hash!);
|
||||
const _controller = await controller!.nextPage(provider, hash!);
|
||||
setController(_controller);
|
||||
};
|
||||
|
||||
|
@ -127,10 +144,10 @@ const AddressTransactions: React.FC = () => {
|
|||
readLastPage();
|
||||
}
|
||||
}
|
||||
}, [checksummedAddress, params.direction, hash, controller]);
|
||||
}, [provider, checksummedAddress, params.direction, hash, controller]);
|
||||
|
||||
const page = useMemo(() => controller?.getPage(), [controller]);
|
||||
const reverseCache = useENSCache(page);
|
||||
const reverseCache = useENSCache(provider, page);
|
||||
|
||||
document.title = `Address ${params.addressOrName} | Otterscan`;
|
||||
|
||||
|
|
65
src/App.tsx
65
src/App.tsx
|
@ -3,40 +3,47 @@ import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
|
|||
import Home from "./Home";
|
||||
import Search from "./Search";
|
||||
import Title from "./Title";
|
||||
import { useProvider, ProviderContext } from "./useProvider";
|
||||
|
||||
const Block = React.lazy(() => import("./Block"));
|
||||
const BlockTransactions = React.lazy(() => import("./BlockTransactions"));
|
||||
const AddressTransactions = React.lazy(() => import("./AddressTransactions"));
|
||||
const Transaction = React.lazy(() => import("./Transaction"));
|
||||
|
||||
const App = () => (
|
||||
<Suspense fallback={<>LOADING</>}>
|
||||
<Router>
|
||||
<Switch>
|
||||
<Route path="/" exact>
|
||||
<Home />
|
||||
</Route>
|
||||
<Route path="/search" exact>
|
||||
<Search />
|
||||
</Route>
|
||||
<Route>
|
||||
<Title />
|
||||
<Route path="/block/:blockNumberOrHash" exact>
|
||||
<Block />
|
||||
</Route>
|
||||
<Route path="/block/:blockNumber/txs" exact>
|
||||
<BlockTransactions />
|
||||
</Route>
|
||||
<Route path="/tx/:txhash">
|
||||
<Transaction />
|
||||
</Route>
|
||||
<Route path="/address/:addressOrName/:direction?">
|
||||
<AddressTransactions />
|
||||
</Route>
|
||||
</Route>
|
||||
</Switch>
|
||||
</Router>
|
||||
</Suspense>
|
||||
);
|
||||
const App = () => {
|
||||
const provider = useProvider();
|
||||
|
||||
return (
|
||||
<Suspense fallback={<>LOADING</>}>
|
||||
<ProviderContext.Provider value={provider}>
|
||||
<Router>
|
||||
<Switch>
|
||||
<Route path="/" exact>
|
||||
<Home />
|
||||
</Route>
|
||||
<Route path="/search" exact>
|
||||
<Search />
|
||||
</Route>
|
||||
<Route>
|
||||
<Title />
|
||||
<Route path="/block/:blockNumberOrHash" exact>
|
||||
<Block />
|
||||
</Route>
|
||||
<Route path="/block/:blockNumber/txs" exact>
|
||||
<BlockTransactions />
|
||||
</Route>
|
||||
<Route path="/tx/:txhash">
|
||||
<Transaction />
|
||||
</Route>
|
||||
<Route path="/address/:addressOrName/:direction?">
|
||||
<AddressTransactions />
|
||||
</Route>
|
||||
</Route>
|
||||
</Switch>
|
||||
</Router>
|
||||
</ProviderContext.Provider>
|
||||
</Suspense>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(App);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useEffect, useState, useMemo } from "react";
|
||||
import React, { useEffect, useState, useMemo, useContext } from "react";
|
||||
import { useParams, NavLink } from "react-router-dom";
|
||||
import { ethers, BigNumber } from "ethers";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
@ -6,7 +6,6 @@ import {
|
|||
faChevronLeft,
|
||||
faChevronRight,
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { provider } from "./ethersconfig";
|
||||
import StandardFrame from "./StandardFrame";
|
||||
import StandardSubtitle from "./StandardSubtitle";
|
||||
import ContentFrame from "./ContentFrame";
|
||||
|
@ -17,6 +16,7 @@ import BlockLink from "./components/BlockLink";
|
|||
import AddressOrENSName from "./components/AddressOrENSName";
|
||||
import TransactionValue from "./components/TransactionValue";
|
||||
import HexValue from "./components/HexValue";
|
||||
import { ProviderContext } from "./useProvider";
|
||||
import { useLatestBlockNumber } from "./useLatestBlock";
|
||||
|
||||
type BlockParams = {
|
||||
|
@ -34,10 +34,15 @@ interface ExtendedBlock extends ethers.providers.Block {
|
|||
}
|
||||
|
||||
const Block: React.FC = () => {
|
||||
const provider = useContext(ProviderContext);
|
||||
const params = useParams<BlockParams>();
|
||||
|
||||
const [block, setBlock] = useState<ExtendedBlock>();
|
||||
useEffect(() => {
|
||||
if (!provider) {
|
||||
return;
|
||||
}
|
||||
|
||||
const readBlock = async () => {
|
||||
let blockPromise: Promise<any>;
|
||||
if (ethers.utils.isHexString(params.blockNumberOrHash, 32)) {
|
||||
|
@ -80,7 +85,7 @@ const Block: React.FC = () => {
|
|||
setBlock(extBlock);
|
||||
};
|
||||
readBlock();
|
||||
}, [params.blockNumberOrHash]);
|
||||
}, [provider, params.blockNumberOrHash]);
|
||||
|
||||
useEffect(() => {
|
||||
if (block) {
|
||||
|
@ -97,7 +102,7 @@ const Block: React.FC = () => {
|
|||
}
|
||||
}, [block]);
|
||||
|
||||
const latestBlockNumber = useLatestBlockNumber();
|
||||
const latestBlockNumber = useLatestBlockNumber(provider);
|
||||
|
||||
return (
|
||||
<StandardFrame>
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import React, { useEffect, useState, useMemo } from "react";
|
||||
import React, { useEffect, useState, useMemo, useContext } from "react";
|
||||
import { useParams, useLocation } from "react-router";
|
||||
import { ethers } from "ethers";
|
||||
import queryString from "query-string";
|
||||
import { provider } from "./ethersconfig";
|
||||
import StandardFrame from "./StandardFrame";
|
||||
import StandardSubtitle from "./StandardSubtitle";
|
||||
import ContentFrame from "./ContentFrame";
|
||||
|
@ -14,6 +13,7 @@ import BlockLink from "./components/BlockLink";
|
|||
import { ProcessedTransaction } from "./types";
|
||||
import { PAGE_SIZE } from "./params";
|
||||
import { useFeeToggler } from "./search/useFeeToggler";
|
||||
import { ProviderContext } from "./useProvider";
|
||||
import { useENSCache } from "./useReverseCache";
|
||||
|
||||
type BlockParams = {
|
||||
|
@ -25,6 +25,7 @@ type PageParams = {
|
|||
};
|
||||
|
||||
const BlockTransactions: React.FC = () => {
|
||||
const provider = useContext(ProviderContext);
|
||||
const params = useParams<BlockParams>();
|
||||
const location = useLocation<PageParams>();
|
||||
const qs = queryString.parse(location.search);
|
||||
|
@ -42,6 +43,10 @@ const BlockTransactions: React.FC = () => {
|
|||
|
||||
const [txs, setTxs] = useState<ProcessedTransaction[]>();
|
||||
useEffect(() => {
|
||||
if (!provider) {
|
||||
return;
|
||||
}
|
||||
|
||||
const readBlock = async () => {
|
||||
const [_block, _receipts] = await Promise.all([
|
||||
provider.getBlockWithTransactions(blockNumber.toNumber()),
|
||||
|
@ -94,7 +99,7 @@ const BlockTransactions: React.FC = () => {
|
|||
setTxs(processedResponses);
|
||||
};
|
||||
readBlock();
|
||||
}, [blockNumber]);
|
||||
}, [provider, blockNumber]);
|
||||
|
||||
const page = useMemo(() => {
|
||||
if (!txs) {
|
||||
|
@ -105,7 +110,7 @@ const BlockTransactions: React.FC = () => {
|
|||
}, [txs, pageNumber]);
|
||||
const total = useMemo(() => txs?.length ?? 0, [txs]);
|
||||
|
||||
const reverseCache = useENSCache(page);
|
||||
const reverseCache = useENSCache(provider, page);
|
||||
|
||||
document.title = `Block #${blockNumber} Txns | Otterscan`;
|
||||
|
||||
|
|
13
src/Home.tsx
13
src/Home.tsx
|
@ -1,12 +1,13 @@
|
|||
import React, { useState } from "react";
|
||||
import React, { useState, useContext } from "react";
|
||||
import { NavLink, useHistory } from "react-router-dom";
|
||||
import { ethers } from "ethers";
|
||||
import Logo from "./Logo";
|
||||
import Timestamp from "./components/Timestamp";
|
||||
import { ProviderContext } from "./useProvider";
|
||||
import { useLatestBlock } from "./useLatestBlock";
|
||||
import { ERIGON_NODE } from "./ethersconfig";
|
||||
|
||||
const Home: React.FC = () => {
|
||||
const provider = useContext(ProviderContext);
|
||||
const [search, setSearch] = useState<string>();
|
||||
const [canSubmit, setCanSubmit] = useState<boolean>(false);
|
||||
const history = useHistory();
|
||||
|
@ -25,7 +26,7 @@ const Home: React.FC = () => {
|
|||
history.push(`/search?q=${search}`);
|
||||
};
|
||||
|
||||
const latestBlock = useLatestBlock();
|
||||
const latestBlock = useLatestBlock(provider);
|
||||
|
||||
document.title = "Home | Otterscan";
|
||||
|
||||
|
@ -65,7 +66,11 @@ const Home: React.FC = () => {
|
|||
</NavLink>
|
||||
)}
|
||||
<span className="mx-auto mt-5 text-xs text-gray-500">
|
||||
Using Erigon node at {ERIGON_NODE}
|
||||
{provider ? (
|
||||
<>Using Erigon node at {provider.connection.url}</>
|
||||
) : (
|
||||
<>Waiting for the provider...</>
|
||||
)}
|
||||
</span>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
import React, { useState, useEffect, useCallback, useMemo } from "react";
|
||||
import React, {
|
||||
useState,
|
||||
useEffect,
|
||||
useCallback,
|
||||
useMemo,
|
||||
useContext,
|
||||
} from "react";
|
||||
import { Route, Switch, useParams } from "react-router-dom";
|
||||
import { BigNumber, ethers } from "ethers";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
@ -6,7 +12,6 @@ import {
|
|||
faCheckCircle,
|
||||
faTimesCircle,
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { provider } from "./ethersconfig";
|
||||
import StandardFrame from "./StandardFrame";
|
||||
import StandardSubtitle from "./StandardSubtitle";
|
||||
import Tab from "./components/Tab";
|
||||
|
@ -22,6 +27,7 @@ import FormattedBalance from "./components/FormattedBalance";
|
|||
import TokenTransferItem from "./TokenTransferItem";
|
||||
import erc20 from "./erc20.json";
|
||||
import { TokenMetas, TokenTransfer, TransactionData, Transfer } from "./types";
|
||||
import { ProviderContext } from "./useProvider";
|
||||
|
||||
const TRANSFER_TOPIC =
|
||||
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef";
|
||||
|
@ -31,11 +37,16 @@ type TransactionParams = {
|
|||
};
|
||||
|
||||
const Transaction: React.FC = () => {
|
||||
const provider = useContext(ProviderContext);
|
||||
const params = useParams<TransactionParams>();
|
||||
const { txhash } = params;
|
||||
|
||||
const [txData, setTxData] = useState<TransactionData>();
|
||||
useEffect(() => {
|
||||
if (!provider) {
|
||||
return;
|
||||
}
|
||||
|
||||
const readBlock = async () => {
|
||||
const [_response, _receipt] = await Promise.all([
|
||||
provider.getTransaction(txhash),
|
||||
|
@ -109,7 +120,7 @@ const Transaction: React.FC = () => {
|
|||
});
|
||||
};
|
||||
readBlock();
|
||||
}, [txhash]);
|
||||
}, [provider, txhash]);
|
||||
|
||||
const [transfers, setTransfers] = useState<Transfer[]>();
|
||||
const sendsEthToMiner = useMemo(() => {
|
||||
|
@ -126,7 +137,7 @@ const Transaction: React.FC = () => {
|
|||
}, [txData, transfers]);
|
||||
|
||||
const traceTransfersUsingOtsTrace = useCallback(async () => {
|
||||
if (!txData) {
|
||||
if (!provider || !txData) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -143,7 +154,7 @@ const Transaction: React.FC = () => {
|
|||
}
|
||||
|
||||
setTransfers(_transfers);
|
||||
}, [txData]);
|
||||
}, [provider, txData]);
|
||||
useEffect(() => {
|
||||
traceTransfersUsingOtsTrace();
|
||||
}, [traceTransfersUsingOtsTrace]);
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
import { ethers } from "ethers";
|
||||
|
||||
export const ERIGON_NODE =
|
||||
process.env.REACT_APP_ERIGON_URL || "http://127.0.0.1:8545";
|
||||
|
||||
export const provider = new ethers.providers.JsonRpcProvider(
|
||||
ERIGON_NODE,
|
||||
"mainnet"
|
||||
);
|
|
@ -1,5 +1,4 @@
|
|||
import { ethers } from "ethers";
|
||||
import { provider } from "../ethersconfig";
|
||||
import { PAGE_SIZE } from "../params";
|
||||
import { ProcessedTransaction, TransactionChunk } from "../types";
|
||||
|
||||
|
@ -27,7 +26,10 @@ export class SearchController {
|
|||
}
|
||||
}
|
||||
|
||||
private static rawToProcessed = (_rawRes: any) => {
|
||||
private static rawToProcessed = (
|
||||
provider: ethers.providers.JsonRpcProvider,
|
||||
_rawRes: any
|
||||
) => {
|
||||
const _res: ethers.providers.TransactionResponse[] = _rawRes.txs.map(
|
||||
(t: any) => provider.formatter.transactionResponse(t)
|
||||
);
|
||||
|
@ -56,6 +58,7 @@ export class SearchController {
|
|||
};
|
||||
|
||||
private static async readBackPage(
|
||||
provider: ethers.providers.JsonRpcProvider,
|
||||
address: string,
|
||||
baseBlock: number
|
||||
): Promise<TransactionChunk> {
|
||||
|
@ -64,10 +67,11 @@ export class SearchController {
|
|||
baseBlock,
|
||||
PAGE_SIZE,
|
||||
]);
|
||||
return this.rawToProcessed(_rawRes);
|
||||
return this.rawToProcessed(provider, _rawRes);
|
||||
}
|
||||
|
||||
private static async readForwardPage(
|
||||
provider: ethers.providers.JsonRpcProvider,
|
||||
address: string,
|
||||
baseBlock: number
|
||||
): Promise<TransactionChunk> {
|
||||
|
@ -76,11 +80,14 @@ export class SearchController {
|
|||
baseBlock,
|
||||
PAGE_SIZE,
|
||||
]);
|
||||
return this.rawToProcessed(_rawRes);
|
||||
return this.rawToProcessed(provider, _rawRes);
|
||||
}
|
||||
|
||||
static async firstPage(address: string): Promise<SearchController> {
|
||||
const newTxs = await SearchController.readBackPage(address, 0);
|
||||
static async firstPage(
|
||||
provider: ethers.providers.JsonRpcProvider,
|
||||
address: string
|
||||
): Promise<SearchController> {
|
||||
const newTxs = await SearchController.readBackPage(provider, address, 0);
|
||||
return new SearchController(
|
||||
address,
|
||||
newTxs.txs,
|
||||
|
@ -91,14 +98,19 @@ export class SearchController {
|
|||
}
|
||||
|
||||
static async middlePage(
|
||||
provider: ethers.providers.JsonRpcProvider,
|
||||
address: string,
|
||||
hash: string,
|
||||
next: boolean
|
||||
): Promise<SearchController> {
|
||||
const tx = await provider.getTransaction(hash);
|
||||
const newTxs = next
|
||||
? await SearchController.readBackPage(address, tx.blockNumber!)
|
||||
: await SearchController.readForwardPage(address, tx.blockNumber!);
|
||||
? await SearchController.readBackPage(provider, address, tx.blockNumber!)
|
||||
: await SearchController.readForwardPage(
|
||||
provider,
|
||||
address,
|
||||
tx.blockNumber!
|
||||
);
|
||||
return new SearchController(
|
||||
address,
|
||||
newTxs.txs,
|
||||
|
@ -108,8 +120,11 @@ export class SearchController {
|
|||
);
|
||||
}
|
||||
|
||||
static async lastPage(address: string): Promise<SearchController> {
|
||||
const newTxs = await SearchController.readForwardPage(address, 0);
|
||||
static async lastPage(
|
||||
provider: ethers.providers.JsonRpcProvider,
|
||||
address: string
|
||||
): Promise<SearchController> {
|
||||
const newTxs = await SearchController.readForwardPage(provider, address, 0);
|
||||
return new SearchController(
|
||||
address,
|
||||
newTxs.txs,
|
||||
|
@ -123,7 +138,10 @@ export class SearchController {
|
|||
return this.txs.slice(this.pageStart, this.pageEnd);
|
||||
}
|
||||
|
||||
async prevPage(hash: string): Promise<SearchController> {
|
||||
async prevPage(
|
||||
provider: ethers.providers.JsonRpcProvider,
|
||||
hash: string
|
||||
): Promise<SearchController> {
|
||||
// Already on this page
|
||||
if (this.txs[this.pageEnd - 1].hash === hash) {
|
||||
return this;
|
||||
|
@ -133,6 +151,7 @@ export class SearchController {
|
|||
const overflowPage = this.txs.slice(0, this.pageStart);
|
||||
const baseBlock = this.txs[0].blockNumber;
|
||||
const prevPage = await SearchController.readForwardPage(
|
||||
provider,
|
||||
this.address,
|
||||
baseBlock
|
||||
);
|
||||
|
@ -148,7 +167,10 @@ export class SearchController {
|
|||
return this;
|
||||
}
|
||||
|
||||
async nextPage(hash: string): Promise<SearchController> {
|
||||
async nextPage(
|
||||
provider: ethers.providers.JsonRpcProvider,
|
||||
hash: string
|
||||
): Promise<SearchController> {
|
||||
// Already on this page
|
||||
if (this.txs[this.pageStart].hash === hash) {
|
||||
return this;
|
||||
|
@ -158,6 +180,7 @@ export class SearchController {
|
|||
const overflowPage = this.txs.slice(this.pageEnd);
|
||||
const baseBlock = this.txs[this.txs.length - 1].blockNumber;
|
||||
const nextPage = await SearchController.readBackPage(
|
||||
provider,
|
||||
this.address,
|
||||
baseBlock
|
||||
);
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
import { useState, useEffect } from "react";
|
||||
|
||||
export type OtterscanConfig = {
|
||||
erigonURL: string;
|
||||
};
|
||||
|
||||
export const useErigon = (): [boolean?, OtterscanConfig?] => {
|
||||
const [configOK, setConfigOK] = useState<boolean>();
|
||||
const [config, setConfig] = useState<OtterscanConfig>();
|
||||
|
||||
useEffect(() => {
|
||||
const readConfig = async () => {
|
||||
const res = await fetch("/config.json");
|
||||
|
||||
if (res.ok) {
|
||||
const _config: OtterscanConfig = await res.json();
|
||||
setConfig(_config);
|
||||
setConfigOK(res.ok);
|
||||
}
|
||||
};
|
||||
readConfig();
|
||||
}, []);
|
||||
|
||||
return [configOK, config];
|
||||
};
|
|
@ -1,11 +1,14 @@
|
|||
import { useState, useEffect } from "react";
|
||||
import { ethers } from "ethers";
|
||||
import { provider } from "./ethersconfig";
|
||||
|
||||
export const useLatestBlock = () => {
|
||||
export const useLatestBlock = (provider?: ethers.providers.JsonRpcProvider) => {
|
||||
const [latestBlock, setLatestBlock] = useState<ethers.providers.Block>();
|
||||
|
||||
useEffect(() => {
|
||||
if (!provider) {
|
||||
return;
|
||||
}
|
||||
|
||||
const readLatestBlock = async () => {
|
||||
const blockNum = await provider.getBlockNumber();
|
||||
const _raw = await provider.send("erigon_getHeaderByNumber", [blockNum]);
|
||||
|
@ -26,15 +29,21 @@ export const useLatestBlock = () => {
|
|||
return () => {
|
||||
provider.removeListener("block", listener);
|
||||
};
|
||||
}, []);
|
||||
}, [provider]);
|
||||
|
||||
return latestBlock;
|
||||
};
|
||||
|
||||
export const useLatestBlockNumber = () => {
|
||||
export const useLatestBlockNumber = (
|
||||
provider?: ethers.providers.JsonRpcProvider
|
||||
) => {
|
||||
const [latestBlock, setLatestBlock] = useState<number>();
|
||||
|
||||
useEffect(() => {
|
||||
if (!provider) {
|
||||
return;
|
||||
}
|
||||
|
||||
const readLatestBlock = async () => {
|
||||
const blockNum = await provider.getBlockNumber();
|
||||
setLatestBlock(blockNum);
|
||||
|
@ -49,7 +58,7 @@ export const useLatestBlockNumber = () => {
|
|||
return () => {
|
||||
provider.removeListener("block", listener);
|
||||
};
|
||||
}, []);
|
||||
}, [provider]);
|
||||
|
||||
return latestBlock;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
import React from "react";
|
||||
import { ethers } from "ethers";
|
||||
import { useErigon } from "./useErigon";
|
||||
|
||||
export const DEFAULT_ERIGON_URL = "http://127.0.0.1:8545";
|
||||
|
||||
export const useProvider = (): ethers.providers.JsonRpcProvider | undefined => {
|
||||
const [configOK, config] = useErigon();
|
||||
if (!configOK) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let erigonURL = config?.erigonURL;
|
||||
if (erigonURL === "") {
|
||||
console.info(`Using default erigon URL: ${DEFAULT_ERIGON_URL}`);
|
||||
erigonURL = DEFAULT_ERIGON_URL;
|
||||
} else {
|
||||
console.log(`Using configured erigon URL: ${erigonURL}`);
|
||||
}
|
||||
|
||||
return new ethers.providers.JsonRpcProvider(erigonURL, "mainnet");
|
||||
};
|
||||
|
||||
export const ProviderContext = React.createContext<
|
||||
ethers.providers.JsonRpcProvider | undefined
|
||||
>(undefined);
|
|
@ -1,12 +1,15 @@
|
|||
import { useState, useEffect } from "react";
|
||||
import { ethers } from "ethers";
|
||||
import { ENSReverseCache, ProcessedTransaction } from "./types";
|
||||
import { provider } from "./ethersconfig";
|
||||
|
||||
export const useENSCache = (page?: ProcessedTransaction[]) => {
|
||||
export const useENSCache = (
|
||||
provider?: ethers.providers.JsonRpcProvider,
|
||||
page?: ProcessedTransaction[]
|
||||
) => {
|
||||
const [reverseCache, setReverseCache] = useState<ENSReverseCache>();
|
||||
|
||||
useEffect(() => {
|
||||
if (!page) {
|
||||
if (!provider || !page) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -38,7 +41,7 @@ export const useENSCache = (page?: ProcessedTransaction[]) => {
|
|||
setReverseCache(cache);
|
||||
};
|
||||
reverseResolve();
|
||||
}, [page]);
|
||||
}, [provider, page]);
|
||||
|
||||
return reverseCache;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue