From 626bc68b9f6c8dcdcf34d08e7e7ba13ef01efd19 Mon Sep 17 00:00:00 2001 From: Eugene Chybisov <18644653+chybisov@users.noreply.github.com> Date: Wed, 19 Apr 2023 13:03:35 +0700 Subject: [PATCH] feat: new wallet management (#69) * refactor: remove web3-react * refactor: external change propagation * fix: external disconnect behavior * refactor: cleanup unnecessary files * chore: cleanup unused code * feat: add autoConnect * fix: auto connect * fix: walletconnect * feat: re-enable tally * fix: type export * fix: type import * chore: remove unused files * chore: remove unused files * refactor: playground wallet provider * fix: import * feat: add frontier * feat: frontier logo * feat: add apex wallet, optimize connectors * refactor: cleanup * refactor: unshift wallets into back of connected wallets array * chore: clean widget walletprovider * feat: add default wallet * fix: walletautomation * fix: playground wallet connect * chore: remove logs * fix: external disconnet sync * refactor: widget-embedded walletprovider * feat: improve default wallet handling * chore: simplify wallet select page * feat: autoconnect based on specific wallets * chore: cleanup * chore: bump packages --------- Co-authored-by: Addminus --- packages/wallet-management/package.json | 10 +- .../src/LiFiWalletManagement.ts | 165 ++-- .../src/connectors/coinbaseWallet.ts | 12 - .../src/connectors/eip1193.ts | 68 -- .../wallet-management/src/connectors/empty.ts | 5 - .../src/connectors/injectedConnector.ts | 185 +++++ .../src/connectors/metaMask.ts | 23 - .../src/connectors/network.ts | 10 - .../src/connectors/tallyho.ts | 203 ----- .../wallet-management/src/connectors/url.ts | 10 - .../src/connectors/walletConnect.ts | 105 --- .../src/connectors/walletConnectConnector.ts | 145 ++++ packages/wallet-management/src/index.ts | 3 +- .../wallet-management/src/injectedData.ts | 21 - .../src/priorityConnector.ts | 33 - packages/wallet-management/src/types/index.ts | 92 +++ .../wallet-management/src/walletAutomation.ts | 87 +-- .../src/walletIcons/frontier.svg | 20 + .../src/walletIcons/index.ts | 8 +- .../{detected.svg => placeholder.svg} | 0 .../wallet-management/src/walletIcons/tp.svg | 11 - .../src/walletPersistance.ts | 119 ++- .../wallet-management/src/walletProviders.ts | 343 --------- packages/wallet-management/src/wallets.ts | 344 ++++++--- packages/widget-embedded/package.json | 6 +- .../src/components/NFTOpenSea/NFTOpenSea.tsx | 5 +- .../src/providers/WalletProvider.tsx | 95 ++- packages/widget-playground/package.json | 2 +- packages/widget-playground/src/App.tsx | 31 +- .../src/components/WalletButtons.tsx | 5 +- packages/widget-playground/src/config.ts | 5 + .../src/providers/WalletProvider.tsx | 96 ++- .../src/components/ActiveSwaps/index.ts | 1 - .../SelectWalletPage/SelectWalletPage.tsx | 18 +- .../WalletProvider/WalletProvider.tsx | 126 +++- .../src/providers/WalletProvider/index.ts | 2 +- .../src/providers/WalletProvider/types.ts | 2 +- yarn.lock | 711 +++--------------- 38 files changed, 1212 insertions(+), 1915 deletions(-) delete mode 100644 packages/wallet-management/src/connectors/coinbaseWallet.ts delete mode 100644 packages/wallet-management/src/connectors/eip1193.ts delete mode 100644 packages/wallet-management/src/connectors/empty.ts create mode 100644 packages/wallet-management/src/connectors/injectedConnector.ts delete mode 100644 packages/wallet-management/src/connectors/metaMask.ts delete mode 100644 packages/wallet-management/src/connectors/network.ts delete mode 100644 packages/wallet-management/src/connectors/tallyho.ts delete mode 100644 packages/wallet-management/src/connectors/url.ts delete mode 100644 packages/wallet-management/src/connectors/walletConnect.ts create mode 100644 packages/wallet-management/src/connectors/walletConnectConnector.ts delete mode 100644 packages/wallet-management/src/injectedData.ts delete mode 100644 packages/wallet-management/src/priorityConnector.ts create mode 100644 packages/wallet-management/src/types/index.ts create mode 100644 packages/wallet-management/src/walletIcons/frontier.svg rename packages/wallet-management/src/walletIcons/{detected.svg => placeholder.svg} (100%) delete mode 100644 packages/wallet-management/src/walletIcons/tp.svg delete mode 100644 packages/wallet-management/src/walletProviders.ts diff --git a/packages/wallet-management/package.json b/packages/wallet-management/package.json index 0f9c3742c..11252ec14 100644 --- a/packages/wallet-management/package.json +++ b/packages/wallet-management/package.json @@ -48,21 +48,13 @@ "lifi" ], "dependencies": { - "@coinbase/wallet-sdk": "^3.6.5", + "@coinbase/wallet-sdk": "^3.7.0", "@ethersproject/abstract-signer": "^5.7.0", "@ethersproject/experimental": "^5.7.0", "@ethersproject/providers": "^5.7.2", "@lifi/sdk": "^2.0.0-beta.8", "@walletconnect/ethereum-provider": "^1.8.0", "@walletconnect/web3-provider": "^1.8.0", - "@web3-react/coinbase-wallet": "^8.0.35-beta.0", - "@web3-react/core": "^8.0.35-beta.0", - "@web3-react/eip1193": "^8.0.27-beta.0", - "@web3-react/empty": "^8.0.20-beta.0", - "@web3-react/metamask": "^8.0.30-beta.0", - "@web3-react/network": "^8.0.27-beta.0", - "@web3-react/types": "^8.0.20-beta.0", - "@web3-react/url": "^8.0.25-beta.0", "react": "^18.2.0" }, "devDependencies": { diff --git a/packages/wallet-management/src/LiFiWalletManagement.ts b/packages/wallet-management/src/LiFiWalletManagement.ts index 0061d5832..28f512a97 100644 --- a/packages/wallet-management/src/LiFiWalletManagement.ts +++ b/packages/wallet-management/src/LiFiWalletManagement.ts @@ -1,130 +1,61 @@ -import type { Signer } from '@ethersproject/abstract-signer'; -import type { ExternalProvider } from '@ethersproject/providers'; -import { Web3Provider } from '@ethersproject/providers'; -import type { Connector } from '@web3-react/types'; -import { useCallback, useEffect, useState } from 'react'; -import { usePriorityConnector } from './priorityConnector'; -// import { usePriorityConnector, usePriorityProvider } from './connectorHooks'; -import { getInjectedAddress } from './injectedData'; +import events from 'events'; +import type { Wallet } from './types'; import { addToActiveWallets, addToDeactivatedWallets, - isWalletDeactivated, removeFromActiveWallets, removeFromDeactivatedWallets, } from './walletPersistance'; -import type { Wallet } from './walletProviders'; -export const useLiFiWalletManagement = () => { - const priorityConnector = usePriorityConnector(); - // "any" because of https://github.com/ethers-io/ethers.js/issues/866 - // const priorityProvider = usePriorityProvider('any'); - // const [currentProvider, setCurrentProvider] = useState(); - const [currentConnector, setCurrentConnector] = useState(); - const [signer, setSigner] = useState(); - - const flushCurrentWalletData = () => { - setCurrentConnector(undefined); - // setCurrentProvider(undefined); - setSigner(undefined); - }; - - // eslint-disable-next-line react-hooks/exhaustive-deps - const calcWalletData = (connector?: Connector) => { - if (connector) { - const provider = new Web3Provider( - (connector.provider as ExternalProvider) || (window as any).ethereum, - 'any', // fallback - ); - // setCurrentProvider(() => provider); - setCurrentConnector(() => connector); - setSigner(() => provider?.getSigner?.()); +export class LiFiWalletManagement extends events.EventEmitter { + connectedWallets: Wallet[] = []; + + public connect = async (wallet: Wallet) => { + try { + await wallet.connect(); + wallet.addListener('walletAccountChanged', this.handleAccountDataChange); + this.connectedWallets.unshift(wallet); + removeFromDeactivatedWallets({ + address: wallet.account?.address || '', + name: wallet.name, + }); + addToActiveWallets({ + address: wallet.account?.address || '', + name: wallet.name, + }); + } catch (e) { + throw e; } }; - const connect = useCallback( - async (wallet?: Wallet) => { - try { - if (wallet) { - const { connector } = wallet.web3react; - await connector.activate(); - calcWalletData(connector); - } else { - await priorityConnector.activate(); - } - } catch (e) { - console.log(e); + public async autoConnect(wallets: Wallet[]) { + for (const wallet of wallets) { + if (wallet.autoConnect) { + await wallet.autoConnect(); + wallet.addListener( + 'walletAccountChanged', + this.handleAccountDataChange, + ); + this.connectedWallets.unshift(wallet); } - const selectedAddress = getInjectedAddress(wallet); - removeFromDeactivatedWallets(selectedAddress); - addToActiveWallets(selectedAddress); - }, - [calcWalletData, priorityConnector], - ); - - const disconnect = useCallback( - async (wallet?: Wallet) => { - const selectedAddress = getInjectedAddress(wallet); - removeFromActiveWallets(selectedAddress); - addToDeactivatedWallets(selectedAddress); - if (wallet) { - await currentConnector?.deactivate?.(); - flushCurrentWalletData(); - } else if (priorityConnector.deactivate) { - await priorityConnector.deactivate?.(); - flushCurrentWalletData(); - } else { - await priorityConnector.resetState(); - flushCurrentWalletData(); - } - }, - [priorityConnector, currentConnector], - ); - - // eager connect - useEffect(() => { - const selectedAddress = getInjectedAddress(); - if (!isWalletDeactivated(selectedAddress) && priorityConnector) { - priorityConnector.connectEagerly?.(); - calcWalletData(priorityConnector); } - }, [ - priorityConnector, - // eslint-disable-next-line react-hooks/exhaustive-deps - (window as any).ethereum?.selectedAddress, - // eslint-disable-next-line react-hooks/exhaustive-deps - (window as any).tally?.selectedAddress, - ]); - - // injected wallet listeners - useEffect(() => { - const { ethereum } = window as any; - const handleChainChanged = async (chainId: string | number) => { - await currentConnector?.activate(); - calcWalletData(currentConnector); - }; - const handleAccountsChanged = async (accounts: string[]) => { - if (!accounts.length) { - await currentConnector?.deactivate?.(); - flushCurrentWalletData(); - } - }; - - ethereum?.on('chainChanged', handleChainChanged); - ethereum?.on('accountsChanged', handleAccountsChanged); - - return () => { - if (ethereum?.removeListener) { - ethereum.removeListener('chainChanged', handleChainChanged); - ethereum.removeListener('accountsChanged', handleAccountsChanged); - } - }; - }, [currentConnector]); - - return { - connect, - disconnect, - signer, - provider: signer?.provider, + } + + public disconnect = async (wallet: Wallet) => { + wallet.removeAllListeners(); + removeFromActiveWallets({ + address: wallet.account?.address || '', + name: wallet.name, + }); + addToDeactivatedWallets({ + address: wallet.account?.address || '', + name: wallet.name, + }); + + wallet.disconnect(); }; -}; + + private handleAccountDataChange() { + this.emit('walletChanged', this.connectedWallets); + } +} diff --git a/packages/wallet-management/src/connectors/coinbaseWallet.ts b/packages/wallet-management/src/connectors/coinbaseWallet.ts deleted file mode 100644 index 17dceed63..000000000 --- a/packages/wallet-management/src/connectors/coinbaseWallet.ts +++ /dev/null @@ -1,12 +0,0 @@ -// import { CoinbaseWallet } from '@web3-react/coinbase-wallet'; -// import { initializeConnector } from '@web3-react/core'; -// import { URLS } from '../chains'; - -// export const [coinbaseWallet, hooks] = initializeConnector( -// (actions) => -// new CoinbaseWallet(actions, { -// url: URLS[1][0], -// }), -// ); - -export {}; diff --git a/packages/wallet-management/src/connectors/eip1193.ts b/packages/wallet-management/src/connectors/eip1193.ts deleted file mode 100644 index 5d7251686..000000000 --- a/packages/wallet-management/src/connectors/eip1193.ts +++ /dev/null @@ -1,68 +0,0 @@ -// eslint-disable-next-line max-classes-per-file -import { Eip1193Bridge } from '@ethersproject/experimental'; -import { Web3Provider } from '@ethersproject/providers'; -import { initializeConnector } from '@web3-react/core'; -import type { EIP1193ConstructorArgs } from '@web3-react/eip1193'; -import { EIP1193 } from '@web3-react/eip1193'; -import type { Empty } from '@web3-react/empty'; -import { EMPTY } from '@web3-react/empty'; -import type { ProviderConnectInfo, ProviderRpcError } from '@web3-react/types'; - -class Eip1193BridgeWithoutAccounts extends Eip1193Bridge { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - request(request: { method: string; params?: any[] }): Promise { - return super.request(request); - } -} -class EIP1193Listener extends EIP1193 { - constructor({ actions, provider, onError }: EIP1193ConstructorArgs) { - super({ actions, provider, onError }); - - this.provider = provider; - - this.provider.on('connect', ({ chainId }: ProviderConnectInfo): void => { - console.log('connect:', chainId); - }); - - this.provider.on('disconnect', (error: ProviderRpcError): void => { - this.actions.resetState(); - this.onError?.(error); - }); - - this.provider.on('chainChanged', (chainId: string): void => { - console.log(chainId); - }); - - this.provider.on('accountsChanged', (accounts: string[]): void => { - console.log('eip1193 accounts', accounts); - }); - } -} - -export const createEip1193Connector = () => { - const { ethereum } = window as any; - const currentProvider = ethereum ? new Web3Provider(ethereum) : null; - - const eip1193Provider = new Eip1193BridgeWithoutAccounts( - currentProvider!.getSigner(), - currentProvider!, - ); - const [eip1193, hooks] = initializeConnector( - (actions) => - eip1193Provider - ? new EIP1193({ - actions, - provider: eip1193Provider, - onError: (error) => console.warn(error), - }) - : EMPTY, - // supportedChains.map((chain) => chain.id), - ); - - console.log('eip1193:', eip1193); - - return { - connector: eip1193, - hooks, - }; -}; diff --git a/packages/wallet-management/src/connectors/empty.ts b/packages/wallet-management/src/connectors/empty.ts deleted file mode 100644 index 353a5ce8e..000000000 --- a/packages/wallet-management/src/connectors/empty.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { initializeConnector } from '@web3-react/core'; -import type { Empty } from '@web3-react/empty'; -import { EMPTY } from '@web3-react/empty'; - -export const [empty, hooks] = initializeConnector(() => EMPTY); diff --git a/packages/wallet-management/src/connectors/injectedConnector.ts b/packages/wallet-management/src/connectors/injectedConnector.ts new file mode 100644 index 000000000..77ecb0bf0 --- /dev/null +++ b/packages/wallet-management/src/connectors/injectedConnector.ts @@ -0,0 +1,185 @@ +import type { Token } from '@lifi/sdk'; +import { ethers } from 'ethers'; +import events from 'events'; +import type { + AccountData, + InjectedConnectorConstructorArgs, + Provider, + ProviderConnectInfo, + ProviderRpcError, + Wallet, +} from '../types'; +import { + addChain, + switchChain, + switchChainAndAddToken, +} from '../walletAutomation'; +import { isWalletDeactivated } from '../walletPersistance'; + +export class InjectedConnector extends events.EventEmitter implements Wallet { + private windowProvider: Provider | undefined; + public isActivationInProgress: boolean = false; + public account: AccountData | undefined; + public name: string; + public icon: string; + public installed: () => boolean; + + constructor( + constructorArgs: InjectedConnectorConstructorArgs, + windowConnector = (window as any).ethereum as Provider, + autoConnect = false, + ) { + super(); + this.initializeProvider(windowConnector); + this.name = constructorArgs.name; + this.icon = constructorArgs.icon; + this.installed = constructorArgs.installed; + } + + private initializeProvider(connectorWindowProperty: Provider) { + if (window === undefined) { + throw new Error('window is not defined. This should not have happened.'); + } + this.windowProvider = connectorWindowProperty; + this.windowProvider?.on( + 'connect', + async ({ chainId }: ProviderConnectInfo): Promise => { + await this.calcAccountData(); + }, + ); + this.windowProvider?.on( + 'disconnect', + async (error: ProviderRpcError): Promise => { + await this.calcAccountData(); + }, + ); + this.windowProvider?.on( + 'chainChanged', + async (chainId: string): Promise => { + await this.calcAccountData(); + }, + ); + this.windowProvider?.on( + 'accountsChanged', + async (accounts: string[]): Promise => { + if (!accounts.length) { + this.account = undefined; + + this.emit('walletAccountChanged', this); + return; + } + await this.calcAccountData(); + }, + ); + } + public async autoConnect() { + if (window === undefined) { + throw new Error('window is not defined. This should not have happened.'); + } + + if (!this.windowProvider) { + throw new Error('provider is not defined.'); + } + + if (this.isActivationInProgress) { + return; + } + try { + const selectedAddress = this.windowProvider.selectedAddress; + if ( + !isWalletDeactivated({ + address: selectedAddress || '', + name: this.name, + }) + ) { + await this.calcAccountData(); + } + } catch (e) { + throw e; + } + } + + public async connect() { + if (window === undefined) { + throw new Error('window is not defined. This should not have happened.'); + } + + if (!this.windowProvider) { + throw new Error('provider is not defined.'); + } + + if (this.isActivationInProgress) { + return; + } + + this.isActivationInProgress = true; + try { + await this.windowProvider?.request({ + method: 'eth_requestAccounts', + }); + await this.calcAccountData(); + } catch (error) { + this.isActivationInProgress = false; + throw error; + } + + this.isActivationInProgress = false; + } + + public disconnect(): void | Promise { + this.account = undefined; + this.isActivationInProgress = false; + } + + public async switchChain(chainId: number) { + if (window === undefined) { + throw new Error('window is not defined. This should not have happened.'); + } + + if (!this.windowProvider) { + throw new Error('provider is not defined.'); + } + return switchChain(this.windowProvider, chainId); + } + + public async addChain(chainId: number) { + if (window === undefined) { + throw new Error('window is not defined. This should not have happened.'); + } + + if (!this.windowProvider) { + throw new Error('provider is not defined.'); + } + return addChain(this.windowProvider, chainId); + } + + public async addToken(chainId: number, token: Token) { + if (window === undefined) { + throw new Error('window is not defined. This should not have happened.'); + } + + if (!this.windowProvider) { + throw new Error('provider is not defined.'); + } + return switchChainAndAddToken(this.windowProvider, chainId, token); + } + + private async calcAccountData() { + if (!this.windowProvider) { + throw new Error('provider is not defined.'); + } + + const provider = new ethers.providers.Web3Provider( + this.windowProvider, + 'any', + ); + const signer = provider.getSigner(); + this.account = { + chainId: await signer.getChainId(), + address: await signer.getAddress(), + signer, + provider, + }; + this.emit('walletAccountChanged', this); + } +} diff --git a/packages/wallet-management/src/connectors/metaMask.ts b/packages/wallet-management/src/connectors/metaMask.ts deleted file mode 100644 index e6a95972f..000000000 --- a/packages/wallet-management/src/connectors/metaMask.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { initializeConnector } from '@web3-react/core'; -import { MetaMask } from '@web3-react/metamask'; - -export const [metaMask, hooks] = initializeConnector( - (actions) => new MetaMask({ actions }), -); - -export const createMetamaskConnector = () => { - const [connector, hooks] = initializeConnector( - (actions) => new MetaMask({ actions }), - ); - return { connector, hooks }; -}; - -/* -Known issues: -issue: metamask uninitialized -https://github.com/MetaMask/metamask-extension/issues/9407 -https://github.com/MetaMask/metamask-extension/issues/13465 - -issue: unexpected updating of eth_accounts -Issue stems from web3React. Issue does not impact performance or functionality -*/ diff --git a/packages/wallet-management/src/connectors/network.ts b/packages/wallet-management/src/connectors/network.ts deleted file mode 100644 index 01a050dbc..000000000 --- a/packages/wallet-management/src/connectors/network.ts +++ /dev/null @@ -1,10 +0,0 @@ -// import { initializeConnector } from '@web3-react/core'; -// import { Network } from '@web3-react/network'; -// import { URLS } from '../chains'; - -// export const [network, hooks] = initializeConnector( -// (actions) => new Network(actions, URLS), -// Object.keys(URLS).map((chainId) => Number(chainId)), -// ); - -export {}; diff --git a/packages/wallet-management/src/connectors/tallyho.ts b/packages/wallet-management/src/connectors/tallyho.ts deleted file mode 100644 index 49b8bb518..000000000 --- a/packages/wallet-management/src/connectors/tallyho.ts +++ /dev/null @@ -1,203 +0,0 @@ -/* eslint-disable consistent-return */ -/* eslint-disable prefer-promise-reject-errors */ -/* eslint-disable no-void */ -import { initializeConnector } from '@web3-react/core'; -import type { - Actions, - Provider, - ProviderConnectInfo, - ProviderRpcError, -} from '@web3-react/types'; -import { Connector } from '@web3-react/types'; - -declare global { - interface Window { - tally?: TallyHoProvider; - } -} - -export interface TallyHoProvider extends Provider { - isTally: boolean; -} -export interface ConnectEagerlyConfig { - retries: number; - timeoutMs: number; -} - -function isTally(provider: unknown): provider is TallyHoProvider { - return ( - typeof provider === 'object' && - provider !== null && - 'request' in provider && - 'isTally' in provider && - (provider as TallyHoProvider).isTally === true - ); -} - -function isConnectEagerlyConfig(arg: unknown): arg is ConnectEagerlyConfig { - return ( - typeof arg === 'object' && - typeof (arg as ConnectEagerlyConfig).retries === 'number' && - typeof (arg as ConnectEagerlyConfig).timeoutMs === 'number' - ); -} - -function parseChainId(chainId: string) { - return Number.parseInt(chainId, 16); -} - -export class TallyHo extends Connector { - /** {@inheritdoc Connector.provider} */ - provider: Provider | undefined; - - public isCurrentlyUsed: boolean = false; - - /** - * This parameter is used to make sure only one initialization is in progress at a time. - * E.g.: When `connectEagerly` constructor parameter set to true and the `tallyHo.connectEagerly()` - * method is used in an useEffect then it results in 2 requests. - */ - isActivationInProgress = false; - - /** - * @param connectEagerly - A flag indicating whether connection should be initiated when the class is constructed. - */ - constructor( - actions: Actions, - connectEagerly?: boolean | ConnectEagerlyConfig, - ) { - super(actions); - - if (connectEagerly) { - if (connectEagerly === true) { - void this.connectEagerly(); - } else if (isConnectEagerlyConfig(connectEagerly)) { - void this.connectEagerly(connectEagerly); - } else { - throw new Error( - `connectEagerly is expected to be 'true' OR {retries: number, timeoutMs: number}, but ${JSON.stringify( - connectEagerly, - )} was received instead.`, - ); - } - } - } - - /** {@inheritdoc Connector.connectEagerly} */ - public async connectEagerly( - config: ConnectEagerlyConfig = { retries: 5, timeoutMs: 500 }, - ): Promise { - return new Promise((resolve, reject) => { - let counter = 0; - - /** - * When `connectEagerly` is set to true at class initialization time there is no window present. - * But it is usually ready in 1-2 seconds, so we shall wait for it. - */ - function waitForWindow() { - if (typeof window === 'undefined') { - counter++; - - if (counter === config.retries) { - reject( - `window was not present after ${config.retries} retries (with ${config.timeoutMs}ms wait period). Try using the connectEagerly method in a useEffect`, - ); - } - - setTimeout(waitForWindow, config.timeoutMs); - } else { - resolve(); - } - } - - waitForWindow(); - }).then(() => this.activate()); - } - - /** {@inheritdoc Connector.activate} */ - public async activate(): Promise { - if (window === undefined) { - throw new Error( - "window is not defined. This should not have happened. 'Toto, I have a feeling we're not in Kansas anymore! 🌪'", - ); - } - - if (!this.provider) { - this.initializeProvider(); - } - - if (this.isActivationInProgress) return; - - this.isActivationInProgress = true; - - if (isTally(this.provider)) { - const cancelActivation = this.actions.startActivation(); - this.isCurrentlyUsed = true; - - return this.provider - .request({ method: 'eth_requestAccounts' }) - .then((accounts) => - Promise.all([ - this.provider?.request({ - method: 'eth_chainId', - }) as Promise, - accounts as string[], - ]).then(([chainId, accounts]) => { - this.actions.update({ chainId: parseChainId(chainId), accounts }); - }), - ) - .catch((error: Error) => { - this.actions.resetState(); - cancelActivation(); - }) - .finally(() => { - this.isActivationInProgress = false; - }); - } - } - - private initializeProvider() { - if (!isTally(window.tally)) { - throw new Error( - "You don't seem to have TallyHo installed because window.tally is not a TallyHo provider.", - ); - } - this.provider = window.tally; - - this.provider.on('connect', ({ chainId }: ProviderConnectInfo): void => { - this.actions.update({ chainId: parseChainId(chainId) }); - }); - - this.provider.on('disconnect', (error: ProviderRpcError): void => { - this.actions.update({ accounts: [], chainId: undefined }); - this.actions.resetState(); - }); - - this.provider.on('chainChanged', (chainId: string): void => { - this.actions.update({ chainId: parseChainId(chainId) }); - }); - - this.provider.on('accountsChanged', (accounts: string[]): void => { - if (!accounts.length) { - this.actions.update({ accounts: [], chainId: undefined }); - this.actions.resetState(); - } - this.actions.update({ accounts }); - }); - } - - public deactivate(): void | Promise { - if (this.provider) { - this.provider = undefined; - this.isCurrentlyUsed = false; - this.actions.resetState(); - } - } -} - -export const createTallyHoConnector = () => { - const [tallyHo, hooks] = initializeConnector( - (actions) => new TallyHo(actions, false), - ); - return { connector: tallyHo, hooks }; -}; diff --git a/packages/wallet-management/src/connectors/url.ts b/packages/wallet-management/src/connectors/url.ts deleted file mode 100644 index cbacc9724..000000000 --- a/packages/wallet-management/src/connectors/url.ts +++ /dev/null @@ -1,10 +0,0 @@ -// import { initializeConnector } from '@web3-react/core'; -// import { Url } from '@web3-react/url'; -// import { URLS } from '../chains'; - -// export const [url, hooks] = initializeConnector( -// (actions) => new Url(actions, URLS[1][0]), -// [1], -// ); - -export {}; diff --git a/packages/wallet-management/src/connectors/walletConnect.ts b/packages/wallet-management/src/connectors/walletConnect.ts deleted file mode 100644 index e1b448ec3..000000000 --- a/packages/wallet-management/src/connectors/walletConnect.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { supportedChains } from '@lifi/sdk'; -import WalletConnectProvider from '@walletconnect/ethereum-provider'; -import { initializeConnector } from '@web3-react/core'; -import type { Actions } from '@web3-react/types'; -import { Connector } from '@web3-react/types'; -import type { EventEmitter } from 'node:events'; - -interface WalletConnectOptions { - rpc: { - [chainId: number]: string; - }; -} - -interface MockWalletConnectProvider - extends Omit, - EventEmitter {} - -export class WalletConnect extends Connector { - private readonly options?: WalletConnectOptions; - - public provider: MockWalletConnectProvider | undefined; - - public walletConnectProvider: WalletConnectProvider | undefined; - - public isCurrentlyUsed: boolean = false; - - constructor(actions: Actions, options?: WalletConnectOptions) { - super(actions); - this.options = options; - } - - private async startListening(): Promise { - // Subscribe to accounts change - this.provider?.on('accountsChanged', (accounts: string[]) => { - this.actions.update({ accounts }); - }); - - // Subscribe to chainId change - this.provider?.on('chainChanged', (chainId: number) => { - this.actions.update({ chainId }); - }); - - // Subscribe to session disconnection - this.provider?.on('disconnect', (code: number, reason: string) => { - this.actions.update({ accounts: [], chainId: undefined }); - this.actions.resetState(); - this.isCurrentlyUsed = false; - }); - } - - public connectEagerly = () => {}; - - public async activate(): Promise { - this.actions.startActivation(); - this.isCurrentlyUsed = true; - - // Reset provider for every connection attempt - const walletConnectProvider = new WalletConnectProvider({ - rpc: this.options!.rpc, - }); - this.provider = - walletConnectProvider as unknown as MockWalletConnectProvider; - this.walletConnectProvider = walletConnectProvider; - - await this.provider?.enable(); // open modal - this.startListening(); - - this.actions.update({ accounts: this.provider.accounts }); - - this.actions.update({ chainId: this.provider.chainId }); - } - - public async deactivate(): Promise { - if (this.provider) { - await this.provider?.disconnect(); - this.isCurrentlyUsed = false; - this.actions.resetState(); - } - } -} - -export const [walletConnect, hooks] = initializeConnector( - (actions) => - new WalletConnect(actions, { - rpc: Object.fromEntries( - supportedChains.map((chain) => { - return [chain.id, chain.metamask.rpcUrls[0] || '']; - }), - ), - }), -); - -export const createWalletConnectConnector = () => { - const [connector, hooks] = initializeConnector( - (actions) => - new WalletConnect(actions, { - rpc: Object.fromEntries( - supportedChains.map((chain) => { - return [chain.id, chain.metamask.rpcUrls[0] || '']; - }), - ), - }), - ); - return { connector, hooks }; -}; diff --git a/packages/wallet-management/src/connectors/walletConnectConnector.ts b/packages/wallet-management/src/connectors/walletConnectConnector.ts new file mode 100644 index 000000000..67843e8ea --- /dev/null +++ b/packages/wallet-management/src/connectors/walletConnectConnector.ts @@ -0,0 +1,145 @@ +import type { Token } from '@lifi/sdk'; +import WalletConnectProvider from '@walletconnect/ethereum-provider'; +import { ethers } from 'ethers'; +import events from 'events'; +import type { EventEmitter } from 'node:events'; +import type { + AccountData, + Wallet, + WalletConnectConnectorConstructorArgs, +} from '../types'; +import { + addChain, + switchChain, + switchChainAndAddToken, +} from '../walletAutomation'; + +interface MockWalletConnectProvider + extends Omit, + EventEmitter {} + +export class WalletConnectConnector + extends events.EventEmitter + implements Wallet +{ + private readonly options?: { + [chainId: number]: string; + }; + + public provider: MockWalletConnectProvider | undefined; + + public walletConnectProvider: WalletConnectProvider | undefined; + + public isActivationInProgress: boolean = false; + public account: AccountData | undefined; + public name: string; + public icon: string; + public installed: () => boolean; + + constructor(constructorArgs: WalletConnectConnectorConstructorArgs) { + super(); + this.options = constructorArgs.rpc; + this.name = constructorArgs.name; + this.icon = constructorArgs.icon; + this.installed = constructorArgs.installed; + } + + private async startListening(): Promise { + // Subscribe to accounts change + this.provider?.on('accountsChanged', async (accounts: string[]) => { + if (!accounts.length) { + this.account = undefined; + this.emit('walletAccountChanged', this); + return; + } + await this.calcAccountData(); + }); + // Subscribe to chainId change + this.provider?.on('chainChanged', async (chainId: number) => { + await this.calcAccountData(); + }); + + // Subscribe to session disconnection + this.provider?.on('disconnect', async (code: number, reason: string) => { + await this.calcAccountData(); + }); + } + + public async connect(): Promise { + if (this.isActivationInProgress) { + return; + } + this.isActivationInProgress = true; + + // Reset provider for every connection attempt + const walletConnectProvider = new WalletConnectProvider({ + rpc: this.options!, + }); + this.provider = + walletConnectProvider as unknown as MockWalletConnectProvider; + this.walletConnectProvider = walletConnectProvider; + + try { + await this.walletConnectProvider?.enable(); // open modal + this.startListening(); + await this.calcAccountData(); + } catch (e) { + this.isActivationInProgress = false; + throw e; + } + this.isActivationInProgress = false; + } + + public async disconnect(): Promise { + if (this.provider) { + await this.provider?.disconnect(); + await this.walletConnectProvider?.disconnect(); + this.provider = undefined; + this.walletConnectProvider = undefined; + this.isActivationInProgress = false; + this.account = undefined; + this.emit('walletAccountChanged', this); + } + } + + public async switchChain(chainId: number) { + if (!this.provider) { + throw new Error('provider is not defined.'); + } + return switchChain(this.provider, chainId); + } + + public async addChain(chainId: number) { + if (!this.provider) { + throw new Error('provider is not defined.'); + } + return addChain(this.provider, chainId); + } + + public async addToken(chainId: number, token: Token) { + if (!this.provider) { + throw new Error('provider is not defined.'); + } + return switchChainAndAddToken(this.provider, chainId, token); + } + + private async calcAccountData() { + if (!this.walletConnectProvider) { + throw new Error('provider is not defined.'); + } + const provider = new ethers.providers.Web3Provider( + this.walletConnectProvider!, + 'any', + ); + + const signer = provider.getSigner(); + this.account = { + chainId: await signer.getChainId(), + address: await signer.getAddress(), + signer, + provider, + }; + + this.emit('walletAccountChanged', this); + } +} diff --git a/packages/wallet-management/src/index.ts b/packages/wallet-management/src/index.ts index e70cc4e49..cc36aa1b9 100644 --- a/packages/wallet-management/src/index.ts +++ b/packages/wallet-management/src/index.ts @@ -1,5 +1,6 @@ export * from './LiFiWalletManagement'; +export * from './types'; export * from './walletAutomation'; export * from './walletIcons'; -export * from './walletProviders'; +export * from './walletPersistance'; export * from './wallets'; diff --git a/packages/wallet-management/src/injectedData.ts b/packages/wallet-management/src/injectedData.ts deleted file mode 100644 index b58dc58b5..000000000 --- a/packages/wallet-management/src/injectedData.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { Wallet } from '.'; -import { wallets } from './wallets'; - -export const getInjectedAddress = (wallet?: Wallet) => { - switch (wallet?.name) { - case wallets.metamask.name: - return getMetamaskInjectedAddress(); - case wallets.tallyho.name: - return getTallyInjectedAddress(); - default: - return getMetamaskInjectedAddress() ?? getTallyInjectedAddress(); - } -}; - -const getMetamaskInjectedAddress = () => { - return (window as any).ethereum?.selectedAddress; -}; - -const getTallyInjectedAddress = () => { - return (window as any).ethereum?.selectedAddress; -}; diff --git a/packages/wallet-management/src/priorityConnector.ts b/packages/wallet-management/src/priorityConnector.ts deleted file mode 100644 index 2d980051f..000000000 --- a/packages/wallet-management/src/priorityConnector.ts +++ /dev/null @@ -1,33 +0,0 @@ -import type { Web3ReactHooks } from '@web3-react/core'; -import { getPriorityConnector } from '@web3-react/core'; -import type { Connector } from '@web3-react/types'; -import { supportedWallets } from './walletProviders'; -// import { eip1193, hooks as eip1193Hooks } from './connectors/eip1193'; - -// const metamaskWallet = supportedWallets.find( -// (wallet) => wallet.name === 'MetaMask', -// ); -const connectorHookList: [Connector, Web3ReactHooks][] = supportedWallets.map( - (wallet) => [wallet.web3react.connector, wallet.web3react.hooks], -); -export const { - useSelectedStore, - useSelectedChainId, - useSelectedAccounts, - useSelectedIsActivating, - useSelectedAccount, - useSelectedIsActive, - useSelectedProvider, - useSelectedENSNames, - useSelectedENSName, - usePriorityConnector, - usePriorityStore, - usePriorityChainId, - usePriorityAccounts, - usePriorityIsActivating, - usePriorityAccount, - usePriorityIsActive, - usePriorityProvider, - usePriorityENSNames, - usePriorityENSName, -} = getPriorityConnector(...connectorHookList); diff --git a/packages/wallet-management/src/types/index.ts b/packages/wallet-management/src/types/index.ts new file mode 100644 index 000000000..9a358f6f6 --- /dev/null +++ b/packages/wallet-management/src/types/index.ts @@ -0,0 +1,92 @@ +import type { Signer } from '@ethersproject/abstract-signer'; +import type { Token } from '@lifi/sdk'; +import type { ethers } from 'ethers'; +import type events from 'events'; +import type EventEmitter from 'node:events'; + +export interface ProviderConnectInfo { + readonly chainId: string; +} +export interface ProviderRpcError extends Error { + message: string; + code: number; + data?: unknown; +} + +export interface RequestArguments { + readonly method: string; + readonly params?: readonly unknown[] | object; +} + +export interface Provider extends EventEmitter { + request(args: RequestArguments): Promise; + selectedAddress?: string; + chainId?: any; +} + +export interface AccountData { + chainId: number; + address: string; + signer: Signer; + provider: ethers.providers.Web3Provider; +} +export interface InjectedConnectorConstructorArgs { + name: string; + icon: string; + installed: () => boolean; +} +export interface WalletConnectConnectorConstructorArgs { + name: string; + icon: string; + installed: () => boolean; + rpc: { + [chainId: number]: string; + }; +} + +export interface Wallet extends events.EventEmitter { + name: string; + icon: string; + isActivationInProgress: boolean; + account: AccountData | undefined; + installed: () => boolean; + connect: () => Promise; + autoConnect?: () => Promise; + disconnect: () => void; + switchChain: (chainId: number) => Promise; + addChain: (chainId: number) => Promise; + addToken: (chainId: number, token: Token) => Promise; +} + +export enum ProviderIdentityFlag { + AlphaWallet = 'isAlphaWallet', + AToken = 'isAToken', + BlockWallet = 'isBlockWallet', + Binance = 'bbcSignTx', + Bitpie = 'isBitpie', + Coinbase = 'isToshi', + CoinbaseExtension = 'isCoinbaseWallet', + Detected = 'request', + Dcent = 'isDcentWallet', + Frame = 'isFrame', + HuobiWallet = 'isHbWallet', + HyperPay = 'isHyperPay', + ImToken = 'isImToken', + Liquality = 'isLiquality', + MeetOne = 'wallet', + MetaMask = 'isMetaMask', + MyKey = 'isMYKEY', + OwnBit = 'isOwnbit', + Status = 'isStatus', + TallyHo = 'isTally', + Trust = 'isTrust', + TokenPocket = 'isTokenPocket', + TP = 'isTp', + WalletIo = 'isWalletIO', + XDEFI = '__XDEFI', + OneInch = 'isOneInchIOSWallet', + Tokenary = 'isTokenary', + MathWallet = 'isMathWallet', + Frontier = 'isFrontier', + ApexWallet = 'isApexWallet', +} diff --git a/packages/wallet-management/src/walletAutomation.ts b/packages/wallet-management/src/walletAutomation.ts index 7beffee84..b6989479b 100644 --- a/packages/wallet-management/src/walletAutomation.ts +++ b/packages/wallet-management/src/walletAutomation.ts @@ -5,36 +5,13 @@ import { MetaMaskProviderErrorCode, prefixChainId, } from '@lifi/sdk'; -import { supportedWallets } from '@lifi/wallet-management'; -import type { TallyHo } from './connectors/tallyho'; -import type { WalletConnect } from './connectors/walletConnect'; +import type { Provider } from './types'; -const getAppropriateProvider = () => { - const walletConnect = supportedWallets.find( - (wallet) => wallet.name === 'Wallet Connect', - ); - const tallyho = supportedWallets.find((wallet) => wallet.name === 'Tally Ho'); - - let provider: any; - if ((walletConnect?.web3react.connector as WalletConnect).isCurrentlyUsed) { - provider = (walletConnect?.web3react.connector as WalletConnect) - .walletConnectProvider; - } else if ((tallyho?.web3react.connector as TallyHo).isCurrentlyUsed) { - const { tally } = window as any; - provider = tally; - } else { - const { ethereum } = window as any; - provider = ethereum; - } - return provider; -}; - -export const switchChain = async (chainId: number): Promise => { +export const switchChain = async ( + provider: Provider, + chainId: number, +): Promise => { return new Promise((resolve, reject) => { - const provider: any = getAppropriateProvider(); - if (!provider) { - resolve(false); - } try { provider .request({ @@ -43,7 +20,7 @@ export const switchChain = async (chainId: number): Promise => { }) .catch((error: any) => { if (error.code !== MetaMaskProviderErrorCode.userRejectedRequest) { - addChain(chainId).then((result) => resolve(result)); + addChain(provider, chainId).then((result) => resolve(result)); } else { reject(error); } @@ -56,7 +33,7 @@ export const switchChain = async (chainId: number): Promise => { } catch (error: any) { // const ERROR_CODE_UNKNOWN_CHAIN = 4902 if (error.code !== MetaMaskProviderErrorCode.userRejectedRequest) { - addChain(chainId).then((result) => resolve(result)); + addChain(provider, chainId).then((result) => resolve(result)); } else { console.error(error); resolve(false); @@ -65,13 +42,7 @@ export const switchChain = async (chainId: number): Promise => { }); }; -export const addChain = async (chainId: number) => { - const provider: any = getAppropriateProvider(); - - if (!provider) { - return false; - } - +export const addChain = async (provider: Provider, chainId: number) => { const params = getChainById(chainId).metamask; try { await provider.request({ @@ -85,12 +56,7 @@ export const addChain = async (chainId: number) => { return false; }; -export const addToken = async (token: Token) => { - const provider: any = getAppropriateProvider(); - - if (!provider) { - return false; - } +export const addToken = async (provider: Provider, token: Token) => { try { // wasAdded is a boolean. Like any RPC method, an error may be thrown. const wasAdded = await provider.request({ @@ -112,22 +78,27 @@ export const addToken = async (token: Token) => { return false; }; -export const switchChainAndAddToken = async (chainId: number, token: Token) => { - const provider: any = getAppropriateProvider(); - - if (!provider) { - return; - } +export const switchChainAndAddToken = async ( + provider: Provider, + chainId: number, + token: Token, +) => { const chainIdPrefixed = prefixChainId(chainId); - if (chainIdPrefixed !== provider.chainId) { - await switchChain(chainId); - provider.once('chainChanged', async (id: string) => { - if (parseInt(id, 10) === chainId) { - await addToken(token); - } - }); - } else { - await addToken(token); + try { + if (chainIdPrefixed !== provider.chainId) { + await switchChain(provider, chainId); + provider.once('chainChanged', async (id: string) => { + if (parseInt(id, 10) === chainId) { + await addToken(provider, token); + } + }); + } else { + await addToken(provider, token); + } + return true; + } catch (e) { + console.error(e); + return false; } }; diff --git a/packages/wallet-management/src/walletIcons/frontier.svg b/packages/wallet-management/src/walletIcons/frontier.svg new file mode 100644 index 000000000..73e0e9d68 --- /dev/null +++ b/packages/wallet-management/src/walletIcons/frontier.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + diff --git a/packages/wallet-management/src/walletIcons/index.ts b/packages/wallet-management/src/walletIcons/index.ts index ecf6a49fb..74e878496 100644 --- a/packages/wallet-management/src/walletIcons/index.ts +++ b/packages/wallet-management/src/walletIcons/index.ts @@ -6,7 +6,6 @@ import blockwallet from './blockwallet.svg'; import brave from './brave.svg'; import coinbase from './coinbase.svg'; import dcent from './dcent.svg'; -import detected from './detected.svg'; import frame from './frame.svg'; import huobiwallet from './huobiwallet.svg'; import hyperpay from './hyperpay.svg'; @@ -23,24 +22,26 @@ import status from './status.svg'; import tallyho from './tallyho.svg'; import tokenary from './tokenary.svg'; import tokenpocket from './tokenpocket.svg'; -import tp from './tp.svg'; import trust from './trust.svg'; import walletConnect from './walletConnect.svg'; import walletio from './walletio.svg'; import xdefi from './xdefi.svg'; +import frontier from './frontier.svg'; +import placeholder from './placeholder.svg'; export const walletIcons = { mathwallet, walletConnect, alphawallet, atoken, + frontier, blockwallet, binance, + placeholder, bitpie, brave, coinbase, dcent, - detected, frame, huobiwallet, hyperpay, @@ -56,7 +57,6 @@ export const walletIcons = { tallyho, tokenary, tokenpocket, - tp, trust, walletio, xdefi, diff --git a/packages/wallet-management/src/walletIcons/detected.svg b/packages/wallet-management/src/walletIcons/placeholder.svg similarity index 100% rename from packages/wallet-management/src/walletIcons/detected.svg rename to packages/wallet-management/src/walletIcons/placeholder.svg diff --git a/packages/wallet-management/src/walletIcons/tp.svg b/packages/wallet-management/src/walletIcons/tp.svg deleted file mode 100644 index 00dedd2d9..000000000 --- a/packages/wallet-management/src/walletIcons/tp.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - diff --git a/packages/wallet-management/src/walletPersistance.ts b/packages/wallet-management/src/walletPersistance.ts index c271de7e4..05cf9fcd9 100644 --- a/packages/wallet-management/src/walletPersistance.ts +++ b/packages/wallet-management/src/walletPersistance.ts @@ -1,17 +1,50 @@ -const storeWallets = (wallets: Array) => { - const lowerCaseWallets = wallets.map((address) => address.toLowerCase()); +interface PersistedWallet { + address: string; + name: string; +} + +function isPersistedWallet(object: any): object is PersistedWallet { + return typeof object.address === 'string' && typeof object.name === 'string'; +} +const normalizeWallets = (wallets: PersistedWallet[]) => { + return wallets.map((wallet) => ({ + address: wallet.address.toLowerCase(), + name: wallet.name, + })); +}; + +const deepEqual = (x: any, y: any): boolean => { + const ok = Object.keys, + tx = typeof x, + ty = typeof y; + return x && y && tx === 'object' && tx === ty + ? ok(x).length === ok(y).length && + ok(x).every((key) => deepEqual(x[key], y[key])) + : x === y; +}; + +const storeWallets = (wallets: PersistedWallet[]) => { + const normalizedWallets: PersistedWallet[] = normalizeWallets(wallets); localStorage.setItem( 'li.fi-wallets', - JSON.stringify(Array.from(new Set(lowerCaseWallets))), + JSON.stringify(Array.from(new Set(normalizedWallets))), ); }; -const readWallets = (): Array => { +const readActiveWallets = (): Array => { const walletsString = localStorage.getItem('li.fi-wallets'); if (walletsString) { try { - return JSON.parse(walletsString); + const parsedWalletObjects = JSON.parse(walletsString); + if ( + parsedWalletObjects.some((wallet: any) => !isPersistedWallet(wallet)) + ) { + throw new Error('Malformed persisted active wallets'); + } else { + return parsedWalletObjects; + } } catch (e) { + localStorage.removeItem('li.fi-wallets'); return []; } } else { @@ -19,20 +52,28 @@ const readWallets = (): Array => { } }; -const storeDeactivatedWallets = (wallets: string[]) => { - const lowerCaseWallets = wallets.map((address) => address.toLowerCase()); +const storeDeactivatedWallets = (wallets: PersistedWallet[]) => { + const normalizedWallets = normalizeWallets(wallets); localStorage.setItem( 'li.fi-deactivated-wallets', - JSON.stringify(Array.from(new Set(lowerCaseWallets))), + JSON.stringify(Array.from(new Set(normalizedWallets))), ); }; -const readDeactivatedWallets = (): Array => { +const readDeactivatedWallets = (): PersistedWallet[] => { const walletsString = localStorage.getItem('li.fi-deactivated-wallets'); if (walletsString) { try { - return JSON.parse(walletsString); + const parsedWalletObjects = JSON.parse(walletsString); + if ( + parsedWalletObjects.some((wallet: any) => !isPersistedWallet(wallet)) + ) { + throw new Error('Malformed persisted deactivated wallets'); + } else { + return parsedWalletObjects; + } } catch (e) { + localStorage.removeItem('li.fi-deactivated-wallets'); return []; } } else { @@ -40,50 +81,59 @@ const readDeactivatedWallets = (): Array => { } }; -const removeFromActiveWallets = (address?: string | null) => { - if (!address) return; - const lowerCaseAddress = address.toLowerCase(); - const wallets = readWallets(); +const removeFromActiveWallets = (wallet?: PersistedWallet | null) => { + if (!wallet) { + return; + } + const normalizedWallet = normalizeWallets([wallet])[0]; + const wallets = readActiveWallets(); const filteredWallets = wallets.filter( - (address) => address !== lowerCaseAddress, + (wallet) => !deepEqual(wallet, normalizedWallet), ); storeWallets(filteredWallets); }; -const addToDeactivatedWallets = (address?: string | null) => { - if (!address) return; - const lowerCaseAddress = address.toLowerCase(); +const addToDeactivatedWallets = (wallet?: PersistedWallet | null) => { + if (!wallet) { + return; + } + const normalizedWallet = normalizeWallets([wallet])[0]; const deactivatedWallets = readDeactivatedWallets(); - deactivatedWallets.push(lowerCaseAddress); + deactivatedWallets.push(normalizedWallet); storeDeactivatedWallets(deactivatedWallets); }; -const addToActiveWallets = (address?: string | null) => { - if (!address) return; - const lowerCaseAddress = address.toLowerCase(); - const activeWallets = readWallets(); - activeWallets.push(lowerCaseAddress); +const addToActiveWallets = (wallet?: PersistedWallet | null) => { + if (!wallet) { + return; + } + const normalizedWallet = normalizeWallets([wallet])[0]; + const activeWallets = readActiveWallets(); + activeWallets.push(normalizedWallet); storeWallets(activeWallets); }; -const removeFromDeactivatedWallets = (address?: string | null) => { - if (!address) return; - const lowerCaseAddress = address.toLowerCase(); +const removeFromDeactivatedWallets = (wallet?: PersistedWallet | null) => { + if (!wallet) { + return; + } + const normalizedWallet = normalizeWallets([wallet])[0]; const deactivatedWallets = readDeactivatedWallets(); const deactivatedWalletsWithoutAccount = deactivatedWallets.filter( - (wallet) => wallet !== lowerCaseAddress, + (wallet) => !deepEqual(wallet, normalizedWallet), ); storeDeactivatedWallets(deactivatedWalletsWithoutAccount); }; -const isWalletDeactivated = (address?: string | null): boolean => { - if (!address) return true; - const lowerCaseAddress = address.toLowerCase(); +const isWalletDeactivated = (wallet?: PersistedWallet | null): boolean => { + if (!wallet) { + return true; + } + const normalizedWallet = normalizeWallets([wallet])[0]; const deactivatedWallets = readDeactivatedWallets(); - const deactivatedAddresses = deactivatedWallets.map((address) => - address.toLowerCase(), + return deactivatedWallets.some((deactivatedWallet) => + deepEqual(deactivatedWallet, normalizedWallet), ); - return deactivatedAddresses.includes(lowerCaseAddress); }; export { @@ -92,4 +142,5 @@ export { addToActiveWallets, removeFromDeactivatedWallets, isWalletDeactivated, + readActiveWallets, }; diff --git a/packages/wallet-management/src/walletProviders.ts b/packages/wallet-management/src/walletProviders.ts deleted file mode 100644 index 92a164aca..000000000 --- a/packages/wallet-management/src/walletProviders.ts +++ /dev/null @@ -1,343 +0,0 @@ -import type { Web3ReactHooks } from '@web3-react/core'; -import type { Connector } from '@web3-react/types'; -import { createMetamaskConnector } from './connectors/metaMask'; -import { createTallyHoConnector } from './connectors/tallyho'; -import { createWalletConnectConnector } from './connectors/walletConnect'; -import { walletIcons } from './walletIcons'; - -export interface Wallet { - name: string; - icon: string; - checkProviderIdentity: (helpers: { - provider: any; - // device: Device; - }) => boolean; - web3react: { - connector: Connector; - hooks: Web3ReactHooks; - }; - platforms: string[]; -} - -export enum ProviderIdentityFlag { - AlphaWallet = 'isAlphaWallet', - AToken = 'isAToken', - BlockWallet = 'isBlockWallet', - Binance = 'bbcSignTx', - Bitpie = 'isBitpie', - Coinbase = 'isToshi', - CoinbaseExtension = 'isCoinbaseWallet', - Detected = 'request', - Dcent = 'isDcentWallet', - Frame = 'isFrame', - HuobiWallet = 'isHbWallet', - HyperPay = 'isHyperPay', - ImToken = 'isImToken', - Liquality = 'isLiquality', - MeetOne = 'wallet', - MetaMask = 'isMetaMask', - MyKey = 'isMYKEY', - OwnBit = 'isOwnbit', - Status = 'isStatus', - TallyHo = 'isTally', - Trust = 'isTrust', - TokenPocket = 'isTokenPocket', - TP = 'isTp', - WalletIo = 'isWalletIO', - XDEFI = '__XDEFI', - OneInch = 'isOneInchIOSWallet', - Tokenary = 'isTokenary', - MathWallet = 'isMathWallet', -} - -const metamask: Wallet = { - name: 'MetaMask', - checkProviderIdentity: () => - // Removed for now to allow all kinds of injected wallets to connect using the metamask button as fallback - // !!provider && !!provider[ProviderIdentityFlag.MetaMask], - true, - icon: walletIcons.metamask, - platforms: ['all'], - web3react: createMetamaskConnector(), -}; - -const walletConnect: Wallet = { - name: 'Wallet Connect', - checkProviderIdentity: () => true, - icon: walletIcons.walletConnect, - platforms: ['all'], - web3react: createWalletConnectConnector(), -}; - -const brave: Wallet = { - name: 'Brave', - checkProviderIdentity: ({ provider }) => - // eslint-disable-next-line no-underscore-dangle - (navigator as any).brave && provider?._web3Ref, - icon: walletIcons.brave, - platforms: ['all'], - web3react: createMetamaskConnector(), -}; - -const mathWallet: Wallet = { - name: 'MathWallet', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.MathWallet], - icon: walletIcons.mathwallet, - platforms: ['all'], - web3react: createMetamaskConnector(), -}; - -const tallyho: Wallet = { - name: 'Tally Ho', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.TallyHo], - icon: walletIcons.tallyho, - - platforms: ['desktop'], - web3react: createTallyHoConnector(), -}; - -const blockWallet: Wallet = { - name: 'BlockWallet', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.BlockWallet], - icon: walletIcons.blockwallet, - - platforms: ['desktop'], - web3react: createMetamaskConnector(), -}; - -const binance: Wallet = { - name: 'Binance', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.Binance], - icon: walletIcons.binance, - - platforms: ['desktop'], - web3react: createMetamaskConnector(), -}; - -const coinbase: Wallet = { - name: 'Coinbase', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.Coinbase] || - provider?.providers?.[0]?.[ProviderIdentityFlag.CoinbaseExtension], - icon: walletIcons.coinbase, - - platforms: ['all'], - web3react: createMetamaskConnector(), -}; - -const detected: Wallet = { - name: 'Detected', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.Detected], - icon: walletIcons.detected, - platforms: ['all'], - web3react: createMetamaskConnector(), -}; - -const trust: Wallet = { - name: 'Trust', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.Trust] && - !provider[ProviderIdentityFlag.TokenPocket], - icon: walletIcons.trust, - platforms: ['mobile'], - web3react: createMetamaskConnector(), -}; - -const status: Wallet = { - name: 'Status', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.Status], - icon: walletIcons.status, - platforms: ['mobile'], - web3react: createMetamaskConnector(), -}; - -const alphawallet: Wallet = { - name: 'AlphaWallet', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.AlphaWallet], - icon: walletIcons.alphawallet, - platforms: ['mobile'], - web3react: createMetamaskConnector(), -}; - -const atoken: Wallet = { - name: 'AToken', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.AToken], - icon: walletIcons.atoken, - platforms: ['mobile'], - web3react: createMetamaskConnector(), -}; - -const bitpie: Wallet = { - name: 'Bitpie', - checkProviderIdentity: () => (window as any).Bitpie, - icon: walletIcons.bitpie, - platforms: ['mobile'], - web3react: createMetamaskConnector(), -}; - -const dcent: Wallet = { - name: 'Dcent', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.Dcent], - icon: walletIcons.dcent, - platforms: ['mobile'], - web3react: createMetamaskConnector(), -}; - -const frame: Wallet = { - name: 'Frame', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.Frame], - icon: walletIcons.frame, - platforms: ['desktop'], - web3react: createMetamaskConnector(), -}; - -const huobiwallet: Wallet = { - name: 'HuobiWallet', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.HuobiWallet], - icon: walletIcons.huobiwallet, - platforms: ['mobile'], - web3react: createMetamaskConnector(), -}; - -const hyperpay: Wallet = { - name: 'HyperPay', - // Note: The property `hiWallet` is as of now the only known way of identifying hyperpay - // wallet as it is a direct clone of metamask. `checkProviderIdentity` implementation is subject to - // future changes - checkProviderIdentity: () => (window as any).hiWallet, - icon: walletIcons.hyperpay, - platforms: ['mobile'], - web3react: createMetamaskConnector(), -}; - -const imtoken: Wallet = { - name: 'ImToken', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.ImToken], - icon: walletIcons.imtoken, - platforms: ['mobile'], - web3react: createMetamaskConnector(), -}; - -const liquality: Wallet = { - name: 'Liquality', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.Liquality], - icon: walletIcons.liquality, - platforms: ['desktop'], - web3react: createMetamaskConnector(), -}; - -const meetone: Wallet = { - name: 'MeetOne', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.MeetOne] === 'MEETONE', - icon: walletIcons.meetone, - platforms: ['mobile'], - web3react: createMetamaskConnector(), -}; - -const mykey: Wallet = { - name: 'MyKey', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.MyKey], - icon: walletIcons.mykey, - platforms: ['mobile'], - web3react: createMetamaskConnector(), -}; - -const ownbit: Wallet = { - name: 'OwnBit', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.OwnBit], - icon: walletIcons.ownbit, - platforms: ['mobile'], - web3react: createMetamaskConnector(), -}; - -const tokenpocket: Wallet = { - name: 'TokenPocket', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.TokenPocket] && - !provider[ProviderIdentityFlag.TP], - icon: walletIcons.tokenpocket, - platforms: ['all'], - web3react: createMetamaskConnector(), -}; - -const tp: Wallet = { - name: 'TP', - checkProviderIdentity: ({ provider }) => provider?.[ProviderIdentityFlag.TP], - icon: walletIcons.tp, - platforms: ['mobile'], - web3react: createMetamaskConnector(), -}; - -const xdefi: Wallet = { - name: 'XDEFI', - // eslint-disable-next-line dot-notation - checkProviderIdentity: () => true, - icon: walletIcons.xdefi, - platforms: ['all'], - web3react: createMetamaskConnector(), -}; - -const oneInch: Wallet = { - name: 'OneInch', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.OneInch], - icon: walletIcons.oneInch, - platforms: ['mobile'], - web3react: createMetamaskConnector(), -}; - -const tokenary: Wallet = { - name: 'Tokenary', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.Tokenary], - icon: walletIcons.tokenary, - platforms: ['mobile'], - web3react: createMetamaskConnector(), -}; - -export const supportedWallets = [ - metamask, - walletConnect, - tallyho, - binance, - coinbase, - detected, - trust, - status, - alphawallet, - atoken, - blockWallet, - bitpie, - brave, - dcent, - frame, - huobiwallet, - hyperpay, - imtoken, - liquality, - meetone, - mykey, - ownbit, - tokenpocket, - tp, - xdefi, - oneInch, - tokenary, - mathWallet, -]; diff --git a/packages/wallet-management/src/wallets.ts b/packages/wallet-management/src/wallets.ts index 67896524d..74067a50f 100644 --- a/packages/wallet-management/src/wallets.ts +++ b/packages/wallet-management/src/wallets.ts @@ -1,124 +1,252 @@ +import { supportedChains } from '@lifi/sdk'; +import { InjectedConnector } from './connectors/injectedConnector'; +import { WalletConnectConnector } from './connectors/walletConnectConnector'; +import type { Wallet } from './types'; +import { ProviderIdentityFlag } from './types'; import { walletIcons } from './walletIcons'; -export const wallets = { - alphawallet: { - name: 'AlphaWallet', - icon: walletIcons.alphawallet, - }, - atoken: { - name: 'AToken', - icon: walletIcons.atoken, +const defaultWallet: Wallet = new InjectedConnector({ + // unknown Default wallet that injects as metamask but is not metamask + name: 'Default Wallet', + installed: () => + !!(window as any).ethereum && + !(window as any)?.ethereum?.[ProviderIdentityFlag.MetaMask], + icon: walletIcons.placeholder, +}); + +const metamask: Wallet = new InjectedConnector({ + name: 'MetaMask', + installed: () => !!(window as any)?.ethereum?.[ProviderIdentityFlag.MetaMask], + icon: walletIcons.metamask, +}); + +const walletConnect: Wallet = new WalletConnectConnector({ + name: 'Wallet Connect', + installed: () => true, + icon: walletIcons.walletConnect, + rpc: Object.fromEntries( + supportedChains.map((chain) => { + return [chain.id, chain.metamask.rpcUrls[0] || '']; + }), + ), +}); + +const frontier: Wallet = new InjectedConnector( + { + name: 'Frontier', + installed: () => (window as any).frontier, + icon: walletIcons.frontier, + }, + (window as any).frontier?.ethereum, +); + +const brave: Wallet = new InjectedConnector({ + name: 'Brave', + installed: () => + // eslint-disable-next-line no-underscore-dangle + (navigator as any).brave && (window as any)._web3Ref, + icon: walletIcons.brave, +}); + +const mathWallet: Wallet = new InjectedConnector({ + name: 'MathWallet', + installed: () => (window as any).ethereum?.[ProviderIdentityFlag.MathWallet], + icon: walletIcons.mathwallet, +}); + +const tallyho: Wallet = new InjectedConnector( + { + name: 'Taho', + installed: () => + (window as any).tally && + (window as any).tally?.[ProviderIdentityFlag.TallyHo], + icon: walletIcons.tallyho, }, - binance: { + (window as any).tally, +); + +const blockWallet: Wallet = new InjectedConnector({ + name: 'BlockWallet', + installed: () => (window as any).ethereum?.[ProviderIdentityFlag.BlockWallet], + icon: walletIcons.blockwallet, +}); + +const binance: Wallet = new InjectedConnector( + { name: 'Binance', + installed: () => (window as any).BinanceChain, icon: walletIcons.binance, }, - bitpie: { - name: 'Bitpie', - icon: walletIcons.bitpie, - }, - blockwallet: { - name: 'BlockWallet', - icon: walletIcons.blockwallet, - }, - brave: { - name: 'Brave', - icon: walletIcons.brave, - }, - coinbase: { + (window as any).BinanceChain, +); + +const coinbase: Wallet = new InjectedConnector( + { name: 'Coinbase', + installed: () => (window as any).coinbaseWalletExtension, icon: walletIcons.coinbase, }, - dcent: { - name: 'Dcent', - icon: walletIcons.dcent, - }, - detected: { - name: 'Detected', - icon: walletIcons.detected, + (window as any).coinbaseWalletExtension, +); + +const trust: Wallet = new InjectedConnector( + { + name: 'Trust', + installed: () => (window as any).trustWallet, + icon: walletIcons.trust, }, - frame: { + (window as any).trustWallet, +); + +const status: Wallet = new InjectedConnector({ + name: 'Status', + installed: () => (window as any).ethereum?.[ProviderIdentityFlag.Status], + icon: walletIcons.status, +}); + +const alphawallet: Wallet = new InjectedConnector({ + name: 'AlphaWallet', + installed: () => (window as any).ethereum?.[ProviderIdentityFlag.AlphaWallet], + icon: walletIcons.alphawallet, +}); + +const atoken: Wallet = new InjectedConnector({ + name: 'AToken', + installed: () => (window as any).ethereum?.[ProviderIdentityFlag.AToken], + icon: walletIcons.atoken, +}); + +const apex: Wallet = new InjectedConnector({ + name: 'Apex Wallet', + installed: () => (window as any).ethereum?.[ProviderIdentityFlag.ApexWallet], + icon: walletIcons.placeholder, +}); + +const bitpie: Wallet = new InjectedConnector({ + name: 'Bitpie', + installed: () => (window as any).ethereum?.Bitpie, + icon: walletIcons.bitpie, +}); + +const dcent: Wallet = new InjectedConnector({ + name: 'Dcent', + installed: () => (window as any).ethereum?.[ProviderIdentityFlag.Dcent], + icon: walletIcons.dcent, +}); + +const frame: Wallet = new InjectedConnector( + { name: 'Frame', + installed: () => (window as any).frame, icon: walletIcons.frame, }, - huobiwallet: { - name: 'HuobiWallet', - icon: walletIcons.huobiwallet, - }, - hyperpay: { - name: 'HyperPay', - icon: walletIcons.hyperpay, - }, - imtoken: { - name: 'ImToken', - icon: walletIcons.imtoken, - }, - liquality: { + (window as any).frame, +); + +const huobiwallet: Wallet = new InjectedConnector({ + name: 'HuobiWallet', + installed: () => (window as any).ethereum?.[ProviderIdentityFlag.HuobiWallet], + icon: walletIcons.huobiwallet, +}); + +const hyperpay: Wallet = new InjectedConnector({ + name: 'HyperPay', + // Note: The property `hiWallet` is as of now the only known way of identifying hyperpay + // wallet as it is a direct clone of metamask. `checkProviderIdentity` implementation is subject to + // future changes + installed: () => (window as any).ethereum?.hiWallet, + icon: walletIcons.hyperpay, +}); + +const imtoken: Wallet = new InjectedConnector({ + name: 'ImToken', + installed: () => (window as any).ethereum?.[ProviderIdentityFlag.ImToken], + icon: walletIcons.imtoken, +}); + +const liquality: Wallet = new InjectedConnector( + { name: 'Liquality', + installed: () => (window as any).liquality, icon: walletIcons.liquality, }, - mathwallet: { - name: 'MathWallet', - icon: walletIcons.mathwallet, - }, - meetone: { - name: 'MeetOne', - icon: walletIcons.meetone, - }, - metamask: { - name: 'MetaMask', - icon: walletIcons.metamask, - }, - mykey: { - name: 'MyKey', - icon: walletIcons.mykey, - }, - oneInch: { - name: 'OneInch', - icon: walletIcons.oneInch, - }, - opera: { - name: 'Opera', - icon: walletIcons.opera, - }, - ownbit: { - name: 'OwnBit', - icon: walletIcons.ownbit, - }, - status: { - name: 'Status', - icon: walletIcons.status, - }, - tallyho: { - name: 'Tally Ho', - icon: walletIcons.tallyho, - }, - tokenary: { - name: 'Tokenary', - icon: walletIcons.tokenary, - }, - tokenpocket: { - name: 'TokenPocket', - icon: walletIcons.tokenpocket, - }, - tp: { - name: 'TP', - icon: walletIcons.tp, - }, - trust: { - name: 'Trust Wallet', - icon: walletIcons.trust, - }, - walletConnect: { - name: 'Wallet Connect', - icon: walletIcons.walletConnect, - }, - walletio: { - name: 'Wallet.io', - icon: walletIcons.walletio, - }, - xdefi: { - name: 'XDEFI', - icon: walletIcons.xdefi, - }, -}; + (window as any).liquality, +); + +const meetone: Wallet = new InjectedConnector({ + name: 'MeetOne', + installed: () => + (window as any).ethereum?.[ProviderIdentityFlag.MeetOne] === 'MEETONE', + icon: walletIcons.meetone, +}); + +const mykey: Wallet = new InjectedConnector({ + name: 'MyKey', + installed: () => (window as any).ethereum?.[ProviderIdentityFlag.MyKey], + icon: walletIcons.mykey, +}); + +const ownbit: Wallet = new InjectedConnector({ + name: 'OwnBit', + installed: () => (window as any).ethereum?.[ProviderIdentityFlag.OwnBit], + icon: walletIcons.ownbit, +}); + +const tokenpocket: Wallet = new InjectedConnector({ + name: 'TokenPocket', + installed: () => + (window as any).ethereum?.[ProviderIdentityFlag.TokenPocket] && + !(window as any).ethereum?.[ProviderIdentityFlag.TP], + icon: walletIcons.tokenpocket, +}); + +const xdefi: Wallet = new InjectedConnector({ + name: 'XDEFI', + // eslint-disable-next-line dot-notation + installed: () => (window as any).ethereum?.[ProviderIdentityFlag.XDEFI], + icon: walletIcons.xdefi, +}); + +const oneInch: Wallet = new InjectedConnector({ + name: 'OneInch', + installed: () => (window as any).ethereum?.[ProviderIdentityFlag.OneInch], + icon: walletIcons.oneInch, +}); + +const tokenary: Wallet = new InjectedConnector({ + name: 'Tokenary', + installed: () => (window as any).ethereum?.[ProviderIdentityFlag.Tokenary], + icon: walletIcons.tokenary, +}); + +export const supportedWallets = [ + defaultWallet, + metamask, + walletConnect, + tallyho, + binance, + frontier, + coinbase, + trust, + status, + alphawallet, + atoken, + blockWallet, + bitpie, + brave, + apex, + dcent, + frame, + huobiwallet, + hyperpay, + imtoken, + liquality, + meetone, + mykey, + ownbit, + tokenpocket, + xdefi, + oneInch, + tokenary, + mathWallet, +]; diff --git a/packages/widget-embedded/package.json b/packages/widget-embedded/package.json index c1702233a..9eec98c51 100644 --- a/packages/widget-embedded/package.json +++ b/packages/widget-embedded/package.json @@ -38,17 +38,17 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.10.0", - "web3": "^1.8.2" + "web3": "^1.9.0" }, "devDependencies": { "@esbuild-plugins/node-globals-polyfill": "^0.2.3", "@vitejs/plugin-react": "^3.1.0", "buffer": "^6.0.3", "esbuild": "^0.17.17", - "rollup": "^3.20.5", + "rollup": "^3.20.6", "rollup-plugin-polyfill-node": "^0.12.0", "typescript": "^5.0.4", - "vite": "^4.2.1", + "vite": "^4.2.2", "web-vitals": "^3.3.1" }, "eslintConfig": { diff --git a/packages/widget-embedded/src/components/NFTOpenSea/NFTOpenSea.tsx b/packages/widget-embedded/src/components/NFTOpenSea/NFTOpenSea.tsx index dd19da36d..2c2d92e5a 100644 --- a/packages/widget-embedded/src/components/NFTOpenSea/NFTOpenSea.tsx +++ b/packages/widget-embedded/src/components/NFTOpenSea/NFTOpenSea.tsx @@ -1,4 +1,3 @@ -import { switchChain } from '@lifi/wallet-management'; import type { WidgetContract } from '@lifi/widget'; import { NFT, useWallet } from '@lifi/widget'; import { Seaport } from '@opensea/seaport-js'; @@ -13,7 +12,7 @@ export const NFTOpenSea: React.FC = ({ contractAddress, tokenId, }) => { - const { account } = useWallet(); + const { account, switchChain } = useWallet(); const [contract, setContract] = useState(); const { data, isLoading } = useQuery( ['nft', network, contractAddress, tokenId], @@ -67,7 +66,7 @@ export const NFTOpenSea: React.FC = ({ }; fulfillOrder(); } - }, [data, network]); + }, [account.signer, data, network, switchChain]); const asset = data?.makerAssetBundle.assets[0]; const owner = { diff --git a/packages/widget-embedded/src/providers/WalletProvider.tsx b/packages/widget-embedded/src/providers/WalletProvider.tsx index 7d86dedb7..62c9d645b 100644 --- a/packages/widget-embedded/src/providers/WalletProvider.tsx +++ b/packages/widget-embedded/src/providers/WalletProvider.tsx @@ -1,12 +1,7 @@ import type { Signer } from '@ethersproject/abstract-signer'; import type { Token } from '@lifi/sdk'; import type { Wallet } from '@lifi/wallet-management'; -import { - addChain as walletAddChain, - switchChain as walletSwitchChain, - switchChainAndAddToken, - useLiFiWalletManagement, -} from '@lifi/wallet-management'; +import { LiFiWalletManagement } from '@lifi/wallet-management'; import type { WalletAccount, WalletContextProps } from '@lifi/widget/providers'; import type { FC, PropsWithChildren } from 'react'; import { @@ -36,49 +31,71 @@ const initialContext: WalletContextProps = { const WalletContext = createContext(initialContext); export const useWallet = (): WalletContextProps => useContext(WalletContext); +const liFiWalletManagement = new LiFiWalletManagement(); export const WalletProvider: FC> = ({ children }) => { - const { - connect: walletManagementConnect, - disconnect: walletManagementDisconnect, - signer, - } = useLiFiWalletManagement(); const [account, setAccount] = useState({}); - - const connect = useCallback( - async (wallet?: Wallet) => { - await walletManagementConnect(wallet); - const account = await extractAccountFromSigner(signer); - setAccount(account); - }, - [signer, walletManagementConnect], + const [currentWallet, setCurrentWallet] = useState( + liFiWalletManagement.connectedWallets[0], ); - const disconnect = useCallback(async () => { - await walletManagementDisconnect(); - }, [walletManagementDisconnect]); + const handleWalletUpdate = async (wallet?: Wallet) => { + setCurrentWallet(() => wallet); + const account = await extractAccountFromSigner(wallet?.account?.signer); + setAccount(account); + }; - // only for injected wallets - const switchChain = useCallback(async (chainId: number) => { - return walletSwitchChain(chainId); - }, []); + const connect = useCallback(async (wallet: Wallet) => { + await liFiWalletManagement.connect(wallet); + wallet.on('walletAccountChanged', handleWalletUpdate); - const addChain = useCallback(async (chainId: number) => { - return walletAddChain(chainId); + handleWalletUpdate(wallet); }, []); - const addToken = useCallback(async (chainId: number, token: Token) => { - return switchChainAndAddToken(chainId, token); - }, []); + const disconnect = useCallback(async () => { + if (currentWallet) { + await liFiWalletManagement.disconnect(currentWallet); + currentWallet.removeAllListeners(); + handleWalletUpdate(undefined); + } + }, [currentWallet]); - // keep account information up to date - useEffect(() => { - const updateAccount = async () => { - const account = await extractAccountFromSigner(signer); - setAccount(account); - }; - updateAccount(); - }, [signer]); + const switchChain = useCallback( + async (chainId: number) => { + try { + await currentWallet?.switchChain(chainId); + handleWalletUpdate(currentWallet); + return true; + } catch { + return false; + } + }, + [currentWallet], + ); + + const addChain = useCallback( + async (chainId: number) => { + try { + await currentWallet?.addChain(chainId); + handleWalletUpdate(currentWallet); + + return true; + } catch { + return false; + } + }, + [currentWallet], + ); + + const addToken = useCallback( + async (chainId: number, token: Token) => { + await currentWallet?.addToken(chainId, token); + handleWalletUpdate(currentWallet); + + return; + }, + [currentWallet], + ); const value = useMemo( () => ({ diff --git a/packages/widget-playground/package.json b/packages/widget-playground/package.json index 7057794e8..e86b9a397 100644 --- a/packages/widget-playground/package.json +++ b/packages/widget-playground/package.json @@ -40,7 +40,7 @@ "@vitejs/plugin-react": "^3.1.0", "rollup-plugin-polyfill-node": "^0.12.0", "typescript": "^5.0.4", - "vite": "^4.2.1", + "vite": "^4.2.2", "web-vitals": "^3.3.1" }, "eslintConfig": { diff --git a/packages/widget-playground/src/App.tsx b/packages/widget-playground/src/App.tsx index dc3cffc9e..915572ed4 100644 --- a/packages/widget-playground/src/App.tsx +++ b/packages/widget-playground/src/App.tsx @@ -1,9 +1,5 @@ import type { Token } from '@lifi/sdk'; -import { - addChain, - switchChain, - switchChainAndAddToken, -} from '@lifi/wallet-management'; + import type { WidgetVariant } from '@lifi/widget'; import { LiFiWidget } from '@lifi/widget'; import { @@ -28,7 +24,12 @@ import { ThemeProvider, createTheme } from '@mui/material/styles'; import React, { useEffect, useState } from 'react'; import { WalletButtons } from './components/WalletButtons'; import { WidgetEvents } from './components/WidgetEvents'; -import { WidgetVariants, widgetBaseConfig, widgetConfig } from './config'; +import { + METAMASK_WALLET, + WidgetVariants, + widgetBaseConfig, + widgetConfig, +} from './config'; import './index.css'; import { useWallet } from './providers/WalletProvider'; @@ -126,31 +127,37 @@ export const App = () => { walletManagement: { signer: account.signer, connect: async () => { - await connect(); + await connect(METAMASK_WALLET); return account.signer!; }, disconnect: async () => { - disconnect(); + disconnect(METAMASK_WALLET); }, switchChain: async (reqChainId: number) => { - await switchChain(reqChainId); + await METAMASK_WALLET!.switchChain(reqChainId); if (account.signer) { return account.signer!; } throw Error('No signer object after chain switch'); }, addToken: async (token: Token, chainId: number) => { - await switchChainAndAddToken(chainId, token); + await METAMASK_WALLET!.addToken(chainId, token); }, addChain: async (chainId: number) => { - return addChain(chainId); + return METAMASK_WALLET!.addChain(chainId); }, }, })); } else { setConfig((config) => ({ ...config, walletManagement: undefined })); } - }, [externalWallerManagement, account.signer, connect, disconnect]); + }, [ + externalWallerManagement, + account.signer, + account.address, + connect, + disconnect, + ]); useEffect(() => { setTheme( diff --git a/packages/widget-playground/src/components/WalletButtons.tsx b/packages/widget-playground/src/components/WalletButtons.tsx index 9230afa4a..8c647f0e0 100644 --- a/packages/widget-playground/src/components/WalletButtons.tsx +++ b/packages/widget-playground/src/components/WalletButtons.tsx @@ -1,5 +1,6 @@ import { Box, Button } from '@mui/material'; import { useWallet } from '../providers/WalletProvider'; +import { METAMASK_WALLET } from '../config'; export const WalletButtons = () => { const { connect, disconnect, account } = useWallet(); @@ -7,11 +8,11 @@ export const WalletButtons = () => { return ( {account.isActive && account.address ? ( - ) : ( - )} diff --git a/packages/widget-playground/src/config.ts b/packages/widget-playground/src/config.ts index 1b7b6a1b4..0995fafc4 100644 --- a/packages/widget-playground/src/config.ts +++ b/packages/widget-playground/src/config.ts @@ -1,5 +1,10 @@ import type { WidgetConfig } from '@lifi/widget'; import './index.css'; +import { supportedWallets } from '@lifi/wallet-management'; + +export const METAMASK_WALLET = supportedWallets.find( + (wallet) => wallet.name === 'MetaMask', +); export const WidgetVariants = [ 'default', diff --git a/packages/widget-playground/src/providers/WalletProvider.tsx b/packages/widget-playground/src/providers/WalletProvider.tsx index f7b582ccf..80c1ead49 100644 --- a/packages/widget-playground/src/providers/WalletProvider.tsx +++ b/packages/widget-playground/src/providers/WalletProvider.tsx @@ -1,12 +1,7 @@ import type { Signer } from '@ethersproject/abstract-signer'; import type { Token } from '@lifi/sdk'; import type { Wallet } from '@lifi/wallet-management'; -import { - switchChainAndAddToken, - useLiFiWalletManagement, - addChain as walletAddChain, - switchChain as walletSwitchChain, -} from '@lifi/wallet-management'; +import { LiFiWalletManagement } from '@lifi/wallet-management'; import type { WalletAccount, WalletContextProps } from '@lifi/widget/providers'; import type { FC, PropsWithChildren } from 'react'; import { @@ -17,6 +12,7 @@ import { useMemo, useState, } from 'react'; +import { METAMASK_WALLET } from '../config'; const stub = (): never => { throw new Error( @@ -36,49 +32,69 @@ const initialContext: WalletContextProps = { const WalletContext = createContext(initialContext); export const useWallet = (): WalletContextProps => useContext(WalletContext); +const liFiWalletManagement = new LiFiWalletManagement(); export const WalletProvider: FC> = ({ children }) => { - const { - connect: walletManagementConnect, - disconnect: walletManagementDisconnect, - signer, - } = useLiFiWalletManagement(); const [account, setAccount] = useState({}); + const [currentWallet, setCurrentWallet] = useState(); - const connect = useCallback( - async (wallet?: Wallet) => { - await walletManagementConnect(wallet); - const account = await extractAccountFromSigner(signer); - setAccount(account); - }, - [signer, walletManagementConnect], - ); + const handleWalletUpdate = async (wallet?: Wallet) => { + setCurrentWallet(() => wallet); + const account = await extractAccountFromSigner(wallet?.account?.signer); + setAccount(account); + }; - const disconnect = useCallback(async () => { - await walletManagementDisconnect(); - }, [walletManagementDisconnect]); + const connect = useCallback(async (wallet: Wallet) => { + await liFiWalletManagement.connect(wallet); + wallet.on('walletAccountChanged', handleWalletUpdate); - // only for injected wallets - const switchChain = useCallback(async (chainId: number) => { - return walletSwitchChain(chainId); + handleWalletUpdate(wallet); }, []); - const addChain = useCallback(async (chainId: number) => { - return walletAddChain(chainId); - }, []); + const disconnect = useCallback(async () => { + if (currentWallet) { + await liFiWalletManagement.disconnect(currentWallet); + currentWallet.removeAllListeners(); + handleWalletUpdate(undefined); + } + }, [currentWallet]); - const addToken = useCallback(async (chainId: number, token: Token) => { - return switchChainAndAddToken(chainId, token); - }, []); + const switchChain = useCallback( + async (chainId: number) => { + try { + await currentWallet?.switchChain(chainId); + handleWalletUpdate(currentWallet); + return true; + } catch { + return false; + } + }, + [currentWallet], + ); - // keep account information up to date - useEffect(() => { - const updateAccount = async () => { - const account = await extractAccountFromSigner(signer); - setAccount(account); - }; - updateAccount(); - }, [signer]); + const addChain = useCallback( + async (chainId: number) => { + try { + await currentWallet?.addChain(chainId); + handleWalletUpdate(currentWallet); + + return true; + } catch { + return false; + } + }, + [currentWallet], + ); + + const addToken = useCallback( + async (chainId: number, token: Token) => { + await currentWallet?.addToken(chainId, token); + handleWalletUpdate(currentWallet); + + return; + }, + [currentWallet], + ); const value = useMemo( () => ({ @@ -89,7 +105,7 @@ export const WalletProvider: FC> = ({ children }) => { addToken, account, }), - [account, addChain, addToken, connect, disconnect, switchChain], + [account.address, addChain, addToken, connect, disconnect, switchChain], ); return ( diff --git a/packages/widget/src/components/ActiveSwaps/index.ts b/packages/widget/src/components/ActiveSwaps/index.ts index 00471a269..68e0ff52c 100644 --- a/packages/widget/src/components/ActiveSwaps/index.ts +++ b/packages/widget/src/components/ActiveSwaps/index.ts @@ -1,3 +1,2 @@ export * from './ActiveSwapItem'; export * from './ActiveSwaps'; - diff --git a/packages/widget/src/pages/SelectWalletPage/SelectWalletPage.tsx b/packages/widget/src/pages/SelectWalletPage/SelectWalletPage.tsx index 15ef48c30..2be5b24d9 100644 --- a/packages/widget/src/pages/SelectWalletPage/SelectWalletPage.tsx +++ b/packages/widget/src/pages/SelectWalletPage/SelectWalletPage.tsx @@ -1,5 +1,5 @@ -import type { Wallet } from '@lifi/wallet-management'; import { supportedWallets } from '@lifi/wallet-management'; +import type { Wallet } from '@lifi/wallet-management'; import { Avatar, Button, @@ -27,6 +27,15 @@ export const SelectWalletPage = () => { wallet?: Wallet; }>({ show: false }); + // separate into installed and not installed wallets + const installedWallets = supportedWallets.filter((wallet) => + wallet.installed(), + ); + + const notInstalledWallets = supportedWallets.filter( + (wallet) => !wallet.installed() && wallet.name !== 'Default Wallet', // always remove Default Wallet from not installed Wallets + ); + const closeDialog = () => { setWalletIdentity((state) => ({ ...state, @@ -36,10 +45,7 @@ export const SelectWalletPage = () => { const handleConnect = useCallback( async (wallet: Wallet) => { - const { ethereum } = window as any; - const identityCheckPassed = wallet.checkProviderIdentity({ - provider: ethereum, - }); + const identityCheckPassed = wallet.installed(); if (!identityCheckPassed) { setWalletIdentity({ show: true, @@ -61,7 +67,7 @@ export const SelectWalletPage = () => { paddingRight: 1.5, }} > - {supportedWallets.map((wallet: Wallet) => ( + {[...installedWallets, ...notInstalledWallets].map((wallet: Wallet) => ( handleConnect(wallet)} diff --git a/packages/widget/src/providers/WalletProvider/WalletProvider.tsx b/packages/widget/src/providers/WalletProvider/WalletProvider.tsx index 5cf4f6ebf..732a75a82 100644 --- a/packages/widget/src/providers/WalletProvider/WalletProvider.tsx +++ b/packages/widget/src/providers/WalletProvider/WalletProvider.tsx @@ -1,12 +1,11 @@ import type { Signer } from '@ethersproject/abstract-signer'; import type { Token } from '@lifi/sdk'; -import type { Wallet } from '@lifi/wallet-management'; import { - addChain as walletAddChain, - switchChain as walletSwitchChain, - switchChainAndAddToken, - useLiFiWalletManagement, + LiFiWalletManagement, + readActiveWallets, + supportedWallets, } from '@lifi/wallet-management'; +import type { Wallet } from '@lifi/wallet-management/types'; import type { FC, PropsWithChildren } from 'react'; import { createContext, @@ -19,6 +18,8 @@ import { import { useWidgetConfig } from '../WidgetProvider'; import type { WalletAccount, WalletContextProps } from './types'; +const liFiWalletManagement = new LiFiWalletManagement(); + const stub = (): never => { throw new Error( `You forgot to wrap your component in <${WalletProvider.name}>.`, @@ -40,25 +41,47 @@ export const useWallet = (): WalletContextProps => useContext(WalletContext); export const WalletProvider: FC = ({ children }) => { const { walletManagement } = useWidgetConfig(); - const { - connect: walletManagementConnect, - disconnect: walletManagementDisconnect, - signer, - provider, - } = useLiFiWalletManagement(); const [account, setAccount] = useState({}); + const [currentWallet, setCurrentWallet] = useState(); + + useEffect(() => { + const autoConnect = async () => { + const persistedActiveWallets = readActiveWallets(); + const activeWallets = supportedWallets.filter((wallet) => + persistedActiveWallets.some( + (perstistedWallet) => perstistedWallet.name === wallet.name, + ), + ); + if (!activeWallets.length) { + return; + } + await liFiWalletManagement.autoConnect(activeWallets); + activeWallets[0].on('walletAccountChanged', handleWalletUpdate); + handleWalletUpdate(activeWallets[0]); + }; + autoConnect(); + }, []); + + const handleWalletUpdate = async (wallet?: Wallet) => { + setCurrentWallet(wallet); + const account = await extractAccountFromSigner(wallet?.account?.signer); + setAccount(account); + }; const connect = useCallback( - async (wallet?: Wallet) => { + async (wallet: Wallet) => { if (walletManagement) { const signer = await walletManagement.connect(); const account = await extractAccountFromSigner(signer); setAccount(account); return; } - await walletManagementConnect(wallet); + await liFiWalletManagement.connect(wallet); + wallet.on('walletAccountChanged', handleWalletUpdate); + + handleWalletUpdate(wallet); }, - [walletManagement, walletManagementConnect], + [walletManagement], ); const disconnect = useCallback(async () => { @@ -67,10 +90,13 @@ export const WalletProvider: FC = ({ children }) => { setAccount({}); return; } - await walletManagementDisconnect(); - }, [walletManagement, walletManagementDisconnect]); + if (currentWallet) { + await liFiWalletManagement.disconnect(currentWallet); + currentWallet.removeAllListeners(); + handleWalletUpdate(undefined); + } + }, [walletManagement, currentWallet]); - // only for injected wallets const switchChain = useCallback( async (chainId: number) => { if (walletManagement?.switchChain) { @@ -79,9 +105,15 @@ export const WalletProvider: FC = ({ children }) => { setAccount(account); return true; } - return walletSwitchChain(chainId); + try { + await currentWallet?.switchChain(chainId); + handleWalletUpdate(currentWallet); + return true; + } catch { + return false; + } }, - [walletManagement], + [walletManagement, currentWallet], ); const addChain = useCallback( @@ -89,9 +121,16 @@ export const WalletProvider: FC = ({ children }) => { if (walletManagement?.addChain) { return walletManagement.addChain(chainId); } - return walletAddChain(chainId); + try { + await currentWallet?.addChain(chainId); + handleWalletUpdate(currentWallet); + + return true; + } catch { + return false; + } }, - [walletManagement], + [walletManagement, currentWallet], ); const addToken = useCallback( @@ -99,25 +138,26 @@ export const WalletProvider: FC = ({ children }) => { if (walletManagement?.addToken) { return walletManagement.addToken(token, chainId); } - return switchChainAndAddToken(chainId, token); + await currentWallet?.addToken(chainId, token); + handleWalletUpdate(currentWallet); + + return; }, - [walletManagement], + [walletManagement, currentWallet], ); - // keep account information up to date + // keep widget in sync with changing external signer object useEffect(() => { - const updateAccount = async () => { - let account; - if (walletManagement) { - account = await extractAccountFromSigner(walletManagement?.signer); - } else { - account = await extractAccountFromSigner(signer); - } - - setAccount(account); - }; - updateAccount(); - }, [signer, walletManagement]); + if (walletManagement) { + const updateAccount = async () => { + const account = await extractAccountFromSigner( + walletManagement?.signer, + ); + setAccount(account); + }; + updateAccount(); + } + }, [walletManagement, walletManagement?.signer]); const value = useMemo( () => ({ @@ -127,9 +167,17 @@ export const WalletProvider: FC = ({ children }) => { addChain, addToken, account, - provider, + provider: currentWallet?.account?.provider, }), - [account, addChain, addToken, connect, disconnect, provider, switchChain], + [ + account, + addChain, + addToken, + connect, + disconnect, + currentWallet, + switchChain, + ], ); return ( @@ -146,7 +194,7 @@ export const extractAccountFromSigner = async (signer?: Signer) => { chainId: await signer?.getChainId(), }; } catch (error) { - console.log(error); + console.error(error); return {}; } }; diff --git a/packages/widget/src/providers/WalletProvider/index.ts b/packages/widget/src/providers/WalletProvider/index.ts index 0c5f6d269..a27256a6a 100644 --- a/packages/widget/src/providers/WalletProvider/index.ts +++ b/packages/widget/src/providers/WalletProvider/index.ts @@ -1,2 +1,2 @@ -export * from './types'; export * from './WalletProvider'; +export * from './types'; diff --git a/packages/widget/src/providers/WalletProvider/types.ts b/packages/widget/src/providers/WalletProvider/types.ts index d87a12f96..263a32116 100644 --- a/packages/widget/src/providers/WalletProvider/types.ts +++ b/packages/widget/src/providers/WalletProvider/types.ts @@ -8,7 +8,7 @@ export interface WalletContextProps { provider?: Provider; addChain(chainId: number): Promise; addToken(chainId: number, token: Token): Promise; - disconnect(): void; + disconnect(wallet?: Wallet): void; switchChain(chainId: number): Promise; connect(wallet?: Wallet | undefined): Promise; } diff --git a/yarn.lock b/yarn.lock index da12b7419..698c68750 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1530,7 +1530,7 @@ __metadata: languageName: node linkType: hard -"@coinbase/wallet-sdk@npm:^3.6.5": +"@coinbase/wallet-sdk@npm:^3.7.0": version: 3.7.0 resolution: "@coinbase/wallet-sdk@npm:3.7.0" dependencies: @@ -1710,13 +1710,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.17.16": - version: 0.17.16 - resolution: "@esbuild/android-arm64@npm:0.17.16" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/android-arm64@npm:0.17.17": version: 0.17.17 resolution: "@esbuild/android-arm64@npm:0.17.17" @@ -1724,13 +1717,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm@npm:0.17.16": - version: 0.17.16 - resolution: "@esbuild/android-arm@npm:0.17.16" - conditions: os=android & cpu=arm - languageName: node - linkType: hard - "@esbuild/android-arm@npm:0.17.17": version: 0.17.17 resolution: "@esbuild/android-arm@npm:0.17.17" @@ -1738,13 +1724,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-x64@npm:0.17.16": - version: 0.17.16 - resolution: "@esbuild/android-x64@npm:0.17.16" - conditions: os=android & cpu=x64 - languageName: node - linkType: hard - "@esbuild/android-x64@npm:0.17.17": version: 0.17.17 resolution: "@esbuild/android-x64@npm:0.17.17" @@ -1752,13 +1731,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.17.16": - version: 0.17.16 - resolution: "@esbuild/darwin-arm64@npm:0.17.16" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/darwin-arm64@npm:0.17.17": version: 0.17.17 resolution: "@esbuild/darwin-arm64@npm:0.17.17" @@ -1766,13 +1738,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.17.16": - version: 0.17.16 - resolution: "@esbuild/darwin-x64@npm:0.17.16" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - "@esbuild/darwin-x64@npm:0.17.17": version: 0.17.17 resolution: "@esbuild/darwin-x64@npm:0.17.17" @@ -1780,13 +1745,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.17.16": - version: 0.17.16 - resolution: "@esbuild/freebsd-arm64@npm:0.17.16" - conditions: os=freebsd & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/freebsd-arm64@npm:0.17.17": version: 0.17.17 resolution: "@esbuild/freebsd-arm64@npm:0.17.17" @@ -1794,13 +1752,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.17.16": - version: 0.17.16 - resolution: "@esbuild/freebsd-x64@npm:0.17.16" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - "@esbuild/freebsd-x64@npm:0.17.17": version: 0.17.17 resolution: "@esbuild/freebsd-x64@npm:0.17.17" @@ -1808,13 +1759,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.17.16": - version: 0.17.16 - resolution: "@esbuild/linux-arm64@npm:0.17.16" - conditions: os=linux & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/linux-arm64@npm:0.17.17": version: 0.17.17 resolution: "@esbuild/linux-arm64@npm:0.17.17" @@ -1822,13 +1766,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.17.16": - version: 0.17.16 - resolution: "@esbuild/linux-arm@npm:0.17.16" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - "@esbuild/linux-arm@npm:0.17.17": version: 0.17.17 resolution: "@esbuild/linux-arm@npm:0.17.17" @@ -1836,13 +1773,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.17.16": - version: 0.17.16 - resolution: "@esbuild/linux-ia32@npm:0.17.16" - conditions: os=linux & cpu=ia32 - languageName: node - linkType: hard - "@esbuild/linux-ia32@npm:0.17.17": version: 0.17.17 resolution: "@esbuild/linux-ia32@npm:0.17.17" @@ -1850,13 +1780,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.17.16": - version: 0.17.16 - resolution: "@esbuild/linux-loong64@npm:0.17.16" - conditions: os=linux & cpu=loong64 - languageName: node - linkType: hard - "@esbuild/linux-loong64@npm:0.17.17": version: 0.17.17 resolution: "@esbuild/linux-loong64@npm:0.17.17" @@ -1864,13 +1787,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.17.16": - version: 0.17.16 - resolution: "@esbuild/linux-mips64el@npm:0.17.16" - conditions: os=linux & cpu=mips64el - languageName: node - linkType: hard - "@esbuild/linux-mips64el@npm:0.17.17": version: 0.17.17 resolution: "@esbuild/linux-mips64el@npm:0.17.17" @@ -1878,13 +1794,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.17.16": - version: 0.17.16 - resolution: "@esbuild/linux-ppc64@npm:0.17.16" - conditions: os=linux & cpu=ppc64 - languageName: node - linkType: hard - "@esbuild/linux-ppc64@npm:0.17.17": version: 0.17.17 resolution: "@esbuild/linux-ppc64@npm:0.17.17" @@ -1892,13 +1801,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.17.16": - version: 0.17.16 - resolution: "@esbuild/linux-riscv64@npm:0.17.16" - conditions: os=linux & cpu=riscv64 - languageName: node - linkType: hard - "@esbuild/linux-riscv64@npm:0.17.17": version: 0.17.17 resolution: "@esbuild/linux-riscv64@npm:0.17.17" @@ -1906,13 +1808,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.17.16": - version: 0.17.16 - resolution: "@esbuild/linux-s390x@npm:0.17.16" - conditions: os=linux & cpu=s390x - languageName: node - linkType: hard - "@esbuild/linux-s390x@npm:0.17.17": version: 0.17.17 resolution: "@esbuild/linux-s390x@npm:0.17.17" @@ -1920,13 +1815,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.17.16": - version: 0.17.16 - resolution: "@esbuild/linux-x64@npm:0.17.16" - conditions: os=linux & cpu=x64 - languageName: node - linkType: hard - "@esbuild/linux-x64@npm:0.17.17": version: 0.17.17 resolution: "@esbuild/linux-x64@npm:0.17.17" @@ -1934,13 +1822,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.17.16": - version: 0.17.16 - resolution: "@esbuild/netbsd-x64@npm:0.17.16" - conditions: os=netbsd & cpu=x64 - languageName: node - linkType: hard - "@esbuild/netbsd-x64@npm:0.17.17": version: 0.17.17 resolution: "@esbuild/netbsd-x64@npm:0.17.17" @@ -1948,13 +1829,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.17.16": - version: 0.17.16 - resolution: "@esbuild/openbsd-x64@npm:0.17.16" - conditions: os=openbsd & cpu=x64 - languageName: node - linkType: hard - "@esbuild/openbsd-x64@npm:0.17.17": version: 0.17.17 resolution: "@esbuild/openbsd-x64@npm:0.17.17" @@ -1962,13 +1836,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.17.16": - version: 0.17.16 - resolution: "@esbuild/sunos-x64@npm:0.17.16" - conditions: os=sunos & cpu=x64 - languageName: node - linkType: hard - "@esbuild/sunos-x64@npm:0.17.17": version: 0.17.17 resolution: "@esbuild/sunos-x64@npm:0.17.17" @@ -1976,13 +1843,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.17.16": - version: 0.17.16 - resolution: "@esbuild/win32-arm64@npm:0.17.16" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/win32-arm64@npm:0.17.17": version: 0.17.17 resolution: "@esbuild/win32-arm64@npm:0.17.17" @@ -1990,13 +1850,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.17.16": - version: 0.17.16 - resolution: "@esbuild/win32-ia32@npm:0.17.16" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - "@esbuild/win32-ia32@npm:0.17.17": version: 0.17.17 resolution: "@esbuild/win32-ia32@npm:0.17.17" @@ -2004,13 +1857,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.17.16": - version: 0.17.16 - resolution: "@esbuild/win32-x64@npm:0.17.16" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - "@esbuild/win32-x64@npm:0.17.17": version: 0.17.17 resolution: "@esbuild/win32-x64@npm:0.17.17" @@ -2135,7 +1981,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/address@npm:5.7.0, @ethersproject/address@npm:^5, @ethersproject/address@npm:^5.7.0": +"@ethersproject/address@npm:5.7.0, @ethersproject/address@npm:^5.7.0": version: 5.7.0 resolution: "@ethersproject/address@npm:5.7.0" dependencies: @@ -2328,7 +2174,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/providers@npm:5.7.2, @ethersproject/providers@npm:^5, @ethersproject/providers@npm:^5.5.1, @ethersproject/providers@npm:^5.7.2": +"@ethersproject/providers@npm:5.7.2, @ethersproject/providers@npm:^5.5.1, @ethersproject/providers@npm:^5.7.2": version: 5.7.2 resolution: "@ethersproject/providers@npm:5.7.2" dependencies: @@ -2778,11 +2624,11 @@ __metadata: linkType: hard "@lifi/types@npm:^3.2.1": - version: 3.2.2 - resolution: "@lifi/types@npm:3.2.2" + version: 3.2.6 + resolution: "@lifi/types@npm:3.2.6" dependencies: ethers: ^5.7.2 - checksum: 3625a827720d4918531c93ff08d51dbaf3b1df25f973b01f49b4b198589674acb037bf22a74d57d2ed1d055f353246d0449f78ceb2296a798e69bd4fad441afe + checksum: d0e76a4c2f9af198c4518396fa063d58b01ea52f7283f8104c743e8a3efaa17f90fb261693b383943b470a5694917132dc8baf39d2033ad411987eebf336d3a9 languageName: node linkType: hard @@ -2790,21 +2636,13 @@ __metadata: version: 0.0.0-use.local resolution: "@lifi/wallet-management@workspace:packages/wallet-management" dependencies: - "@coinbase/wallet-sdk": ^3.6.5 + "@coinbase/wallet-sdk": ^3.7.0 "@ethersproject/abstract-signer": ^5.7.0 "@ethersproject/experimental": ^5.7.0 "@ethersproject/providers": ^5.7.2 "@lifi/sdk": ^2.0.0-beta.8 "@walletconnect/ethereum-provider": ^1.8.0 "@walletconnect/web3-provider": ^1.8.0 - "@web3-react/coinbase-wallet": ^8.0.35-beta.0 - "@web3-react/core": ^8.0.35-beta.0 - "@web3-react/eip1193": ^8.0.27-beta.0 - "@web3-react/empty": ^8.0.20-beta.0 - "@web3-react/metamask": ^8.0.30-beta.0 - "@web3-react/network": ^8.0.27-beta.0 - "@web3-react/types": ^8.0.20-beta.0 - "@web3-react/url": ^8.0.25-beta.0 cpy-cli: ^4.2.0 react: ^18.2.0 typescript: ^5.0.4 @@ -2834,12 +2672,12 @@ __metadata: react: ^18.2.0 react-dom: ^18.2.0 react-router-dom: ^6.10.0 - rollup: ^3.20.5 + rollup: ^3.20.6 rollup-plugin-polyfill-node: ^0.12.0 typescript: ^5.0.4 - vite: ^4.2.1 + vite: ^4.2.2 web-vitals: ^3.3.1 - web3: ^1.8.2 + web3: ^1.9.0 languageName: unknown linkType: soft @@ -2862,7 +2700,7 @@ __metadata: react-router-dom: ^6.10.0 rollup-plugin-polyfill-node: ^0.12.0 typescript: ^5.0.4 - vite: ^4.2.1 + vite: ^4.2.2 web-vitals: ^3.3.1 languageName: unknown linkType: soft @@ -2910,13 +2748,6 @@ __metadata: languageName: unknown linkType: soft -"@metamask/detect-provider@npm:^1.2.0": - version: 1.2.0 - resolution: "@metamask/detect-provider@npm:1.2.0" - checksum: 2c152534a8dd15bc1430bb5159cdf58993549a644cff344a1ff43f4ede8f041aad72b909e822747f6545de3ed293a740ecffc86a859daf7a925c4096efd61eb3 - languageName: node - linkType: hard - "@metamask/safe-event-emitter@npm:2.0.0, @metamask/safe-event-emitter@npm:^2.0.0": version: 2.0.0 resolution: "@metamask/safe-event-emitter@npm:2.0.0" @@ -3968,13 +3799,13 @@ __metadata: languageName: node linkType: hard -"@tufjs/models@npm:1.0.2": - version: 1.0.2 - resolution: "@tufjs/models@npm:1.0.2" +"@tufjs/models@npm:1.0.3": + version: 1.0.3 + resolution: "@tufjs/models@npm:1.0.3" dependencies: "@tufjs/canonical-json": 1.0.0 - minimatch: ^8.0.3 - checksum: 40f234e1b168498340acf4eca51c16df118c56144d3a20c4d659045677ac93121c74b98419c0437f9f701a75cbf9b4d03290e6a7b07eb3218174cbb658044308 + minimatch: ^7.4.6 + checksum: 4499de770bd1300510971289ea09038945544db4cd4ef56218986f2587cec77a4971d2b519f87cb67f736edc78d590b65ed0cb2c6ce7467249298611ffea83d0 languageName: node linkType: hard @@ -4042,9 +3873,9 @@ __metadata: linkType: hard "@types/estree@npm:*, @types/estree@npm:^1.0.0": - version: 1.0.0 - resolution: "@types/estree@npm:1.0.0" - checksum: 910d97fb7092c6738d30a7430ae4786a38542023c6302b95d46f49420b797f21619cdde11fa92b338366268795884111c2eb10356e4bd2c8ad5b92941e9e6443 + version: 1.0.1 + resolution: "@types/estree@npm:1.0.1" + checksum: e9aa175eacb797216fafce4d41e8202c7a75555bc55232dee0f9903d7171f8f19f0ae7d5191bb1a88cb90e65468be508c0df850a9fb81b4433b293a5a749899d languageName: node linkType: hard @@ -4205,18 +4036,7 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:*": - version: 18.0.35 - resolution: "@types/react@npm:18.0.35" - dependencies: - "@types/prop-types": "*" - "@types/scheduler": "*" - csstype: ^3.0.2 - checksum: e65670397216e037b150a509ec08189140b4c20b82b612ac00b2a7133202be2d1def1e7ee69617b2df06ab4c00c43c4ee23e84788ad661aea9664da2f27c518a - languageName: node - linkType: hard - -"@types/react@npm:^18.0.37": +"@types/react@npm:*, @types/react@npm:^18.0.37": version: 18.0.37 resolution: "@types/react@npm:18.0.37" dependencies: @@ -4307,31 +4127,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^5.5.0": - version: 5.58.0 - resolution: "@typescript-eslint/eslint-plugin@npm:5.58.0" - dependencies: - "@eslint-community/regexpp": ^4.4.0 - "@typescript-eslint/scope-manager": 5.58.0 - "@typescript-eslint/type-utils": 5.58.0 - "@typescript-eslint/utils": 5.58.0 - debug: ^4.3.4 - grapheme-splitter: ^1.0.4 - ignore: ^5.2.0 - natural-compare-lite: ^1.4.0 - semver: ^7.3.7 - tsutils: ^3.21.0 - peerDependencies: - "@typescript-eslint/parser": ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: e5d76d43c466ebd4b552e3307eff72ab5ae8a0c09a1d35fa13b62769ac3336df94d9281728ab5aafd2c14a0a644133583edcd708fce60a9a82df1db3ca3b8e14 - languageName: node - linkType: hard - -"@typescript-eslint/eslint-plugin@npm:^5.59.0": +"@typescript-eslint/eslint-plugin@npm:^5.5.0, @typescript-eslint/eslint-plugin@npm:^5.59.0": version: 5.59.0 resolution: "@typescript-eslint/eslint-plugin@npm:5.59.0" dependencies: @@ -4356,34 +4152,17 @@ __metadata: linkType: hard "@typescript-eslint/experimental-utils@npm:^5.0.0": - version: 5.58.0 - resolution: "@typescript-eslint/experimental-utils@npm:5.58.0" - dependencies: - "@typescript-eslint/utils": 5.58.0 - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: e2f20ec272267afc5726f5cda4ccd055782dc04fc48b88c18e23ab89b523f85c6ab1029dff29adcc17b4c0a020e5d700dceec28933258bbd4ab0e33763e81b5e - languageName: node - linkType: hard - -"@typescript-eslint/parser@npm:^5.5.0": - version: 5.58.0 - resolution: "@typescript-eslint/parser@npm:5.58.0" + version: 5.59.0 + resolution: "@typescript-eslint/experimental-utils@npm:5.59.0" dependencies: - "@typescript-eslint/scope-manager": 5.58.0 - "@typescript-eslint/types": 5.58.0 - "@typescript-eslint/typescript-estree": 5.58.0 - debug: ^4.3.4 + "@typescript-eslint/utils": 5.59.0 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 38681da48a40132c0538579c818ceef9ba2793ab8f79236c3f64980ba1649bb87cb367cd79d37bf2982b8bfbc28f91846b8676f9bd333e8b691c9befffd8874a + checksum: f31c2346cf309c910e662778f3ce3b8e8bb97875282c30ff0fdccdb38719f12c7408843828972297adb0d4ffc1555539e6aa6f48dcc77fef36ca5b1e515a4caf languageName: node linkType: hard -"@typescript-eslint/parser@npm:^5.59.0": +"@typescript-eslint/parser@npm:^5.5.0, @typescript-eslint/parser@npm:^5.59.0": version: 5.59.0 resolution: "@typescript-eslint/parser@npm:5.59.0" dependencies: @@ -4400,16 +4179,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:5.58.0": - version: 5.58.0 - resolution: "@typescript-eslint/scope-manager@npm:5.58.0" - dependencies: - "@typescript-eslint/types": 5.58.0 - "@typescript-eslint/visitor-keys": 5.58.0 - checksum: f0d3df5cc3c461fe63ef89ad886b53c239cc7c1d9061d83d8a9d9c8e087e5501eac84bebff8a954728c17ccea191f235686373d54d2b8b6370af2bcf2b18e062 - languageName: node - linkType: hard - "@typescript-eslint/scope-manager@npm:5.59.0": version: 5.59.0 resolution: "@typescript-eslint/scope-manager@npm:5.59.0" @@ -4420,23 +4189,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:5.58.0": - version: 5.58.0 - resolution: "@typescript-eslint/type-utils@npm:5.58.0" - dependencies: - "@typescript-eslint/typescript-estree": 5.58.0 - "@typescript-eslint/utils": 5.58.0 - debug: ^4.3.4 - tsutils: ^3.21.0 - peerDependencies: - eslint: "*" - peerDependenciesMeta: - typescript: - optional: true - checksum: 803f24daed185152bf86952d4acebb5ea18ff03db5f28750368edf76fdea46b4b0f8803ae0b61c0282b47181c9977113457b16e33d5d2cb33b13855f55c5e5b2 - languageName: node - linkType: hard - "@typescript-eslint/type-utils@npm:5.59.0": version: 5.59.0 resolution: "@typescript-eslint/type-utils@npm:5.59.0" @@ -4454,13 +4206,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:5.58.0": - version: 5.58.0 - resolution: "@typescript-eslint/types@npm:5.58.0" - checksum: 8622a73d73220c4a7111537825f488c0271272032a1d4e129dc722bc6e8b3ec84f64469b2ca3b8dae7da3a9c18953ce1449af51f5f757dad60835eb579ad1d2c - languageName: node - linkType: hard - "@typescript-eslint/types@npm:5.59.0": version: 5.59.0 resolution: "@typescript-eslint/types@npm:5.59.0" @@ -4468,24 +4213,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:5.58.0": - version: 5.58.0 - resolution: "@typescript-eslint/typescript-estree@npm:5.58.0" - dependencies: - "@typescript-eslint/types": 5.58.0 - "@typescript-eslint/visitor-keys": 5.58.0 - debug: ^4.3.4 - globby: ^11.1.0 - is-glob: ^4.0.3 - semver: ^7.3.7 - tsutils: ^3.21.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 51b668ec858db0c040a71dff526273945cee4ba5a9b240528d503d02526685882d900cf071c6636a4d9061ed3fd4a7274f7f1a23fba55c4b48b143344b4009c7 - languageName: node - linkType: hard - "@typescript-eslint/typescript-estree@npm:5.59.0": version: 5.59.0 resolution: "@typescript-eslint/typescript-estree@npm:5.59.0" @@ -4504,25 +4231,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/utils@npm:5.58.0, @typescript-eslint/utils@npm:^5.58.0": - version: 5.58.0 - resolution: "@typescript-eslint/utils@npm:5.58.0" - dependencies: - "@eslint-community/eslint-utils": ^4.2.0 - "@types/json-schema": ^7.0.9 - "@types/semver": ^7.3.12 - "@typescript-eslint/scope-manager": 5.58.0 - "@typescript-eslint/types": 5.58.0 - "@typescript-eslint/typescript-estree": 5.58.0 - eslint-scope: ^5.1.1 - semver: ^7.3.7 - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: c618ae67963ecf96b1492c09afaeb363f542f0d6780bcac4af3c26034e3b20034666b2d523aa94821df813aafb57a0b150a7d5c2224fe8257452ad1de2237a58 - languageName: node - linkType: hard - -"@typescript-eslint/utils@npm:5.59.0": +"@typescript-eslint/utils@npm:5.59.0, @typescript-eslint/utils@npm:^5.58.0": version: 5.59.0 resolution: "@typescript-eslint/utils@npm:5.59.0" dependencies: @@ -4540,16 +4249,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:5.58.0": - version: 5.58.0 - resolution: "@typescript-eslint/visitor-keys@npm:5.58.0" - dependencies: - "@typescript-eslint/types": 5.58.0 - eslint-visitor-keys: ^3.3.0 - checksum: ab2d1f37660559954c840429ef78bbf71834063557e3e68e435005b4987970b9356fdf217ead53f7a57f66f5488dc478062c5c44bf17053a8bf041733539b98f - languageName: node - linkType: hard - "@typescript-eslint/visitor-keys@npm:5.59.0": version: 5.59.0 resolution: "@typescript-eslint/visitor-keys@npm:5.59.0" @@ -4863,102 +4562,6 @@ __metadata: languageName: node linkType: hard -"@web3-react/coinbase-wallet@npm:^8.0.35-beta.0": - version: 8.0.35-beta.0 - resolution: "@web3-react/coinbase-wallet@npm:8.0.35-beta.0" - dependencies: - "@web3-react/types": ^8.0.20-beta.0 - peerDependencies: - "@coinbase/wallet-sdk": ^3.0.4 - checksum: fa8a9e313cb0cb25e90c160545870d4d8657b55b3d42d42cbadb78a5a5c6e8979347ed84315aa6e50fb67c58e9e4c9d26d23d3f4200c22aa94bbfb770b0167d1 - languageName: node - linkType: hard - -"@web3-react/core@npm:^8.0.35-beta.0": - version: 8.0.35-beta.0 - resolution: "@web3-react/core@npm:8.0.35-beta.0" - dependencies: - "@ethersproject/providers": ^5 - "@web3-react/store": ^8.0.25-beta.0 - "@web3-react/types": ^8.0.20-beta.0 - zustand: ^4.0.0-rc.0 - peerDependencies: - react: ">=16.8" - dependenciesMeta: - "@ethersproject/providers": - optional: true - checksum: 4c129fbcd97436d62fa788c06b53ee49966f9be3f27f0f5882863949ecfa8c2d7d3d79053d959dd4fb5a1d5775606ae2ba9ccd78b0d8033cb76b6f2513702629 - languageName: node - linkType: hard - -"@web3-react/eip1193@npm:^8.0.27-beta.0": - version: 8.0.27-beta.0 - resolution: "@web3-react/eip1193@npm:8.0.27-beta.0" - dependencies: - "@web3-react/types": ^8.0.20-beta.0 - checksum: d50109144fc887be8e94a78ae4a39d49939a6909fb0c14d263906adf2998f9c14f3a73564b67cf896431bf5b2f3e41ed90197aa134a350316ab02354586e0b51 - languageName: node - linkType: hard - -"@web3-react/empty@npm:^8.0.20-beta.0": - version: 8.0.20-beta.0 - resolution: "@web3-react/empty@npm:8.0.20-beta.0" - dependencies: - "@web3-react/types": ^8.0.20-beta.0 - checksum: 56d74ce0daf0a9706d92e9c5a726d7b716bfc774c4ec83b8632920661890e882c53094c80f86fd4361aefa963b9d6291b17b4a916d83a864db069521832644cc - languageName: node - linkType: hard - -"@web3-react/metamask@npm:^8.0.30-beta.0": - version: 8.0.30-beta.0 - resolution: "@web3-react/metamask@npm:8.0.30-beta.0" - dependencies: - "@metamask/detect-provider": ^1.2.0 - "@web3-react/types": ^8.0.20-beta.0 - checksum: a9fb153045d996c5fd3d2a2352dd668ede5309e4c96a0b19a2e5a8ae58b04dba77c5d0da543ff5ac7c3b111a3152f42c77cd00c5e1f5f3b97ab38287198c9aae - languageName: node - linkType: hard - -"@web3-react/network@npm:^8.0.27-beta.0": - version: 8.0.27-beta.0 - resolution: "@web3-react/network@npm:8.0.27-beta.0" - dependencies: - "@ethersproject/providers": ^5 - "@web3-react/types": ^8.0.20-beta.0 - checksum: 5073c450aa7450790c37f262660490a751de8218a392d87d7fd4cb8c20107996479c83adf0a04f14e69444ca40d330eb6dd180be56d80f6b46ef2996372886b1 - languageName: node - linkType: hard - -"@web3-react/store@npm:^8.0.25-beta.0": - version: 8.0.25-beta.0 - resolution: "@web3-react/store@npm:8.0.25-beta.0" - dependencies: - "@ethersproject/address": ^5 - "@web3-react/types": ^8.0.20-beta.0 - zustand: ^4.0.0-rc.0 - checksum: f7061e8eb1e10774f3508a9557459e6ff7586ba7b980a4910f727066ca77bbbac3c5dad4ce7fab67c16646d4e2156a60bd736c32e0d7ec2c059eb9979810ab86 - languageName: node - linkType: hard - -"@web3-react/types@npm:^8.0.20-beta.0": - version: 8.0.20-beta.0 - resolution: "@web3-react/types@npm:8.0.20-beta.0" - dependencies: - zustand: ^4.0.0-rc.0 - checksum: 65a91fd1c7dfdb21affc2c29d67d697004a0eaeecfb3491da9da9adfc665b2b4c4fe794e5d23d182ad4809fc94ae4e2906cedbca4f5025af697e863b1f672d40 - languageName: node - linkType: hard - -"@web3-react/url@npm:^8.0.25-beta.0": - version: 8.0.25-beta.0 - resolution: "@web3-react/url@npm:8.0.25-beta.0" - dependencies: - "@ethersproject/providers": ^5 - "@web3-react/types": ^8.0.20-beta.0 - checksum: 635d156f511f58764533f2ee706d1d9b647cb07373a3ba2de56f12e792166cd579ec64547de2360ae97faf6d7b0f44b1e39118f598582be0b91f938304c0f440 - languageName: node - linkType: hard - "@yarnpkg/lockfile@npm:^1.1.0": version: 1.1.0 resolution: "@yarnpkg/lockfile@npm:1.1.0" @@ -5471,9 +5074,9 @@ __metadata: linkType: hard "axe-core@npm:^4.6.2": - version: 4.6.3 - resolution: "axe-core@npm:4.6.3" - checksum: d0c46be92b9707c48b88a53cd5f471b155a2bfc8bf6beffb514ecd14e30b4863e340b5fc4f496d82a3c562048088c1f3ff5b93b9b3b026cb9c3bfacfd535da10 + version: 4.7.0 + resolution: "axe-core@npm:4.7.0" + checksum: f086bcab42be1761ba2b0b127dec350087f4c3a853bba8dd58f69d898cefaac31a1561da23146f6f3c07954c76171d1f2ce460e555e052d2b02cd79af628fa4a languageName: node linkType: hard @@ -6130,9 +5733,9 @@ __metadata: linkType: hard "caniuse-lite@npm:^1.0.30001449": - version: 1.0.30001478 - resolution: "caniuse-lite@npm:1.0.30001478" - checksum: 27a370dcb32a6a35e186307aabc570da1cd0fccc849913665e7df6822a87286de99509b163304e0586c23c539a991717fb68ed84b85bbd21b2cb86475ae5ffb2 + version: 1.0.30001480 + resolution: "caniuse-lite@npm:1.0.30001480" + checksum: c0b40f02f45ee99c73f732a3118028b2ab1544962d473d84f2afcb898a5e3099bd4c45f316ebc466fb1dbda904e86b72695578ca531a0bfa9d6337e7aad1ee2a languageName: node linkType: hard @@ -6799,11 +6402,11 @@ __metadata: linkType: hard "core-js-compat@npm:^3.25.1": - version: 3.30.0 - resolution: "core-js-compat@npm:3.30.0" + version: 3.30.1 + resolution: "core-js-compat@npm:3.30.1" dependencies: browserslist: ^4.21.5 - checksum: 51a34d8a292de51f52ac2d72b18ee94743a905d4570a42214262426ebf8f026c853fee22cf4d6c61c2d95f861749421c4de48e9389f551745c5ac1477a5f929f + checksum: e450a9771fc927ce982333929e1c4b32f180f641e4cfff9de6ed44b5930de19be7707cf74f45d1746ca69b8e8ac0698a555cb7244fbfbed6c38ca93844207bf7 languageName: node linkType: hard @@ -7294,9 +6897,9 @@ __metadata: linkType: hard "dijkstrajs@npm:^1.0.1": - version: 1.0.2 - resolution: "dijkstrajs@npm:1.0.2" - checksum: 8cd822441a26f190da24d69bfab7b433d080b09e069e41e046ac84e152f182a1ed9478d531b34126e000adaa7b73114a0f85fcac117a7d25b3edf302d57c0d09 + version: 1.0.3 + resolution: "dijkstrajs@npm:1.0.3" + checksum: 82ff2c6633f235dd5e6bed04ec62cdfb1f327b4d7534557bd52f18991313f864ee50654543072fff4384a92b643ada4d5452f006b7098dbdfad6c8744a8c9e08 languageName: node linkType: hard @@ -7431,9 +7034,9 @@ __metadata: linkType: hard "electron-to-chromium@npm:^1.4.284": - version: 1.4.361 - resolution: "electron-to-chromium@npm:1.4.361" - checksum: 66b3210c9c5abec7812ce8b936a9e53fa49a2ccb8b4345e1e4d601dfff5e1e22d07ddddeaf84b0dd6bb01522e505dbb7fc91929a7028b02281e5928f36d2e4dc + version: 1.4.368 + resolution: "electron-to-chromium@npm:1.4.368" + checksum: b8ec4128a81c86c287cb2d677504c64d50f30c3c1d6dd9700a93797c6311f9f94b1c49a3e5112f5cfb3987a9bbade0133f9ec9898dae592db981059d5c2abdbb languageName: node linkType: hard @@ -7688,7 +7291,7 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.17.17": +"esbuild@npm:^0.17.17, esbuild@npm:^0.17.5": version: 0.17.17 resolution: "esbuild@npm:0.17.17" dependencies: @@ -7765,83 +7368,6 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.17.5": - version: 0.17.16 - resolution: "esbuild@npm:0.17.16" - dependencies: - "@esbuild/android-arm": 0.17.16 - "@esbuild/android-arm64": 0.17.16 - "@esbuild/android-x64": 0.17.16 - "@esbuild/darwin-arm64": 0.17.16 - "@esbuild/darwin-x64": 0.17.16 - "@esbuild/freebsd-arm64": 0.17.16 - "@esbuild/freebsd-x64": 0.17.16 - "@esbuild/linux-arm": 0.17.16 - "@esbuild/linux-arm64": 0.17.16 - "@esbuild/linux-ia32": 0.17.16 - "@esbuild/linux-loong64": 0.17.16 - "@esbuild/linux-mips64el": 0.17.16 - "@esbuild/linux-ppc64": 0.17.16 - "@esbuild/linux-riscv64": 0.17.16 - "@esbuild/linux-s390x": 0.17.16 - "@esbuild/linux-x64": 0.17.16 - "@esbuild/netbsd-x64": 0.17.16 - "@esbuild/openbsd-x64": 0.17.16 - "@esbuild/sunos-x64": 0.17.16 - "@esbuild/win32-arm64": 0.17.16 - "@esbuild/win32-ia32": 0.17.16 - "@esbuild/win32-x64": 0.17.16 - dependenciesMeta: - "@esbuild/android-arm": - optional: true - "@esbuild/android-arm64": - optional: true - "@esbuild/android-x64": - optional: true - "@esbuild/darwin-arm64": - optional: true - "@esbuild/darwin-x64": - optional: true - "@esbuild/freebsd-arm64": - optional: true - "@esbuild/freebsd-x64": - optional: true - "@esbuild/linux-arm": - optional: true - "@esbuild/linux-arm64": - optional: true - "@esbuild/linux-ia32": - optional: true - "@esbuild/linux-loong64": - optional: true - "@esbuild/linux-mips64el": - optional: true - "@esbuild/linux-ppc64": - optional: true - "@esbuild/linux-riscv64": - optional: true - "@esbuild/linux-s390x": - optional: true - "@esbuild/linux-x64": - optional: true - "@esbuild/netbsd-x64": - optional: true - "@esbuild/openbsd-x64": - optional: true - "@esbuild/sunos-x64": - optional: true - "@esbuild/win32-arm64": - optional: true - "@esbuild/win32-ia32": - optional: true - "@esbuild/win32-x64": - optional: true - bin: - esbuild: bin/esbuild - checksum: c9787d8e05b9c4f762761be31a7847b5b4492b9b997808b7098479fef9a3260f1b8ca01e9b38376b6698f4394bfe088acb4f797a697b45b965cd664e103aafa7 - languageName: node - linkType: hard - "escalade@npm:^3.1.1": version: 3.1.1 resolution: "escalade@npm:3.1.1" @@ -7931,14 +7457,14 @@ __metadata: linkType: hard "eslint-module-utils@npm:^2.7.4": - version: 2.7.4 - resolution: "eslint-module-utils@npm:2.7.4" + version: 2.8.0 + resolution: "eslint-module-utils@npm:2.8.0" dependencies: debug: ^3.2.7 peerDependenciesMeta: eslint: optional: true - checksum: 5da13645daff145a5c922896b258f8bba560722c3767254e458d894ff5fbb505d6dfd945bffa932a5b0ae06714da2379bd41011c4c20d2d59cc83e23895360f7 + checksum: 74c6dfea7641ebcfe174be61168541a11a14aa8d72e515f5f09af55cd0d0862686104b0524aa4b8e0ce66418a44aa38a94d2588743db5fd07a6b49ffd16921d2 languageName: node linkType: hard @@ -8095,12 +7621,12 @@ __metadata: linkType: hard "eslint-scope@npm:^7.1.1": - version: 7.1.1 - resolution: "eslint-scope@npm:7.1.1" + version: 7.2.0 + resolution: "eslint-scope@npm:7.2.0" dependencies: esrecurse: ^4.3.0 estraverse: ^5.2.0 - checksum: 9f6e974ab2db641ca8ab13508c405b7b859e72afe9f254e8131ff154d2f40c99ad4545ce326fd9fde3212ff29707102562a4834f1c48617b35d98c71a97fbf3e + checksum: 64591a2d8b244ade9c690b59ef238a11d5c721a98bcee9e9f445454f442d03d3e04eda88e95a4daec558220a99fa384309d9faae3d459bd40e7a81b4063980ae languageName: node linkType: hard @@ -10223,7 +9749,7 @@ __metadata: languageName: node linkType: hard -"is-core-module@npm:^2.11.0, is-core-module@npm:^2.5.0, is-core-module@npm:^2.8.1, is-core-module@npm:^2.9.0": +"is-core-module@npm:^2.11.0, is-core-module@npm:^2.12.0, is-core-module@npm:^2.5.0, is-core-module@npm:^2.8.1, is-core-module@npm:^2.9.0": version: 2.12.0 resolution: "is-core-module@npm:2.12.0" dependencies: @@ -11376,9 +10902,9 @@ __metadata: linkType: hard "lru-cache@npm:^9.0.0": - version: 9.0.1 - resolution: "lru-cache@npm:9.0.1" - checksum: 48e31a2a059730174d4b9c77c679ff922ee90ed8762376fd7a3ff5a1fae992bca26b9010dd985aff763d8444c3822c0d9ebeaba7d0552c764c200c40dedeaebd + version: 9.1.0 + resolution: "lru-cache@npm:9.1.0" + checksum: 97b46faa2e8195b75b1c48a5515f8e458b8f6a0d0933c0484a4e45b6aa67406dcc5f6c8774fef206fd918dce6a4b4a6f627541fbdf74f8e6b3c71f688f43041e languageName: node linkType: hard @@ -11451,8 +10977,8 @@ __metadata: linkType: hard "make-fetch-happen@npm:^11.0.0, make-fetch-happen@npm:^11.0.1": - version: 11.0.3 - resolution: "make-fetch-happen@npm:11.0.3" + version: 11.1.0 + resolution: "make-fetch-happen@npm:11.1.0" dependencies: agentkeepalive: ^4.2.1 cacache: ^17.0.0 @@ -11469,7 +10995,7 @@ __metadata: promise-retry: ^2.0.1 socks-proxy-agent: ^7.0.0 ssri: ^10.0.0 - checksum: f718d6b6945d967fa02ae8c6b1146c6e36335b0f9654c5757fd57211a5bcc13bf1dfbaa0d2fdfe8bdd13f78b0e2aa79b4d4438f824dcf0d2ea74883baae1ae31 + checksum: bce5bdde6848f45c085bdb8b5f3a04deb284c0478bd8fac9ffc5bb611981f8b94c9496839513593f9a967db14d470452e72cbb3ffc1ddc054d8790ca33ed61eb languageName: node linkType: hard @@ -11744,7 +11270,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^7.4.2": +"minimatch@npm:^7.4.2, minimatch@npm:^7.4.6": version: 7.4.6 resolution: "minimatch@npm:7.4.6" dependencies: @@ -11753,7 +11279,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^8.0.2, minimatch@npm:^8.0.3": +"minimatch@npm:^8.0.2": version: 8.0.4 resolution: "minimatch@npm:8.0.4" dependencies: @@ -11805,8 +11331,8 @@ __metadata: linkType: hard "minipass-fetch@npm:^3.0.0": - version: 3.0.1 - resolution: "minipass-fetch@npm:3.0.1" + version: 3.0.2 + resolution: "minipass-fetch@npm:3.0.2" dependencies: encoding: ^0.1.13 minipass: ^4.0.0 @@ -11815,7 +11341,7 @@ __metadata: dependenciesMeta: encoding: optional: true - checksum: b5eecf462ab8409891e4b8a786260e411304b958e45e10820b0a5d31f7841ccbce5f85e49934a34fdb94501206c273bde1988b9c0ad1625bdfb9883d90285420 + checksum: f86eea7113d82d40a3527143d94b0f06da56d83642477d563a0c462cef1b1955429ffc78330dbc70fbc1bb53692408fdd11233de4b68727b41a3bb6e12b33ada languageName: node linkType: hard @@ -12076,7 +11602,7 @@ __metadata: languageName: node linkType: hard -"nanoid@npm:^3.3.4": +"nanoid@npm:^3.3.6": version: 3.3.6 resolution: "nanoid@npm:3.3.6" bin: @@ -12450,7 +11976,7 @@ __metadata: languageName: node linkType: hard -"npm-registry-fetch@npm:14.0.3, npm-registry-fetch@npm:^14.0.0, npm-registry-fetch@npm:^14.0.3": +"npm-registry-fetch@npm:14.0.3": version: 14.0.3 resolution: "npm-registry-fetch@npm:14.0.3" dependencies: @@ -12480,6 +12006,21 @@ __metadata: languageName: node linkType: hard +"npm-registry-fetch@npm:^14.0.0, npm-registry-fetch@npm:^14.0.3": + version: 14.0.4 + resolution: "npm-registry-fetch@npm:14.0.4" + dependencies: + make-fetch-happen: ^11.0.0 + minipass: ^4.0.0 + minipass-fetch: ^3.0.0 + minipass-json-stream: ^1.0.1 + minizlib: ^2.1.2 + npm-package-arg: ^10.0.0 + proc-log: ^3.0.0 + checksum: 7d6e82f3fe8ce50b7e04490580fa7294e9934025db47e922c8d26c9a6c81374f91dd7e32e3c8fa34089dbd321adb128627f1c02d233714f77b5795140224af49 + languageName: node + linkType: hard + "npm-run-path@npm:^4.0.1": version: 4.0.1 resolution: "npm-run-path@npm:4.0.1" @@ -13141,12 +12682,12 @@ __metadata: linkType: hard "path-scurry@npm:^1.6.1": - version: 1.6.4 - resolution: "path-scurry@npm:1.6.4" + version: 1.7.0 + resolution: "path-scurry@npm:1.7.0" dependencies: lru-cache: ^9.0.0 minipass: ^5.0.0 - checksum: bd5262b51dc35b0d6f0b1d4fa4445789839982bd649904f18fe43717ecc3021d2313a80768b56cd0428f5ca50d740a6c609e747cd6a053efaa802e07eb5b7b18 + checksum: 4e86df0fa6848cef1ba672d4a332b8dbd0297c42d5123bcc419d714c34b25ee6775b0d2e66dd5e698a38e9bcd808f8fc47333e3a3357307cada98e16bfae8b98 languageName: node linkType: hard @@ -13262,13 +12803,13 @@ __metadata: linkType: hard "postcss@npm:^8.4.21": - version: 8.4.21 - resolution: "postcss@npm:8.4.21" + version: 8.4.22 + resolution: "postcss@npm:8.4.22" dependencies: - nanoid: ^3.3.4 + nanoid: ^3.3.6 picocolors: ^1.0.0 source-map-js: ^1.0.2 - checksum: e39ac60ccd1542d4f9d93d894048aac0d686b3bb38e927d8386005718e6793dbbb46930f0a523fe382f1bbd843c6d980aaea791252bf5e176180e5a4336d9679 + checksum: 7473dfb7ac5b4cb03576c39d687d7fc02c826ab08af97df15b5d3970662532d44a18a0994f392a9c3658ee17c292e7a55990e586b90ca0afcc9f36df13e07029 languageName: node linkType: hard @@ -14144,15 +13685,15 @@ __metadata: linkType: hard "resolve@npm:^1.10.0, resolve@npm:^1.14.2, resolve@npm:^1.19.0, resolve@npm:^1.22.1": - version: 1.22.2 - resolution: "resolve@npm:1.22.2" + version: 1.22.3 + resolution: "resolve@npm:1.22.3" dependencies: - is-core-module: ^2.11.0 + is-core-module: ^2.12.0 path-parse: ^1.0.7 supports-preserve-symlinks-flag: ^1.0.0 bin: resolve: bin/resolve - checksum: 7e5df75796ebd429445d102d5824482ee7e567f0070b2b45897b29bb4f613dcbc262e0257b8aeedb3089330ccaea0d6a0464df1a77b2992cf331dcda0f4cb549 + checksum: fb834b81348428cb545ff1b828a72ea28feb5a97c026a1cf40aa1008352c72811ff4d4e71f2035273dc536dcfcae20c13604ba6283c612d70fa0b6e44519c374 languageName: node linkType: hard @@ -14170,15 +13711,15 @@ __metadata: linkType: hard "resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.22.1#~builtin": - version: 1.22.2 - resolution: "resolve@patch:resolve@npm%3A1.22.2#~builtin::version=1.22.2&hash=c3c19d" + version: 1.22.3 + resolution: "resolve@patch:resolve@npm%3A1.22.3#~builtin::version=1.22.3&hash=c3c19d" dependencies: - is-core-module: ^2.11.0 + is-core-module: ^2.12.0 path-parse: ^1.0.7 supports-preserve-symlinks-flag: ^1.0.0 bin: resolve: bin/resolve - checksum: 66cc788f13b8398de18eb4abb3aed90435c84bb8935953feafcf7231ba4cd191b2c10b4a87b1e9681afc34fb138c705f91f7330ff90bfa36f457e5584076a2b8 + checksum: ad59734723b596d0891321c951592ed9015a77ce84907f89c9d9307dd0c06e11a67906a3e628c4cae143d3e44898603478af0ddeb2bba3f229a9373efe342665 languageName: node linkType: hard @@ -14282,9 +13823,9 @@ __metadata: languageName: node linkType: hard -"rollup@npm:^3.18.0": - version: 3.20.2 - resolution: "rollup@npm:3.20.2" +"rollup@npm:^3.18.0, rollup@npm:^3.20.6": + version: 3.20.6 + resolution: "rollup@npm:3.20.6" dependencies: fsevents: ~2.3.2 dependenciesMeta: @@ -14292,21 +13833,7 @@ __metadata: optional: true bin: rollup: dist/bin/rollup - checksum: 34b0932839b7c2a5d1742fb21ce95a47e0b49a0849f4abee2dccf25833187aa7babb898ca90d4fc761cffa4102b9ed0ac6ad7f6f6b96c8b8e2d67305abc5da65 - languageName: node - linkType: hard - -"rollup@npm:^3.20.5": - version: 3.20.5 - resolution: "rollup@npm:3.20.5" - dependencies: - fsevents: ~2.3.2 - dependenciesMeta: - fsevents: - optional: true - bin: - rollup: dist/bin/rollup - checksum: 5f154ea6835bd3700478d399f152237d190eb0ea48d75983f87da5e01f5f624a7264e163e0f2a5d84079d6a5d116c620f0d2bef34f757723406606b7d04fb6a9 + checksum: fa30f1e1d214b8c62e631d3c181a75d61bc9c20fca38220d6f938bb3bf734a874e407cd641c90f550dc2b127df5029dfb3108be08934a654f1f40b50f368b0c2 languageName: node linkType: hard @@ -14531,13 +14058,13 @@ __metadata: linkType: hard "semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8": - version: 7.4.0 - resolution: "semver@npm:7.4.0" + version: 7.5.0 + resolution: "semver@npm:7.5.0" dependencies: lru-cache: ^6.0.0 bin: semver: bin/semver.js - checksum: debf7f4d6fa36fdc5ef82bd7fc3603b6412165c8a3963a30be0c45a587be1a49e7681e80aa109da1875765741af24edc6e021cee1ba16ae96f649d06c5df296d + checksum: 2d266937756689a76f124ffb4c1ea3e1bbb2b263219f90ada8a11aebebe1280b13bb76cca2ca96bdee3dbc554cbc0b24752eb895b2a51577aa644427e9229f2b languageName: node linkType: hard @@ -14680,15 +14207,15 @@ __metadata: linkType: hard "sigstore@npm:^1.0.0": - version: 1.2.0 - resolution: "sigstore@npm:1.2.0" + version: 1.3.0 + resolution: "sigstore@npm:1.3.0" dependencies: "@sigstore/protobuf-specs": ^0.1.0 make-fetch-happen: ^11.0.1 - tuf-js: ^1.0.0 + tuf-js: ^1.1.3 bin: sigstore: bin/sigstore.js - checksum: 8b06341a1bee97f363a8cab62102b27c88714c5ad9743fada5effb46cc3a5935c27c8149669384f0be7040c8f0c4e69bb7d533f138bdcf3aba91b803a69eac77 + checksum: 93c78211c2c7245d7d860589ec37fbd822203674c4065a6970fe0740904fac4c7c44d9870016e923865ef2a897b3d56f91ca6162117c4ea3a1153dac1b4b8402 languageName: node linkType: hard @@ -15492,13 +15019,13 @@ __metadata: languageName: node linkType: hard -"tuf-js@npm:^1.0.0": - version: 1.1.3 - resolution: "tuf-js@npm:1.1.3" +"tuf-js@npm:^1.1.3": + version: 1.1.4 + resolution: "tuf-js@npm:1.1.4" dependencies: - "@tufjs/models": 1.0.2 + "@tufjs/models": 1.0.3 make-fetch-happen: ^11.0.1 - checksum: 87efe13069b681a131e5643f8bc8ee9ac07f8abeaa32096b896d2842416fcd0f8de29ad5e70be22f18d97a7b4723d72dd8b3962bb838312ff6e7d7465ed3489c + checksum: 73595ac6028dd9cf68a65b88730d47ff88f63e836efc2904476939598480d6625745ca43a8f5bb754f667dfd431b81fc81b0e49fc3fdfc2df0cf271536829af9 languageName: node linkType: hard @@ -15814,16 +15341,16 @@ __metadata: linkType: hard "update-browserslist-db@npm:^1.0.10": - version: 1.0.10 - resolution: "update-browserslist-db@npm:1.0.10" + version: 1.0.11 + resolution: "update-browserslist-db@npm:1.0.11" dependencies: escalade: ^3.1.1 picocolors: ^1.0.0 peerDependencies: browserslist: ">= 4.21.0" bin: - browserslist-lint: cli.js - checksum: 12db73b4f63029ac407b153732e7cd69a1ea8206c9100b482b7d12859cd3cd0bc59c602d7ae31e652706189f1acb90d42c53ab24a5ba563ed13aebdddc5561a0 + update-browserslist-db: cli.js + checksum: b98327518f9a345c7cad5437afae4d2ae7d865f9779554baf2a200fdf4bac4969076b679b1115434bd6557376bdd37ca7583d0f9b8f8e302d7d4cc1e91b5f231 languageName: node linkType: hard @@ -15992,9 +15519,9 @@ __metadata: languageName: node linkType: hard -"vite@npm:^4.2.1": - version: 4.2.1 - resolution: "vite@npm:4.2.1" +"vite@npm:^4.2.2": + version: 4.2.2 + resolution: "vite@npm:4.2.2" dependencies: esbuild: ^0.17.5 fsevents: ~2.3.2 @@ -16026,7 +15553,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 70eb162ffc299017a3c310e3adc95e9661def6b17aafd1f8e5e02e516766060435590dbe3df1e4e95acc3583c728a76e91f07c546221d1e701f1b2b021293f45 + checksum: 7fff9d046f6091c02e030aa5f45e68939b9bec1dd15d4e2c3c084d82ec185300295f3db26f537daf2e19f9ad191be260bf70e5fe0e2d9054f174a7ad457623f8 languageName: node linkType: hard @@ -16346,7 +15873,7 @@ __metadata: languageName: node linkType: hard -"web3@npm:^1.8.2": +"web3@npm:^1.9.0": version: 1.9.0 resolution: "web3@npm:1.9.0" dependencies: @@ -16844,7 +16371,7 @@ __metadata: languageName: node linkType: hard -"zustand@npm:^4.0.0-rc.0, zustand@npm:^4.3.7": +"zustand@npm:^4.3.7": version: 4.3.7 resolution: "zustand@npm:4.3.7" dependencies: