From fe31c8309b4ac5b6575208a4817fb88eb548de1c Mon Sep 17 00:00:00 2001 From: Felipe Mendes Date: Fri, 30 Aug 2024 08:11:52 -0300 Subject: [PATCH] chore: add safety for localstorage (#2770) --- packages/base/adapters/evm/ethers/client.ts | 50 ++++--- packages/base/adapters/evm/ethers5/client.ts | 48 ++++--- .../base/adapters/solana/web3js/client.ts | 17 +-- packages/base/package.json | 3 +- packages/base/utils/SafeLocalStorage.test.ts | 49 +++++++ packages/base/utils/SafeLocalStorage.ts | 40 ++++++ .../src/ethers/EthersConstantsUtil.ts | 2 +- pnpm-lock.yaml | 124 +++--------------- 8 files changed, 167 insertions(+), 166 deletions(-) create mode 100644 packages/base/utils/SafeLocalStorage.test.ts create mode 100644 packages/base/utils/SafeLocalStorage.ts diff --git a/packages/base/adapters/evm/ethers/client.ts b/packages/base/adapters/evm/ethers/client.ts index 3b5a8f91a2..55880827ea 100644 --- a/packages/base/adapters/evm/ethers/client.ts +++ b/packages/base/adapters/evm/ethers/client.ts @@ -53,6 +53,7 @@ import type { W3mFrameTypes } from '@web3modal/wallet' import type { AppKit } from '../../../src/client.js' import type { AppKitOptions } from '../../../utils/TypesUtil.js' import type { OptionsControllerState } from '@web3modal/core' +import { SafeLocalStorage } from '../../../utils/SafeLocalStorage.js' // -- Types --------------------------------------------------------------------- export interface AdapterOptions extends Pick { @@ -168,7 +169,7 @@ export class EVMEthersClient { getApprovedCaipNetworksData: async () => new Promise(async resolve => { - const walletChoice = localStorage.getItem(EthersConstantsUtil.WALLET_ID) + const walletChoice = SafeLocalStorage.getItem(EthersConstantsUtil.WALLET_ID) if (walletChoice?.includes(ConstantsUtil.WALLET_CONNECT_CONNECTOR_ID)) { const provider = await this.getWalletConnectProvider() if (!provider) { @@ -343,7 +344,7 @@ export class EVMEthersClient { disconnect: async () => { const provider = EthersStoreUtil.state.provider const providerType = EthersStoreUtil.state.providerType - localStorage.removeItem(EthersConstantsUtil.WALLET_ID) + SafeLocalStorage.removeItem(EthersConstantsUtil.WALLET_ID) EthersStoreUtil.reset() this.appKit?.setClientId(null) if (siweConfig?.options?.signOutOnDisconnect) { @@ -368,7 +369,7 @@ export class EVMEthersClient { } provider?.emit?.('disconnect') - localStorage.removeItem(EthersConstantsUtil.WALLET_ID) + SafeLocalStorage.removeItem(EthersConstantsUtil.WALLET_ID) EthersStoreUtil.reset() }, @@ -641,7 +642,7 @@ export class EVMEthersClient { public async disconnect() { const { provider, providerType } = EthersStoreUtil.state - localStorage.removeItem(EthersConstantsUtil.WALLET_ID) + SafeLocalStorage.removeItem(EthersConstantsUtil.WALLET_ID) EthersStoreUtil.reset() this.appKit?.setClientId(null) @@ -752,7 +753,7 @@ export class EVMEthersClient { private async checkActiveWalletConnectProvider() { const WalletConnectProvider = await this.getWalletConnectProvider() - const walletId = localStorage.getItem(EthersConstantsUtil.WALLET_ID) + const walletId = SafeLocalStorage.getItem(EthersConstantsUtil.WALLET_ID) if (WalletConnectProvider) { if (walletId === ConstantsUtil.WALLET_CONNECT_CONNECTOR_ID) { @@ -766,7 +767,7 @@ export class EVMEthersClient { private checkActiveInjectedProvider(config: ProviderType) { const InjectedProvider = config.injected - const walletId = localStorage.getItem(EthersConstantsUtil.WALLET_ID) + const walletId = SafeLocalStorage.getItem(EthersConstantsUtil.WALLET_ID) if (InjectedProvider) { if (walletId === ConstantsUtil.INJECTED_CONNECTOR_ID) { @@ -778,7 +779,7 @@ export class EVMEthersClient { private checkActiveCoinbaseProvider(config: ProviderType) { const CoinbaseProvider = config.coinbase as unknown as ExternalProvider - const walletId = localStorage.getItem(EthersConstantsUtil.WALLET_ID) + const walletId = SafeLocalStorage.getItem(EthersConstantsUtil.WALLET_ID) if (CoinbaseProvider) { if (walletId === ConstantsUtil.COINBASE_SDK_CONNECTOR_ID) { @@ -786,7 +787,7 @@ export class EVMEthersClient { this.setCoinbaseProvider(config) this.watchCoinbase(config) } else { - localStorage.removeItem(EthersConstantsUtil.WALLET_ID) + SafeLocalStorage.removeItem(EthersConstantsUtil.WALLET_ID) EthersStoreUtil.reset() } } @@ -794,7 +795,7 @@ export class EVMEthersClient { } private checkActive6963Provider() { - const currentActiveWallet = window?.localStorage.getItem(EthersConstantsUtil.WALLET_ID) + const currentActiveWallet = SafeLocalStorage.getItem(EthersConstantsUtil.WALLET_ID) if (currentActiveWallet) { const currentProvider = this.EIP6963Providers.find( provider => provider.info.name === currentActiveWallet @@ -806,7 +807,7 @@ export class EVMEthersClient { } private async setWalletConnectProvider() { - window?.localStorage.setItem( + SafeLocalStorage.setItem( EthersConstantsUtil.WALLET_ID, ConstantsUtil.WALLET_CONNECT_CONNECTOR_ID ) @@ -835,7 +836,7 @@ export class EVMEthersClient { } private async setInjectedProvider(config: ProviderType) { - window?.localStorage.setItem(EthersConstantsUtil.WALLET_ID, ConstantsUtil.INJECTED_CONNECTOR_ID) + SafeLocalStorage.setItem(EthersConstantsUtil.WALLET_ID, ConstantsUtil.INJECTED_CONNECTOR_ID) const InjectedProvider = config.injected if (InjectedProvider) { @@ -857,7 +858,7 @@ export class EVMEthersClient { } private async setEIP6963Provider(provider: Provider, name: string) { - window?.localStorage.setItem(EthersConstantsUtil.WALLET_ID, name) + SafeLocalStorage.setItem(EthersConstantsUtil.WALLET_ID, name) if (provider) { const { addresses, chainId } = await EthersHelpersUtil.getUserInfo(provider) @@ -878,10 +879,7 @@ export class EVMEthersClient { } private async setCoinbaseProvider(config: ProviderType) { - window?.localStorage.setItem( - EthersConstantsUtil.WALLET_ID, - ConstantsUtil.COINBASE_SDK_CONNECTOR_ID - ) + SafeLocalStorage.setItem(EthersConstantsUtil.WALLET_ID, ConstantsUtil.COINBASE_SDK_CONNECTOR_ID) const CoinbaseProvider = config.coinbase if (CoinbaseProvider) { const { addresses, chainId } = await EthersHelpersUtil.getUserInfo(CoinbaseProvider) @@ -902,7 +900,7 @@ export class EVMEthersClient { } private async setAuthProvider() { - window?.localStorage.setItem(EthersConstantsUtil.WALLET_ID, ConstantsUtil.AUTH_CONNECTOR_ID) + SafeLocalStorage.setItem(EthersConstantsUtil.WALLET_ID, ConstantsUtil.AUTH_CONNECTOR_ID) if (this.authProvider) { this.appKit?.setLoading(true) @@ -945,7 +943,7 @@ export class EVMEthersClient { const provider = await this.getWalletConnectProvider() function disconnectHandler() { - localStorage.removeItem(EthersConstantsUtil.WALLET_ID) + SafeLocalStorage.removeItem(EthersConstantsUtil.WALLET_ID) EthersStoreUtil.reset() provider?.removeListener('disconnect', disconnectHandler) provider?.removeListener('accountsChanged', accountsChangedHandler) @@ -976,7 +974,7 @@ export class EVMEthersClient { const provider = config.injected function disconnectHandler() { - localStorage.removeItem(EthersConstantsUtil.WALLET_ID) + SafeLocalStorage.removeItem(EthersConstantsUtil.WALLET_ID) EthersStoreUtil.reset() provider?.removeListener('disconnect', disconnectHandler) @@ -989,7 +987,7 @@ export class EVMEthersClient { if (currentAccount) { EthersStoreUtil.setAddress(getOriginalAddress(currentAccount) as Address) } else { - localStorage.removeItem(EthersConstantsUtil.WALLET_ID) + SafeLocalStorage.removeItem(EthersConstantsUtil.WALLET_ID) EthersStoreUtil.reset() } } @@ -1013,7 +1011,7 @@ export class EVMEthersClient { private watchEIP6963(provider: Provider) { function disconnectHandler() { - localStorage.removeItem(EthersConstantsUtil.WALLET_ID) + SafeLocalStorage.removeItem(EthersConstantsUtil.WALLET_ID) EthersStoreUtil.reset() provider.removeListener('disconnect', disconnectHandler) provider.removeListener('accountsChanged', accountsChangedHandler) @@ -1030,7 +1028,7 @@ export class EVMEthersClient { ) } else { this.appKit?.setAllAccounts([], this.chain) - localStorage.removeItem(EthersConstantsUtil.WALLET_ID) + SafeLocalStorage.removeItem(EthersConstantsUtil.WALLET_ID) EthersStoreUtil.reset() } } @@ -1054,9 +1052,9 @@ export class EVMEthersClient { private watchCoinbase(config: ProviderType) { const provider = config.coinbase - const walletId = localStorage.getItem(EthersConstantsUtil.WALLET_ID) + const walletId = SafeLocalStorage.getItem(EthersConstantsUtil.WALLET_ID) function disconnectHandler() { - localStorage.removeItem(EthersConstantsUtil.WALLET_ID) + SafeLocalStorage.removeItem(EthersConstantsUtil.WALLET_ID) EthersStoreUtil.reset() provider?.removeListener('disconnect', disconnectHandler) @@ -1069,7 +1067,7 @@ export class EVMEthersClient { if (currentAccount) { EthersStoreUtil.setAddress(getOriginalAddress(currentAccount) as Address) } else { - localStorage.removeItem(EthersConstantsUtil.WALLET_ID) + SafeLocalStorage.removeItem(EthersConstantsUtil.WALLET_ID) EthersStoreUtil.reset() } } @@ -1322,7 +1320,7 @@ export class EVMEthersClient { } private syncConnectedWalletInfo() { - const currentActiveWallet = window?.localStorage.getItem(EthersConstantsUtil.WALLET_ID) + const currentActiveWallet = SafeLocalStorage.getItem(EthersConstantsUtil.WALLET_ID) const providerType = EthersStoreUtil.state.providerType if (providerType === ConstantsUtil.EIP6963_CONNECTOR_ID) { diff --git a/packages/base/adapters/evm/ethers5/client.ts b/packages/base/adapters/evm/ethers5/client.ts index 700027efff..af886bb415 100644 --- a/packages/base/adapters/evm/ethers5/client.ts +++ b/packages/base/adapters/evm/ethers5/client.ts @@ -34,6 +34,7 @@ import type { Chain as AvailableChain } from '@web3modal/common' import type { AppKit } from '../../../src/client.js' import type { AppKitOptions } from '../../../utils/TypesUtil.js' import type { OptionsControllerState } from '@web3modal/core' +import { SafeLocalStorage } from '../../../utils/SafeLocalStorage.js' // -- Types --------------------------------------------------------------------- export interface AdapterOptions extends Pick { @@ -145,7 +146,7 @@ export class EVMEthers5Client { getApprovedCaipNetworksData: async () => new Promise(async resolve => { - const walletChoice = localStorage.getItem(EthersConstantsUtil.WALLET_ID) + const walletChoice = SafeLocalStorage.getItem(EthersConstantsUtil.WALLET_ID) if (walletChoice?.includes(ConstantsUtil.WALLET_CONNECT_CONNECTOR_ID)) { const provider = await this.getWalletConnectProvider() if (!provider) { @@ -312,7 +313,7 @@ export class EVMEthers5Client { disconnect: async () => { const provider = EthersStoreUtil.state.provider const providerType = EthersStoreUtil.state.providerType - localStorage.removeItem(EthersConstantsUtil.WALLET_ID) + SafeLocalStorage.removeItem(EthersConstantsUtil.WALLET_ID) EthersStoreUtil.reset() this.appKit?.setClientId(null) if (siweConfig?.options?.signOutOnDisconnect) { @@ -335,7 +336,7 @@ export class EVMEthers5Client { } provider?.emit?.('disconnect') - localStorage.removeItem(EthersConstantsUtil.WALLET_ID) + SafeLocalStorage.removeItem(EthersConstantsUtil.WALLET_ID) EthersStoreUtil.reset() }, @@ -513,7 +514,7 @@ export class EVMEthers5Client { public async disconnect() { const { provider, providerType } = EthersStoreUtil.state - localStorage.removeItem(EthersConstantsUtil.WALLET_ID) + SafeLocalStorage.removeItem(EthersConstantsUtil.WALLET_ID) EthersStoreUtil.reset() this.appKit?.setClientId(null) @@ -589,7 +590,7 @@ export class EVMEthers5Client { private async checkActiveWalletConnectProvider() { const WalletConnectProvider = await this.getWalletConnectProvider() - const walletId = localStorage.getItem(EthersConstantsUtil.WALLET_ID) + const walletId = SafeLocalStorage.getItem(EthersConstantsUtil.WALLET_ID) if (WalletConnectProvider) { if (walletId === ConstantsUtil.WALLET_CONNECT_CONNECTOR_ID) { @@ -603,7 +604,7 @@ export class EVMEthers5Client { private checkActiveInjectedProvider(config: ProviderType) { const InjectedProvider = config.injected - const walletId = localStorage.getItem(EthersConstantsUtil.WALLET_ID) + const walletId = SafeLocalStorage.getItem(EthersConstantsUtil.WALLET_ID) if (InjectedProvider) { if (walletId === ConstantsUtil.INJECTED_CONNECTOR_ID) { @@ -615,7 +616,7 @@ export class EVMEthers5Client { private checkActiveCoinbaseProvider(config: ProviderType) { const CoinbaseProvider = config.coinbase as unknown as ExternalProvider - const walletId = localStorage.getItem(EthersConstantsUtil.WALLET_ID) + const walletId = SafeLocalStorage.getItem(EthersConstantsUtil.WALLET_ID) if (CoinbaseProvider) { if (walletId === ConstantsUtil.COINBASE_SDK_CONNECTOR_ID) { @@ -623,7 +624,7 @@ export class EVMEthers5Client { this.setCoinbaseProvider(config) this.watchCoinbase(config) } else { - localStorage.removeItem(EthersConstantsUtil.WALLET_ID) + SafeLocalStorage.removeItem(EthersConstantsUtil.WALLET_ID) EthersStoreUtil.reset() } } @@ -631,7 +632,7 @@ export class EVMEthers5Client { } private checkActive6963Provider() { - const currentActiveWallet = window?.localStorage.getItem(EthersConstantsUtil.WALLET_ID) + const currentActiveWallet = SafeLocalStorage.getItem(EthersConstantsUtil.WALLET_ID) if (currentActiveWallet) { const currentProvider = this.EIP6963Providers.find( provider => provider.info.name === currentActiveWallet @@ -643,7 +644,7 @@ export class EVMEthers5Client { } private async setWalletConnectProvider() { - window?.localStorage.setItem( + SafeLocalStorage.setItem( EthersConstantsUtil.WALLET_ID, ConstantsUtil.WALLET_CONNECT_CONNECTOR_ID ) @@ -660,7 +661,7 @@ export class EVMEthers5Client { } private async setEIP6963Provider(provider: Provider, name: string) { - window?.localStorage.setItem(EthersConstantsUtil.WALLET_ID, name) + SafeLocalStorage.setItem(EthersConstantsUtil.WALLET_ID, name) if (provider) { const { addresses, chainId } = await EthersHelpersUtil.getUserInfo(provider) @@ -677,7 +678,7 @@ export class EVMEthers5Client { } private async setInjectedProvider(config: ProviderType) { - window?.localStorage.setItem(EthersConstantsUtil.WALLET_ID, ConstantsUtil.INJECTED_CONNECTOR_ID) + SafeLocalStorage.setItem(EthersConstantsUtil.WALLET_ID, ConstantsUtil.INJECTED_CONNECTOR_ID) const InjectedProvider = config.injected if (InjectedProvider) { @@ -695,10 +696,7 @@ export class EVMEthers5Client { } private async setCoinbaseProvider(config: ProviderType) { - window?.localStorage.setItem( - EthersConstantsUtil.WALLET_ID, - ConstantsUtil.COINBASE_SDK_CONNECTOR_ID - ) + SafeLocalStorage.setItem(EthersConstantsUtil.WALLET_ID, ConstantsUtil.COINBASE_SDK_CONNECTOR_ID) const CoinbaseProvider = config.coinbase if (CoinbaseProvider) { const { addresses, chainId } = await EthersHelpersUtil.getUserInfo(CoinbaseProvider) @@ -718,7 +716,7 @@ export class EVMEthers5Client { const WalletConnectProvider = await this.getWalletConnectProvider() function disconnectHandler() { - localStorage.removeItem(EthersConstantsUtil.WALLET_ID) + SafeLocalStorage.removeItem(EthersConstantsUtil.WALLET_ID) EthersStoreUtil.reset() WalletConnectProvider?.removeListener('disconnect', disconnectHandler) @@ -750,7 +748,7 @@ export class EVMEthers5Client { const InjectedProvider = config.injected function disconnectHandler() { - localStorage.removeItem(EthersConstantsUtil.WALLET_ID) + SafeLocalStorage.removeItem(EthersConstantsUtil.WALLET_ID) EthersStoreUtil.reset() InjectedProvider?.removeListener('disconnect', disconnectHandler) @@ -763,7 +761,7 @@ export class EVMEthers5Client { if (currentAccount) { EthersStoreUtil.setAddress(utils.getAddress(currentAccount) as Address) } else { - localStorage.removeItem(EthersConstantsUtil.WALLET_ID) + SafeLocalStorage.removeItem(EthersConstantsUtil.WALLET_ID) EthersStoreUtil.reset() } } @@ -787,7 +785,7 @@ export class EVMEthers5Client { private watchEIP6963(provider: Provider) { function disconnectHandler() { - localStorage.removeItem(EthersConstantsUtil.WALLET_ID) + SafeLocalStorage.removeItem(EthersConstantsUtil.WALLET_ID) EthersStoreUtil.reset() provider.removeListener('disconnect', disconnectHandler) @@ -800,7 +798,7 @@ export class EVMEthers5Client { if (currentAccount) { EthersStoreUtil.setAddress(utils.getAddress(currentAccount) as Address) } else { - localStorage.removeItem(EthersConstantsUtil.WALLET_ID) + SafeLocalStorage.removeItem(EthersConstantsUtil.WALLET_ID) EthersStoreUtil.reset() } } @@ -822,10 +820,10 @@ export class EVMEthers5Client { private watchCoinbase(config: ProviderType) { const CoinbaseProvider = config.coinbase - const walletId = localStorage.getItem(EthersConstantsUtil.WALLET_ID) + const walletId = SafeLocalStorage.getItem(EthersConstantsUtil.WALLET_ID) function disconnectHandler() { - localStorage.removeItem(EthersConstantsUtil.WALLET_ID) + SafeLocalStorage.removeItem(EthersConstantsUtil.WALLET_ID) EthersStoreUtil.reset() CoinbaseProvider?.removeListener('disconnect', disconnectHandler) @@ -835,7 +833,7 @@ export class EVMEthers5Client { function accountsChangedHandler(accounts: string[]) { if (accounts.length === 0) { - localStorage.removeItem(EthersConstantsUtil.WALLET_ID) + SafeLocalStorage.removeItem(EthersConstantsUtil.WALLET_ID) EthersStoreUtil.reset() } else { EthersStoreUtil.setAddress(accounts[0] as Address) @@ -993,7 +991,7 @@ export class EVMEthers5Client { } private syncConnectedWalletInfo() { - const currentActiveWallet = window?.localStorage.getItem(EthersConstantsUtil.WALLET_ID) + const currentActiveWallet = SafeLocalStorage.getItem(EthersConstantsUtil.WALLET_ID) const providerType = EthersStoreUtil.state.providerType if (providerType === ConstantsUtil.EIP6963_CONNECTOR_ID) { diff --git a/packages/base/adapters/solana/web3js/client.ts b/packages/base/adapters/solana/web3js/client.ts index 8fe3946d26..5d2c1105b2 100644 --- a/packages/base/adapters/solana/web3js/client.ts +++ b/packages/base/adapters/solana/web3js/client.ts @@ -45,6 +45,7 @@ import { withSolanaNamespace } from './utils/withSolanaNamespace.js' import type { AppKit } from '../../../src/client.js' import type { AppKitOptions } from '../../../utils/TypesUtil.js' import type { OptionsControllerState } from '@web3modal/core' +import { SafeLocalStorage } from '../../../utils/SafeLocalStorage.js' export interface Web3ModalClientOptions extends Omit { @@ -222,7 +223,7 @@ export class SolanaWeb3JsClient { const chain = SolHelpersUtil.getChainFromCaip( chains, - typeof window === 'object' ? localStorage.getItem(SolConstantsUtil.CAIP_CHAIN_ID) : '' + SafeLocalStorage.getItem(SolConstantsUtil.CAIP_CHAIN_ID) || '' ) this.defaultChain = chain as CaipNetwork @@ -260,7 +261,7 @@ export class SolanaWeb3JsClient { if (NetworkController.state.caipNetwork && !SolStoreUtil.state.isConnected) { SolStoreUtil.setCaipChainId(`solana:${newChain.chainId}`) SolStoreUtil.setCurrentChain(newChain) - localStorage.setItem(SolConstantsUtil.CAIP_CHAIN_ID, `solana:${newChain.chainId}`) + SafeLocalStorage.setItem(SolConstantsUtil.CAIP_CHAIN_ID, `solana:${newChain.chainId}`) ApiController.reFetchWallets() } }) @@ -302,7 +303,7 @@ export class SolanaWeb3JsClient { // -- Private ----------------------------------------------------------------- private syncConnectedWalletInfo() { - const currentActiveWallet = window?.localStorage.getItem(SolConstantsUtil.WALLET_ID) + const currentActiveWallet = SafeLocalStorage.getItem(SolConstantsUtil.WALLET_ID) const provider = SolStoreUtil.state.provider if (provider?.type === 'WALLET_CONNECT') { @@ -387,7 +388,7 @@ export class SolanaWeb3JsClient { const chain = SolHelpersUtil.getChainFromCaip(this.chains, caipChainId) SolStoreUtil.setCaipChainId(chain.id) SolStoreUtil.setCurrentChain(chain) - localStorage.setItem(SolConstantsUtil.CAIP_CHAIN_ID, chain.id) + SafeLocalStorage.setItem(SolConstantsUtil.CAIP_CHAIN_ID, chain.id) await this.syncNetwork() await this.syncAccount() @@ -459,7 +460,7 @@ export class SolanaWeb3JsClient { SolStoreUtil.setProvider(provider) this.provider = provider - window?.localStorage.setItem(SolConstantsUtil.WALLET_ID, provider.name) + SafeLocalStorage.setItem(SolConstantsUtil.WALLET_ID, provider.name) await this.appKit?.setApprovedCaipNetworksData(this.chain) @@ -539,7 +540,7 @@ export class SolanaWeb3JsClient { } function disconnectHandler() { - localStorage.removeItem(SolConstantsUtil.WALLET_ID) + SafeLocalStorage.removeItem(SolConstantsUtil.WALLET_ID) SolStoreUtil.reset() provider.removeListener('disconnect', disconnectHandler) @@ -555,7 +556,7 @@ export class SolanaWeb3JsClient { if (currentAccount) { SolStoreUtil.setAddress(currentAccount) } else { - localStorage.removeItem(SolConstantsUtil.WALLET_ID) + SafeLocalStorage.removeItem(SolConstantsUtil.WALLET_ID) SolStoreUtil.reset() } } @@ -614,7 +615,7 @@ export class SolanaWeb3JsClient { } private addProvider(...providers: Provider[]) { - const activeProviderName = localStorage.getItem(SolConstantsUtil.WALLET_ID) + const activeProviderName = SafeLocalStorage.getItem(SolConstantsUtil.WALLET_ID) for (const provider of providers) { this.availableProviders = this.availableProviders.filter(p => p.name !== provider.name) diff --git a/packages/base/package.json b/packages/base/package.json index 4e5c574a0c..73f878b9da 100644 --- a/packages/base/package.json +++ b/packages/base/package.json @@ -13,7 +13,8 @@ "build": "tsc --build tsconfig.build.json", "watch": "tsc --watch", "typecheck": "tsc --noEmit", - "lint": "eslint . --ext .js,.jsx,.ts,.tsx" + "lint": "eslint . --ext .js,.jsx,.ts,.tsx", + "test": "vitest run --coverage.enabled=true --coverage.reporter=json --coverage.reporter=json-summary --coverage.reportOnFailure=true" }, "exports": { ".": { diff --git a/packages/base/utils/SafeLocalStorage.test.ts b/packages/base/utils/SafeLocalStorage.test.ts new file mode 100644 index 0000000000..8415025d0c --- /dev/null +++ b/packages/base/utils/SafeLocalStorage.test.ts @@ -0,0 +1,49 @@ +import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest' + +import { SafeLocalStorage } from './SafeLocalStorage' + +const previousLocalStorage = globalThis.localStorage +const previousWindow = globalThis.window + +afterAll(() => { + Object.assign(globalThis, { localStorage: previousLocalStorage, window: previousWindow }) +}) + +describe('SafeLocalStorage unsafe', () => { + beforeAll(() => { + Object.assign(globalThis, { window: {}, localStorage: undefined }) + }) + + it('should not setItem', () => { + const key = '@w3m/wallet_id' + + expect(SafeLocalStorage.setItem(key, '1')).toBe(undefined) + expect(SafeLocalStorage.getItem(key)).toBe(null) + expect(SafeLocalStorage.removeItem(key)).toBe(undefined) + }) +}) + +describe('SafeLocalStorage safe', () => { + let getItem = vi.fn(() => '{"test":"test"}') + let setItem = vi.fn() + let removeItem = vi.fn() + + beforeAll(() => { + Object.assign(globalThis, { window: {}, localStorage: { getItem, setItem, removeItem } }) + }) + + it('should setItem', () => { + expect(SafeLocalStorage.setItem('@w3m/wallet_id', 'test')).toBe(undefined) + expect(setItem).toHaveBeenCalledWith('@w3m/wallet_id', '"test"') + }) + + it('should getItem', () => { + expect(SafeLocalStorage.getItem('@w3m/wallet_id')).toEqual({ test: 'test' }) + expect(getItem).toHaveBeenCalledWith('@w3m/wallet_id') + }) + + it('should removeItem', () => { + expect(SafeLocalStorage.removeItem('@w3m/wallet_id')).toBe(undefined) + expect(removeItem).toHaveBeenCalledWith('@w3m/wallet_id') + }) +}) diff --git a/packages/base/utils/SafeLocalStorage.ts b/packages/base/utils/SafeLocalStorage.ts new file mode 100644 index 0000000000..cfcad189d2 --- /dev/null +++ b/packages/base/utils/SafeLocalStorage.ts @@ -0,0 +1,40 @@ +export type SafeLocalStorageItems = { + '@w3m/wallet_id': string + '@w3m/solana_caip_chain': string + '@w3m/solana_wallet': string +} + +export const SafeLocalStorage = { + setItem( + key: Key, + value: SafeLocalStorageItems[Key] + ): void { + if (isSafe()) { + localStorage.setItem(key, JSON.stringify(value)) + } + }, + getItem(key: Key): SafeLocalStorageItems[Key] | null { + if (isSafe()) { + const value = localStorage.getItem(key) + + if (value) { + try { + return JSON.parse(value) + } catch { + return null + } + } + } + + return null + }, + removeItem(key: Key): void { + if (isSafe()) { + localStorage.removeItem(key) + } + } +} + +function isSafe(): boolean { + return typeof window !== 'undefined' && typeof localStorage !== 'undefined' +} diff --git a/packages/scaffold-utils/src/ethers/EthersConstantsUtil.ts b/packages/scaffold-utils/src/ethers/EthersConstantsUtil.ts index 4f1689ab19..f123e4a819 100644 --- a/packages/scaffold-utils/src/ethers/EthersConstantsUtil.ts +++ b/packages/scaffold-utils/src/ethers/EthersConstantsUtil.ts @@ -2,4 +2,4 @@ export const EthersConstantsUtil = { WALLET_ID: '@w3m/wallet_id', ERROR_CODE_UNRECOGNIZED_CHAIN_ID: 4902, ERROR_CODE_DEFAULT: 5000 -} +} as const diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9e9c086b8a..1f19e3ae94 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -108,7 +108,7 @@ importers: version: 2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4) wagmi: specifier: 2.12.5 - version: 2.12.5(@tanstack/query-core@5.24.8)(@tanstack/react-query@5.24.8(react@18.2.0))(@types/react@18.2.62)(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(rollup@4.21.1)(typescript@5.3.3)(utf-8-validate@5.0.10)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4) + version: 2.12.5(@tanstack/query-core@5.24.8)(@tanstack/react-query@5.24.8(react@18.2.0))(@types/react@18.2.62)(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react-native@0.75.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.3.3)(utf-8-validate@5.0.10))(react@18.2.0)(rollup@4.21.1)(typescript@5.3.3)(utf-8-validate@5.0.10)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4) zustand: specifier: 4.5.2 version: 4.5.2(@types/react@18.2.62)(react@18.2.0) @@ -374,7 +374,7 @@ importers: version: 2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4) wagmi: specifier: 2.12.5 - version: 2.12.5(@tanstack/query-core@5.24.8)(@tanstack/react-query@5.24.8(react@18.2.0))(@types/react@18.2.62)(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(rollup@4.21.1)(typescript@5.3.3)(utf-8-validate@5.0.10)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4) + version: 2.12.5(@tanstack/query-core@5.24.8)(@tanstack/react-query@5.24.8(react@18.2.0))(@types/react@18.2.62)(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react-native@0.75.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.3.3)(utf-8-validate@5.0.10))(react@18.2.0)(rollup@4.21.1)(typescript@5.3.3)(utf-8-validate@5.0.10)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4) devDependencies: '@types/node': specifier: 20.11.5 @@ -510,7 +510,7 @@ importers: version: 5.2.11(@types/node@20.11.5)(terser@5.31.6) wagmi: specifier: 2.12.5 - version: 2.12.5(@tanstack/query-core@5.24.8)(@tanstack/react-query@5.24.8(react@18.2.0))(@types/react@18.2.62)(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(rollup@4.21.1)(typescript@5.3.3)(utf-8-validate@5.0.10)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4) + version: 2.12.5(@tanstack/query-core@5.24.8)(@tanstack/react-query@5.24.8(react@18.2.0))(@types/react@18.2.62)(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react-native@0.75.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.3.3)(utf-8-validate@5.0.10))(react@18.2.0)(rollup@4.21.1)(typescript@5.3.3)(utf-8-validate@5.0.10)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4) devDependencies: '@types/react': specifier: 18.2.62 @@ -20067,45 +20067,6 @@ snapshots: - utf-8-validate - zod - '@wagmi/connectors@5.1.5(@types/react@18.2.62)(@wagmi/core@2.13.4(@tanstack/query-core@5.24.8)(@types/react@18.2.62)(react@18.2.0)(typescript@5.3.3)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4)))(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(rollup@4.21.1)(typescript@5.3.3)(utf-8-validate@5.0.10)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4)': - dependencies: - '@coinbase/wallet-sdk': 4.0.4 - '@metamask/sdk': 0.27.0(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react-native@0.75.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.0)(bufferutil@4.0.8)(react@18.2.0)(typescript@5.3.3)(utf-8-validate@5.0.10))(react@18.2.0)(rollup@4.21.1)(utf-8-validate@5.0.10) - '@safe-global/safe-apps-provider': 0.18.3(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4) - '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4) - '@wagmi/core': 2.13.4(@tanstack/query-core@5.24.8)(@types/react@18.2.62)(react@18.2.0)(typescript@5.3.3)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4)) - '@walletconnect/ethereum-provider': 2.14.0(@types/react@18.2.62)(bufferutil@4.0.8)(react@18.2.0)(utf-8-validate@5.0.10) - '@walletconnect/modal': 2.6.2(@types/react@18.2.62)(react@18.2.0) - cbw-sdk: '@coinbase/wallet-sdk@3.9.3' - viem: 2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4) - optionalDependencies: - typescript: 5.3.3 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@types/react' - - '@upstash/redis' - - '@vercel/kv' - - bufferutil - - encoding - - ioredis - - react - - react-dom - - react-native - - rollup - - supports-color - - uWebSockets.js - - utf-8-validate - - zod - '@wagmi/core@2.13.4(@tanstack/query-core@5.24.8)(@types/react@18.2.0)(react@18.2.0)(typescript@5.3.3)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4))': dependencies: eventemitter3: 5.0.1 @@ -22664,7 +22625,7 @@ snapshots: '@typescript-eslint/parser': 6.18.1(eslint@8.56.0)(typescript@5.3.3) eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0))(eslint@8.56.0) eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.56.0) eslint-plugin-jsx-a11y: 6.9.0(eslint@8.56.0) eslint-plugin-react: 7.35.0(eslint@8.56.0) @@ -22683,8 +22644,8 @@ snapshots: '@typescript-eslint/parser': 6.18.1(eslint@8.57.0)(typescript@5.3.3) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@6.18.1(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint@8.57.0) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@6.18.1(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.18.1(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.9.0(eslint@8.57.0) eslint-plugin-react: 7.35.0(eslint@8.57.0) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0) @@ -22707,13 +22668,13 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0): + eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0))(eslint@8.56.0): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.3.6 enhanced-resolve: 5.17.1 eslint: 8.56.0 - eslint-module-utils: 2.8.2(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0))(eslint@8.56.0) + eslint-module-utils: 2.8.2(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0))(eslint@8.56.0))(eslint@8.56.0) fast-glob: 3.3.2 get-tsconfig: 4.7.6 is-bun-module: 1.1.0 @@ -22726,54 +22687,44 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.18.1(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0): + eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.18.1(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint@8.57.0))(eslint@8.57.0): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.3.6 enhanced-resolve: 5.17.1 eslint: 8.57.0 - eslint-module-utils: 2.8.2(@typescript-eslint/parser@6.18.1(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.18.1(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) + eslint-module-utils: 2.8.2(@typescript-eslint/parser@6.18.1(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.18.1(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) fast-glob: 3.3.2 get-tsconfig: 4.7.6 is-bun-module: 1.1.0 is-glob: 4.0.3 optionalDependencies: - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.18.1(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0) transitivePeerDependencies: - '@typescript-eslint/parser' - eslint-import-resolver-node - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.8.2(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0))(eslint@8.56.0): + eslint-module-utils@2.8.2(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0))(eslint@8.56.0))(eslint@8.56.0): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 6.18.1(eslint@8.56.0)(typescript@5.3.3) eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0))(eslint@8.56.0) transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.2(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): - dependencies: - debug: 3.2.7 - optionalDependencies: - '@typescript-eslint/parser': 6.18.1(eslint@8.56.0)(typescript@5.3.3) - eslint: 8.57.0 - eslint-import-resolver-node: 0.3.9 - transitivePeerDependencies: - - supports-color - - eslint-module-utils@2.8.2(@typescript-eslint/parser@6.18.1(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.18.1(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0): + eslint-module-utils@2.8.2(@typescript-eslint/parser@6.18.1(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.18.1(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 6.18.1(eslint@8.57.0)(typescript@5.3.3) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@6.18.1(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@6.18.1(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint@8.57.0))(eslint@8.57.0) transitivePeerDependencies: - supports-color @@ -22787,7 +22738,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.2(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0))(eslint@8.56.0) + eslint-module-utils: 2.8.2(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint@8.56.0))(eslint@8.56.0))(eslint@8.56.0) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -22804,7 +22755,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint@8.57.0): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.18.1(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0): dependencies: array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 @@ -22814,7 +22765,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.2(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) + eslint-module-utils: 2.8.2(@typescript-eslint/parser@6.18.1(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.18.1(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -22825,7 +22776,7 @@ snapshots: semver: 6.3.1 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 6.18.1(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.18.1(eslint@8.57.0)(typescript@5.3.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -27958,43 +27909,6 @@ snapshots: - utf-8-validate - zod - wagmi@2.12.5(@tanstack/query-core@5.24.8)(@tanstack/react-query@5.24.8(react@18.2.0))(@types/react@18.2.62)(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(rollup@4.21.1)(typescript@5.3.3)(utf-8-validate@5.0.10)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4): - dependencies: - '@tanstack/react-query': 5.24.8(react@18.2.0) - '@wagmi/connectors': 5.1.5(@types/react@18.2.62)(@wagmi/core@2.13.4(@tanstack/query-core@5.24.8)(@types/react@18.2.62)(react@18.2.0)(typescript@5.3.3)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4)))(bufferutil@4.0.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(rollup@4.21.1)(typescript@5.3.3)(utf-8-validate@5.0.10)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4) - '@wagmi/core': 2.13.4(@tanstack/query-core@5.24.8)(@types/react@18.2.62)(react@18.2.0)(typescript@5.3.3)(viem@2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4)) - react: 18.2.0 - use-sync-external-store: 1.2.0(react@18.2.0) - viem: 2.19.6(bufferutil@4.0.8)(typescript@5.3.3)(utf-8-validate@5.0.10)(zod@3.22.4) - optionalDependencies: - typescript: 5.3.3 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@tanstack/query-core' - - '@types/react' - - '@upstash/redis' - - '@vercel/kv' - - bufferutil - - encoding - - immer - - ioredis - - react-dom - - react-native - - rollup - - supports-color - - uWebSockets.js - - utf-8-validate - - zod - walker@1.0.8: dependencies: makeerror: 1.0.12