From 59b9eb5867947957304b965349feb07a1e7ee42d Mon Sep 17 00:00:00 2001 From: Ben Kremer Date: Thu, 17 Mar 2022 16:56:54 +0100 Subject: [PATCH] refactor(dapp-v2): separates `chainData` into own context/hook --- dapps/react-dapp-v2/src/App.tsx | 4 +- .../src/contexts/ChainDataContext.tsx | 70 +++++++++++++++++++ .../src/contexts/JsonRpcContext.tsx | 42 ++--------- dapps/react-dapp-v2/src/index.tsx | 14 ++-- 4 files changed, 87 insertions(+), 43 deletions(-) create mode 100644 dapps/react-dapp-v2/src/contexts/ChainDataContext.tsx diff --git a/dapps/react-dapp-v2/src/App.tsx b/dapps/react-dapp-v2/src/App.tsx index c6e5c06..e110ce7 100644 --- a/dapps/react-dapp-v2/src/App.tsx +++ b/dapps/react-dapp-v2/src/App.tsx @@ -30,6 +30,7 @@ import { } from "./components/app"; import { useWalletConnectClient } from "./contexts/ClientContext"; import { useJsonRpc } from "./contexts/JsonRpcContext"; +import { useChainData } from "./contexts/ChainDataContext"; export default function App() { const [modal, setModal] = useState(""); @@ -55,7 +56,6 @@ export default function App() { // Use `JsonRpcContext` to provide us with relevant RPC methods and states. const { - chainData, ping, ethereumRpc, cosmosRpc, @@ -66,6 +66,8 @@ export default function App() { setIsTestnet, } = useJsonRpc(); + const { chainData } = useChainData(); + // Close the pairing modal after a session is established. useEffect(() => { if (session && modal === "pairing") { diff --git a/dapps/react-dapp-v2/src/contexts/ChainDataContext.tsx b/dapps/react-dapp-v2/src/contexts/ChainDataContext.tsx new file mode 100644 index 0000000..012d64a --- /dev/null +++ b/dapps/react-dapp-v2/src/contexts/ChainDataContext.tsx @@ -0,0 +1,70 @@ +import { apiGetChainNamespace, ChainsMap } from "caip-api"; +import { createContext, ReactNode, useContext, useEffect, useState } from "react"; +import { SolanaChainData } from "../chains/solana"; + +import { ChainNamespaces, getAllChainNamespaces } from "../helpers"; + +/** + * Types + */ +interface IContext { + chainData: ChainNamespaces; +} + +/** + * Context + */ +export const ChainDataContext = createContext({} as IContext); + +/** + * Provider + */ +export function ChainDataContextProvider({ children }: { children: ReactNode | ReactNode[] }) { + const [chainData, setChainData] = useState({}); + + const loadChainData = async () => { + const namespaces = getAllChainNamespaces(); + const chainData: ChainNamespaces = {}; + await Promise.all( + namespaces.map(async namespace => { + let chains: ChainsMap | undefined; + try { + if (namespace === "solana") { + chains = SolanaChainData; + } else { + chains = await apiGetChainNamespace(namespace); + } + } catch (e) { + // ignore error + } + if (typeof chains !== "undefined") { + chainData[namespace] = chains; + } + }), + ); + + setChainData(chainData); + }; + + useEffect(() => { + loadChainData(); + }, []); + + return ( + + {children} + + ); +} + +export function useChainData() { + const context = useContext(ChainDataContext); + if (context === undefined) { + throw new Error("useChainData must be used within a ChainDataContextProvider"); + } + return context; +} diff --git a/dapps/react-dapp-v2/src/contexts/JsonRpcContext.tsx b/dapps/react-dapp-v2/src/contexts/JsonRpcContext.tsx index 19d3cfb..e32d6f4 100644 --- a/dapps/react-dapp-v2/src/contexts/JsonRpcContext.tsx +++ b/dapps/react-dapp-v2/src/contexts/JsonRpcContext.tsx @@ -1,29 +1,26 @@ import { BigNumber, utils } from "ethers"; -import { createContext, ReactNode, useContext, useEffect, useState } from "react"; +import { createContext, ReactNode, useContext, useState } from "react"; import * as encoding from "@walletconnect/encoding"; +import { TypedDataField } from "@ethersproject/abstract-signer"; import { formatDirectSignDoc, stringifySignDocValues } from "cosmos-wallet"; import bs58 from "bs58"; import { verifyMessageSignature } from "solana-wallet"; +import { clusterApiUrl, Connection, Keypair, SystemProgram, Transaction } from "@solana/web3.js"; import { - ChainNamespaces, eip712, formatTestTransaction, - getAllChainNamespaces, getLocalStorageTestnetFlag, hashPersonalMessage, verifySignature, } from "../helpers"; import { useWalletConnectClient } from "./ClientContext"; -import { apiGetChainNamespace, ChainsMap } from "caip-api"; -import { TypedDataField } from "@ethersproject/abstract-signer"; import { DEFAULT_COSMOS_METHODS, DEFAULT_EIP155_METHODS, DEFAULT_SOLANA_METHODS, } from "../constants"; -import { clusterApiUrl, Connection, Keypair, SystemProgram, Transaction } from "@solana/web3.js"; -import { SolanaChainData } from "../chains/solana"; +import { useChainData } from "./ChainDataContext"; /** * Types @@ -59,7 +56,6 @@ interface IContext { testSignMessage: TRpcRequestCallback; testSignTransaction: TRpcRequestCallback; }; - chainData: ChainNamespaces; rpcResult?: IRpcResult | null; isRpcRequestPending: boolean; isTestnet: boolean; @@ -77,38 +73,11 @@ export const JsonRpcContext = createContext({} as IContext); export function JsonRpcContextProvider({ children }: { children: ReactNode | ReactNode[] }) { const [pending, setPending] = useState(false); const [result, setResult] = useState(); - const [chainData, setChainData] = useState({}); const [isTestnet, setIsTestnet] = useState(getLocalStorageTestnetFlag()); const { client, session, accounts, balances, solanaPublicKeys } = useWalletConnectClient(); - useEffect(() => { - loadChainData(); - }, []); - - const loadChainData = async () => { - const namespaces = getAllChainNamespaces(); - const chainData: ChainNamespaces = {}; - await Promise.all( - namespaces.map(async namespace => { - let chains: ChainsMap | undefined; - try { - if (namespace === "solana") { - chains = SolanaChainData; - } else { - chains = await apiGetChainNamespace(namespace); - } - } catch (e) { - // ignore error - } - if (typeof chains !== "undefined") { - chainData[namespace] = chains; - } - }), - ); - - setChainData(chainData); - }; + const { chainData } = useChainData(); const _createJsonRpcRequestHandler = (rpcRequest: (chainId: string, address: string) => Promise) => @@ -568,7 +537,6 @@ export function JsonRpcContextProvider({ children }: { children: ReactNode | Rea return ( - - - - - + + + + + + + , document.getElementById("root"), );