From 34e175f24c454804fb85c0056f872edeab94808e Mon Sep 17 00:00:00 2001 From: Ben Kremer Date: Fri, 4 Feb 2022 16:53:03 +0100 Subject: [PATCH] feat: memoize ClientContext value --- .../src/contexts/ClientContext.tsx | 172 +++++++++++------- 1 file changed, 104 insertions(+), 68 deletions(-) diff --git a/dapps/react-dapp-v2/src/contexts/ClientContext.tsx b/dapps/react-dapp-v2/src/contexts/ClientContext.tsx index a4b9d49..d1d7b00 100644 --- a/dapps/react-dapp-v2/src/contexts/ClientContext.tsx +++ b/dapps/react-dapp-v2/src/contexts/ClientContext.tsx @@ -1,7 +1,15 @@ import Client, { CLIENT_EVENTS } from "@walletconnect/client"; import { PairingTypes, SessionTypes } from "@walletconnect/types"; import QRCodeModal from "@walletconnect/legacy-modal"; -import { createContext, ReactNode, useContext, useEffect, useState } from "react"; +import { + createContext, + ReactNode, + useCallback, + useContext, + useEffect, + useMemo, + useState, +} from "react"; import { DEFAULT_APP_METADATA, DEFAULT_COSMOS_METHODS, @@ -104,70 +112,79 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac } }; - const onSessionConnected = async (incomingSession: SessionTypes.Settled) => { - setSession(incomingSession); - onSessionUpdate(incomingSession.state.accounts, incomingSession.permissions.blockchain.chains); - }; - - const onSessionUpdate = async (accounts: string[], chains: string[]) => { + const onSessionUpdate = useCallback(async (accounts: string[], chains: string[]) => { setChains(chains); setAccounts(accounts); await getAccountBalances(accounts); - }; + }, []); - const connect = async (pairing?: { topic: string }) => { - if (typeof client === "undefined") { - throw new Error("WalletConnect is not initialized"); - } - console.log("connect", pairing); - // TODO: - // if (modal === "pairing") { - // closeModal(); - // } - try { - const supportedNamespaces: string[] = []; - chains.forEach(chainId => { - const [namespace] = chainId.split(":"); - if (!supportedNamespaces.includes(namespace)) { - supportedNamespaces.push(namespace); - } - }); - const methods: string[] = supportedNamespaces - .map(namespace => { - switch (namespace) { - case "eip155": - return DEFAULT_EIP155_METHODS; - case "cosmos": - return DEFAULT_COSMOS_METHODS; - default: - throw new Error(`No default methods for namespace: ${namespace}`); + const onSessionConnected = useCallback( + async (incomingSession: SessionTypes.Settled) => { + setSession(incomingSession); + onSessionUpdate( + incomingSession.state.accounts, + incomingSession.permissions.blockchain.chains, + ); + }, + [onSessionUpdate], + ); + + const connect = useCallback( + async (pairing?: { topic: string }) => { + if (typeof client === "undefined") { + throw new Error("WalletConnect is not initialized"); + } + console.log("connect", pairing); + // TODO: + // if (modal === "pairing") { + // closeModal(); + // } + try { + const supportedNamespaces: string[] = []; + chains.forEach(chainId => { + const [namespace] = chainId.split(":"); + if (!supportedNamespaces.includes(namespace)) { + supportedNamespaces.push(namespace); } - }) - .flat(); - const session = await client.connect({ - metadata: getAppMetadata() || DEFAULT_APP_METADATA, - pairing, - permissions: { - blockchain: { - chains, + }); + const methods: string[] = supportedNamespaces + .map(namespace => { + switch (namespace) { + case "eip155": + return DEFAULT_EIP155_METHODS; + case "cosmos": + return DEFAULT_COSMOS_METHODS; + default: + throw new Error(`No default methods for namespace: ${namespace}`); + } + }) + .flat(); + const session = await client.connect({ + metadata: getAppMetadata() || DEFAULT_APP_METADATA, + pairing, + permissions: { + blockchain: { + chains, + }, + jsonrpc: { + methods, + }, }, - jsonrpc: { - methods, - }, - }, - }); + }); - onSessionConnected(session); - } catch (e) { - console.error(e); - // ignore rejection - } + onSessionConnected(session); + } catch (e) { + console.error(e); + // ignore rejection + } - // close modal in case it was open - QRCodeModal.close(); - }; + // close modal in case it was open + QRCodeModal.close(); + }, + [chains, client, onSessionConnected], + ); - const disconnect = async () => { + const disconnect = useCallback(async () => { if (typeof client === "undefined") { throw new Error("WalletConnect is not initialized"); } @@ -179,7 +196,7 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac topic: session.topic, reason: ERROR.USER_DISCONNECTED.format(), }); - }; + }, [client, session]); const getAccountBalances = async (_accounts: string[]) => { setFetching(true); @@ -226,20 +243,39 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac init(); }, []); + const value = useMemo( + () => ({ + pairings, + fetching, + loading, + balances, + accounts, + chains, + client, + session, + connect, + disconnect, + setChains, + }), + [ + pairings, + fetching, + loading, + balances, + accounts, + chains, + client, + session, + connect, + disconnect, + setChains, + ], + ); + return ( {children}