From eea9b15768f9bb3737302b80b3cfadd5bbd49b16 Mon Sep 17 00:00:00 2001 From: enesozturk Date: Tue, 17 Sep 2024 14:01:09 +0300 Subject: [PATCH 01/17] refactor: update local storage keys --- .../adapters/ethers/src/tests/client.test.ts | 26 ++++--- .../adapters/ethers5/src/tests/client.test.ts | 26 ++++--- .../src/ethers/EthersConstantsUtil.ts | 1 - .../src/solana/SolanaConstantsUtil.ts | 2 - packages/appkit/src/utils/ConstantsUtil.ts | 3 - packages/common/src/utils/SafeLocalStorage.ts | 36 +++++---- .../common/tests/SafeLocalStorage.test.ts | 14 ++-- packages/core/src/utils/StorageUtil.ts | 77 ++++--------------- packages/core/tests/utils/StorageUtil.test.ts | 20 ++--- packages/wallet/src/W3mFrameConstants.ts | 3 +- packages/wallet/src/W3mFrameProvider.ts | 1 - 11 files changed, 89 insertions(+), 120 deletions(-) diff --git a/packages/adapters/ethers/src/tests/client.test.ts b/packages/adapters/ethers/src/tests/client.test.ts index 385c33d41e..c278bef6e3 100644 --- a/packages/adapters/ethers/src/tests/client.test.ts +++ b/packages/adapters/ethers/src/tests/client.test.ts @@ -9,8 +9,8 @@ import { EthersHelpersUtil, type ProviderId, type ProviderType } from '@reown/ap import { ConstantsUtil } from '@reown/appkit-utils' import { arbitrum, mainnet, polygon } from '@reown/appkit/networks' import { ProviderUtil } from '@reown/appkit/store' -import { SafeLocalStorage } from '@reown/appkit-common' -import { WcConstantsUtil, type BlockchainApiLookupEnsName } from '@reown/appkit' +import { SafeLocalStorage, SafeLocalStorageKeys } from '@reown/appkit-common' +import { type BlockchainApiLookupEnsName } from '@reown/appkit' import { InfuraProvider, JsonRpcProvider } from 'ethers' import type { CaipNetwork, ChainNamespace } from '@reown/appkit-common' @@ -519,8 +519,14 @@ describe('EthersAdapter', () => { const mockProvider = { request: vi.fn() } await client['setProvider'](mockProvider as any, 'injected', 'MetaMask') - expect(SafeLocalStorage.setItem).toHaveBeenCalledWith(WcConstantsUtil.WALLET_ID, 'injected') - expect(SafeLocalStorage.setItem).toHaveBeenCalledWith(WcConstantsUtil.WALLET_NAME, 'MetaMask') + expect(SafeLocalStorage.setItem).toHaveBeenCalledWith( + SafeLocalStorageKeys.WALLET_ID, + 'injected' + ) + expect(SafeLocalStorage.setItem).toHaveBeenCalledWith( + SafeLocalStorageKeys.WALLET_NAME, + 'MetaMask' + ) expect(mockAppKit.setCaipNetwork).toHaveBeenCalled() expect(mockAppKit.setCaipAddress).toHaveBeenCalled() expect(ProviderUtil.setProviderId).toHaveBeenCalledWith('eip155', 'injected') @@ -557,7 +563,7 @@ describe('EthersAdapter', () => { )[1] await disconnectHandler() - expect(SafeLocalStorage.removeItem).toHaveBeenCalledWith(WcConstantsUtil.WALLET_ID) + expect(SafeLocalStorage.removeItem).toHaveBeenCalledWith(SafeLocalStorageKeys.WALLET_ID) expect(mockProvider.removeListener).toHaveBeenCalledTimes(3) }) @@ -595,8 +601,8 @@ describe('EthersAdapter', () => { } vi.spyOn(SafeLocalStorage, 'getItem').mockImplementation(key => { - if (key === WcConstantsUtil.WALLET_ID) return ConstantsUtil.INJECTED_CONNECTOR_ID - if (key === WcConstantsUtil.WALLET_NAME) return 'MetaMask' + if (key === SafeLocalStorageKeys.WALLET_ID) return ConstantsUtil.INJECTED_CONNECTOR_ID + if (key === SafeLocalStorageKeys.WALLET_NAME) return 'MetaMask' return null }) @@ -613,7 +619,7 @@ describe('EthersAdapter', () => { client['checkActiveProviders'](mockConfig as ProviderType) - expect(SafeLocalStorage.getItem).toHaveBeenCalledWith(WcConstantsUtil.WALLET_ID) + expect(SafeLocalStorage.getItem).toHaveBeenCalledWith(SafeLocalStorageKeys.WALLET_ID) expect(client['setProvider']).toHaveBeenCalledWith( mockInjectedProvider, ConstantsUtil.INJECTED_CONNECTOR_ID @@ -635,7 +641,7 @@ describe('EthersAdapter', () => { client['checkActiveProviders'](mockConfig as ProviderType) - expect(SafeLocalStorage.getItem).toHaveBeenCalledWith(WcConstantsUtil.WALLET_ID) + expect(SafeLocalStorage.getItem).toHaveBeenCalledWith(SafeLocalStorageKeys.WALLET_ID) expect(client['setProvider']).not.toHaveBeenCalled() expect(client['setupProviderListeners']).not.toHaveBeenCalled() }) @@ -649,7 +655,7 @@ describe('EthersAdapter', () => { client['checkActiveProviders'](mockConfig as ProviderType) - expect(SafeLocalStorage.getItem).toHaveBeenCalledWith(WcConstantsUtil.WALLET_ID) + expect(SafeLocalStorage.getItem).toHaveBeenCalledWith(SafeLocalStorageKeys.WALLET_ID) expect(client['setProvider']).not.toHaveBeenCalled() expect(client['setupProviderListeners']).not.toHaveBeenCalled() }) diff --git a/packages/adapters/ethers5/src/tests/client.test.ts b/packages/adapters/ethers5/src/tests/client.test.ts index 37dd009a4e..6966e3db5b 100644 --- a/packages/adapters/ethers5/src/tests/client.test.ts +++ b/packages/adapters/ethers5/src/tests/client.test.ts @@ -9,8 +9,8 @@ import { EthersHelpersUtil, type ProviderId, type ProviderType } from '@reown/ap import { ConstantsUtil } from '@reown/appkit-utils' import { arbitrum, mainnet, polygon } from '@reown/appkit/networks' import { ProviderUtil } from '@reown/appkit/store' -import { SafeLocalStorage } from '@reown/appkit-common' -import { WcConstantsUtil, type BlockchainApiLookupEnsName } from '@reown/appkit' +import { SafeLocalStorage, SafeLocalStorageKeys } from '@reown/appkit-common' +import { type BlockchainApiLookupEnsName } from '@reown/appkit' import { ethers } from 'ethers5' import type { CaipNetwork, ChainNamespace } from '@reown/appkit-common' @@ -524,8 +524,14 @@ describe('EthersAdapter', () => { const mockProvider = { request: vi.fn() } await client['setProvider'](mockProvider as any, 'injected', 'MetaMask') - expect(SafeLocalStorage.setItem).toHaveBeenCalledWith(WcConstantsUtil.WALLET_ID, 'injected') - expect(SafeLocalStorage.setItem).toHaveBeenCalledWith(WcConstantsUtil.WALLET_NAME, 'MetaMask') + expect(SafeLocalStorage.setItem).toHaveBeenCalledWith( + SafeLocalStorageKeys.WALLET_ID, + 'injected' + ) + expect(SafeLocalStorage.setItem).toHaveBeenCalledWith( + SafeLocalStorageKeys.WALLET_NAME, + 'MetaMask' + ) expect(mockAppKit.setCaipNetwork).toHaveBeenCalled() expect(ProviderUtil.setProviderId).toHaveBeenCalledWith('eip155', 'injected') expect(ProviderUtil.setProvider).toHaveBeenCalledWith('eip155', mockProvider) @@ -561,7 +567,7 @@ describe('EthersAdapter', () => { )[1] await disconnectHandler() - expect(SafeLocalStorage.removeItem).toHaveBeenCalledWith(WcConstantsUtil.WALLET_ID) + expect(SafeLocalStorage.removeItem).toHaveBeenCalledWith(SafeLocalStorageKeys.WALLET_ID) expect(mockProvider.removeListener).toHaveBeenCalledTimes(3) }) @@ -599,8 +605,8 @@ describe('EthersAdapter', () => { } vi.spyOn(SafeLocalStorage, 'getItem').mockImplementation(key => { - if (key === WcConstantsUtil.WALLET_ID) return ConstantsUtil.INJECTED_CONNECTOR_ID - if (key === WcConstantsUtil.WALLET_NAME) return 'MetaMask' + if (key === SafeLocalStorageKeys.WALLET_ID) return ConstantsUtil.INJECTED_CONNECTOR_ID + if (key === SafeLocalStorageKeys.WALLET_NAME) return 'MetaMask' return null }) @@ -617,7 +623,7 @@ describe('EthersAdapter', () => { client['checkActiveProviders'](mockConfig as ProviderType) - expect(SafeLocalStorage.getItem).toHaveBeenCalledWith(WcConstantsUtil.WALLET_ID) + expect(SafeLocalStorage.getItem).toHaveBeenCalledWith(SafeLocalStorageKeys.WALLET_ID) expect(client['setProvider']).toHaveBeenCalledWith( mockInjectedProvider, ConstantsUtil.INJECTED_CONNECTOR_ID @@ -639,7 +645,7 @@ describe('EthersAdapter', () => { client['checkActiveProviders'](mockConfig as ProviderType) - expect(SafeLocalStorage.getItem).toHaveBeenCalledWith(WcConstantsUtil.WALLET_ID) + expect(SafeLocalStorage.getItem).toHaveBeenCalledWith(SafeLocalStorageKeys.WALLET_ID) expect(client['setProvider']).not.toHaveBeenCalled() expect(client['setupProviderListeners']).not.toHaveBeenCalled() }) @@ -653,7 +659,7 @@ describe('EthersAdapter', () => { client['checkActiveProviders'](mockConfig as ProviderType) - expect(SafeLocalStorage.getItem).toHaveBeenCalledWith(WcConstantsUtil.WALLET_ID) + expect(SafeLocalStorage.getItem).toHaveBeenCalledWith(SafeLocalStorageKeys.WALLET_ID) expect(client['setProvider']).not.toHaveBeenCalled() expect(client['setupProviderListeners']).not.toHaveBeenCalled() }) diff --git a/packages/appkit-utils/src/ethers/EthersConstantsUtil.ts b/packages/appkit-utils/src/ethers/EthersConstantsUtil.ts index f123e4a819..70696b74c3 100644 --- a/packages/appkit-utils/src/ethers/EthersConstantsUtil.ts +++ b/packages/appkit-utils/src/ethers/EthersConstantsUtil.ts @@ -1,5 +1,4 @@ export const EthersConstantsUtil = { - WALLET_ID: '@w3m/wallet_id', ERROR_CODE_UNRECOGNIZED_CHAIN_ID: 4902, ERROR_CODE_DEFAULT: 5000 } as const diff --git a/packages/appkit-utils/src/solana/SolanaConstantsUtil.ts b/packages/appkit-utils/src/solana/SolanaConstantsUtil.ts index a1c2de0d50..3c03554ad3 100644 --- a/packages/appkit-utils/src/solana/SolanaConstantsUtil.ts +++ b/packages/appkit-utils/src/solana/SolanaConstantsUtil.ts @@ -19,8 +19,6 @@ export const SolConstantsUtil = { /** * Mainnet program ID */ - WALLET_ID: '@w3m/solana_wallet', - CAIP_CHAIN_ID: '@w3m/solana_caip_chain', ERROR_CODE_UNRECOGNIZED_CHAIN_ID: 4902, ERROR_CODE_DEFAULT: 5000, DEFAULT_CHAIN: { diff --git a/packages/appkit/src/utils/ConstantsUtil.ts b/packages/appkit/src/utils/ConstantsUtil.ts index 39773b1535..3ff57eb05b 100644 --- a/packages/appkit/src/utils/ConstantsUtil.ts +++ b/packages/appkit/src/utils/ConstantsUtil.ts @@ -1,7 +1,4 @@ export const WcConstantsUtil = { - WALLET_ID: '@w3m/wallet_id' as const, - WALLET_NAME: '@w3m/wallet_name' as const, - ACTIVE_CAIPNETWORK: '@w3m/active_caipnetwork' as const, ERROR_CODE_UNRECOGNIZED_CHAIN_ID: 4902, ERROR_CODE_DEFAULT: 5000 } diff --git a/packages/common/src/utils/SafeLocalStorage.ts b/packages/common/src/utils/SafeLocalStorage.ts index 107003d96b..f1fc7007df 100644 --- a/packages/common/src/utils/SafeLocalStorage.ts +++ b/packages/common/src/utils/SafeLocalStorage.ts @@ -1,21 +1,29 @@ export type SafeLocalStorageItems = { - '@w3m/wallet_id': string - '@w3m/wallet_name': string - '@w3m/solana_wallet': string - '@w3m/solana_caip_chain': string - '@w3m/active_caip_network': string - '@w3m/active_caip_network_id': string - '@w3m/connected_connector': string + '@appkit/wallet_id': string + '@appkit/wallet_name': string + '@appkit/solana_wallet': string + '@appkit/solana_caip_chain': string + '@appkit/active_caip_network': string + '@appkit/active_caip_network_id': string + '@appkit/connected_connector': string + '@appkit/connected_social': string + '@appkit/connected_social_username': string + '@appkit/recent_wallets': string + '@appkit/deeplink_choice': string } export const SafeLocalStorageKeys = { - WALLET_ID: '@w3m/wallet_id', - WALLET_NAME: '@w3m/wallet_name', - SOLANA_WALLET: '@w3m/solana_wallet', - SOLANA_CAIP_CHAIN: '@w3m/solana_caip_chain', - ACTIVE_CAIP_NETWORK: '@w3m/active_caip_network', - ACTIVE_CAIP_NETWORK_ID: '@w3m/active_caip_network_id', - CONNECTED_CONNECTOR: '@w3m/connected_connector' + WALLET_ID: '@appkit/wallet_id', + WALLET_NAME: '@appkit/wallet_name', + SOLANA_WALLET: '@appkit/solana_wallet', + SOLANA_CAIP_CHAIN: '@appkit/solana_caip_chain', + ACTIVE_CAIP_NETWORK: '@appkit/active_caip_network', + ACTIVE_CAIP_NETWORK_ID: '@appkit/active_caip_network_id', + CONNECTED_CONNECTOR: '@appkit/connected_connector', + CONNECTED_SOCIAL: '@appkit/connected_social', + CONNECTED_SOCIAL_USERNAME: '@appkit/connected_social_username', + RECENT_WALLETS: '@appkit/recent_wallets', + DEEPLINK_CHOICE: '@appkit/deeplink_choice' } as const export const SafeLocalStorage = { diff --git a/packages/common/tests/SafeLocalStorage.test.ts b/packages/common/tests/SafeLocalStorage.test.ts index dfabb7e131..96c174d653 100644 --- a/packages/common/tests/SafeLocalStorage.test.ts +++ b/packages/common/tests/SafeLocalStorage.test.ts @@ -15,7 +15,7 @@ describe('SafeLocalStorage unsafe', () => { }) it('should not setItem', () => { - const key = '@w3m/wallet_id' + const key = '@appkit/wallet_id' expect(SafeLocalStorage.setItem(key, '1')).toBe(undefined) expect(SafeLocalStorage.getItem(key)).toBe(null) @@ -33,17 +33,17 @@ describe('SafeLocalStorage safe', () => { }) it('should setItem', () => { - expect(SafeLocalStorage.setItem('@w3m/wallet_id', 'test')).toBe(undefined) - expect(setItem).toHaveBeenCalledWith('@w3m/wallet_id', '"test"') + expect(SafeLocalStorage.setItem('@appkit/wallet_id', 'test')).toBe(undefined) + expect(setItem).toHaveBeenCalledWith('@appkit/wallet_id', '"test"') }) it('should getItem', () => { - expect(SafeLocalStorage.getItem('@w3m/wallet_id')).toEqual({ test: 'test' }) - expect(getItem).toHaveBeenCalledWith('@w3m/wallet_id') + expect(SafeLocalStorage.getItem('@appkit/wallet_id')).toEqual({ test: 'test' }) + expect(getItem).toHaveBeenCalledWith('@appkit/wallet_id') }) it('should removeItem', () => { - expect(SafeLocalStorage.removeItem('@w3m/wallet_id')).toBe(undefined) - expect(removeItem).toHaveBeenCalledWith('@w3m/wallet_id') + expect(SafeLocalStorage.removeItem('@appkit/wallet_id')).toBe(undefined) + expect(removeItem).toHaveBeenCalledWith('@appkit/wallet_id') }) }) diff --git a/packages/core/src/utils/StorageUtil.ts b/packages/core/src/utils/StorageUtil.ts index 964c299c56..0895874686 100644 --- a/packages/core/src/utils/StorageUtil.ts +++ b/packages/core/src/utils/StorageUtil.ts @@ -1,42 +1,28 @@ /* eslint-disable no-console */ +import { SafeLocalStorage, SafeLocalStorageKeys } from '@reown/appkit-common' import type { WcWallet, ConnectorType, SocialProvider } from './TypeUtil.js' -// -- Helpers ----------------------------------------------------------------- -const WC_DEEPLINK = 'WALLETCONNECT_DEEPLINK_CHOICE' -const W3M_RECENT = '@w3m/recent' -const W3M_CONNECTED_CONNECTOR = '@w3m/connected_connector' -const W3M_CONNECTED_SOCIAL = '@w3m/connected_social' -const W3M_CONNECTED_SOCIAL_USERNAME = '@w3m-storage/SOCIAL_USERNAME' - // -- Utility ----------------------------------------------------------------- export const StorageUtil = { setWalletConnectDeepLink({ href, name }: { href: string; name: string }) { try { - localStorage.setItem(WC_DEEPLINK, JSON.stringify({ href, name })) + SafeLocalStorage.setItem(SafeLocalStorageKeys.DEEPLINK_CHOICE, JSON.stringify({ href, name })) } catch { console.info('Unable to set WalletConnect deep link') } }, getWalletConnectDeepLink() { - try { - const deepLink = localStorage.getItem(WC_DEEPLINK) - if (deepLink) { - return JSON.parse(deepLink) - } - } catch { - console.info('Unable to get WalletConnect deep link') + const deepLink = SafeLocalStorage.getItem(SafeLocalStorageKeys.DEEPLINK_CHOICE) + if (deepLink) { + return JSON.parse(deepLink) } return undefined }, deleteWalletConnectDeepLink() { - try { - localStorage.removeItem(WC_DEEPLINK) - } catch { - console.info('Unable to delete WalletConnect deep link') - } + SafeLocalStorage.removeItem(SafeLocalStorageKeys.DEEPLINK_CHOICE) }, setAppKitRecent(wallet: WcWallet) { @@ -48,7 +34,7 @@ export const StorageUtil = { if (recentWallets.length > 2) { recentWallets.pop() } - localStorage.setItem(W3M_RECENT, JSON.stringify(recentWallets)) + SafeLocalStorage.setItem(SafeLocalStorageKeys.RECENT_WALLETS, JSON.stringify(recentWallets)) } } catch { console.info('Unable to set AppKit recent') @@ -56,60 +42,31 @@ export const StorageUtil = { }, getRecentWallets(): WcWallet[] { - try { - const recent = localStorage.getItem(W3M_RECENT) - - return recent ? JSON.parse(recent) : [] - } catch { - console.info('Unable to get AppKit recent') - } - - return [] + const recentWallets = SafeLocalStorage.getItem(SafeLocalStorageKeys.RECENT_WALLETS) + return (recentWallets as unknown as WcWallet[]) || [] }, setConnectedConnector(connectorType: ConnectorType) { - try { - localStorage.setItem(W3M_CONNECTED_CONNECTOR, connectorType) - } catch { - console.info('Unable to set Connected Connector') - } + SafeLocalStorage.setItem(SafeLocalStorageKeys.CONNECTED_CONNECTOR, connectorType) }, getConnectedConnector() { - try { - return localStorage.getItem(W3M_CONNECTED_CONNECTOR) as ConnectorType - } catch { - console.info('Unable to get Connected Connector') - } - - return undefined + return SafeLocalStorage.getItem(SafeLocalStorageKeys.CONNECTED_CONNECTOR) as ConnectorType }, setConnectedSocialProvider(socialProvider: SocialProvider) { - try { - localStorage.setItem(W3M_CONNECTED_SOCIAL, socialProvider) - } catch { - console.info('Unable to set Connected Social Provider') - } + SafeLocalStorage.setItem(SafeLocalStorageKeys.CONNECTED_SOCIAL, socialProvider) }, getConnectedSocialProvider() { - try { - return localStorage.getItem(W3M_CONNECTED_SOCIAL) - } catch { - console.info('Unable to get Connected Social Provider') - } + return SafeLocalStorage.getItem(SafeLocalStorageKeys.CONNECTED_SOCIAL) as SocialProvider + }, - return undefined + setConnectedSocialUsername(username: string) { + SafeLocalStorage.setItem(SafeLocalStorageKeys.CONNECTED_SOCIAL_USERNAME, username) }, getConnectedSocialUsername() { - try { - return localStorage.getItem(W3M_CONNECTED_SOCIAL_USERNAME) - } catch { - console.info('Unable to get Connected Social Username') - } - - return undefined + return SafeLocalStorage.getItem(SafeLocalStorageKeys.CONNECTED_SOCIAL_USERNAME) as string } } diff --git a/packages/core/tests/utils/StorageUtil.test.ts b/packages/core/tests/utils/StorageUtil.test.ts index 8f2b810d45..227a228934 100644 --- a/packages/core/tests/utils/StorageUtil.test.ts +++ b/packages/core/tests/utils/StorageUtil.test.ts @@ -36,7 +36,7 @@ describe('StorageUtil', () => { it('should set WalletConnect deep link in localStorage', () => { const deepLink = { href: 'https://example.com', name: 'Example Wallet' } StorageUtil.setWalletConnectDeepLink(deepLink) - expect(localStorage.getItem('WALLETCONNECT_DEEPLINK_CHOICE')).toBe(JSON.stringify(deepLink)) + expect(localStorage.getItem('@appkit/deeplink_choice')).toBe(JSON.stringify(deepLink)) }) it('should handle errors when setting deep link', () => { @@ -53,7 +53,7 @@ describe('StorageUtil', () => { describe('getWalletConnectDeepLink', () => { it('should get WalletConnect deep link from localStorage', () => { const deepLink = { href: 'https://example.com', name: 'Example Wallet' } - localStorage.setItem('WALLETCONNECT_DEEPLINK_CHOICE', JSON.stringify(deepLink)) + localStorage.setItem('@appkit/deeplink_choice', JSON.stringify(deepLink)) expect(StorageUtil.getWalletConnectDeepLink()).toEqual(deepLink) }) @@ -75,11 +75,11 @@ describe('StorageUtil', () => { describe('deleteWalletConnectDeepLink', () => { it('should delete WalletConnect deep link from localStorage', () => { localStorage.setItem( - 'WALLETCONNECT_DEEPLINK_CHOICE', + '@appkit/deeplink_choice', JSON.stringify({ href: 'https://example.com', name: 'Example Wallet' }) ) StorageUtil.deleteWalletConnectDeepLink() - expect(localStorage.getItem('WALLETCONNECT_DEEPLINK_CHOICE')).toBeNull() + expect(localStorage.getItem('@appkit/deeplink_choice')).toBeNull() }) it('should handle errors when deleting deep link', () => { @@ -125,7 +125,7 @@ describe('StorageUtil', () => { it('should return recent wallets', () => { const wallet: WcWallet = { id: 'wallet1', name: 'Wallet 1' } - localStorage.setItem('@w3m/recent', JSON.stringify([wallet])) + localStorage.setItem('@appkit/recent', JSON.stringify([wallet])) expect(StorageUtil.getRecentWallets()).toEqual([wallet]) }) }) @@ -134,14 +134,14 @@ describe('StorageUtil', () => { it('should set connected connector', () => { const connector: ConnectorType = 'INJECTED' StorageUtil.setConnectedConnector(connector) - expect(localStorage.getItem('@w3m/connected_connector')).toBe(connector) + expect(localStorage.getItem('@appkit/connected_connector')).toBe(connector) }) }) describe('getConnectedConnector', () => { it('should get connected connector', () => { const connector: ConnectorType = 'INJECTED' - localStorage.setItem('@w3m/connected_connector', connector) + localStorage.setItem('@appkit/connected_connector', connector) expect(StorageUtil.getConnectedConnector()).toBe(connector) }) }) @@ -150,14 +150,14 @@ describe('StorageUtil', () => { it('should set connected social provider', () => { const provider: SocialProvider = 'google' StorageUtil.setConnectedSocialProvider(provider) - expect(localStorage.getItem('@w3m/connected_social')).toBe(provider) + expect(localStorage.getItem('@appkit/connected_social')).toBe(provider) }) }) describe('getConnectedSocialProvider', () => { it('should get connected social provider', () => { const provider: SocialProvider = 'google' - localStorage.setItem('@w3m/connected_social', provider) + localStorage.setItem('@appkit/connected_social', provider) expect(StorageUtil.getConnectedSocialProvider()).toBe(provider) }) }) @@ -165,7 +165,7 @@ describe('StorageUtil', () => { describe('getConnectedSocialUsername', () => { it('should get connected social username', () => { const username = 'testuser' - localStorage.setItem('@w3m-storage/SOCIAL_USERNAME', username) + localStorage.setItem('@appkit-wallet/SOCIAL_USERNAME', username) expect(StorageUtil.getConnectedSocialUsername()).toBe(username) }) }) diff --git a/packages/wallet/src/W3mFrameConstants.ts b/packages/wallet/src/W3mFrameConstants.ts index 6d83e2d4a1..02761eb121 100644 --- a/packages/wallet/src/W3mFrameConstants.ts +++ b/packages/wallet/src/W3mFrameConstants.ts @@ -7,7 +7,7 @@ export const W3mFrameConstants = { APP_EVENT_KEY: '@w3m-app/', FRAME_EVENT_KEY: '@w3m-frame/', RPC_METHOD_KEY: 'RPC_', - STORAGE_KEY: '@w3m-storage/', + STORAGE_KEY: '@appkit-wallet/', SESSION_TOKEN_KEY: 'SESSION_TOKEN_KEY', EMAIL_LOGIN_USED_KEY: 'EMAIL_LOGIN_USED_KEY', @@ -18,7 +18,6 @@ export const W3mFrameConstants = { SMART_ACCOUNT_ENABLED: 'SMART_ACCOUNT_ENABLED', SMART_ACCOUNT_ENABLED_NETWORKS: 'SMART_ACCOUNT_ENABLED_NETWORKS', SOCIAL_USERNAME: 'SOCIAL_USERNAME', - SOCIAL: '@w3m/connected_social', APP_SWITCH_NETWORK: '@w3m-app/SWITCH_NETWORK', APP_CONNECT_EMAIL: '@w3m-app/CONNECT_EMAIL', diff --git a/packages/wallet/src/W3mFrameProvider.ts b/packages/wallet/src/W3mFrameProvider.ts index 678d5c64f7..925bee1a68 100644 --- a/packages/wallet/src/W3mFrameProvider.ts +++ b/packages/wallet/src/W3mFrameProvider.ts @@ -502,7 +502,6 @@ export class W3mFrameProvider { W3mFrameStorage.delete(W3mFrameConstants.EMAIL) W3mFrameStorage.delete(W3mFrameConstants.LAST_USED_CHAIN_KEY) W3mFrameStorage.delete(W3mFrameConstants.SOCIAL_USERNAME) - W3mFrameStorage.delete(W3mFrameConstants.SOCIAL, true) } private setLastUsedChainId(chainId: string | number) { From 920ba1659f7724de2a558eae67fd4fa5a317502d Mon Sep 17 00:00:00 2001 From: enesozturk Date: Tue, 17 Sep 2024 14:05:43 +0300 Subject: [PATCH 02/17] chore: format files --- packages/adapters/ethers5/src/tests/client.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/adapters/ethers5/src/tests/client.test.ts b/packages/adapters/ethers5/src/tests/client.test.ts index 6966e3db5b..7d7ee470eb 100644 --- a/packages/adapters/ethers5/src/tests/client.test.ts +++ b/packages/adapters/ethers5/src/tests/client.test.ts @@ -10,7 +10,7 @@ import { ConstantsUtil } from '@reown/appkit-utils' import { arbitrum, mainnet, polygon } from '@reown/appkit/networks' import { ProviderUtil } from '@reown/appkit/store' import { SafeLocalStorage, SafeLocalStorageKeys } from '@reown/appkit-common' -import { type BlockchainApiLookupEnsName } from '@reown/appkit' +import { type BlockchainApiLookupEnsName } from '@reown/appkit' import { ethers } from 'ethers5' import type { CaipNetwork, ChainNamespace } from '@reown/appkit-common' From 66a7bc6833bde573a773f0faffb7b026738ab36f Mon Sep 17 00:00:00 2001 From: enesozturk Date: Tue, 17 Sep 2024 14:37:23 +0300 Subject: [PATCH 03/17] chore: revert storage util --- packages/common/src/utils/SafeLocalStorage.ts | 2 +- packages/core/src/utils/StorageUtil.ts | 71 ++++++++++++++----- packages/core/tests/utils/StorageUtil.test.ts | 19 ++--- 3 files changed, 66 insertions(+), 26 deletions(-) diff --git a/packages/common/src/utils/SafeLocalStorage.ts b/packages/common/src/utils/SafeLocalStorage.ts index f1fc7007df..deef953139 100644 --- a/packages/common/src/utils/SafeLocalStorage.ts +++ b/packages/common/src/utils/SafeLocalStorage.ts @@ -32,7 +32,7 @@ export const SafeLocalStorage = { value: SafeLocalStorageItems[Key] ): void { if (isSafe()) { - localStorage.setItem(key, JSON.stringify(value)) + localStorage.setItem(key, value) } }, getItem(key: Key): SafeLocalStorageItems[Key] | null { diff --git a/packages/core/src/utils/StorageUtil.ts b/packages/core/src/utils/StorageUtil.ts index 0895874686..bc240673c6 100644 --- a/packages/core/src/utils/StorageUtil.ts +++ b/packages/core/src/utils/StorageUtil.ts @@ -1,28 +1,36 @@ /* eslint-disable no-console */ -import { SafeLocalStorage, SafeLocalStorageKeys } from '@reown/appkit-common' +import { SafeLocalStorageKeys } from '@reown/appkit-common' import type { WcWallet, ConnectorType, SocialProvider } from './TypeUtil.js' // -- Utility ----------------------------------------------------------------- export const StorageUtil = { setWalletConnectDeepLink({ href, name }: { href: string; name: string }) { try { - SafeLocalStorage.setItem(SafeLocalStorageKeys.DEEPLINK_CHOICE, JSON.stringify({ href, name })) + localStorage.setItem(SafeLocalStorageKeys.DEEPLINK_CHOICE, JSON.stringify({ href, name })) } catch { console.info('Unable to set WalletConnect deep link') } }, getWalletConnectDeepLink() { - const deepLink = SafeLocalStorage.getItem(SafeLocalStorageKeys.DEEPLINK_CHOICE) - if (deepLink) { - return JSON.parse(deepLink) + try { + const deepLink = localStorage.getItem(SafeLocalStorageKeys.DEEPLINK_CHOICE) + if (deepLink) { + return JSON.parse(deepLink) + } + } catch { + console.info('Unable to get WalletConnect deep link') } return undefined }, deleteWalletConnectDeepLink() { - SafeLocalStorage.removeItem(SafeLocalStorageKeys.DEEPLINK_CHOICE) + try { + localStorage.removeItem(SafeLocalStorageKeys.DEEPLINK_CHOICE) + } catch { + console.info('Unable to delete WalletConnect deep link') + } }, setAppKitRecent(wallet: WcWallet) { @@ -34,7 +42,7 @@ export const StorageUtil = { if (recentWallets.length > 2) { recentWallets.pop() } - SafeLocalStorage.setItem(SafeLocalStorageKeys.RECENT_WALLETS, JSON.stringify(recentWallets)) + localStorage.setItem(SafeLocalStorageKeys.RECENT_WALLETS, JSON.stringify(recentWallets)) } } catch { console.info('Unable to set AppKit recent') @@ -42,31 +50,60 @@ export const StorageUtil = { }, getRecentWallets(): WcWallet[] { - const recentWallets = SafeLocalStorage.getItem(SafeLocalStorageKeys.RECENT_WALLETS) - return (recentWallets as unknown as WcWallet[]) || [] + try { + const recent = localStorage.getItem(SafeLocalStorageKeys.RECENT_WALLETS) + + return recent ? JSON.parse(recent) : [] + } catch { + console.info('Unable to get AppKit recent') + } + + return [] }, setConnectedConnector(connectorType: ConnectorType) { - SafeLocalStorage.setItem(SafeLocalStorageKeys.CONNECTED_CONNECTOR, connectorType) + try { + localStorage.setItem(SafeLocalStorageKeys.CONNECTED_CONNECTOR, connectorType) + } catch { + console.info('Unable to set Connected Connector') + } }, getConnectedConnector() { - return SafeLocalStorage.getItem(SafeLocalStorageKeys.CONNECTED_CONNECTOR) as ConnectorType + try { + return localStorage.getItem(SafeLocalStorageKeys.CONNECTED_CONNECTOR) as ConnectorType + } catch { + console.info('Unable to get Connected Connector') + } + + return undefined }, setConnectedSocialProvider(socialProvider: SocialProvider) { - SafeLocalStorage.setItem(SafeLocalStorageKeys.CONNECTED_SOCIAL, socialProvider) + try { + localStorage.setItem(SafeLocalStorageKeys.CONNECTED_SOCIAL, socialProvider) + } catch { + console.info('Unable to set Connected Social Provider') + } }, getConnectedSocialProvider() { - return SafeLocalStorage.getItem(SafeLocalStorageKeys.CONNECTED_SOCIAL) as SocialProvider - }, + try { + return localStorage.getItem(SafeLocalStorageKeys.CONNECTED_SOCIAL) + } catch { + console.info('Unable to get Connected Social Provider') + } - setConnectedSocialUsername(username: string) { - SafeLocalStorage.setItem(SafeLocalStorageKeys.CONNECTED_SOCIAL_USERNAME, username) + return undefined }, getConnectedSocialUsername() { - return SafeLocalStorage.getItem(SafeLocalStorageKeys.CONNECTED_SOCIAL_USERNAME) as string + try { + return localStorage.getItem(SafeLocalStorageKeys.CONNECTED_SOCIAL_USERNAME) + } catch { + console.info('Unable to get Connected Social Username') + } + + return undefined } } diff --git a/packages/core/tests/utils/StorageUtil.test.ts b/packages/core/tests/utils/StorageUtil.test.ts index 227a228934..9a2d9352c3 100644 --- a/packages/core/tests/utils/StorageUtil.test.ts +++ b/packages/core/tests/utils/StorageUtil.test.ts @@ -1,6 +1,7 @@ -import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' +import { describe, it, expect, vi, afterEach, beforeAll, beforeEach } from 'vitest' import { StorageUtil } from '../../src/utils/StorageUtil' import type { WcWallet, ConnectorType, SocialProvider } from '../../src/utils/TypeUtil' +import { SafeLocalStorageKeys } from '@reown/appkit-common' // Mock localStorage const localStorageMock = (() => { @@ -36,7 +37,9 @@ describe('StorageUtil', () => { it('should set WalletConnect deep link in localStorage', () => { const deepLink = { href: 'https://example.com', name: 'Example Wallet' } StorageUtil.setWalletConnectDeepLink(deepLink) - expect(localStorage.getItem('@appkit/deeplink_choice')).toBe(JSON.stringify(deepLink)) + expect(localStorageMock.getItem(SafeLocalStorageKeys.DEEPLINK_CHOICE)).toBe( + JSON.stringify(deepLink) + ) }) it('should handle errors when setting deep link', () => { @@ -125,7 +128,7 @@ describe('StorageUtil', () => { it('should return recent wallets', () => { const wallet: WcWallet = { id: 'wallet1', name: 'Wallet 1' } - localStorage.setItem('@appkit/recent', JSON.stringify([wallet])) + localStorage.setItem(SafeLocalStorageKeys.RECENT_WALLETS, JSON.stringify([wallet])) expect(StorageUtil.getRecentWallets()).toEqual([wallet]) }) }) @@ -134,14 +137,14 @@ describe('StorageUtil', () => { it('should set connected connector', () => { const connector: ConnectorType = 'INJECTED' StorageUtil.setConnectedConnector(connector) - expect(localStorage.getItem('@appkit/connected_connector')).toBe(connector) + expect(localStorage.getItem(SafeLocalStorageKeys.CONNECTED_CONNECTOR)).toBe(connector) }) }) describe('getConnectedConnector', () => { it('should get connected connector', () => { const connector: ConnectorType = 'INJECTED' - localStorage.setItem('@appkit/connected_connector', connector) + localStorage.setItem(SafeLocalStorageKeys.CONNECTED_CONNECTOR, connector) expect(StorageUtil.getConnectedConnector()).toBe(connector) }) }) @@ -150,14 +153,14 @@ describe('StorageUtil', () => { it('should set connected social provider', () => { const provider: SocialProvider = 'google' StorageUtil.setConnectedSocialProvider(provider) - expect(localStorage.getItem('@appkit/connected_social')).toBe(provider) + expect(localStorage.getItem(SafeLocalStorageKeys.CONNECTED_SOCIAL)).toBe(provider) }) }) describe('getConnectedSocialProvider', () => { it('should get connected social provider', () => { const provider: SocialProvider = 'google' - localStorage.setItem('@appkit/connected_social', provider) + localStorage.setItem(SafeLocalStorageKeys.CONNECTED_SOCIAL, provider) expect(StorageUtil.getConnectedSocialProvider()).toBe(provider) }) }) @@ -165,7 +168,7 @@ describe('StorageUtil', () => { describe('getConnectedSocialUsername', () => { it('should get connected social username', () => { const username = 'testuser' - localStorage.setItem('@appkit-wallet/SOCIAL_USERNAME', username) + localStorage.setItem(SafeLocalStorageKeys.CONNECTED_SOCIAL_USERNAME, username) expect(StorageUtil.getConnectedSocialUsername()).toBe(username) }) }) From 3730a42ace26d3d669691aaccd6d44e27e78f7ae Mon Sep 17 00:00:00 2001 From: enesozturk Date: Tue, 17 Sep 2024 14:43:12 +0300 Subject: [PATCH 04/17] chore: linter and test issues --- packages/common/tests/SafeLocalStorage.test.ts | 2 +- packages/core/tests/utils/StorageUtil.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/common/tests/SafeLocalStorage.test.ts b/packages/common/tests/SafeLocalStorage.test.ts index 96c174d653..9e528ea3f3 100644 --- a/packages/common/tests/SafeLocalStorage.test.ts +++ b/packages/common/tests/SafeLocalStorage.test.ts @@ -34,7 +34,7 @@ describe('SafeLocalStorage safe', () => { it('should setItem', () => { expect(SafeLocalStorage.setItem('@appkit/wallet_id', 'test')).toBe(undefined) - expect(setItem).toHaveBeenCalledWith('@appkit/wallet_id', '"test"') + expect(setItem).toHaveBeenCalledWith('@appkit/wallet_id', 'test') }) it('should getItem', () => { diff --git a/packages/core/tests/utils/StorageUtil.test.ts b/packages/core/tests/utils/StorageUtil.test.ts index 9a2d9352c3..2a59a5da51 100644 --- a/packages/core/tests/utils/StorageUtil.test.ts +++ b/packages/core/tests/utils/StorageUtil.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, vi, afterEach, beforeAll, beforeEach } from 'vitest' +import { describe, it, expect, vi, afterEach, beforeEach } from 'vitest' import { StorageUtil } from '../../src/utils/StorageUtil' import type { WcWallet, ConnectorType, SocialProvider } from '../../src/utils/TypeUtil' import { SafeLocalStorageKeys } from '@reown/appkit-common' From 67065e8b9429c6bf6472847010a731e4266890a6 Mon Sep 17 00:00:00 2001 From: enesozturk Date: Tue, 17 Sep 2024 16:14:01 +0300 Subject: [PATCH 05/17] chore: add changeset file --- .changeset/wise-bobcats-hang.md | 38 +++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .changeset/wise-bobcats-hang.md diff --git a/.changeset/wise-bobcats-hang.md b/.changeset/wise-bobcats-hang.md new file mode 100644 index 0000000000..d2b1000398 --- /dev/null +++ b/.changeset/wise-bobcats-hang.md @@ -0,0 +1,38 @@ +--- +'@reown/appkit-adapter-ethers5': patch +'@reown/appkit-adapter-ethers': patch +'@reown/appkit-utils': patch +'@reown/appkit': patch +'@reown/appkit-common': patch +'@reown/appkit-wallet': patch +'@reown/appkit-core': patch +'@apps/demo': patch +'@apps/gallery': patch +'@apps/laboratory': patch +'@examples/html-ethers': patch +'@examples/html-ethers5': patch +'@examples/html-wagmi': patch +'@examples/next-ethers': patch +'@examples/next-wagmi': patch +'@examples/react-ethers': patch +'@examples/react-ethers5': patch +'@examples/react-solana': patch +'@examples/react-wagmi': patch +'@examples/vue-ethers5': patch +'@examples/vue-solana': patch +'@examples/vue-wagmi': patch +'@reown/appkit-adapter-polkadot': patch +'@reown/appkit-adapter-solana': patch +'@reown/appkit-adapter-wagmi': patch +'@reown/appkit-cdn': patch +'@reown/appkit-ethers': patch +'@reown/appkit-ethers5': patch +'@reown/appkit-polyfills': patch +'@reown/appkit-scaffold-ui': patch +'@reown/appkit-siwe': patch +'@reown/appkit-solana': patch +'@reown/appkit-ui': patch +'@reown/appkit-wagmi': patch +--- + +Updates the localstorage keys From a288e874120da9d5dbf4317b121d84666abb4f75 Mon Sep 17 00:00:00 2001 From: enesozturk Date: Tue, 17 Sep 2024 17:31:39 +0300 Subject: [PATCH 06/17] Trigger workflow From bb68d9cf6e4d48024b1d1b014fb4281410e1e90a Mon Sep 17 00:00:00 2001 From: enesozturk Date: Wed, 18 Sep 2024 13:58:19 +0300 Subject: [PATCH 07/17] refactor: update local storage get and sets --- .../pages/library/multichain-wagmi-solana.tsx | 23 +++--------- packages/adapters/solana/src/client.ts | 4 -- packages/adapters/wagmi/src/client.ts | 4 -- .../appkit/src/universal-adapter/client.ts | 37 ++++++------------- packages/common/src/utils/SafeLocalStorage.ts | 18 ++++++--- .../core/src/controllers/ChainController.ts | 4 +- 6 files changed, 33 insertions(+), 57 deletions(-) diff --git a/apps/laboratory/src/pages/library/multichain-wagmi-solana.tsx b/apps/laboratory/src/pages/library/multichain-wagmi-solana.tsx index 26add712ef..25c12cbad2 100644 --- a/apps/laboratory/src/pages/library/multichain-wagmi-solana.tsx +++ b/apps/laboratory/src/pages/library/multichain-wagmi-solana.tsx @@ -7,17 +7,13 @@ import { ConstantsUtil } from '../../utils/ConstantsUtil' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { WagmiProvider } from 'wagmi' import { - arbitrum, mainnet, polygon, - base, - binanceSmartChain, solana, - solanaTestnet, - solanaDevnet, + arbitrum, optimism, - zkSync, - sepolia + solanaTestnet, + solanaDevnet } from '@reown/appkit/networks' import { AppKitButtons } from '../../components/AppKitButtons' import { HuobiWalletAdapter, SolflareWalletAdapter } from '@solana/wallet-adapter-wallets' @@ -25,7 +21,7 @@ import { MultiChainTestsWagmiSolana } from '../../components/MultiChainTestsWagm const queryClient = new QueryClient() -const networks = [mainnet, optimism, polygon, zkSync, arbitrum, sepolia] +const networks = [mainnet, polygon, solana, arbitrum, optimism, solanaTestnet, solanaDevnet] const wagmiAdapter = new WagmiAdapter({ ssr: true, @@ -39,16 +35,7 @@ const solanaWeb3JsAdapter = new SolanaAdapter({ const modal = createAppKit({ adapters: [wagmiAdapter, solanaWeb3JsAdapter], - networks: [ - mainnet, - polygon, - base, - binanceSmartChain, - arbitrum, - solana, - solanaTestnet, - solanaDevnet - ], + networks, defaultNetwork: mainnet, projectId: ConstantsUtil.ProjectId, features: { diff --git a/packages/adapters/solana/src/client.ts b/packages/adapters/solana/src/client.ts index 3a88327966..90d80ff2b9 100644 --- a/packages/adapters/solana/src/client.ts +++ b/packages/adapters/solana/src/client.ts @@ -140,10 +140,6 @@ export class SolanaAdapter implements ChainAdapter { this.networkControllerClient = { switchCaipNetwork: async caipNetwork => { if (caipNetwork) { - SafeLocalStorage.setItem( - SafeLocalStorageKeys.ACTIVE_CAIP_NETWORK, - JSON.stringify(caipNetwork) - ) try { await this.switchNetwork(caipNetwork) } catch (error) { diff --git a/packages/adapters/wagmi/src/client.ts b/packages/adapters/wagmi/src/client.ts index 683eef9349..766bcb2733 100644 --- a/packages/adapters/wagmi/src/client.ts +++ b/packages/adapters/wagmi/src/client.ts @@ -230,10 +230,6 @@ export class WagmiAdapter implements ChainAdapter { this.networkControllerClient = { switchCaipNetwork: async caipNetwork => { - SafeLocalStorage.setItem( - SafeLocalStorageKeys.ACTIVE_CAIP_NETWORK, - JSON.stringify(caipNetwork) - ) const chainId = Number(NetworkUtil.caipNetworkIdToNumber(caipNetwork?.id)) if (chainId && this.wagmiConfig) { diff --git a/packages/appkit/src/universal-adapter/client.ts b/packages/appkit/src/universal-adapter/client.ts index 563cfe7b7e..f615deb697 100644 --- a/packages/appkit/src/universal-adapter/client.ts +++ b/packages/appkit/src/universal-adapter/client.ts @@ -95,10 +95,6 @@ export class UniversalAdapterClient { // @ts-expect-error switchCaipNetwork is async for some adapter but not for this adapter switchCaipNetwork: caipNetwork => { if (caipNetwork) { - SafeLocalStorage.setItem( - SafeLocalStorageKeys.ACTIVE_CAIP_NETWORK, - JSON.stringify(caipNetwork) - ) try { this.switchNetwork(caipNetwork) } catch (error) { @@ -397,32 +393,23 @@ export class UniversalAdapterClient { }) const storedCaipNetwork = SafeLocalStorage.getItem(SafeLocalStorageKeys.ACTIVE_CAIP_NETWORK) + const activeCaipNetwork = ChainController.state.activeCaipNetwork - if (storedCaipNetwork) { - try { - const parsedCaipNetwork = JSON.parse(storedCaipNetwork) as CaipNetwork - if (parsedCaipNetwork) { - NetworkController.setActiveCaipNetwork(parsedCaipNetwork) - } - } catch (error) { - console.warn('>>> Error setting active caip network', error) + try { + if (storedCaipNetwork) { + NetworkController.setActiveCaipNetwork(storedCaipNetwork) + } else if (!activeCaipNetwork) { + this.setDefaultNetwork(nameSpaces) + } else if ( + !NetworkController.state.approvedCaipNetworkIds?.includes(activeCaipNetwork.id) + ) { + this.setDefaultNetwork(nameSpaces) } - } else if (!ChainController.state.activeCaipNetwork) { - this.setDefaultNetwork(nameSpaces) - } else if ( - !NetworkController.state.approvedCaipNetworkIds?.includes( - ChainController.state.activeCaipNetwork.id - ) - ) { - this.setDefaultNetwork(nameSpaces) + } catch (error) { + console.warn('>>> Error setting active caip network', error) } } - SafeLocalStorage.setItem( - SafeLocalStorageKeys.ACTIVE_CAIP_NETWORK, - JSON.stringify(this.appKit?.getCaipNetwork()) - ) - this.syncAccount() this.watchWalletConnect() } diff --git a/packages/common/src/utils/SafeLocalStorage.ts b/packages/common/src/utils/SafeLocalStorage.ts index deef953139..5fc7aabb24 100644 --- a/packages/common/src/utils/SafeLocalStorage.ts +++ b/packages/common/src/utils/SafeLocalStorage.ts @@ -1,9 +1,11 @@ +import type { CaipNetwork } from './TypeUtil' + export type SafeLocalStorageItems = { '@appkit/wallet_id': string '@appkit/wallet_name': string '@appkit/solana_wallet': string '@appkit/solana_caip_chain': string - '@appkit/active_caip_network': string + '@appkit/active_caip_network': CaipNetwork '@appkit/active_caip_network_id': string '@appkit/connected_connector': string '@appkit/connected_social': string @@ -32,10 +34,16 @@ export const SafeLocalStorage = { value: SafeLocalStorageItems[Key] ): void { if (isSafe()) { - localStorage.setItem(key, value) + if (typeof value === 'string') { + localStorage.setItem(key, value) + } else { + localStorage.setItem(key, JSON.stringify(value)) + } } }, - getItem(key: Key): SafeLocalStorageItems[Key] | null { + getItem( + key: Key + ): SafeLocalStorageItems[Key] | undefined { if (isSafe()) { const value = localStorage.getItem(key) @@ -43,12 +51,12 @@ export const SafeLocalStorage = { try { return JSON.parse(value) } catch { - return value + return undefined } } } - return null + return undefined }, removeItem(key: Key): void { if (isSafe()) { diff --git a/packages/core/src/controllers/ChainController.ts b/packages/core/src/controllers/ChainController.ts index a344f7e241..76194d9b3b 100644 --- a/packages/core/src/controllers/ChainController.ts +++ b/packages/core/src/controllers/ChainController.ts @@ -262,6 +262,8 @@ export const ChainController = { if (caipNetwork.chainNamespace !== state.activeChain) { this.setActiveChain(caipNetwork.chainNamespace, caipNetwork) + SafeLocalStorage.setItem(SafeLocalStorageKeys.ACTIVE_CAIP_NETWORK, caipNetwork) + SafeLocalStorage.setItem(SafeLocalStorageKeys.ACTIVE_CAIP_NETWORK_ID, caipNetwork.id) return } @@ -273,7 +275,7 @@ export const ChainController = { selectedNetworkId: caipNetwork?.id }) - SafeLocalStorage.setItem(SafeLocalStorageKeys.ACTIVE_CAIP_NETWORK, JSON.stringify(caipNetwork)) + SafeLocalStorage.setItem(SafeLocalStorageKeys.ACTIVE_CAIP_NETWORK, caipNetwork) SafeLocalStorage.setItem(SafeLocalStorageKeys.ACTIVE_CAIP_NETWORK_ID, caipNetwork.id) }, From 499dcd2c2d6f2e70773d1e963e71bedb24e060a0 Mon Sep 17 00:00:00 2001 From: enesozturk Date: Wed, 18 Sep 2024 14:07:43 +0300 Subject: [PATCH 08/17] fix: build and test issues --- .../adapters/ethers/src/tests/client.test.ts | 4 ++-- .../adapters/ethers5/src/tests/client.test.ts | 2 +- .../src/connectors/UniversalConnector.ts | 9 +++----- packages/common/src/utils/SafeLocalStorage.ts | 2 +- .../common/tests/SafeLocalStorage.test.ts | 2 +- .../core/src/controllers/ChainController.ts | 23 ++++++++----------- 6 files changed, 18 insertions(+), 24 deletions(-) diff --git a/packages/adapters/ethers/src/tests/client.test.ts b/packages/adapters/ethers/src/tests/client.test.ts index c278bef6e3..fa86bac689 100644 --- a/packages/adapters/ethers/src/tests/client.test.ts +++ b/packages/adapters/ethers/src/tests/client.test.ts @@ -603,7 +603,7 @@ describe('EthersAdapter', () => { vi.spyOn(SafeLocalStorage, 'getItem').mockImplementation(key => { if (key === SafeLocalStorageKeys.WALLET_ID) return ConstantsUtil.INJECTED_CONNECTOR_ID if (key === SafeLocalStorageKeys.WALLET_NAME) return 'MetaMask' - return null + return undefined }) vi.spyOn(client as any, 'setProvider').mockImplementation(() => Promise.resolve()) @@ -631,7 +631,7 @@ describe('EthersAdapter', () => { }) it('should not set provider when wallet ID is not found', () => { - vi.spyOn(SafeLocalStorage, 'getItem').mockReturnValue(null) + vi.spyOn(SafeLocalStorage, 'getItem').mockReturnValue(undefined) const mockConfig = { injected: mockInjectedProvider, diff --git a/packages/adapters/ethers5/src/tests/client.test.ts b/packages/adapters/ethers5/src/tests/client.test.ts index 7d7ee470eb..7c18060bc4 100644 --- a/packages/adapters/ethers5/src/tests/client.test.ts +++ b/packages/adapters/ethers5/src/tests/client.test.ts @@ -607,7 +607,7 @@ describe('EthersAdapter', () => { vi.spyOn(SafeLocalStorage, 'getItem').mockImplementation(key => { if (key === SafeLocalStorageKeys.WALLET_ID) return ConstantsUtil.INJECTED_CONNECTOR_ID if (key === SafeLocalStorageKeys.WALLET_NAME) return 'MetaMask' - return null + return undefined }) vi.spyOn(client as any, 'setProvider').mockImplementation(() => Promise.resolve()) diff --git a/packages/adapters/wagmi/src/connectors/UniversalConnector.ts b/packages/adapters/wagmi/src/connectors/UniversalConnector.ts index 039c4902df..ec0324c416 100644 --- a/packages/adapters/wagmi/src/connectors/UniversalConnector.ts +++ b/packages/adapters/wagmi/src/connectors/UniversalConnector.ts @@ -22,7 +22,7 @@ import { WcHelpersUtil } from '@reown/appkit' import type { AppKitOptions } from '@reown/appkit' import type { AppKit } from '@reown/appkit' import { convertToAppKitChains } from '../utils/helpers.js' -import { SafeLocalStorage, SafeLocalStorageKeys, type CaipNetwork } from '@reown/appkit-common' +import { SafeLocalStorage, SafeLocalStorageKeys } from '@reown/appkit-common' type UniversalConnector = Connector & { onDisplayUri(uri: string): void @@ -232,11 +232,8 @@ export function walletConnect(parameters: AppKitOptionsParams, appKit: AppKit) { if (chainId && currentChainId !== chainId) { const storedCaipNetwork = SafeLocalStorage.getItem(SafeLocalStorageKeys.ACTIVE_CAIP_NETWORK) - if (storedCaipNetwork) { - const parsedCaipNetwork = JSON.parse(storedCaipNetwork) as CaipNetwork - if (parsedCaipNetwork.chainNamespace === 'eip155') { - await this.switchChain?.({ chainId: Number(parsedCaipNetwork.chainId) }) - } + if (storedCaipNetwork && storedCaipNetwork.chainNamespace === 'eip155') { + await this.switchChain?.({ chainId: Number(storedCaipNetwork.chainId) }) } else { await this.switchChain?.({ chainId }) } diff --git a/packages/common/src/utils/SafeLocalStorage.ts b/packages/common/src/utils/SafeLocalStorage.ts index 5fc7aabb24..dd7d4e89f0 100644 --- a/packages/common/src/utils/SafeLocalStorage.ts +++ b/packages/common/src/utils/SafeLocalStorage.ts @@ -1,4 +1,4 @@ -import type { CaipNetwork } from './TypeUtil' +import type { CaipNetwork } from './TypeUtil.js' export type SafeLocalStorageItems = { '@appkit/wallet_id': string diff --git a/packages/common/tests/SafeLocalStorage.test.ts b/packages/common/tests/SafeLocalStorage.test.ts index 9e528ea3f3..0618554d21 100644 --- a/packages/common/tests/SafeLocalStorage.test.ts +++ b/packages/common/tests/SafeLocalStorage.test.ts @@ -18,7 +18,7 @@ describe('SafeLocalStorage unsafe', () => { const key = '@appkit/wallet_id' expect(SafeLocalStorage.setItem(key, '1')).toBe(undefined) - expect(SafeLocalStorage.getItem(key)).toBe(null) + expect(SafeLocalStorage.getItem(key)).toBe(undefined) expect(SafeLocalStorage.removeItem(key)).toBe(undefined) }) }) diff --git a/packages/core/src/controllers/ChainController.ts b/packages/core/src/controllers/ChainController.ts index 76194d9b3b..2744eeb2e3 100644 --- a/packages/core/src/controllers/ChainController.ts +++ b/packages/core/src/controllers/ChainController.ts @@ -131,20 +131,17 @@ export const ChainController = { if (adapters.length === 0) { const storedCaipNetwork = SafeLocalStorage.getItem(SafeLocalStorageKeys.ACTIVE_CAIP_NETWORK) - if (storedCaipNetwork) { - try { - const parsedCaipNetwork = JSON.parse(storedCaipNetwork) as CaipNetwork - if (parsedCaipNetwork) { - state.activeChain = parsedCaipNetwork.chainNamespace - this.setActiveCaipNetwork(parsedCaipNetwork) - } - } catch (error) { - console.warn('>>> Error setting active caip network', error) + try { + if (storedCaipNetwork) { + state.activeChain = storedCaipNetwork.chainNamespace + this.setActiveCaipNetwork(storedCaipNetwork) + } else { + state.activeChain = + adapter?.defaultNetwork?.chainNamespace ?? adapter.caipNetworks[0]?.chainNamespace + this.setActiveCaipNetwork(adapter?.defaultNetwork ?? adapter.caipNetworks[0]) } - } else { - state.activeChain = - adapter?.defaultNetwork?.chainNamespace ?? adapter.caipNetworks[0]?.chainNamespace - this.setActiveCaipNetwork(adapter?.defaultNetwork ?? adapter.caipNetworks[0]) + } catch (error) { + console.warn('>>> Error setting active caip network', error) } } From 69ca8d2d02c6f53dc93b95fb5ea2c9288726c496 Mon Sep 17 00:00:00 2001 From: enesozturk Date: Wed, 18 Sep 2024 14:11:02 +0300 Subject: [PATCH 09/17] chore: type issues --- packages/adapters/ethers5/src/tests/client.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/adapters/ethers5/src/tests/client.test.ts b/packages/adapters/ethers5/src/tests/client.test.ts index 7c18060bc4..a0e57eebb8 100644 --- a/packages/adapters/ethers5/src/tests/client.test.ts +++ b/packages/adapters/ethers5/src/tests/client.test.ts @@ -635,7 +635,7 @@ describe('EthersAdapter', () => { }) it('should not set provider when wallet ID is not found', () => { - vi.spyOn(SafeLocalStorage, 'getItem').mockReturnValue(null) + vi.spyOn(SafeLocalStorage, 'getItem').mockReturnValue(undefined) const mockConfig = { injected: mockInjectedProvider, From 61981a191e9bb0577c36e5b57b1bf338392f3e52 Mon Sep 17 00:00:00 2001 From: tomiir Date: Wed, 18 Sep 2024 15:18:43 -0300 Subject: [PATCH 10/17] chore: always stringify value. Fix test --- packages/common/src/utils/SafeLocalStorage.ts | 10 +++---- .../common/tests/SafeLocalStorage.test.ts | 27 +++++++++++++++++-- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/packages/common/src/utils/SafeLocalStorage.ts b/packages/common/src/utils/SafeLocalStorage.ts index dd7d4e89f0..bd17539122 100644 --- a/packages/common/src/utils/SafeLocalStorage.ts +++ b/packages/common/src/utils/SafeLocalStorage.ts @@ -34,11 +34,7 @@ export const SafeLocalStorage = { value: SafeLocalStorageItems[Key] ): void { if (isSafe()) { - if (typeof value === 'string') { - localStorage.setItem(key, value) - } else { - localStorage.setItem(key, JSON.stringify(value)) - } + localStorage.setItem(key, JSON.stringify(value)) } }, getItem( @@ -50,7 +46,9 @@ export const SafeLocalStorage = { if (value) { try { return JSON.parse(value) - } catch { + } catch (e) { + console.warn('Error parsing value from localStorage', e) + return undefined } } diff --git a/packages/common/tests/SafeLocalStorage.test.ts b/packages/common/tests/SafeLocalStorage.test.ts index 0618554d21..298ed8c202 100644 --- a/packages/common/tests/SafeLocalStorage.test.ts +++ b/packages/common/tests/SafeLocalStorage.test.ts @@ -5,6 +5,16 @@ import { SafeLocalStorage } from '../src/utils/SafeLocalStorage' const previousLocalStorage = globalThis.localStorage const previousWindow = globalThis.window +const mockCaipNetwork = { + id: 'eip155:1' as const, + chainId: 1, + chainNamespace: 'eip155' as const, + name: 'Ethereum', + currency: 'ETH', + explorerUrl: 'https://etherscan.io', + rpcUrl: 'https://mainnet.infura.io/v3' +} + afterAll(() => { Object.assign(globalThis, { localStorage: previousLocalStorage, window: previousWindow }) }) @@ -32,12 +42,18 @@ describe('SafeLocalStorage safe', () => { Object.assign(globalThis, { window: {}, localStorage: { getItem, setItem, removeItem } }) }) + afterAll(() => { + getItem.mockClear() + setItem.mockClear() + removeItem.mockClear() + }) + it('should setItem', () => { expect(SafeLocalStorage.setItem('@appkit/wallet_id', 'test')).toBe(undefined) - expect(setItem).toHaveBeenCalledWith('@appkit/wallet_id', 'test') + expect(setItem).toHaveBeenCalledWith('@appkit/wallet_id', JSON.stringify('test')) }) - it('should getItem', () => { + it('should getItem ', () => { expect(SafeLocalStorage.getItem('@appkit/wallet_id')).toEqual({ test: 'test' }) expect(getItem).toHaveBeenCalledWith('@appkit/wallet_id') }) @@ -46,4 +62,11 @@ describe('SafeLocalStorage safe', () => { expect(SafeLocalStorage.removeItem('@appkit/wallet_id')).toBe(undefined) expect(removeItem).toHaveBeenCalledWith('@appkit/wallet_id') }) + + it('getItem should return undefined when value is not valid JSON', () => { + getItem.mockReturnValueOnce('test') + + expect(SafeLocalStorage.getItem('@appkit/wallet_id')).toBe(undefined) + expect(getItem).toHaveBeenCalledWith('@appkit/wallet_id') + }) }) From 874a621927b73e9ef8baaec42c545de8bb1710f5 Mon Sep 17 00:00:00 2001 From: tomiir Date: Wed, 18 Sep 2024 15:21:18 -0300 Subject: [PATCH 11/17] chore: remove unused var --- packages/common/tests/SafeLocalStorage.test.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/packages/common/tests/SafeLocalStorage.test.ts b/packages/common/tests/SafeLocalStorage.test.ts index 298ed8c202..c9e2f574dd 100644 --- a/packages/common/tests/SafeLocalStorage.test.ts +++ b/packages/common/tests/SafeLocalStorage.test.ts @@ -5,16 +5,6 @@ import { SafeLocalStorage } from '../src/utils/SafeLocalStorage' const previousLocalStorage = globalThis.localStorage const previousWindow = globalThis.window -const mockCaipNetwork = { - id: 'eip155:1' as const, - chainId: 1, - chainNamespace: 'eip155' as const, - name: 'Ethereum', - currency: 'ETH', - explorerUrl: 'https://etherscan.io', - rpcUrl: 'https://mainnet.infura.io/v3' -} - afterAll(() => { Object.assign(globalThis, { localStorage: previousLocalStorage, window: previousWindow }) }) From ccc5ebdd9d330e1da2b683ff606cd52f07ee584c Mon Sep 17 00:00:00 2001 From: tomiir Date: Wed, 18 Sep 2024 15:46:52 -0300 Subject: [PATCH 12/17] chore: close toast when rejecting message --- apps/laboratory/tests/shared/validators/ModalValidator.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/laboratory/tests/shared/validators/ModalValidator.ts b/apps/laboratory/tests/shared/validators/ModalValidator.ts index 23eb041ecf..2dc78b59a1 100644 --- a/apps/laboratory/tests/shared/validators/ModalValidator.ts +++ b/apps/laboratory/tests/shared/validators/ModalValidator.ts @@ -96,6 +96,10 @@ export class ModalValidator { async expectRejectedSign() { // We use Chakra Toast and it's not quite straightforward to set the `data-testid` attribute on the toast element. await expect(this.page.getByText(ConstantsUtil.SigningFailedToastTitle)).toBeVisible() + const closeButton = this.page.locator('#toast-close-button') + + await expect(closeButton).toBeVisible() + await closeButton.click() } async expectSwitchedNetwork(network: string) { From bf7aefbf489419d0ce279c1579d25e57228d9f13 Mon Sep 17 00:00:00 2001 From: tomiir Date: Wed, 18 Sep 2024 16:41:16 -0300 Subject: [PATCH 13/17] chore: use SafeLocalStorage on StorageUtil. Adjust tests --- .../tests/shared/utils/validation.ts | 2 +- packages/common/src/utils/SafeLocalStorage.ts | 9 +- packages/core/src/utils/StorageUtil.ts | 24 +++--- packages/core/tests/utils/StorageUtil.test.ts | 82 ++++++++++--------- 4 files changed, 65 insertions(+), 52 deletions(-) diff --git a/apps/laboratory/tests/shared/utils/validation.ts b/apps/laboratory/tests/shared/utils/validation.ts index bed6966135..57493449fb 100644 --- a/apps/laboratory/tests/shared/utils/validation.ts +++ b/apps/laboratory/tests/shared/utils/validation.ts @@ -8,6 +8,6 @@ export async function expectConnection( await modalValidator.expectConnected() await walletValidator.expectConnected() await modalValidator.page.evaluate( - `window.localStorage.setItem('WALLETCONNECT_DEEPLINK_CHOICE', '')` + `window.localStorage.setItem('@appkit/deeplink_choice', JSON.stringify({ href: '', name: '' }))` ) } diff --git a/packages/common/src/utils/SafeLocalStorage.ts b/packages/common/src/utils/SafeLocalStorage.ts index bd17539122..56f2697ffd 100644 --- a/packages/common/src/utils/SafeLocalStorage.ts +++ b/packages/common/src/utils/SafeLocalStorage.ts @@ -11,7 +11,7 @@ export type SafeLocalStorageItems = { '@appkit/connected_social': string '@appkit/connected_social_username': string '@appkit/recent_wallets': string - '@appkit/deeplink_choice': string + '@appkit/deeplink_choice': { href: string; name: string } } export const SafeLocalStorageKeys = { @@ -47,7 +47,7 @@ export const SafeLocalStorage = { try { return JSON.parse(value) } catch (e) { - console.warn('Error parsing value from localStorage', e) + console.warn('Error parsing value from localStorage', key, e) return undefined } @@ -60,6 +60,11 @@ export const SafeLocalStorage = { if (isSafe()) { localStorage.removeItem(key) } + }, + clear(): void { + if (isSafe()) { + localStorage.clear() + } } } diff --git a/packages/core/src/utils/StorageUtil.ts b/packages/core/src/utils/StorageUtil.ts index bc240673c6..f1b9ff8dd6 100644 --- a/packages/core/src/utils/StorageUtil.ts +++ b/packages/core/src/utils/StorageUtil.ts @@ -1,12 +1,12 @@ /* eslint-disable no-console */ -import { SafeLocalStorageKeys } from '@reown/appkit-common' +import { SafeLocalStorage, SafeLocalStorageKeys } from '@reown/appkit-common' import type { WcWallet, ConnectorType, SocialProvider } from './TypeUtil.js' // -- Utility ----------------------------------------------------------------- export const StorageUtil = { setWalletConnectDeepLink({ href, name }: { href: string; name: string }) { try { - localStorage.setItem(SafeLocalStorageKeys.DEEPLINK_CHOICE, JSON.stringify({ href, name })) + SafeLocalStorage.setItem(SafeLocalStorageKeys.DEEPLINK_CHOICE, { href, name }) } catch { console.info('Unable to set WalletConnect deep link') } @@ -14,9 +14,9 @@ export const StorageUtil = { getWalletConnectDeepLink() { try { - const deepLink = localStorage.getItem(SafeLocalStorageKeys.DEEPLINK_CHOICE) + const deepLink = SafeLocalStorage.getItem(SafeLocalStorageKeys.DEEPLINK_CHOICE) if (deepLink) { - return JSON.parse(deepLink) + return deepLink } } catch { console.info('Unable to get WalletConnect deep link') @@ -27,7 +27,7 @@ export const StorageUtil = { deleteWalletConnectDeepLink() { try { - localStorage.removeItem(SafeLocalStorageKeys.DEEPLINK_CHOICE) + SafeLocalStorage.removeItem(SafeLocalStorageKeys.DEEPLINK_CHOICE) } catch { console.info('Unable to delete WalletConnect deep link') } @@ -42,7 +42,7 @@ export const StorageUtil = { if (recentWallets.length > 2) { recentWallets.pop() } - localStorage.setItem(SafeLocalStorageKeys.RECENT_WALLETS, JSON.stringify(recentWallets)) + SafeLocalStorage.setItem(SafeLocalStorageKeys.RECENT_WALLETS, JSON.stringify(recentWallets)) } } catch { console.info('Unable to set AppKit recent') @@ -51,7 +51,7 @@ export const StorageUtil = { getRecentWallets(): WcWallet[] { try { - const recent = localStorage.getItem(SafeLocalStorageKeys.RECENT_WALLETS) + const recent = SafeLocalStorage.getItem(SafeLocalStorageKeys.RECENT_WALLETS) return recent ? JSON.parse(recent) : [] } catch { @@ -63,7 +63,7 @@ export const StorageUtil = { setConnectedConnector(connectorType: ConnectorType) { try { - localStorage.setItem(SafeLocalStorageKeys.CONNECTED_CONNECTOR, connectorType) + SafeLocalStorage.setItem(SafeLocalStorageKeys.CONNECTED_CONNECTOR, connectorType) } catch { console.info('Unable to set Connected Connector') } @@ -71,7 +71,7 @@ export const StorageUtil = { getConnectedConnector() { try { - return localStorage.getItem(SafeLocalStorageKeys.CONNECTED_CONNECTOR) as ConnectorType + return SafeLocalStorage.getItem(SafeLocalStorageKeys.CONNECTED_CONNECTOR) as ConnectorType } catch { console.info('Unable to get Connected Connector') } @@ -81,7 +81,7 @@ export const StorageUtil = { setConnectedSocialProvider(socialProvider: SocialProvider) { try { - localStorage.setItem(SafeLocalStorageKeys.CONNECTED_SOCIAL, socialProvider) + SafeLocalStorage.setItem(SafeLocalStorageKeys.CONNECTED_SOCIAL, socialProvider) } catch { console.info('Unable to set Connected Social Provider') } @@ -89,7 +89,7 @@ export const StorageUtil = { getConnectedSocialProvider() { try { - return localStorage.getItem(SafeLocalStorageKeys.CONNECTED_SOCIAL) + return SafeLocalStorage.getItem(SafeLocalStorageKeys.CONNECTED_SOCIAL) } catch { console.info('Unable to get Connected Social Provider') } @@ -99,7 +99,7 @@ export const StorageUtil = { getConnectedSocialUsername() { try { - return localStorage.getItem(SafeLocalStorageKeys.CONNECTED_SOCIAL_USERNAME) + return SafeLocalStorage.getItem(SafeLocalStorageKeys.CONNECTED_SOCIAL_USERNAME) } catch { console.info('Unable to get Connected Social Username') } diff --git a/packages/core/tests/utils/StorageUtil.test.ts b/packages/core/tests/utils/StorageUtil.test.ts index 2a59a5da51..056095545f 100644 --- a/packages/core/tests/utils/StorageUtil.test.ts +++ b/packages/core/tests/utils/StorageUtil.test.ts @@ -1,31 +1,39 @@ -import { describe, it, expect, vi, afterEach, beforeEach } from 'vitest' +import { describe, it, expect, vi, afterEach, beforeEach, beforeAll, afterAll } from 'vitest' import { StorageUtil } from '../../src/utils/StorageUtil' import type { WcWallet, ConnectorType, SocialProvider } from '../../src/utils/TypeUtil' +import { SafeLocalStorage } from '@reown/appkit-common' import { SafeLocalStorageKeys } from '@reown/appkit-common' -// Mock localStorage -const localStorageMock = (() => { - let store: { [key: string]: string } = {} - return { - getItem: (key: string) => store[key] || null, - setItem: (key: string, value: string) => { - store[key] = value.toString() - }, - removeItem: (key: string) => { - delete store[key] - }, - clear: () => { - store = {} - } - } -})() - -Object.defineProperty(global, 'localStorage', { value: localStorageMock }) - -describe('StorageUtil', () => { +const previousLocalStorage = globalThis.localStorage +const previousWindow = globalThis.window +let store: { [key: string]: string } = {} + +afterAll(() => { + Object.assign(globalThis, { localStorage: previousLocalStorage, window: previousWindow }) +}) + +describe.only('StorageUtil', () => { + beforeAll(() => { + Object.assign(globalThis, { + window: {}, + localStorage: { + getItem: (key: string) => store[key] || null, + setItem: (key: string, value: string) => { + store[key] = value.toString() + }, + removeItem: (key: string) => { + delete store[key] + }, + clear: () => { + store = {} + } + } + }) + }) + beforeEach(() => { // Clear localStorage before each test - localStorage.clear() + SafeLocalStorage.clear() }) afterEach(() => { @@ -37,9 +45,9 @@ describe('StorageUtil', () => { it('should set WalletConnect deep link in localStorage', () => { const deepLink = { href: 'https://example.com', name: 'Example Wallet' } StorageUtil.setWalletConnectDeepLink(deepLink) - expect(localStorageMock.getItem(SafeLocalStorageKeys.DEEPLINK_CHOICE)).toBe( - JSON.stringify(deepLink) - ) + const savedDL = SafeLocalStorage.getItem(SafeLocalStorageKeys.DEEPLINK_CHOICE) + expect(savedDL?.href).toBe(deepLink.href) + expect(savedDL?.name).toBe(deepLink.name) }) it('should handle errors when setting deep link', () => { @@ -56,7 +64,7 @@ describe('StorageUtil', () => { describe('getWalletConnectDeepLink', () => { it('should get WalletConnect deep link from localStorage', () => { const deepLink = { href: 'https://example.com', name: 'Example Wallet' } - localStorage.setItem('@appkit/deeplink_choice', JSON.stringify(deepLink)) + SafeLocalStorage.setItem('@appkit/deeplink_choice', deepLink) expect(StorageUtil.getWalletConnectDeepLink()).toEqual(deepLink) }) @@ -77,12 +85,12 @@ describe('StorageUtil', () => { describe('deleteWalletConnectDeepLink', () => { it('should delete WalletConnect deep link from localStorage', () => { - localStorage.setItem( - '@appkit/deeplink_choice', - JSON.stringify({ href: 'https://example.com', name: 'Example Wallet' }) - ) + SafeLocalStorage.setItem('@appkit/deeplink_choice', { + href: 'https://example.com', + name: 'Example Wallet' + }) StorageUtil.deleteWalletConnectDeepLink() - expect(localStorage.getItem('@appkit/deeplink_choice')).toBeNull() + expect(SafeLocalStorage.getItem('@appkit/deeplink_choice')).toBeUndefined() }) it('should handle errors when deleting deep link', () => { @@ -128,7 +136,7 @@ describe('StorageUtil', () => { it('should return recent wallets', () => { const wallet: WcWallet = { id: 'wallet1', name: 'Wallet 1' } - localStorage.setItem(SafeLocalStorageKeys.RECENT_WALLETS, JSON.stringify([wallet])) + SafeLocalStorage.setItem(SafeLocalStorageKeys.RECENT_WALLETS, JSON.stringify([wallet])) expect(StorageUtil.getRecentWallets()).toEqual([wallet]) }) }) @@ -137,14 +145,14 @@ describe('StorageUtil', () => { it('should set connected connector', () => { const connector: ConnectorType = 'INJECTED' StorageUtil.setConnectedConnector(connector) - expect(localStorage.getItem(SafeLocalStorageKeys.CONNECTED_CONNECTOR)).toBe(connector) + expect(SafeLocalStorage.getItem(SafeLocalStorageKeys.CONNECTED_CONNECTOR)).toBe(connector) }) }) describe('getConnectedConnector', () => { it('should get connected connector', () => { const connector: ConnectorType = 'INJECTED' - localStorage.setItem(SafeLocalStorageKeys.CONNECTED_CONNECTOR, connector) + SafeLocalStorage.setItem(SafeLocalStorageKeys.CONNECTED_CONNECTOR, connector) expect(StorageUtil.getConnectedConnector()).toBe(connector) }) }) @@ -153,14 +161,14 @@ describe('StorageUtil', () => { it('should set connected social provider', () => { const provider: SocialProvider = 'google' StorageUtil.setConnectedSocialProvider(provider) - expect(localStorage.getItem(SafeLocalStorageKeys.CONNECTED_SOCIAL)).toBe(provider) + expect(SafeLocalStorage.getItem(SafeLocalStorageKeys.CONNECTED_SOCIAL)).toBe(provider) }) }) describe('getConnectedSocialProvider', () => { it('should get connected social provider', () => { const provider: SocialProvider = 'google' - localStorage.setItem(SafeLocalStorageKeys.CONNECTED_SOCIAL, provider) + SafeLocalStorage.setItem(SafeLocalStorageKeys.CONNECTED_SOCIAL, provider) expect(StorageUtil.getConnectedSocialProvider()).toBe(provider) }) }) @@ -168,7 +176,7 @@ describe('StorageUtil', () => { describe('getConnectedSocialUsername', () => { it('should get connected social username', () => { const username = 'testuser' - localStorage.setItem(SafeLocalStorageKeys.CONNECTED_SOCIAL_USERNAME, username) + SafeLocalStorage.setItem(SafeLocalStorageKeys.CONNECTED_SOCIAL_USERNAME, username) expect(StorageUtil.getConnectedSocialUsername()).toBe(username) }) }) From 97b643e22db5da767c32fa9f665d1a22775dca0a Mon Sep 17 00:00:00 2001 From: tomiir Date: Thu, 19 Sep 2024 15:39:37 -0300 Subject: [PATCH 14/17] chore: removeo nly --- packages/core/tests/utils/StorageUtil.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/tests/utils/StorageUtil.test.ts b/packages/core/tests/utils/StorageUtil.test.ts index 056095545f..5095c69998 100644 --- a/packages/core/tests/utils/StorageUtil.test.ts +++ b/packages/core/tests/utils/StorageUtil.test.ts @@ -12,7 +12,7 @@ afterAll(() => { Object.assign(globalThis, { localStorage: previousLocalStorage, window: previousWindow }) }) -describe.only('StorageUtil', () => { +describe('StorageUtil', () => { beforeAll(() => { Object.assign(globalThis, { window: {}, From 169e9a97c822a172436e184655bf00dce410ad30 Mon Sep 17 00:00:00 2001 From: tomiir Date: Thu, 19 Sep 2024 16:45:43 -0300 Subject: [PATCH 15/17] fix: do not instantiate public key if namespace is not solana --- packages/adapters/solana/src/client.ts | 2 +- .../adapters/solana/src/providers/AuthProvider.ts | 7 ++++--- packages/wallet/src/W3mFrameProvider.ts | 14 ++++++++++++-- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/packages/adapters/solana/src/client.ts b/packages/adapters/solana/src/client.ts index c25f1a962e..919d1fbacb 100644 --- a/packages/adapters/solana/src/client.ts +++ b/packages/adapters/solana/src/client.ts @@ -144,7 +144,7 @@ export class SolanaAdapter implements ChainAdapter { try { await this.switchNetwork(caipNetwork) } catch (error) { - // SolStoreUtil.setError(error) + console.warn('Error switching network', error) } } }, diff --git a/packages/adapters/solana/src/providers/AuthProvider.ts b/packages/adapters/solana/src/providers/AuthProvider.ts index abcebb7e9f..a0c780cf22 100644 --- a/packages/adapters/solana/src/providers/AuthProvider.ts +++ b/packages/adapters/solana/src/providers/AuthProvider.ts @@ -57,8 +57,8 @@ export class AuthProvider extends ProviderEventEmitter implements Provider, Prov get publicKey(): PublicKey | undefined { const session = this.getSession() - - if (session) { + const namespace = this.getActiveNamespace() + if (session && namespace === 'solana') { return new PublicKey(session.address) } @@ -201,7 +201,8 @@ export class AuthProvider extends ProviderEventEmitter implements Provider, Prov required?: Required ): Required extends true ? PublicKey : PublicKey | undefined { const session = this.getSession() - if (!session) { + const namespace = this.getActiveNamespace() + if (!session || namespace !== 'solana') { if (required) { throw new Error('Account is required') } diff --git a/packages/wallet/src/W3mFrameProvider.ts b/packages/wallet/src/W3mFrameProvider.ts index a3d4279bd0..ef1c39c268 100644 --- a/packages/wallet/src/W3mFrameProvider.ts +++ b/packages/wallet/src/W3mFrameProvider.ts @@ -472,7 +472,13 @@ export class W3mFrameProvider { } }) - function handler(framEvent: W3mFrameTypes.FrameEvent) { + function handler(framEvent: W3mFrameTypes.FrameEvent, logger: W3mFrameLogger) { + if (framEvent.id !== id) { + return + } + + logger.logger.info?.({ framEvent, id }, 'Received frame response') + if (framEvent.type === `@w3m-frame/${type}_SUCCESS`) { if ('payload' in framEvent) { resolve(framEvent.payload) @@ -485,7 +491,11 @@ export class W3mFrameProvider { reject(new Error('An error occurred')) } } - this.w3mFrame.events.registerFrameEventHandler(id, handler, abortController.signal) + this.w3mFrame.events.registerFrameEventHandler( + id, + frameEvent => handler(frameEvent, this.w3mLogger), + abortController.signal + ) }) } From 162d3dbec5ebda1c6ecc9ff45dd29b47634f59f9 Mon Sep 17 00:00:00 2001 From: tomiir Date: Thu, 19 Sep 2024 17:24:59 -0300 Subject: [PATCH 16/17] fix: switch network flow --- .../multichain-wagmi-solana.spec.ts | 2 +- packages/adapters/wagmi/src/client.ts | 2 +- .../core/src/controllers/ChainController.ts | 3 +- .../core/src/controllers/NetworkController.ts | 30 ++++--------------- 4 files changed, 8 insertions(+), 29 deletions(-) diff --git a/apps/laboratory/tests/multichain/multichain-wagmi-solana.spec.ts b/apps/laboratory/tests/multichain/multichain-wagmi-solana.spec.ts index 3aa394866d..696430d028 100644 --- a/apps/laboratory/tests/multichain/multichain-wagmi-solana.spec.ts +++ b/apps/laboratory/tests/multichain/multichain-wagmi-solana.spec.ts @@ -48,7 +48,7 @@ test.skip('it should show disabled networks', async () => { await modalPage.closeModal() }) -test('it should switch networks and sign', async () => { +test.only('it should switch networks and sign', async () => { const chains = ['Polygon', 'Solana'] async function processChain(index: number) { diff --git a/packages/adapters/wagmi/src/client.ts b/packages/adapters/wagmi/src/client.ts index c26deac9cb..9ee8283a7b 100644 --- a/packages/adapters/wagmi/src/client.ts +++ b/packages/adapters/wagmi/src/client.ts @@ -603,7 +603,7 @@ export class WagmiAdapter implements ChainAdapter { >) { const isConnected = ChainController.state.activeCaipAddress - if (status === 'disconnected' && isConnected) { + if (status === 'disconnected' && !isConnected) { this.appKit?.resetAccount(this.chainNamespace) this.appKit?.resetWcConnection() this.appKit?.resetNetwork() diff --git a/packages/core/src/controllers/ChainController.ts b/packages/core/src/controllers/ChainController.ts index 2744eeb2e3..057cae7b49 100644 --- a/packages/core/src/controllers/ChainController.ts +++ b/packages/core/src/controllers/ChainController.ts @@ -305,9 +305,8 @@ export const ChainController = { const chain = state.activeChain const isWcConnector = walletId === 'walletConnect' const universalNetworkControllerClient = state.universalAdapter.networkControllerClient - const hasWagmiAdapter = state.chains.get('eip155')?.adapterType === 'wagmi' - const shouldUseUniversalAdapter = (isWcConnector && !hasWagmiAdapter) || state.noAdapters + const shouldUseUniversalAdapter = isWcConnector || state.noAdapters if (shouldUseUniversalAdapter) { if (!universalNetworkControllerClient) { diff --git a/packages/core/src/controllers/NetworkController.ts b/packages/core/src/controllers/NetworkController.ts index 36b04841c7..5e886b8985 100644 --- a/packages/core/src/controllers/NetworkController.ts +++ b/packages/core/src/controllers/NetworkController.ts @@ -4,8 +4,6 @@ import { ModalController } from './ModalController.js' import { CoreHelperUtil } from '../utils/CoreHelperUtil.js' import { NetworkUtil, - SafeLocalStorage, - SafeLocalStorageKeys, type CaipNetwork, type CaipNetworkId, type ChainNamespace @@ -185,30 +183,12 @@ export const NetworkController = { }, async switchActiveNetwork(network: NetworkControllerState['caipNetwork']) { - const sameNamespace = network?.chainNamespace === ChainController.state.activeChain - - let networkControllerClient: NetworkControllerState['_client'] = undefined - const isWcConnector = - SafeLocalStorage.getItem(SafeLocalStorageKeys.WALLET_ID) === 'walletConnect' - const hasWagmiAdapter = ChainController.state.chains.get('eip155')?.adapterType === 'wagmi' - - if (isWcConnector && network?.chainNamespace === 'solana') { - if (hasWagmiAdapter) { - networkControllerClient = ChainController.state.chains.get(network.chainNamespace) - ?.networkControllerClient - } else { - networkControllerClient = ChainController.state.universalAdapter.networkControllerClient - } - } else if (isWcConnector && !hasWagmiAdapter) { - networkControllerClient = ChainController.state.universalAdapter.networkControllerClient - } else if (sameNamespace) { - networkControllerClient = ChainController.getNetworkControllerClient() - } else { - networkControllerClient = network - ? ChainController.state.chains.get(network.chainNamespace)?.networkControllerClient - : undefined - } + const networkControllerClient = ChainController.getNetworkControllerClient() + console.log( + '>> NetworkController switchActiveNetwork networkControllerClient:', + networkControllerClient + ) await networkControllerClient?.switchCaipNetwork(network) ChainController.setActiveCaipNetwork(network) From 1eb7feb8856d6dbfa4e2fb4c575c8144d265515d Mon Sep 17 00:00:00 2001 From: tomiir Date: Thu, 19 Sep 2024 17:25:10 -0300 Subject: [PATCH 17/17] chore: remove log --- packages/core/src/controllers/NetworkController.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/core/src/controllers/NetworkController.ts b/packages/core/src/controllers/NetworkController.ts index 5e886b8985..3bab3f3f32 100644 --- a/packages/core/src/controllers/NetworkController.ts +++ b/packages/core/src/controllers/NetworkController.ts @@ -185,10 +185,6 @@ export const NetworkController = { async switchActiveNetwork(network: NetworkControllerState['caipNetwork']) { const networkControllerClient = ChainController.getNetworkControllerClient() - console.log( - '>> NetworkController switchActiveNetwork networkControllerClient:', - networkControllerClient - ) await networkControllerClient?.switchCaipNetwork(network) ChainController.setActiveCaipNetwork(network)