From 3a925a1db7a7ff377d349900b1fc8b84a1a5c63f Mon Sep 17 00:00:00 2001 From: Usame Algan Date: Tue, 14 Nov 2023 12:39:33 +0100 Subject: [PATCH] fix: Lazy load mpc core kit --- .gitignore | 3 +- .../common/ConnectWallet/WalletDetails.tsx | 4 +- src/components/common/SocialSigner/index.tsx | 7 +- src/components/welcome/WelcomeLogin/index.tsx | 4 +- .../wallets/mpc/__tests__/useMPC.test.ts | 134 +++++------------ src/hooks/wallets/mpc/useMPC.ts | 140 +++++++++--------- .../wallets/mpc/useRehydrateSocialWallet.ts | 59 ++++++++ src/hooks/wallets/mpc/useSocialWallet.ts | 56 +------ src/pages/_app.tsx | 4 +- src/services/mpc/SocialLoginModule.ts | 24 +-- 10 files changed, 199 insertions(+), 236 deletions(-) create mode 100644 src/hooks/wallets/mpc/useRehydrateSocialWallet.ts diff --git a/.gitignore b/.gitignore index 97916164f6..505387fd77 100644 --- a/.gitignore +++ b/.gitignore @@ -52,4 +52,5 @@ yalc.lock /public/worker-*.js /public/workbox-*.js /public/workbox-*.js.map -/public/fallback* \ No newline at end of file +/public/fallback* +/public/*.js.LICENSE.txt \ No newline at end of file diff --git a/src/components/common/ConnectWallet/WalletDetails.tsx b/src/components/common/ConnectWallet/WalletDetails.tsx index 5f0442f50a..ca8627db8d 100644 --- a/src/components/common/ConnectWallet/WalletDetails.tsx +++ b/src/components/common/ConnectWallet/WalletDetails.tsx @@ -1,8 +1,10 @@ import { Box, Divider, SvgIcon, Typography } from '@mui/material' +import dynamic from 'next/dynamic' import type { ReactElement } from 'react' import LockIcon from '@/public/images/common/lock.svg' -import SocialSigner from '@/components/common/SocialSigner' + +const SocialSigner = dynamic(() => import('@/components/common/SocialSigner')) import WalletLogin from '@/components/welcome/WelcomeLogin/WalletLogin' const WalletDetails = ({ onConnect }: { onConnect: () => void }): ReactElement => { diff --git a/src/components/common/SocialSigner/index.tsx b/src/components/common/SocialSigner/index.tsx index c7f1138219..bef9d919b6 100644 --- a/src/components/common/SocialSigner/index.tsx +++ b/src/components/common/SocialSigner/index.tsx @@ -1,4 +1,7 @@ +import useSocialWallet from '@/hooks/wallets/mpc/useSocialWallet' +import { type ISocialWalletService } from '@/services/mpc/interfaces' import { Box, Button, LinearProgress, SvgIcon, Tooltip, Typography } from '@mui/material' +import { COREKIT_STATUS } from '@web3auth/mpc-core-kit' import { useCallback, useContext, useMemo, useState } from 'react' import { PasswordRecovery } from '@/components/common/SocialSigner/PasswordRecovery' import GoogleLogo from '@/public/images/welcome/logo-google.svg' @@ -15,8 +18,6 @@ import { isSocialLoginWallet } from '@/services/mpc/SocialLoginModule' import { CGW_NAMES } from '@/hooks/wallets/consts' import { type ChainInfo } from '@safe-global/safe-gateway-typescript-sdk' import { TxModalContext } from '@/components/tx-flow' -import { COREKIT_STATUS } from '@web3auth/mpc-core-kit' -import useSocialWallet from '@/hooks/wallets/mpc/useSocialWallet' import madProps from '@/utils/mad-props' import { asError } from '@/services/exceptions/utils' import ErrorMessage from '@/components/tx/ErrorMessage' @@ -41,7 +42,7 @@ const useIsSocialWalletEnabled = () => { } type SocialSignerLoginProps = { - socialWalletService: ReturnType + socialWalletService: ISocialWalletService | undefined wallet: ReturnType supportedChains: ReturnType isMPCLoginEnabled: ReturnType diff --git a/src/components/welcome/WelcomeLogin/index.tsx b/src/components/welcome/WelcomeLogin/index.tsx index ad768bf84a..8163d2436a 100644 --- a/src/components/welcome/WelcomeLogin/index.tsx +++ b/src/components/welcome/WelcomeLogin/index.tsx @@ -1,9 +1,9 @@ -import SocialSigner from '@/components/common/SocialSigner' import { AppRoutes } from '@/config/routes' import { useHasFeature } from '@/hooks/useChains' import { FEATURES } from '@/utils/chains' import { Paper, SvgIcon, Typography, Divider, Link, Box } from '@mui/material' import SafeLogo from '@/public/images/logo-text.svg' +import dynamic from 'next/dynamic' import css from './styles.module.css' import { useRouter } from 'next/router' import WalletLogin from './WalletLogin' @@ -11,6 +11,8 @@ import { LOAD_SAFE_EVENTS, CREATE_SAFE_EVENTS } from '@/services/analytics/event import Track from '@/components/common/Track' import { trackEvent } from '@/services/analytics' +const SocialSigner = dynamic(() => import('@/components/common/SocialSigner')) + const WelcomeLogin = () => { const router = useRouter() const isSocialLoginEnabled = useHasFeature(FEATURES.SOCIAL_LOGIN) diff --git a/src/hooks/wallets/mpc/__tests__/useMPC.test.ts b/src/hooks/wallets/mpc/__tests__/useMPC.test.ts index 2cdfd3f689..7c839a0cb8 100644 --- a/src/hooks/wallets/mpc/__tests__/useMPC.test.ts +++ b/src/hooks/wallets/mpc/__tests__/useMPC.test.ts @@ -1,8 +1,7 @@ import * as useOnboard from '@/hooks/wallets/useOnboard' import * as socialWalletOptions from '@/services/mpc/config' -import { renderHook, waitFor } from '@/tests/test-utils' -import { _getMPCCoreKitInstance, setMPCCoreKitInstance, useInitMPC } from '../useMPC' -import * as useChains from '@/hooks/useChains' +import { waitFor } from '@/tests/test-utils' +import { _getMPCCoreKitInstance, initMPC, setMPCCoreKitInstance } from '../useMPC' import { type ChainInfo, RPC_AUTHENTICATION } from '@safe-global/safe-gateway-typescript-sdk' import { hexZeroPad } from 'ethers/lib/utils' import { ONBOARD_MPC_MODULE_LABEL } from '@/services/mpc/SocialLoginModule' @@ -63,53 +62,55 @@ class EventEmittingMockProvider { } } -describe('useInitMPC', () => { +describe('initMPC', () => { + const mockOnboard = { + state: { + get: () => ({ + wallets: [], + walletModules: [], + }), + }, + } as unknown as OnboardAPI + + const mockChain = { + chainId: '5', + chainName: 'Goerli', + blockExplorerUriTemplate: { + address: 'https://goerli.someprovider.io/{address}', + txHash: 'https://goerli.someprovider.io/{txHash}', + api: 'https://goerli.someprovider.io/', + }, + nativeCurrency: { + decimals: 18, + logoUri: 'https://logo.goerli.com', + name: 'Goerli ETH', + symbol: 'ETH', + }, + rpcUri: { + authentication: RPC_AUTHENTICATION.NO_AUTHENTICATION, + value: 'https://goerli.somerpc.io', + }, + } as unknown as ChainInfo + beforeEach(() => { jest.resetAllMocks() jest.spyOn(socialWalletOptions, 'isSocialWalletOptions').mockReturnValue(true) }) + it('should set the coreKit if user is not logged in yet', async () => { - const connectWalletSpy = jest.fn().mockImplementation(() => Promise.resolve()) - jest.spyOn(useOnboard, 'connectWallet').mockImplementation(connectWalletSpy) + jest.spyOn(useOnboard, 'connectWallet').mockImplementation(() => Promise.resolve(undefined)) jest.spyOn(useOnboard, 'getConnectedWallet').mockReturnValue(null) - jest.spyOn(useOnboard, 'default').mockReturnValue({ - state: { - get: () => ({ - wallets: [], - walletModules: [], - }), - }, - } as unknown as OnboardAPI) - jest.spyOn(useChains, 'useCurrentChain').mockReturnValue({ - chainId: '5', - chainName: 'Goerli', - blockExplorerUriTemplate: { - address: 'https://goerli.someprovider.io/{address}', - txHash: 'https://goerli.someprovider.io/{txHash}', - api: 'https://goerli.someprovider.io/', - }, - nativeCurrency: { - decimals: 18, - logoUri: 'https://logo.goerli.com', - name: 'Goerli ETH', - symbol: 'ETH', - }, - rpcUri: { - authentication: RPC_AUTHENTICATION.NO_AUTHENTICATION, - value: 'https://goerli.somerpc.io', - }, - } as unknown as ChainInfo) const mockWeb3AuthMpcCoreKit = jest.spyOn(require('@web3auth/mpc-core-kit'), 'Web3AuthMPCCoreKit') mockWeb3AuthMpcCoreKit.mockImplementation(() => { return new MockMPCCoreKit(COREKIT_STATUS.INITIALIZED, null) }) - renderHook(() => useInitMPC()) + await initMPC(mockChain, mockOnboard) await waitFor(() => { expect(_getMPCCoreKitInstance()).toBeDefined() - expect(connectWalletSpy).not.toBeCalled() + expect(useOnboard.connectWallet).not.toBeCalled() }) }) @@ -117,33 +118,6 @@ describe('useInitMPC', () => { const connectWalletSpy = jest.fn().mockImplementation(() => Promise.resolve()) jest.spyOn(useOnboard, 'connectWallet').mockImplementation(connectWalletSpy) jest.spyOn(useOnboard, 'getConnectedWallet').mockReturnValue(null) - jest.spyOn(useOnboard, 'default').mockReturnValue({ - state: { - get: () => ({ - wallets: [], - walletModules: [], - }), - }, - } as unknown as OnboardAPI) - jest.spyOn(useChains, 'useCurrentChain').mockReturnValue({ - chainId: '5', - chainName: 'Goerli', - blockExplorerUriTemplate: { - address: 'https://goerli.someprovider.io/{address}', - txHash: 'https://goerli.someprovider.io/{txHash}', - api: 'https://goerli.someprovider.io/', - }, - nativeCurrency: { - decimals: 18, - logoUri: 'https://logo.goerli.com', - name: 'Goerli ETH', - symbol: 'ETH', - }, - rpcUri: { - authentication: RPC_AUTHENTICATION.NO_AUTHENTICATION, - value: 'https://goerli.somerpc.io', - }, - } as unknown as ChainInfo) const mockWeb3AuthMpcCoreKit = jest.spyOn(require('@web3auth/mpc-core-kit'), 'Web3AuthMPCCoreKit') const mockProvider = jest.fn() @@ -151,7 +125,7 @@ describe('useInitMPC', () => { return new MockMPCCoreKit(COREKIT_STATUS.LOGGED_IN, mockProvider as unknown as MPCProvider) }) - renderHook(() => useInitMPC()) + await initMPC(mockChain, mockOnboard) await waitFor(() => { expect(connectWalletSpy).toBeCalled() @@ -160,41 +134,13 @@ describe('useInitMPC', () => { }) it('should copy event handlers and emit chainChanged if the current chain is updated', async () => { - const connectWalletSpy = jest.fn().mockImplementation(() => Promise.resolve()) - jest.spyOn(useOnboard, 'connectWallet').mockImplementation(connectWalletSpy) + jest.spyOn(useOnboard, 'connectWallet').mockImplementation(() => Promise.resolve(undefined)) jest.spyOn(useOnboard, 'getConnectedWallet').mockReturnValue({ address: hexZeroPad('0x1', 20), label: ONBOARD_MPC_MODULE_LABEL, chainId: '1', provider: {} as unknown as EIP1193Provider, }) - jest.spyOn(useOnboard, 'default').mockReturnValue({ - state: { - get: () => ({ - wallets: [], - walletModules: [], - }), - }, - } as unknown as OnboardAPI) - jest.spyOn(useChains, 'useCurrentChain').mockReturnValue({ - chainId: '5', - chainName: 'Goerli', - blockExplorerUriTemplate: { - address: 'https://goerli.someprovider.io/{address}', - txHash: 'https://goerli.someprovider.io/{txHash}', - api: 'https://goerli.someprovider.io/', - }, - nativeCurrency: { - decimals: 18, - logoUri: 'https://logo.goerli.com', - name: 'Goerli ETH', - symbol: 'ETH', - }, - rpcUri: { - authentication: RPC_AUTHENTICATION.NO_AUTHENTICATION, - value: 'https://goerli.somerpc.io', - }, - } as unknown as ChainInfo) const mockWeb3AuthMpcCoreKit = jest.spyOn(require('@web3auth/mpc-core-kit'), 'Web3AuthMPCCoreKit') const mockChainChangedListener = jest.fn() @@ -215,12 +161,12 @@ describe('useInitMPC', () => { return new MockMPCCoreKit(COREKIT_STATUS.LOGGED_IN, mockProvider as unknown as MPCProvider) }) - renderHook(() => useInitMPC()) + await initMPC(mockChain, mockOnboard) await waitFor(() => { expect(mockChainChangedListener).toHaveBeenCalledWith('0x5') expect(_getMPCCoreKitInstance()).toBeDefined() - expect(connectWalletSpy).not.toBeCalled() + expect(useOnboard.connectWallet).not.toBeCalled() }) }) }) diff --git a/src/hooks/wallets/mpc/useMPC.ts b/src/hooks/wallets/mpc/useMPC.ts index b0b9d8544a..94794b242b 100644 --- a/src/hooks/wallets/mpc/useMPC.ts +++ b/src/hooks/wallets/mpc/useMPC.ts @@ -1,88 +1,82 @@ -import { useEffect } from 'react' +import { IS_PRODUCTION } from '@/config/constants' +import { connectWallet, getConnectedWallet } from '@/hooks/wallets/useOnboard' import ExternalStore from '@/services/ExternalStore' -import { COREKIT_STATUS, Web3AuthMPCCoreKit, WEB3AUTH_NETWORK } from '@web3auth/mpc-core-kit' -import { CHAIN_NAMESPACES } from '@web3auth/base' - -import { useCurrentChain } from '@/hooks/useChains' -import { getRpcServiceUrl } from '../web3' -import useOnboard, { connectWallet, getConnectedWallet } from '@/hooks/wallets/useOnboard' -import { useInitSocialWallet } from './useSocialWallet' +import { SOCIAL_WALLET_OPTIONS } from '@/services/mpc/config' import { ONBOARD_MPC_MODULE_LABEL } from '@/services/mpc/SocialLoginModule' -import { isSocialWalletOptions, SOCIAL_WALLET_OPTIONS } from '@/services/mpc/config' -import { IS_PRODUCTION } from '@/config/constants' +import { type ChainInfo } from '@safe-global/safe-gateway-typescript-sdk' +import { type OnboardAPI } from '@web3-onboard/core' +import type { Web3AuthMPCCoreKit } from '@web3auth/mpc-core-kit' +import { COREKIT_STATUS } from '@web3auth/mpc-core-kit' +import { getRpcServiceUrl } from '../web3' const { getStore, setStore, useStore } = new ExternalStore() -export const useInitMPC = () => { - const chain = useCurrentChain() - const onboard = useOnboard() - useInitSocialWallet() +export const initMPC = async (chain: ChainInfo, onboard: OnboardAPI) => { + const chainConfig = { + chainId: `0x${Number(chain.chainId).toString(16)}`, + chainNamespace: 'eip155', + rpcTarget: getRpcServiceUrl(chain.rpcUri), + displayName: chain.chainName, + blockExplorer: new URL(chain.blockExplorerUriTemplate.address).origin, + ticker: chain.nativeCurrency.symbol, + tickerName: chain.nativeCurrency.name, + } - useEffect(() => { - if (!chain || !onboard || !isSocialWalletOptions(SOCIAL_WALLET_OPTIONS)) { - return - } + const currentInstance = getStore() + let previousChainChangedListeners: Function[] = [] + if (currentInstance?.provider) { + // We are already connected. We copy onboards event listener for the chainChanged event to propagate a potentially new chainId + const oldProvider = currentInstance.provider + previousChainChangedListeners = oldProvider.listeners('chainChanged') + } - const chainConfig = { - chainId: `0x${Number(chain.chainId).toString(16)}`, - chainNamespace: CHAIN_NAMESPACES.EIP155, - rpcTarget: getRpcServiceUrl(chain.rpcUri), - displayName: chain.chainName, - blockExplorer: new URL(chain.blockExplorerUriTemplate.address).origin, - ticker: chain.nativeCurrency.symbol, - tickerName: chain.nativeCurrency.name, - } + const { Web3AuthMPCCoreKit, WEB3AUTH_NETWORK } = await import('@web3auth/mpc-core-kit') - const currentInstance = getStore() - let previousChainChangedListeners: Function[] = [] - if (currentInstance?.provider) { - // We are already connected. We copy onboards event listener for the chainChanged event to propagate a potentially new chainId - const oldProvider = currentInstance.provider - previousChainChangedListeners = oldProvider.listeners('chainChanged') - } + const web3AuthCoreKit = new Web3AuthMPCCoreKit({ + web3AuthClientId: SOCIAL_WALLET_OPTIONS.web3AuthClientId, + // Available networks are "sapphire_devnet", "sapphire_mainnet" + web3AuthNetwork: WEB3AUTH_NETWORK.MAINNET, + baseUrl: `${window.location.origin}/`, + uxMode: 'popup', + enableLogging: !IS_PRODUCTION, + //@ts-ignore + chainConfig, + manualSync: true, + hashedFactorNonce: 'safe-global-sfa-nonce', + }) - const web3AuthCoreKit = new Web3AuthMPCCoreKit({ - web3AuthClientId: SOCIAL_WALLET_OPTIONS.web3AuthClientId, - // Available networks are "sapphire_devnet", "sapphire_mainnet" - web3AuthNetwork: WEB3AUTH_NETWORK.MAINNET, - baseUrl: `${window.location.origin}/`, - uxMode: 'popup', - enableLogging: !IS_PRODUCTION, - chainConfig, - manualSync: true, - hashedFactorNonce: 'safe-global-sfa-nonce', - }) + return web3AuthCoreKit + .init() + .then(() => { + setStore(web3AuthCoreKit) + // If rehydration was successful, connect to onboard + if (web3AuthCoreKit.status !== COREKIT_STATUS.LOGGED_IN || !web3AuthCoreKit.provider) { + return web3AuthCoreKit + } - web3AuthCoreKit - .init() - .then(() => { - setStore(web3AuthCoreKit) - // If rehydration was successful, connect to onboard - if (web3AuthCoreKit.status !== COREKIT_STATUS.LOGGED_IN || !web3AuthCoreKit.provider) { - return - } - const connectedWallet = getConnectedWallet(onboard.state.get().wallets) - if (!connectedWallet) { - connectWallet(onboard, { - autoSelect: { - label: ONBOARD_MPC_MODULE_LABEL, - disableModals: true, - }, - }).catch((reason) => console.error('Error connecting to MPC module:', reason)) - } else { - const newProvider = web3AuthCoreKit.provider + const connectedWallet = getConnectedWallet(onboard.state.get().wallets) + if (!connectedWallet) { + connectWallet(onboard, { + autoSelect: { + label: ONBOARD_MPC_MODULE_LABEL, + disableModals: true, + }, + }).catch((reason) => console.error('Error connecting to MPC module:', reason)) + } else { + const newProvider = web3AuthCoreKit.provider - // To propagate the changedChain we disconnect and connect - if (previousChainChangedListeners.length > 0 && newProvider) { - previousChainChangedListeners.forEach((previousListener) => - newProvider.addListener('chainChanged', (...args: []) => previousListener(...args)), - ) - newProvider.emit('chainChanged', `0x${Number(chainConfig.chainId).toString(16)}`) - } + // To propagate the changedChain we disconnect and connect + if (previousChainChangedListeners.length > 0 && newProvider) { + previousChainChangedListeners.forEach((previousListener) => + newProvider.addListener('chainChanged', (...args: []) => previousListener(...args)), + ) + newProvider.emit('chainChanged', `0x${Number(chainConfig.chainId).toString(16)}`) } - }) - .catch((error) => console.error(error)) - }, [chain, onboard]) + } + + return web3AuthCoreKit + }) + .catch((error) => console.error(error)) } export const _getMPCCoreKitInstance = getStore diff --git a/src/hooks/wallets/mpc/useRehydrateSocialWallet.ts b/src/hooks/wallets/mpc/useRehydrateSocialWallet.ts new file mode 100644 index 0000000000..cb9c454c15 --- /dev/null +++ b/src/hooks/wallets/mpc/useRehydrateSocialWallet.ts @@ -0,0 +1,59 @@ +import useAddressBook from '@/hooks/useAddressBook' +import useChainId from '@/hooks/useChainId' +import { useCurrentChain } from '@/hooks/useChains' +import useOnboard, { connectWallet } from '@/hooks/wallets/useOnboard' +import { ONBOARD_MPC_MODULE_LABEL } from '@/services/mpc/SocialLoginModule' +import { useAppDispatch } from '@/store' +import { upsertAddressBookEntry } from '@/store/addressBookSlice' +import { useEffect } from 'react' +import { checksumAddress } from '@/utils/addresses' + +const useRehydrateSocialWallet = () => { + const chain = useCurrentChain() + const onboard = useOnboard() + const currentChainId = useChainId() + const addressBook = useAddressBook() + const dispatch = useAppDispatch() + + useEffect(() => { + if (!chain || !onboard) return + + const rehydrate = async () => { + const { initMPC } = await import('./useMPC') + const { initSocialWallet } = await import('./useSocialWallet') + const mpcCoreKit = await initMPC(chain, onboard) + + if (!mpcCoreKit) return + + const socialWalletService = await initSocialWallet(mpcCoreKit) + + const onConnect = async () => { + const wallets = await connectWallet(onboard, { + autoSelect: { + label: ONBOARD_MPC_MODULE_LABEL, + disableModals: true, + }, + }).catch((reason) => console.error('Error connecting to MPC module:', reason)) + + // If the signer is not in the address book => add the user's email as name + const userInfo = socialWalletService?.getUserInfo() + if (userInfo && wallets && currentChainId && wallets.length > 0) { + const address = wallets[0].accounts[0]?.address + if (address) { + const signerAddress = checksumAddress(address) + if (addressBook[signerAddress] === undefined) { + const email = userInfo.email + dispatch(upsertAddressBookEntry({ address: signerAddress, chainId: currentChainId, name: email })) + } + } + } + } + + socialWalletService.setOnConnect(onConnect) + } + + void rehydrate() + }, [addressBook, chain, currentChainId, dispatch, onboard]) +} + +export default useRehydrateSocialWallet diff --git a/src/hooks/wallets/mpc/useSocialWallet.ts b/src/hooks/wallets/mpc/useSocialWallet.ts index d98998ffdd..f0a4d3315c 100644 --- a/src/hooks/wallets/mpc/useSocialWallet.ts +++ b/src/hooks/wallets/mpc/useSocialWallet.ts @@ -1,59 +1,15 @@ -import useAddressBook from '@/hooks/useAddressBook' -import useChainId from '@/hooks/useChainId' import ExternalStore from '@/services/ExternalStore' import type { ISocialWalletService } from '@/services/mpc/interfaces' -import { ONBOARD_MPC_MODULE_LABEL } from '@/services/mpc/SocialLoginModule' -import SocialWalletService from '@/services/mpc/SocialWalletService' -import { useAppDispatch } from '@/store' -import { upsertAddressBookEntry } from '@/store/addressBookSlice' -import { checksumAddress } from '@/utils/addresses' -import { useCallback, useEffect } from 'react' -import useOnboard, { connectWallet } from '../useOnboard' -import useMpc from './useMPC' +import { type Web3AuthMPCCoreKit } from '@web3auth/mpc-core-kit' const { getStore, setStore, useStore } = new ExternalStore() -export const useInitSocialWallet = () => { - const mpcCoreKit = useMpc() - const onboard = useOnboard() - const addressBook = useAddressBook() - const currentChainId = useChainId() - const dispatch = useAppDispatch() - const socialWalletService = useStore() +export const initSocialWallet = async (mpcCoreKit: Web3AuthMPCCoreKit) => { + const SocialWalletService = (await import('@/services/mpc/SocialWalletService')).default + const socialWalletService = new SocialWalletService(mpcCoreKit) + setStore(new SocialWalletService(mpcCoreKit)) - const onConnect = useCallback(async () => { - if (!onboard || !socialWalletService) return - - const wallets = await connectWallet(onboard, { - autoSelect: { - label: ONBOARD_MPC_MODULE_LABEL, - disableModals: true, - }, - }).catch((reason) => console.error('Error connecting to MPC module:', reason)) - - // If the signer is not in the address book => add the user's email as name - const userInfo = socialWalletService.getUserInfo() - if (userInfo && wallets && currentChainId && wallets.length > 0) { - const address = wallets[0].accounts[0]?.address - if (address) { - const signerAddress = checksumAddress(address) - if (addressBook[signerAddress] === undefined) { - const email = userInfo.email - dispatch(upsertAddressBookEntry({ address: signerAddress, chainId: currentChainId, name: email })) - } - } - } - }, [addressBook, currentChainId, dispatch, onboard, socialWalletService]) - - useEffect(() => { - socialWalletService?.setOnConnect(onConnect) - }, [onConnect, socialWalletService]) - - useEffect(() => { - if (mpcCoreKit) { - setStore(new SocialWalletService(mpcCoreKit)) - } - }, [mpcCoreKit]) + return socialWalletService } export const getSocialWalletService = getStore diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index e7b3d6d3d7..65dcbf5fe9 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -1,3 +1,4 @@ +import useRehydrateSocialWallet from '@/hooks/wallets/mpc/useRehydrateSocialWallet' import PasswordRecoveryModal from '@/services/mpc/PasswordRecoveryModal' import Sentry from '@/services/sentry' // needs to be imported first import type { ReactNode } from 'react' @@ -38,7 +39,6 @@ import useSafeMessageNotifications from '@/hooks/messages/useSafeMessageNotifica import useSafeMessagePendingStatuses from '@/hooks/messages/useSafeMessagePendingStatuses' import useChangedValue from '@/hooks/useChangedValue' import { TxModalProvider } from '@/components/tx-flow' -import { useInitMPC } from '@/hooks/wallets/mpc/useMPC' import { WalletConnectProvider } from '@/services/walletconnect/WalletConnectContext' import useABTesting from '@/services/tracking/useAbTesting' import { AbTest } from '@/services/tracking/abTesting' @@ -65,7 +65,7 @@ const InitApp = (): null => { useTxTracking() useSafeMsgTracking() useBeamer() - useInitMPC() + useRehydrateSocialWallet() useABTesting(AbTest.HUMAN_DESCRIPTION) return null diff --git a/src/services/mpc/SocialLoginModule.ts b/src/services/mpc/SocialLoginModule.ts index 6e34ce89d8..84052dfbed 100644 --- a/src/services/mpc/SocialLoginModule.ts +++ b/src/services/mpc/SocialLoginModule.ts @@ -1,14 +1,9 @@ -import { _getMPCCoreKitInstance } from '@/hooks/wallets/mpc/useMPC' -import { getSocialWalletService } from '@/hooks/wallets/mpc/useSocialWallet' import { getWeb3ReadOnly } from '@/hooks/wallets/web3' -import * as PasswordRecoveryModal from '@/services/mpc/PasswordRecoveryModal' import { FEATURES, hasFeature } from '@/utils/chains' import type { ChainInfo } from '@safe-global/safe-gateway-typescript-sdk' import { type WalletInit, ProviderRpcError } from '@web3-onboard/common' import { type EIP1193Provider } from '@web3-onboard/core' -import { COREKIT_STATUS } from '@web3auth/mpc-core-kit' - -const getMPCProvider = () => _getMPCCoreKitInstance()?.provider +import { type Web3AuthMPCCoreKit } from '@web3auth/mpc-core-kit' const assertDefined = (mpcProvider: T | undefined) => { if (!mpcProvider) { @@ -23,9 +18,9 @@ export const isSocialLoginWallet = (walletLabel: string | undefined) => { return walletLabel === ONBOARD_MPC_MODULE_LABEL } -const getConnectedAccounts = async () => { +const getConnectedAccounts = async (provider: typeof Web3AuthMPCCoreKit.prototype.provider | undefined) => { try { - const web3 = assertDefined(getMPCProvider()) + const web3 = assertDefined(provider) return web3.request({ method: 'eth_accounts' }) } catch (e) { throw new ProviderRpcError({ @@ -50,6 +45,13 @@ function MpcModule(chain: ChainInfo): WalletInit { label: ONBOARD_MPC_MODULE_LABEL, getIcon: async () => (await import('./icon')).default, getInterface: async () => { + const { _getMPCCoreKitInstance } = await import('@/hooks/wallets/mpc/useMPC') + const { getSocialWalletService } = await import('@/hooks/wallets/mpc/useSocialWallet') + const { COREKIT_STATUS } = await import('@web3auth/mpc-core-kit') + const { open } = await import('./PasswordRecoveryModal') + + const getMPCProvider = () => _getMPCCoreKitInstance()?.provider + const provider: EIP1193Provider = { on: (event, listener) => { const web3 = assertDefined(getMPCProvider()) @@ -85,11 +87,11 @@ function MpcModule(chain: ChainInfo): WalletInit { const status = await socialWalletService.loginAndCreate() if (status === COREKIT_STATUS.REQUIRED_SHARE) { - PasswordRecoveryModal.open(() => { - getConnectedAccounts().then(resolve).catch(reject) + open(() => { + getConnectedAccounts(getMPCProvider()).then(resolve).catch(reject) }) } else { - getConnectedAccounts().then(resolve).catch(reject) + getConnectedAccounts(getMPCProvider()).then(resolve).catch(reject) } } return