From fc17bccde539162594bca2b5a0143ecab3fac7ce Mon Sep 17 00:00:00 2001 From: Dmitrii Podlesnyi Date: Mon, 18 Nov 2024 21:44:43 +0900 Subject: [PATCH 1/2] feat: add default chain changing to demo page --- .../components/wallet-info/chains-config.tsx | 55 +++++++++++++++++++ .../components/wallet-info/styles.tsx | 27 ++++++++- .../wallet-info/wallet-info-content.tsx | 3 + apps/demo-react/config/rpc.ts | 7 +-- apps/demo-react/hooks/useRpcUrls.ts | 22 ++++++++ apps/demo-react/providers/client-config.tsx | 44 ++++++++++----- apps/demo-react/providers/sdk.tsx | 7 ++- apps/demo-react/providers/web3.tsx | 15 +---- 8 files changed, 143 insertions(+), 37 deletions(-) create mode 100644 apps/demo-react/components/wallet-info/chains-config.tsx create mode 100644 apps/demo-react/hooks/useRpcUrls.ts diff --git a/apps/demo-react/components/wallet-info/chains-config.tsx b/apps/demo-react/components/wallet-info/chains-config.tsx new file mode 100644 index 00000000..7065bd5c --- /dev/null +++ b/apps/demo-react/components/wallet-info/chains-config.tsx @@ -0,0 +1,55 @@ +import { useCallback } from 'react'; +import { useClientConfig } from 'providers/client-config'; +import { + HeadingStyle, + DataTableRowAction, + DataTableRowInput, + DataTableRowStyle, +} from './styles'; +import { useRpcUrls } from 'hooks/useRpcUrls'; + +export const ChainsConfig = () => { + const { defaultChain, supportedChainIds, setSavedClientConfig } = + useClientConfig(); + + const rpcUrls = useRpcUrls(); + + const onChangeDefaultChain = useCallback((chainId: number) => { + setSavedClientConfig({ defaultChain: chainId }); + }, []); + + return ( + <> + Chains config: +
+ + {supportedChainIds.map((chainId) => ( + + {chainId} + {chainId === defaultChain ? (default 🛎️) : ''} + + } + > + + onChangeDefaultChain(chainId)} + variant={chainId === defaultChain ? 'filled' : 'translucent'} + > + 🛎️ + + + ))} + +
+ + ); +}; diff --git a/apps/demo-react/components/wallet-info/styles.tsx b/apps/demo-react/components/wallet-info/styles.tsx index 07f68388..155fc5af 100644 --- a/apps/demo-react/components/wallet-info/styles.tsx +++ b/apps/demo-react/components/wallet-info/styles.tsx @@ -1,5 +1,5 @@ import styled from 'styled-components'; -import { DataTableRow, ButtonIcon } from '@lidofinance/lido-ui'; +import { DataTableRow, ButtonIcon, Button, Input } from '@lidofinance/lido-ui'; export const ContainerStyle = styled.div` position: fixed; @@ -40,6 +40,31 @@ export const HeadingStyle = styled.h4` export const DataTableRowStyle = styled(DataTableRow)` margin: 4px 0; + align-items: center; +`; + +export const DataTableRowInput = styled(Input)` + width: 220px; + + > span { + padding: 4px 10px; + } + + input { + font-size: 12px; + } +`; + +export const DataTableRowAction = styled(Button).attrs({ + size: 'xs', +})` + padding: 0; + min-width: auto; + margin-left: 6px; + border: none; + width: 26px; + height: 26px; + cursor: pointer; `; export const ProviderInfoRowStyle = styled(DataTableRowStyle)` diff --git a/apps/demo-react/components/wallet-info/wallet-info-content.tsx b/apps/demo-react/components/wallet-info/wallet-info-content.tsx index 85e400a3..38dfc111 100644 --- a/apps/demo-react/components/wallet-info/wallet-info-content.tsx +++ b/apps/demo-react/components/wallet-info/wallet-info-content.tsx @@ -12,6 +12,7 @@ import { } from './styles'; import { Web3ProviderInfo } from './provider-info'; import { useClientConfig } from 'providers/client-config'; +import { ChainsConfig } from './chains-config'; export const WalletInfoContent = ({ children, @@ -97,6 +98,8 @@ export const WalletInfoContent = ({ + + {children} ); diff --git a/apps/demo-react/config/rpc.ts b/apps/demo-react/config/rpc.ts index f51254b3..e2bf5157 100644 --- a/apps/demo-react/config/rpc.ts +++ b/apps/demo-react/config/rpc.ts @@ -1,11 +1,6 @@ -import { mainnet, holesky, Chain } from 'wagmi/chains'; +import { Chain } from 'wagmi/chains'; import dynamics from './dynamics'; export const getBackendRPCPath = (chainId: Chain['id']) => { return dynamics.rpcProviderUrls[chainId]; }; - -export const backendRPC = { - [mainnet.id]: getBackendRPCPath(mainnet.id), - [holesky.id]: getBackendRPCPath(holesky.id), -}; diff --git a/apps/demo-react/hooks/useRpcUrls.ts b/apps/demo-react/hooks/useRpcUrls.ts new file mode 100644 index 00000000..6427efc4 --- /dev/null +++ b/apps/demo-react/hooks/useRpcUrls.ts @@ -0,0 +1,22 @@ +import { useMemo } from 'react'; +import { CHAINS } from '@lido-sdk/constants'; +import { useClientConfig } from 'providers/client-config'; +import { getBackendRPCPath } from 'config'; + +export const useRpcUrls = (): Record => { + const { supportedChainIds } = useClientConfig(); + + const backendRPC: Record = useMemo( + () => + supportedChainIds.reduce( + (res, curr) => ({ ...res, [curr]: getBackendRPCPath(curr) }), + { + // Mainnet RPC is always required for some requests, e.g. ETH to USD price, ENS lookup + [CHAINS.Mainnet]: getBackendRPCPath(CHAINS.Mainnet), + }, + ), + [supportedChainIds], + ); + + return backendRPC; +}; diff --git a/apps/demo-react/providers/client-config.tsx b/apps/demo-react/providers/client-config.tsx index a8694fb4..46a7a6da 100644 --- a/apps/demo-react/providers/client-config.tsx +++ b/apps/demo-react/providers/client-config.tsx @@ -17,17 +17,18 @@ import { CHAINS } from 'config/chains'; import { parseEnvConfig } from 'utils/parse-env-config'; type SavedClientConfig = { + defaultChain?: number; rpcUrls: Partial>; }; -type ClientConfigContext = EnvConfigParsed & { - savedClientConfig: SavedClientConfig; - setSavedClientConfig: (config: SavedClientConfig) => void; - isWalletConnectionAllowed: boolean; - setIsWalletConnectionAllowed: (isAllowed: boolean) => void; - setIsWalletInfoIsOpen: (isOpen: boolean) => void; - isWalletInfoIsOpen: boolean; -}; +type ClientConfigContext = EnvConfigParsed & + SavedClientConfig & { + setSavedClientConfig: (config: Partial) => void; + isWalletConnectionAllowed: boolean; + setIsWalletConnectionAllowed: (isAllowed: boolean) => void; + setIsWalletInfoIsOpen: (isOpen: boolean) => void; + isWalletInfoIsOpen: boolean; + }; export const ClientConfigContext = createContext( null, @@ -56,19 +57,34 @@ export const ClientConfigProvider = ({ children }: PropsWithChildren) => { useState(restoredSettings); const setSavedConfigAndRemember = useCallback( - (config: SavedClientConfig) => { - setLocalStorage(config); - setSavedClientConfig(config); + (config: Partial) => { + const fullConfig = { + ...restoredSettings, + ...config, + }; + setLocalStorage(fullConfig); + setSavedClientConfig(fullConfig); }, - [setLocalStorage], + [restoredSettings, setLocalStorage], ); const contextValue = useMemo(() => { const envConfig = parseEnvConfig(dynamics); - return { + const config = { ...envConfig, - savedClientConfig, + ...savedClientConfig, + }; + + const supportedChainIds = config.supportedChainIds.includes( + config.defaultChain, + ) + ? config.supportedChainIds + : [...config.supportedChainIds, config.defaultChain]; + + return { + ...config, + supportedChainIds, setSavedClientConfig: setSavedConfigAndRemember, isWalletConnectionAllowed, setIsWalletConnectionAllowed, diff --git a/apps/demo-react/providers/sdk.tsx b/apps/demo-react/providers/sdk.tsx index 92efa9b2..2a72cdf2 100644 --- a/apps/demo-react/providers/sdk.tsx +++ b/apps/demo-react/providers/sdk.tsx @@ -5,7 +5,7 @@ import { createWalletClient, custom } from 'viem'; import { LidoSDK } from '@lidofinance/lido-ethereum-sdk'; import invariant from 'tiny-invariant'; -import { getBackendRPCPath } from 'config'; +import { useRpcUrls } from 'hooks/useRpcUrls'; const context = createContext(null); @@ -17,6 +17,7 @@ export const useLidoSDK = () => { export const LidoSDKProvider: React.FC = ({ children }) => { const { providerWeb3, chainId, account } = useSDK(); + const rpcUrls = useRpcUrls(); const value = useMemo(() => { const client = providerWeb3 && account @@ -27,14 +28,14 @@ export const LidoSDKProvider: React.FC = ({ children }) => { const sdk = new LidoSDK({ chainId: chainId as any, - rpcUrls: [getBackendRPCPath(chainId)], + rpcUrls: [rpcUrls[chainId]], web3Provider: client as any, logMode: 'none', }); // inject lido_sdk for console access if (typeof window !== 'undefined') (window as any).lido_sdk = sdk; return sdk; - }, [providerWeb3, chainId, account]); + }, [providerWeb3, chainId, account, rpcUrls]); return {children}; }; diff --git a/apps/demo-react/providers/web3.tsx b/apps/demo-react/providers/web3.tsx index 36ead0ed..b05e80dc 100644 --- a/apps/demo-react/providers/web3.tsx +++ b/apps/demo-react/providers/web3.tsx @@ -5,7 +5,6 @@ import { WalletsListEthereum } from 'reef-knot/wallets'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { WagmiProvider, http } from 'wagmi'; import * as wagmiChains from 'wagmi/chains'; -import { CHAINS } from '@lido-sdk/constants'; import type { Transport } from 'viem'; import { ReefKnotWalletsModal, @@ -13,9 +12,9 @@ import { } from 'reef-knot/connect-wallet-modal'; import metrics from 'utils/metrics'; -import { getBackendRPCPath } from 'config'; import { useClientConfig } from 'providers/client-config'; import { SDKLegacyProvider } from './sdk-legacy'; +import { useRpcUrls } from 'hooks/useRpcUrls'; const LINK_DONT_HAVE_WALLET = 'https://support.metamask.io/hc/en-us/articles/360015489531-Getting-started-with-MetaMask'; @@ -50,17 +49,7 @@ const Web3Provider: FC = ({ children }) => { }; }, [defaultChainId, supportedChainIds]); - const backendRPC: Record = useMemo( - () => - supportedChainIds.reduce( - (res, curr) => ({ ...res, [curr]: getBackendRPCPath(curr) }), - { - // Mainnet RPC is always required for some requests, e.g. ETH to USD price, ENS lookup - [CHAINS.Mainnet]: getBackendRPCPath(CHAINS.Mainnet), - }, - ), - [supportedChainIds], - ); + const backendRPC = useRpcUrls(); const transports = useMemo(() => { return supportedChains.reduce>( From 2879add564d94cb0490a0caeafde222afa54a5f4 Mon Sep 17 00:00:00 2001 From: Evgeny Taktarov Date: Fri, 22 Nov 2024 17:34:44 +0700 Subject: [PATCH 2/2] fix: next build --- apps/demo-react/providers/client-config.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/demo-react/providers/client-config.tsx b/apps/demo-react/providers/client-config.tsx index 46a7a6da..06ccf2a9 100644 --- a/apps/demo-react/providers/client-config.tsx +++ b/apps/demo-react/providers/client-config.tsx @@ -65,7 +65,7 @@ export const ClientConfigProvider = ({ children }: PropsWithChildren) => { setLocalStorage(fullConfig); setSavedClientConfig(fullConfig); }, - [restoredSettings, setLocalStorage], + [restoredSettings, setLocalStorage, setSavedClientConfig], ); const contextValue = useMemo(() => {