From 070d6bf8d89dd0409394c9e83dfeba982560d401 Mon Sep 17 00:00:00 2001 From: Gavrila Andrei Date: Fri, 13 Dec 2024 12:09:59 +0200 Subject: [PATCH] Fix walletConnect persistance --- .../CrossWindowProviderStrategy.ts | 7 ++- .../IFrameProviderStrategy.ts | 7 +-- .../WalletConnectProviderStrategy.ts | 47 ++++++++++++------- src/core/providers/helpers/restoreProvider.ts | 11 ++++- .../providers/types/providerFactory.types.ts | 2 +- src/store/actions/config/configActions.ts | 8 ++++ src/store/selectors/configSelectors.ts | 4 ++ src/store/slices/config/config.types.ts | 2 + src/store/slices/config/configSlice.ts | 3 +- 9 files changed, 65 insertions(+), 26 deletions(-) diff --git a/src/core/providers-strategy/CrossWindowProviderStrategy.ts b/src/core/providers-strategy/CrossWindowProviderStrategy.ts index 5d05711..9d980f0 100644 --- a/src/core/providers-strategy/CrossWindowProviderStrategy.ts +++ b/src/core/providers-strategy/CrossWindowProviderStrategy.ts @@ -46,16 +46,15 @@ export class CrossWindowProviderStrategy { }; private buildProvider = () => { + const { address } = getAccount(); + if (!this.provider) { throw new Error(ProviderErrorsEnum.notInitialized); } const provider = this.provider as unknown as IProvider; - if (this.address) { - provider.setAccount({ address: this.address }); - } - + provider.setAccount({ address: this.address || address }); provider.signTransactions = this.signTransactions; provider.signMessage = this.signMessage; diff --git a/src/core/providers-strategy/IFrameProviderStrategy.ts b/src/core/providers-strategy/IFrameProviderStrategy.ts index 04706ad..8d98e7e 100644 --- a/src/core/providers-strategy/IFrameProviderStrategy.ts +++ b/src/core/providers-strategy/IFrameProviderStrategy.ts @@ -1,5 +1,6 @@ import { IframeProvider } from '@multiversx/sdk-web-wallet-iframe-provider/out'; import { IframeLoginTypes } from '@multiversx/sdk-web-wallet-iframe-provider/out/constants'; +import { getAccount } from 'core/methods/account/getAccount'; import { IProvider } from 'core/providers/types/providerFactory.types'; import { networkSelector } from 'store/selectors/networkSelectors'; import { getState } from 'store/store'; @@ -38,15 +39,15 @@ export class IFrameProviderStrategy { }; private buildProvider = () => { + const { address } = getAccount(); + if (!this.provider) { throw new Error(ProviderErrorsEnum.notInitialized); } const provider = this.provider as unknown as IProvider; - if (this.address) { - provider.setAccount({ address: this.address }); - } + provider.setAccount({ address: this.address || address }); return provider; }; diff --git a/src/core/providers-strategy/WalletConnectProviderStrategy.ts b/src/core/providers-strategy/WalletConnectProviderStrategy.ts index 5a6a346..46ba6e3 100644 --- a/src/core/providers-strategy/WalletConnectProviderStrategy.ts +++ b/src/core/providers-strategy/WalletConnectProviderStrategy.ts @@ -18,6 +18,7 @@ import { } from 'core/providers/types/providerFactory.types'; import { defineCustomElements, WalletConnectModal } from 'lib/sdkDappCoreUi'; import { logoutAction } from 'store/actions'; +import { setWalletConnectConfig } from 'store/actions/config/configActions'; import { chainIdSelector, nativeAuthConfigSelector } from 'store/selectors'; import { getState } from 'store/store'; import { ProviderErrorsEnum } from 'types'; @@ -60,8 +61,12 @@ export class WalletConnectProviderStrategy { const eventBus = await this.createEventBus(); - const manager = WalletConnectStateManager.getInstance(eventBus); - this.manager = manager; + if (eventBus) { + const manager = WalletConnectStateManager.getInstance(eventBus); + this.manager = manager; + + setWalletConnectConfig(this.config); + } if (!this.provider) { const { walletConnectProvider, dappMethods } = @@ -74,21 +79,31 @@ export class WalletConnectProviderStrategy { } const onClose = () => { - manager.closeAndReset(); + if (!this.manager) { + throw new Error('State manager is not initialized'); + } + + this.manager.closeAndReset(); }; this.unsubscribeEvents = () => { + if (!eventBus) { + throw new Error('Event bus is not initialized'); + } + eventBus.unsubscribe(WalletConnectEventsEnum.CLOSE, onClose); }; - const { uri = '', approval } = await this.provider.connect({ - methods: this.methods - }); + if (eventBus && this.manager) { + const { uri = '', approval } = await this.provider.connect({ + methods: this.methods + }); - this.approval = approval; - manager.updateWcURI(uri); + this.approval = approval; + this.manager.updateWcURI(uri); - eventBus.subscribe(WalletConnectEventsEnum.CLOSE, onClose); + eventBus.subscribe(WalletConnectEventsEnum.CLOSE, onClose); + } return this.buildProvider(); }; @@ -122,10 +137,10 @@ export class WalletConnectProviderStrategy { await customElements.whenDefined('wallet-connect-modal'); eventBus = await walletConnectModalElement.getEventBus(); - } - if (!eventBus) { - throw new Error('Event bus not provided for WalletConnect provider'); + if (!eventBus) { + throw new Error('Event bus not provided for WalletConnect provider'); + } } return eventBus; @@ -150,11 +165,11 @@ export class WalletConnectProviderStrategy { const handleOnLogin = () => {}; const handleOnLogout = async () => { - if (config.onLogout) { - await config.onLogout(); - } - logoutAction(); + + if (config.logoutRoute) { + safeWindow.location.replace(config.logoutRoute); + } }; const handleOnEvent = (_event: SessionEventTypes['event']) => {}; diff --git a/src/core/providers/helpers/restoreProvider.ts b/src/core/providers/helpers/restoreProvider.ts index 9a4ff0c..450130b 100644 --- a/src/core/providers/helpers/restoreProvider.ts +++ b/src/core/providers/helpers/restoreProvider.ts @@ -1,5 +1,8 @@ import { getAddress } from 'core/methods/account/getAddress'; -import { providerTypeSelector } from 'store/selectors'; +import { + walletConnectConfigSelector, + providerTypeSelector +} from 'store/selectors'; import { getState } from 'store/store'; import { setAccountProvider } from '../accountProvider'; import { ProviderFactory } from '../ProviderFactory'; @@ -7,6 +10,8 @@ import { IProviderConfig } from '../types/providerFactory.types'; export async function restoreProvider() { const type = providerTypeSelector(getState()); + const walletConnectConfig = walletConnectConfigSelector(getState()); + const address = getAddress(); if (!type) { @@ -19,6 +24,10 @@ export async function restoreProvider() { } }; + if (walletConnectConfig) { + config.walletConnect = walletConnectConfig; + } + const provider = await ProviderFactory.create({ type, config diff --git a/src/core/providers/types/providerFactory.types.ts b/src/core/providers/types/providerFactory.types.ts index bfa222f..be74fcd 100644 --- a/src/core/providers/types/providerFactory.types.ts +++ b/src/core/providers/types/providerFactory.types.ts @@ -47,7 +47,7 @@ export interface IProviderConfig { walletConnectV2RelayAddress?: string; walletConnectV2Options?: WalletConnectV2ProviderOptionsType; customRequestMethods?: Array; - onLogout?: () => Promise; + logoutRoute?: string; }; } diff --git a/src/store/actions/config/configActions.ts b/src/store/actions/config/configActions.ts index 08b1bd0..b6b9704 100644 --- a/src/store/actions/config/configActions.ts +++ b/src/store/actions/config/configActions.ts @@ -1,3 +1,4 @@ +import { IProviderConfig } from 'core/providers/types/providerFactory.types'; import { NativeAuthConfigType } from 'services/nativeAuth/nativeAuth.types'; import { getStore } from 'store/store'; @@ -5,3 +6,10 @@ export const setNativeAuthConfig = (config: NativeAuthConfigType) => getStore().setState(({ config: state }) => { state.nativeAuthConfig = config; }); + +export const setWalletConnectConfig = ( + config: IProviderConfig['walletConnect'] +) => + getStore().setState(({ config: state }) => { + state.walletConnectConfig = config; + }); diff --git a/src/store/selectors/configSelectors.ts b/src/store/selectors/configSelectors.ts index d4e507d..bc66dfe 100644 --- a/src/store/selectors/configSelectors.ts +++ b/src/store/selectors/configSelectors.ts @@ -4,3 +4,7 @@ export const configSelector = ({ config }: StoreType) => config; export const nativeAuthConfigSelector = ({ config }: StoreType) => config.nativeAuthConfig; + +export const walletConnectConfigSelector = ({ config }: StoreType) => { + return config.walletConnectConfig; +}; diff --git a/src/store/slices/config/config.types.ts b/src/store/slices/config/config.types.ts index 52b3270..8ec49d4 100644 --- a/src/store/slices/config/config.types.ts +++ b/src/store/slices/config/config.types.ts @@ -1,5 +1,7 @@ +import { IProviderConfig } from 'core/providers/types/providerFactory.types'; import { NativeAuthConfigType } from 'services/nativeAuth/nativeAuth.types'; export interface ConfigSliceType { nativeAuthConfig: NativeAuthConfigType | null; + walletConnectConfig: IProviderConfig['walletConnect'] | null; } diff --git a/src/store/slices/config/configSlice.ts b/src/store/slices/config/configSlice.ts index 3c4500d..9a714e6 100644 --- a/src/store/slices/config/configSlice.ts +++ b/src/store/slices/config/configSlice.ts @@ -7,7 +7,8 @@ import { ConfigSliceType } from './config.types'; // The config should be changed by using the `setNativeAuthConfig` action in some specific cases. // Preferably, the config should be set at the dApp initialization and not changed during the dApp lifecycle. (e.g. when the user logs in/log out) const initialState: ConfigSliceType = { - nativeAuthConfig: null + nativeAuthConfig: null, + walletConnectConfig: null }; function getConfigSlice(): StateCreator<