From 35868ea7af09dd695388ce2915c2fd175ed61038 Mon Sep 17 00:00:00 2001 From: Ben Kremer Date: Tue, 15 Feb 2022 11:52:30 +0100 Subject: [PATCH] feat: sets up passing of custom RPCs to EthereumProvider --- dapps/react-dapp-v2-with-ethers/src/App.tsx | 34 +------------- .../src/contexts/ClientContext.tsx | 44 ++++++++++++++++--- 2 files changed, 41 insertions(+), 37 deletions(-) diff --git a/dapps/react-dapp-v2-with-ethers/src/App.tsx b/dapps/react-dapp-v2-with-ethers/src/App.tsx index b9148f7..a4c447e 100644 --- a/dapps/react-dapp-v2-with-ethers/src/App.tsx +++ b/dapps/react-dapp-v2-with-ethers/src/App.tsx @@ -8,13 +8,7 @@ import Column from "./components/Column"; import Header from "./components/Header"; import Modal from "./components/Modal"; import { DEFAULT_MAIN_CHAINS, DEFAULT_TEST_CHAINS } from "./constants"; -import { - getAllChainNamespaces, - AccountAction, - ChainNamespaces, - getLocalStorageTestnetFlag, - setLocaleStorageTestnetFlag, -} from "./helpers"; +import { AccountAction, getLocalStorageTestnetFlag, setLocaleStorageTestnetFlag } from "./helpers"; import Toggle from "./components/Toggle"; import RequestModal from "./modals/RequestModal"; import PairingModal from "./modals/PairingModal"; @@ -30,7 +24,6 @@ import { SToggleContainer, } from "./components/app"; import { useWalletConnectClient } from "./contexts/ClientContext"; -import { apiGetChainNamespace, ChainsMap } from "caip-api"; import { utils } from "ethers"; interface IFormattedRpcResponse { @@ -42,7 +35,6 @@ interface IFormattedRpcResponse { export default function App() { const [isTestnet, setIsTestnet] = useState(getLocalStorageTestnetFlag()); - const [chainData, setChainData] = useState({}); const [isRpcRequestPending, setIsRpcRequestPending] = useState(false); const [rpcResult, setRpcResult] = useState(); @@ -61,6 +53,7 @@ export default function App() { chain, accounts, balances, + chainData, isFetchingBalances, isInitializing, onEnable, @@ -74,29 +67,6 @@ export default function App() { } }, [session, modal]); - useEffect(() => { - loadChainData(); - }, []); - - const loadChainData = async () => { - const namespaces = getAllChainNamespaces(); - const chainData: ChainNamespaces = {}; - await Promise.all( - namespaces.map(async namespace => { - let chains: ChainsMap | undefined; - try { - chains = await apiGetChainNamespace(namespace); - } catch (e) { - // ignore error - } - if (typeof chains !== "undefined") { - chainData[namespace] = chains; - } - }), - ); - setChainData(chainData); - }; - // TODO: // const onPing = async () => { // openPingModal(); diff --git a/dapps/react-dapp-v2-with-ethers/src/contexts/ClientContext.tsx b/dapps/react-dapp-v2-with-ethers/src/contexts/ClientContext.tsx index 20ec0eb..ebfb8c9 100644 --- a/dapps/react-dapp-v2-with-ethers/src/contexts/ClientContext.tsx +++ b/dapps/react-dapp-v2-with-ethers/src/contexts/ClientContext.tsx @@ -1,4 +1,5 @@ import Client, { CLIENT_EVENTS } from "@walletconnect/client"; +import EthereumProvider from "@walletconnect/ethereum-provider"; import { PairingTypes, SessionTypes } from "@walletconnect/types"; import QRCodeModal from "@walletconnect/legacy-modal"; import { @@ -16,9 +17,9 @@ import { DEFAULT_PROJECT_ID, DEFAULT_RELAY_URL, } from "../constants"; -import { ERROR } from "@walletconnect/utils"; -import EthereumProvider from "@walletconnect/ethereum-provider"; import { providers, utils } from "ethers"; +import { ChainNamespaces, getAllChainNamespaces } from "../helpers"; +import { apiGetChainNamespace, ChainsMap } from "caip-api"; /** * Types @@ -33,7 +34,7 @@ interface IContext { accounts: string[]; balances: { symbol: string; balance: string }[]; isFetchingBalances: boolean; - setChain: (chainId: string) => void; + chainData: ChainNamespaces; onEnable: (chainId: string) => Promise; web3Provider?: providers.Web3Provider; } @@ -60,6 +61,7 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac const [balances, setBalances] = useState<{ symbol: string; balance: string }[]>([]); const [accounts, setAccounts] = useState([]); + const [chainData, setChainData] = useState({}); const [chain, setChain] = useState(""); const resetApp = () => { @@ -70,6 +72,25 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac setChain(""); }; + const loadChainData = async () => { + const namespaces = getAllChainNamespaces(); + const chainData: ChainNamespaces = {}; + await Promise.all( + namespaces.map(async namespace => { + let chains: ChainsMap | undefined; + try { + chains = await apiGetChainNamespace(namespace); + } catch (e) { + // ignore error + } + if (typeof chains !== "undefined") { + chainData[namespace] = chains; + } + }), + ); + setChainData(chainData); + }; + const disconnect = useCallback(async () => { if (typeof ethereumProvider === "undefined") { throw new Error("ethereumProvider is not initialized"); @@ -129,11 +150,20 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac console.log("Enabling EthereumProvider for chainId: ", chainId); + const customRpcs = Object.keys(chainData.eip155).reduce( + (rpcs: Record, chainId) => { + rpcs[chainId] = chainData.eip155[chainId].rpc[0]; + return rpcs; + }, + {}, + ); + // Create WalletConnect Provider const ethereumProvider = new EthereumProvider({ chainId: Number(chainId), rpc: { infuraId: DEFAULT_INFURA_ID, + custom: customRpcs, }, // FIXME: `signer-connection` sub-dep is already specifying beta.23 -> typings mismatch. // @ts-ignore @@ -192,6 +222,10 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac [session, onEnable], ); + useEffect(() => { + loadChainData(); + }, []); + useEffect(() => { if (!client) { createClient(); @@ -220,7 +254,7 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac client, session, disconnect, - setChain, + chainData, onEnable, web3Provider, }), @@ -234,7 +268,7 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac client, session, disconnect, - setChain, + chainData, onEnable, web3Provider, ],