feat: memoize ClientContext value

This commit is contained in:
Ben Kremer 2022-02-04 16:53:03 +01:00
parent dc120c89d2
commit 34e175f24c

View File

@ -1,7 +1,15 @@
import Client, { CLIENT_EVENTS } from "@walletconnect/client"; import Client, { CLIENT_EVENTS } from "@walletconnect/client";
import { PairingTypes, SessionTypes } from "@walletconnect/types"; import { PairingTypes, SessionTypes } from "@walletconnect/types";
import QRCodeModal from "@walletconnect/legacy-modal"; 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 { import {
DEFAULT_APP_METADATA, DEFAULT_APP_METADATA,
DEFAULT_COSMOS_METHODS, DEFAULT_COSMOS_METHODS,
@ -104,70 +112,79 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
} }
}; };
const onSessionConnected = async (incomingSession: SessionTypes.Settled) => { const onSessionUpdate = useCallback(async (accounts: string[], chains: string[]) => {
setSession(incomingSession);
onSessionUpdate(incomingSession.state.accounts, incomingSession.permissions.blockchain.chains);
};
const onSessionUpdate = async (accounts: string[], chains: string[]) => {
setChains(chains); setChains(chains);
setAccounts(accounts); setAccounts(accounts);
await getAccountBalances(accounts); await getAccountBalances(accounts);
}; }, []);
const connect = async (pairing?: { topic: string }) => { const onSessionConnected = useCallback(
if (typeof client === "undefined") { async (incomingSession: SessionTypes.Settled) => {
throw new Error("WalletConnect is not initialized"); setSession(incomingSession);
} onSessionUpdate(
console.log("connect", pairing); incomingSession.state.accounts,
// TODO: incomingSession.permissions.blockchain.chains,
// if (modal === "pairing") { );
// closeModal(); },
// } [onSessionUpdate],
try { );
const supportedNamespaces: string[] = [];
chains.forEach(chainId => { const connect = useCallback(
const [namespace] = chainId.split(":"); async (pairing?: { topic: string }) => {
if (!supportedNamespaces.includes(namespace)) { if (typeof client === "undefined") {
supportedNamespaces.push(namespace); throw new Error("WalletConnect is not initialized");
} }
}); console.log("connect", pairing);
const methods: string[] = supportedNamespaces // TODO:
.map(namespace => { // if (modal === "pairing") {
switch (namespace) { // closeModal();
case "eip155": // }
return DEFAULT_EIP155_METHODS; try {
case "cosmos": const supportedNamespaces: string[] = [];
return DEFAULT_COSMOS_METHODS; chains.forEach(chainId => {
default: const [namespace] = chainId.split(":");
throw new Error(`No default methods for namespace: ${namespace}`); if (!supportedNamespaces.includes(namespace)) {
supportedNamespaces.push(namespace);
} }
}) });
.flat(); const methods: string[] = supportedNamespaces
const session = await client.connect({ .map(namespace => {
metadata: getAppMetadata() || DEFAULT_APP_METADATA, switch (namespace) {
pairing, case "eip155":
permissions: { return DEFAULT_EIP155_METHODS;
blockchain: { case "cosmos":
chains, 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); onSessionConnected(session);
} catch (e) { } catch (e) {
console.error(e); console.error(e);
// ignore rejection // ignore rejection
} }
// close modal in case it was open // close modal in case it was open
QRCodeModal.close(); QRCodeModal.close();
}; },
[chains, client, onSessionConnected],
);
const disconnect = async () => { const disconnect = useCallback(async () => {
if (typeof client === "undefined") { if (typeof client === "undefined") {
throw new Error("WalletConnect is not initialized"); throw new Error("WalletConnect is not initialized");
} }
@ -179,7 +196,7 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
topic: session.topic, topic: session.topic,
reason: ERROR.USER_DISCONNECTED.format(), reason: ERROR.USER_DISCONNECTED.format(),
}); });
}; }, [client, session]);
const getAccountBalances = async (_accounts: string[]) => { const getAccountBalances = async (_accounts: string[]) => {
setFetching(true); setFetching(true);
@ -226,20 +243,39 @@ export function ClientContextProvider({ children }: { children: ReactNode | Reac
init(); 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 ( return (
<ClientContext.Provider <ClientContext.Provider
value={{ value={{
pairings, ...value,
fetching,
loading,
balances,
accounts,
chains,
client,
session,
connect,
disconnect,
setChains,
}} }}
> >
{children} {children}