From f329b3cd7b8744540d763535868852ce4481cfcb Mon Sep 17 00:00:00 2001 From: Addminus Date: Tue, 21 Mar 2023 15:20:44 +0100 Subject: [PATCH 01/32] refactor: remove web3-react --- .../src/LiFiWalletManagement.ts | 255 ++++++----- .../src/connectors/injectedConnector.ts | 150 +++++++ .../src/connectors/tallyho.ts | 406 +++++++++--------- .../src/priorityConnector.ts | 33 -- packages/wallet-management/src/types/index.ts | 21 + .../wallet-management/src/walletAutomation.ts | 69 +-- .../wallet-management/src/walletProviders.ts | 150 +++---- .../src/providers/WalletProvider.tsx | 37 +- packages/widget-playground/src/App.tsx | 11 +- .../src/providers/WalletProvider.tsx | 38 +- .../SelectWalletPage/SelectWalletPage.tsx | 2 +- .../WalletProvider/WalletProvider.tsx | 135 ++++-- .../src/providers/WalletProvider/types.ts | 2 +- 13 files changed, 740 insertions(+), 569 deletions(-) create mode 100644 packages/wallet-management/src/connectors/injectedConnector.ts delete mode 100644 packages/wallet-management/src/priorityConnector.ts create mode 100644 packages/wallet-management/src/types/index.ts diff --git a/packages/wallet-management/src/LiFiWalletManagement.ts b/packages/wallet-management/src/LiFiWalletManagement.ts index 0061d5832..425c99805 100644 --- a/packages/wallet-management/src/LiFiWalletManagement.ts +++ b/packages/wallet-management/src/LiFiWalletManagement.ts @@ -1,130 +1,163 @@ -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 { addToActiveWallets, addToDeactivatedWallets, - isWalletDeactivated, + // 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(); +export class LiFiWalletManagement { + connectedWallets: Wallet[] = []; - const flushCurrentWalletData = () => { - setCurrentConnector(undefined); - // setCurrentProvider(undefined); - setSigner(undefined); + connect = async (wallet: Wallet) => { + try { + await wallet.connector.activate(); + this.connectedWallets.push(wallet); // TODO: add new wallet as first element + removeFromDeactivatedWallets(wallet.connector.account?.address); + addToActiveWallets(wallet.connector.account?.address); + } catch (e) { + throw e; + } }; - // 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?.()); - } + disconnect = async (wallet: Wallet) => { + const selectedAddress = wallet.connector.account?.address; + removeFromActiveWallets(selectedAddress); + addToDeactivatedWallets(selectedAddress); + + wallet.connector.deactivate(); }; +} - 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); - } - const selectedAddress = getInjectedAddress(wallet); - removeFromDeactivatedWallets(selectedAddress); - addToActiveWallets(selectedAddress); - }, - [calcWalletData, priorityConnector], - ); +// 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 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], - ); +// const flushCurrentWalletData = () => { +// setCurrentConnector(undefined); +// // setCurrentProvider(undefined); +// setSigner(undefined); +// }; - // 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, - ]); +// // 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?.()); +// } +// }; - // 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(); - } - }; +// // 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); +// // } +// // const selectedAddress = getInjectedAddress(wallet); +// // removeFromDeactivatedWallets(selectedAddress); +// // addToActiveWallets(selectedAddress); +// // }, +// // [calcWalletData, priorityConnector], +// // ); - ethereum?.on('chainChanged', handleChainChanged); - ethereum?.on('accountsChanged', handleAccountsChanged); +// const connect = useCallback(async (wallet?: Wallet) => { +// console.log('in new connect function'); +// wallet = undefined; +// try { +// if (wallet) { +// console.log(wallet); +// } else { +// const metaMask = supportedWallets.find( +// (wallet) => wallet.name === 'MetaMask', +// ); +// await metaMask?.connector?.activate(); +// console.log(metaMask?.connector); +// } +// } catch (e) { +// console.log(e); +// } +// // const selectedAddress = getInjectedAddress(wallet); +// // removeFromDeactivatedWallets(selectedAddress); +// // addToActiveWallets(selectedAddress); +// }, []); - return () => { - if (ethereum?.removeListener) { - ethereum.removeListener('chainChanged', handleChainChanged); - ethereum.removeListener('accountsChanged', handleAccountsChanged); - } - }; - }, [currentConnector]); +// 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(); +// // } +// }, []); - return { - connect, - disconnect, - signer, - provider: signer?.provider, - }; -}; +// // 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, +// }; +// }; diff --git a/packages/wallet-management/src/connectors/injectedConnector.ts b/packages/wallet-management/src/connectors/injectedConnector.ts new file mode 100644 index 000000000..07db2e60a --- /dev/null +++ b/packages/wallet-management/src/connectors/injectedConnector.ts @@ -0,0 +1,150 @@ +import type { Token } from '@lifi/sdk'; +import type { Signer } from 'ethers'; +import { ethers } from 'ethers'; +import type { Provider, ProviderConnectInfo, ProviderRpcError } from '../types'; +import { + addChain, + switchChain, + switchChainAndAddToken, +} from '../walletAutomation'; + +export interface AccountData { + chainId: number; + address: string; + signer: Signer; + provider: ethers.providers.Web3Provider; +} + +export class InjectedConnector { + private windowProvider: Provider | undefined; + isActivationInProgress: boolean = false; // TODO: check if needed + account: AccountData | undefined; + + constructor(connectorWindowProperty = 'ethereum') { + this.initializeProvider(connectorWindowProperty); + } + + private initializeProvider(connectorWindowProperty: string) { + if (!window[connectorWindowProperty as any]) { + throw new Error( + `window.${connectorWindowProperty} is not a valid connector`, + ); + } + this.windowProvider = window[ + connectorWindowProperty as any + ] as unknown as Provider; + this.windowProvider?.on( + 'connect', + async ({ chainId }: ProviderConnectInfo): Promise => { + console.log('on connect'); + await this.calcAccountData(); + }, + ); + this.windowProvider?.on( + 'disconnect', + async (error: ProviderRpcError): Promise => { + console.log('on disconnect'); + await this.calcAccountData(); + }, + ); + this.windowProvider?.on( + 'chainChanged', + async (chainId: string): Promise => { + console.log('on chainChanged'); + await this.calcAccountData(); + }, + ); + this.windowProvider?.on( + 'accountsChanged', + async (accounts: string[]): Promise => { + console.log('on accountsChanged'); + if (!accounts.length) { + this.account = undefined; + } + await this.calcAccountData(); + }, + ); + } + + public async activate() { + 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 deactivate(): 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, + }; + } +} diff --git a/packages/wallet-management/src/connectors/tallyho.ts b/packages/wallet-management/src/connectors/tallyho.ts index 49b8bb518..8db35351e 100644 --- a/packages/wallet-management/src/connectors/tallyho.ts +++ b/packages/wallet-management/src/connectors/tallyho.ts @@ -1,203 +1,203 @@ -/* 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 }; -}; +// /* 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/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..b15394413 --- /dev/null +++ b/packages/wallet-management/src/types/index.ts @@ -0,0 +1,21 @@ +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?: any[]; + chainId?: any; +} diff --git a/packages/wallet-management/src/walletAutomation.ts b/packages/wallet-management/src/walletAutomation.ts index 7beffee84..aaef6c9bb 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,21 @@ 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); + await switchChain(provider, chainId); provider.once('chainChanged', async (id: string) => { if (parseInt(id, 10) === chainId) { - await addToken(token); + await addToken(provider, token); } }); } else { - await addToken(token); + await addToken(provider, token); } }; diff --git a/packages/wallet-management/src/walletProviders.ts b/packages/wallet-management/src/walletProviders.ts index 4a158d38e..a38a806d0 100644 --- a/packages/wallet-management/src/walletProviders.ts +++ b/packages/wallet-management/src/walletProviders.ts @@ -1,21 +1,11 @@ -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 { InjectedConnector } from './connectors/injectedConnector'; import { walletIcons } from './walletIcons'; export interface Wallet { name: string; icon: string; - checkProviderIdentity: (helpers: { - provider: any; - // device: Device; - }) => boolean; - web3react: { - connector: Connector; - hooks: Web3ReactHooks; - }; + installed: (helpers: { provider: any }) => boolean; + connector: InjectedConnector; platforms: string[]; } @@ -52,162 +42,148 @@ export enum ProviderIdentityFlag { const metamask: Wallet = { name: 'MetaMask', - checkProviderIdentity: ({ provider }) => - // Removed for now to allow all kinds of injected wallets to connect using the metamask button as fallback - // !!provider && !!provider[ProviderIdentityFlag.MetaMask], - true, + installed: ({ provider }) => + !!provider && !!provider[ProviderIdentityFlag.MetaMask], icon: walletIcons.metamask, platforms: ['all'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const walletConnect: Wallet = { name: 'Wallet Connect', - checkProviderIdentity: ({ provider }) => true, + installed: ({ provider }) => true, icon: walletIcons.walletConnect, platforms: ['all'], - web3react: createWalletConnectConnector(), + connector: new InjectedConnector(), }; const brave: Wallet = { name: 'Brave', - checkProviderIdentity: ({ provider }) => + installed: ({ provider }) => // eslint-disable-next-line no-underscore-dangle (navigator as any).brave && provider?._web3Ref, icon: walletIcons.brave, platforms: ['all'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const mathWallet: Wallet = { name: 'MathWallet', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.MathWallet], + installed: ({ provider }) => provider?.[ProviderIdentityFlag.MathWallet], icon: walletIcons.mathwallet, platforms: ['all'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const tallyho: Wallet = { name: 'Tally Ho', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.TallyHo], + installed: ({ provider }) => provider?.[ProviderIdentityFlag.TallyHo], icon: walletIcons.tallyho, platforms: ['desktop'], - web3react: createTallyHoConnector(), + connector: new InjectedConnector(), }; const blockWallet: Wallet = { name: 'BlockWallet', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.BlockWallet], + installed: ({ provider }) => provider?.[ProviderIdentityFlag.BlockWallet], icon: walletIcons.blockwallet, platforms: ['desktop'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const binance: Wallet = { name: 'Binance', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.Binance], + installed: ({ provider }) => provider?.[ProviderIdentityFlag.Binance], icon: walletIcons.binance, - platforms: ['desktop'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const coinbase: Wallet = { name: 'Coinbase', - checkProviderIdentity: ({ provider }) => + installed: ({ provider }) => provider?.[ProviderIdentityFlag.Coinbase] || provider?.providers?.[0]?.[ProviderIdentityFlag.CoinbaseExtension], icon: walletIcons.coinbase, platforms: ['all'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const detected: Wallet = { name: 'Detected', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.Detected], + installed: ({ provider }) => provider?.[ProviderIdentityFlag.Detected], icon: walletIcons.detected, platforms: ['all'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const trust: Wallet = { name: 'Trust', - checkProviderIdentity: ({ provider }) => + installed: ({ provider }) => provider?.[ProviderIdentityFlag.Trust] && !provider[ProviderIdentityFlag.TokenPocket], icon: walletIcons.trust, platforms: ['mobile'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const status: Wallet = { name: 'Status', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.Status], + installed: ({ provider }) => provider?.[ProviderIdentityFlag.Status], icon: walletIcons.status, platforms: ['mobile'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const alphawallet: Wallet = { name: 'AlphaWallet', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.AlphaWallet], + installed: ({ provider }) => provider?.[ProviderIdentityFlag.AlphaWallet], icon: walletIcons.alphawallet, platforms: ['mobile'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const atoken: Wallet = { name: 'AToken', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.AToken], + installed: ({ provider }) => provider?.[ProviderIdentityFlag.AToken], icon: walletIcons.atoken, platforms: ['mobile'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const bitpie: Wallet = { name: 'Bitpie', - checkProviderIdentity: () => (window as any).Bitpie, + installed: () => (window as any).Bitpie, icon: walletIcons.bitpie, platforms: ['mobile'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const dcent: Wallet = { name: 'Dcent', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.Dcent], + installed: ({ provider }) => provider?.[ProviderIdentityFlag.Dcent], icon: walletIcons.dcent, platforms: ['mobile'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const frame: Wallet = { name: 'Frame', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.Frame], + installed: ({ provider }) => provider?.[ProviderIdentityFlag.Frame], icon: walletIcons.frame, platforms: ['desktop'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const huobiwallet: Wallet = { name: 'HuobiWallet', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.HuobiWallet], + installed: ({ provider }) => provider?.[ProviderIdentityFlag.HuobiWallet], icon: walletIcons.huobiwallet, platforms: ['mobile'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const hyperpay: Wallet = { @@ -215,100 +191,94 @@ const hyperpay: Wallet = { // 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, + installed: () => (window as any).hiWallet, icon: walletIcons.hyperpay, platforms: ['mobile'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const imtoken: Wallet = { name: 'ImToken', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.ImToken], + installed: ({ provider }) => provider?.[ProviderIdentityFlag.ImToken], icon: walletIcons.imtoken, platforms: ['mobile'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const liquality: Wallet = { name: 'Liquality', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.Liquality], + installed: ({ provider }) => provider?.[ProviderIdentityFlag.Liquality], icon: walletIcons.liquality, platforms: ['desktop'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const meetone: Wallet = { name: 'MeetOne', - checkProviderIdentity: ({ provider }) => + installed: ({ provider }) => provider?.[ProviderIdentityFlag.MeetOne] === 'MEETONE', icon: walletIcons.meetone, platforms: ['mobile'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const mykey: Wallet = { name: 'MyKey', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.MyKey], + installed: ({ provider }) => provider?.[ProviderIdentityFlag.MyKey], icon: walletIcons.mykey, platforms: ['mobile'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const ownbit: Wallet = { name: 'OwnBit', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.OwnBit], + installed: ({ provider }) => provider?.[ProviderIdentityFlag.OwnBit], icon: walletIcons.ownbit, platforms: ['mobile'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const tokenpocket: Wallet = { name: 'TokenPocket', - checkProviderIdentity: ({ provider }) => + installed: ({ provider }) => provider?.[ProviderIdentityFlag.TokenPocket] && !provider[ProviderIdentityFlag.TP], icon: walletIcons.tokenpocket, platforms: ['all'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const tp: Wallet = { name: 'TP', - checkProviderIdentity: ({ provider }) => provider?.[ProviderIdentityFlag.TP], + installed: ({ provider }) => provider?.[ProviderIdentityFlag.TP], icon: walletIcons.tp, platforms: ['mobile'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const xdefi: Wallet = { name: 'XDEFI', // eslint-disable-next-line dot-notation - checkProviderIdentity: ({ provider }) => true, + installed: ({ provider }) => true, icon: walletIcons.xdefi, platforms: ['all'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const oneInch: Wallet = { name: 'OneInch', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.OneInch], + installed: ({ provider }) => provider?.[ProviderIdentityFlag.OneInch], icon: walletIcons.oneInch, platforms: ['mobile'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; const tokenary: Wallet = { name: 'Tokenary', - checkProviderIdentity: ({ provider }) => - provider?.[ProviderIdentityFlag.Tokenary], + installed: ({ provider }) => provider?.[ProviderIdentityFlag.Tokenary], icon: walletIcons.tokenary, platforms: ['mobile'], - web3react: createMetamaskConnector(), + connector: new InjectedConnector(), }; export const supportedWallets = [ diff --git a/packages/widget-embedded/src/providers/WalletProvider.tsx b/packages/widget-embedded/src/providers/WalletProvider.tsx index 7d86dedb7..c205f485e 100644 --- a/packages/widget-embedded/src/providers/WalletProvider.tsx +++ b/packages/widget-embedded/src/providers/WalletProvider.tsx @@ -1,11 +1,11 @@ import type { Signer } from '@ethersproject/abstract-signer'; import type { Token } from '@lifi/sdk'; import type { Wallet } from '@lifi/wallet-management'; +import { LiFiWalletManagement } from '@lifi/wallet-management'; import { addChain as walletAddChain, switchChain as walletSwitchChain, switchChainAndAddToken, - useLiFiWalletManagement, } from '@lifi/wallet-management'; import type { WalletAccount, WalletContextProps } from '@lifi/widget/providers'; import type { FC, PropsWithChildren } from 'react'; @@ -36,27 +36,25 @@ 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 connect = useCallback(async (wallet: Wallet) => { + await liFiWalletManagement.connect(wallet); + setCurrentWallet(wallet); + }, []); + const disconnect = useCallback(async () => { - await walletManagementDisconnect(); - }, [walletManagementDisconnect]); + if (currentWallet) { + await liFiWalletManagement.disconnect(currentWallet); + } + setCurrentWallet(undefined); + }, [currentWallet]); // only for injected wallets const switchChain = useCallback(async (chainId: number) => { @@ -74,11 +72,14 @@ export const WalletProvider: FC> = ({ children }) => { // keep account information up to date useEffect(() => { const updateAccount = async () => { - const account = await extractAccountFromSigner(signer); + let account; + account = await extractAccountFromSigner( + currentWallet?.connector.account?.signer, + ); setAccount(account); }; updateAccount(); - }, [signer]); + }, [account.signer, currentWallet]); const value = useMemo( () => ({ diff --git a/packages/widget-playground/src/App.tsx b/packages/widget-playground/src/App.tsx index c5beec3fd..417a1e8f6 100644 --- a/packages/widget-playground/src/App.tsx +++ b/packages/widget-playground/src/App.tsx @@ -1,6 +1,7 @@ import type { Token } from '@lifi/sdk'; import { addChain, + supportedWallets, switchChain, switchChainAndAddToken, } from '@lifi/wallet-management'; @@ -126,11 +127,17 @@ export const App = () => { walletManagement: { signer: account.signer, connect: async () => { - await connect(); + const metamask = supportedWallets.find( + (wallet) => wallet.name === 'MetaMask', + ); + await connect(metamask); return account.signer!; }, disconnect: async () => { - disconnect(); + const metamask = supportedWallets.find( + (wallet) => wallet.name === 'MetaMask', + ); + disconnect(metamask); }, switchChain: async (reqChainId: number) => { await switchChain(reqChainId); diff --git a/packages/widget-playground/src/providers/WalletProvider.tsx b/packages/widget-playground/src/providers/WalletProvider.tsx index 7d86dedb7..05efee40d 100644 --- a/packages/widget-playground/src/providers/WalletProvider.tsx +++ b/packages/widget-playground/src/providers/WalletProvider.tsx @@ -1,11 +1,11 @@ import type { Signer } from '@ethersproject/abstract-signer'; import type { Token } from '@lifi/sdk'; import type { Wallet } from '@lifi/wallet-management'; +import { LiFiWalletManagement } from '@lifi/wallet-management'; import { addChain as walletAddChain, switchChain as walletSwitchChain, switchChainAndAddToken, - useLiFiWalletManagement, } from '@lifi/wallet-management'; import type { WalletAccount, WalletContextProps } from '@lifi/widget/providers'; import type { FC, PropsWithChildren } from 'react'; @@ -36,27 +36,21 @@ 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 connect = useCallback(async (wallet: Wallet) => { + await liFiWalletManagement.connect(wallet); + }, []); + + const disconnect = useCallback(async (wallet?: Wallet) => { + await liFiWalletManagement.disconnect(wallet!); + }, []); // only for injected wallets const switchChain = useCallback(async (chainId: number) => { @@ -74,11 +68,17 @@ export const WalletProvider: FC> = ({ children }) => { // keep account information up to date useEffect(() => { const updateAccount = async () => { - const account = await extractAccountFromSigner(signer); + const account = await extractAccountFromSigner( + currentWallet?.connector.account?.signer, + ); setAccount(account); }; + updateAccount(); - }, [signer]); + }, [ + currentWallet?.connector?.account?.chainId, + currentWallet?.connector.account?.signer, + ]); const value = useMemo( () => ({ diff --git a/packages/widget/src/pages/SelectWalletPage/SelectWalletPage.tsx b/packages/widget/src/pages/SelectWalletPage/SelectWalletPage.tsx index f034753e0..8c3b7dee6 100644 --- a/packages/widget/src/pages/SelectWalletPage/SelectWalletPage.tsx +++ b/packages/widget/src/pages/SelectWalletPage/SelectWalletPage.tsx @@ -37,7 +37,7 @@ export const SelectWalletPage = () => { const handleConnect = useCallback( async (wallet: Wallet) => { const { ethereum } = window as any; - const identityCheckPassed = wallet.checkProviderIdentity({ + const identityCheckPassed = wallet.installed({ provider: ethereum, }); if (!identityCheckPassed) { diff --git a/packages/widget/src/providers/WalletProvider/WalletProvider.tsx b/packages/widget/src/providers/WalletProvider/WalletProvider.tsx index 5cf4f6ebf..96194be7f 100644 --- a/packages/widget/src/providers/WalletProvider/WalletProvider.tsx +++ b/packages/widget/src/providers/WalletProvider/WalletProvider.tsx @@ -1,12 +1,8 @@ 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 { FC, PropsWithChildren } from 'react'; import { createContext, @@ -38,27 +34,49 @@ const WalletContext = createContext(initialContext); export const useWallet = (): WalletContextProps => useContext(WalletContext); +const liFiWalletManagement = new LiFiWalletManagement(); + export const WalletProvider: FC = ({ children }) => { const { walletManagement } = useWidgetConfig(); - const { - connect: walletManagementConnect, - disconnect: walletManagementDisconnect, - signer, - provider, - } = useLiFiWalletManagement(); const [account, setAccount] = useState({}); + const [currentWallet, setCurrentWallet] = useState( + liFiWalletManagement.connectedWallets[0], + ); + const testCurrentWallet = + liFiWalletManagement.connectedWallets[0] || undefined; + console.log(testCurrentWallet); + + useEffect(() => { + const sync = async () => { + const account = await extractAccountFromSigner( + liFiWalletManagement.connectedWallets[0].connector.account?.signer, + ); + setAccount(account); + }; + sync(); + }, [ + liFiWalletManagement.connectedWallets[0]?.connector.account?.address, + liFiWalletManagement.connectedWallets[0]?.connector.account?.chainId, + liFiWalletManagement.connectedWallets[0]?.connector.account?.signer, + ]); 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); + const activeWallet = liFiWalletManagement.connectedWallets[0]; + setCurrentWallet(activeWallet); + const account = await extractAccountFromSigner( + activeWallet.connector.account?.signer, + ); + setAccount(account); }, - [walletManagement, walletManagementConnect], + [walletManagement], ); const disconnect = useCallback(async () => { @@ -67,10 +85,13 @@ export const WalletProvider: FC = ({ children }) => { setAccount({}); return; } - await walletManagementDisconnect(); - }, [walletManagement, walletManagementDisconnect]); + if (currentWallet) { + await liFiWalletManagement.disconnect(currentWallet); + setCurrentWallet(undefined); + setAccount({} as WalletAccount); + } + }, [walletManagement, currentWallet]); - // only for injected wallets const switchChain = useCallback( async (chainId: number) => { if (walletManagement?.switchChain) { @@ -79,9 +100,19 @@ export const WalletProvider: FC = ({ children }) => { setAccount(account); return true; } - return walletSwitchChain(chainId); + try { + await currentWallet?.connector.switchChain(chainId); + setCurrentWallet(() => currentWallet); + const account = await extractAccountFromSigner( + currentWallet?.connector.account?.signer, + ); + setAccount(account); + return true; + } catch { + return false; + } }, - [walletManagement], + [walletManagement, currentWallet], ); const addChain = useCallback( @@ -89,9 +120,19 @@ export const WalletProvider: FC = ({ children }) => { if (walletManagement?.addChain) { return walletManagement.addChain(chainId); } - return walletAddChain(chainId); + try { + await currentWallet?.connector.addChain(chainId); + setCurrentWallet(() => currentWallet); + const account = await extractAccountFromSigner( + currentWallet?.connector.account?.signer, + ); + setAccount(account); + return true; + } catch { + return false; + } }, - [walletManagement], + [walletManagement, currentWallet], ); const addToken = useCallback( @@ -99,25 +140,33 @@ export const WalletProvider: FC = ({ children }) => { if (walletManagement?.addToken) { return walletManagement.addToken(token, chainId); } - return switchChainAndAddToken(chainId, token); + await currentWallet?.connector.addToken(chainId, token); + setCurrentWallet(() => currentWallet); + const account = await extractAccountFromSigner( + currentWallet?.connector.account?.signer, + ); + setAccount(account); + return; }, - [walletManagement], + [walletManagement, currentWallet], ); - // keep account information up to date - useEffect(() => { - const updateAccount = async () => { - let account; - if (walletManagement) { - account = await extractAccountFromSigner(walletManagement?.signer); - } else { - account = await extractAccountFromSigner(signer); - } + // // keep account information up to date + // useEffect(() => { + // const updateAccount = async () => { + // let account; + // if (walletManagement) { + // account = await extractAccountFromSigner(walletManagement?.signer); + // } else { + // account = await extractAccountFromSigner( + // currentWallet?.connector.account?.signer, + // ); + // } - setAccount(account); - }; - updateAccount(); - }, [signer, walletManagement]); + // setAccount(account); + // }; + // updateAccount(); + // }, [walletManagement, currentWallet]); const value = useMemo( () => ({ @@ -127,9 +176,17 @@ export const WalletProvider: FC = ({ children }) => { addChain, addToken, account, - provider, + provider: currentWallet?.connector.account?.provider || undefined, }), - [account, addChain, addToken, connect, disconnect, provider, switchChain], + [ + account, + addChain, + addToken, + connect, + disconnect, + currentWallet, + switchChain, + ], ); return ( 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; } From 00c661eec91bfce9bd8d41e7b7cd4bb473e179b5 Mon Sep 17 00:00:00 2001 From: Addminus Date: Tue, 21 Mar 2023 17:10:16 +0100 Subject: [PATCH 02/32] refactor: external change propagation --- .../src/LiFiWalletManagement.ts | 21 +- .../src/connectors/injectedConnector.ts | 43 ++-- packages/wallet-management/src/types/index.ts | 61 +++++ .../wallet-management/src/walletAutomation.ts | 24 +- .../wallet-management/src/walletProviders.ts | 222 +++++------------- .../WalletProvider/WalletProvider.tsx | 62 ++--- 6 files changed, 199 insertions(+), 234 deletions(-) diff --git a/packages/wallet-management/src/LiFiWalletManagement.ts b/packages/wallet-management/src/LiFiWalletManagement.ts index 425c99805..5ca192042 100644 --- a/packages/wallet-management/src/LiFiWalletManagement.ts +++ b/packages/wallet-management/src/LiFiWalletManagement.ts @@ -1,3 +1,5 @@ +import events from 'events'; +import type { Wallet } from './types'; import { addToActiveWallets, addToDeactivatedWallets, @@ -5,29 +7,34 @@ import { removeFromActiveWallets, removeFromDeactivatedWallets, } from './walletPersistance'; -import type { Wallet } from './walletProviders'; -export class LiFiWalletManagement { +export class LiFiWalletManagement extends events.EventEmitter { connectedWallets: Wallet[] = []; connect = async (wallet: Wallet) => { try { - await wallet.connector.activate(); + await wallet.connect(); + wallet.addListener('walletAccountChanged', this.handleAccountDataChange); this.connectedWallets.push(wallet); // TODO: add new wallet as first element - removeFromDeactivatedWallets(wallet.connector.account?.address); - addToActiveWallets(wallet.connector.account?.address); + removeFromDeactivatedWallets(wallet.account?.address); + addToActiveWallets(wallet.account?.address); } catch (e) { throw e; } }; disconnect = async (wallet: Wallet) => { - const selectedAddress = wallet.connector.account?.address; + const selectedAddress = wallet.account?.address; + wallet.removeAllListeners(); removeFromActiveWallets(selectedAddress); addToDeactivatedWallets(selectedAddress); - wallet.connector.deactivate(); + wallet.disconnect(); }; + + private handleAccountDataChange() { + this.emit('walletChanged', this.connectedWallets); + } } // export const useLiFiWalletManagement = () => { diff --git a/packages/wallet-management/src/connectors/injectedConnector.ts b/packages/wallet-management/src/connectors/injectedConnector.ts index 07db2e60a..3befee600 100644 --- a/packages/wallet-management/src/connectors/injectedConnector.ts +++ b/packages/wallet-management/src/connectors/injectedConnector.ts @@ -1,27 +1,37 @@ import type { Token } from '@lifi/sdk'; -import type { Signer } from 'ethers'; import { ethers } from 'ethers'; -import type { Provider, ProviderConnectInfo, ProviderRpcError } from '../types'; +import events from 'events'; +import type { + AccountData, + InjectedConnectorConstructorArgs, + Provider, + ProviderConnectInfo, + ProviderRpcError, + Wallet, +} from '../types'; import { addChain, switchChain, switchChainAndAddToken, } from '../walletAutomation'; -export interface AccountData { - chainId: number; - address: string; - signer: Signer; - provider: ethers.providers.Web3Provider; -} - -export class InjectedConnector { +export class InjectedConnector extends events.EventEmitter implements Wallet { private windowProvider: Provider | undefined; - isActivationInProgress: boolean = false; // TODO: check if needed - account: AccountData | undefined; - - constructor(connectorWindowProperty = 'ethereum') { + public isActivationInProgress: boolean = false; + public account: AccountData | undefined; + public name: string; + public icon: string; + public installed: (helpers: { provider: any }) => boolean; + + constructor( + constructorArgs: InjectedConnectorConstructorArgs, + connectorWindowProperty = 'ethereum', + ) { + super(); this.initializeProvider(connectorWindowProperty); + this.name = constructorArgs.name; + this.icon = constructorArgs.icon; + this.installed = constructorArgs.installed; } private initializeProvider(connectorWindowProperty: string) { @@ -66,7 +76,7 @@ export class InjectedConnector { ); } - public async activate() { + public async connect() { if (window === undefined) { throw new Error('window is not defined. This should not have happened.'); } @@ -93,7 +103,7 @@ export class InjectedConnector { this.isActivationInProgress = false; } - public deactivate(): void | Promise { + public disconnect(): void | Promise { this.account = undefined; this.isActivationInProgress = false; } @@ -146,5 +156,6 @@ export class InjectedConnector { signer, provider, }; + this.emit('walletAccountChanged', this); } } diff --git a/packages/wallet-management/src/types/index.ts b/packages/wallet-management/src/types/index.ts index b15394413..148d97e68 100644 --- a/packages/wallet-management/src/types/index.ts +++ b/packages/wallet-management/src/types/index.ts @@ -1,3 +1,8 @@ +import type { Signer } from '@ethersproject/abstract-signer'; +import type { Token } from '@lifi/sdk'; +import type { ethers } from 'ethers'; +import events from 'events'; + import type EventEmitter from 'node:events'; export interface ProviderConnectInfo { @@ -19,3 +24,59 @@ export interface Provider extends EventEmitter { selectedAddress?: any[]; chainId?: any; } + +export interface AccountData { + chainId: number; + address: string; + signer: Signer; + provider: ethers.providers.Web3Provider; +} +export interface InjectedConnectorConstructorArgs { + name: string; + icon: string; + installed: (helpers: { provider: any }) => boolean; +} + +export interface Wallet extends events.EventEmitter { + name: string; + icon: string; + isActivationInProgress: boolean; + account: AccountData | undefined; + installed: (helpers: { provider: any }) => boolean; + connect: () => 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', +} diff --git a/packages/wallet-management/src/walletAutomation.ts b/packages/wallet-management/src/walletAutomation.ts index aaef6c9bb..b6989479b 100644 --- a/packages/wallet-management/src/walletAutomation.ts +++ b/packages/wallet-management/src/walletAutomation.ts @@ -85,14 +85,20 @@ export const switchChainAndAddToken = async ( ) => { const chainIdPrefixed = prefixChainId(chainId); - 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); + 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/walletProviders.ts b/packages/wallet-management/src/walletProviders.ts index a38a806d0..cfdb97ecf 100644 --- a/packages/wallet-management/src/walletProviders.ts +++ b/packages/wallet-management/src/walletProviders.ts @@ -1,289 +1,195 @@ import { InjectedConnector } from './connectors/injectedConnector'; +import type { Wallet } from './types'; +import { ProviderIdentityFlag } from './types'; import { walletIcons } from './walletIcons'; -export interface Wallet { - name: string; - icon: string; - installed: (helpers: { provider: any }) => boolean; - connector: InjectedConnector; - 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 = { +const metamask: Wallet = new InjectedConnector({ name: 'MetaMask', installed: ({ provider }) => !!provider && !!provider[ProviderIdentityFlag.MetaMask], icon: walletIcons.metamask, - platforms: ['all'], - connector: new InjectedConnector(), -}; +}); -const walletConnect: Wallet = { - name: 'Wallet Connect', - installed: ({ provider }) => true, - icon: walletIcons.walletConnect, - platforms: ['all'], - connector: new InjectedConnector(), -}; +// const walletConnect: Wallet = { +// name: 'Wallet Connect', +// installed: ({ provider }) => true, +// icon: walletIcons.walletConnect, +// platforms: ['all'], +// connector: new InjectedConnector(), +// }; -const brave: Wallet = { +const brave: Wallet = new InjectedConnector({ name: 'Brave', installed: ({ provider }) => // eslint-disable-next-line no-underscore-dangle (navigator as any).brave && provider?._web3Ref, icon: walletIcons.brave, - platforms: ['all'], - connector: new InjectedConnector(), -}; +}); -const mathWallet: Wallet = { +const mathWallet: Wallet = new InjectedConnector({ name: 'MathWallet', installed: ({ provider }) => provider?.[ProviderIdentityFlag.MathWallet], icon: walletIcons.mathwallet, - platforms: ['all'], - connector: new InjectedConnector(), -}; +}); -const tallyho: Wallet = { +const tallyho: Wallet = new InjectedConnector({ name: 'Tally Ho', installed: ({ provider }) => provider?.[ProviderIdentityFlag.TallyHo], icon: walletIcons.tallyho, +}); - platforms: ['desktop'], - connector: new InjectedConnector(), -}; - -const blockWallet: Wallet = { +const blockWallet: Wallet = new InjectedConnector({ name: 'BlockWallet', installed: ({ provider }) => provider?.[ProviderIdentityFlag.BlockWallet], icon: walletIcons.blockwallet, +}); - platforms: ['desktop'], - connector: new InjectedConnector(), -}; - -const binance: Wallet = { +const binance: Wallet = new InjectedConnector({ name: 'Binance', installed: ({ provider }) => provider?.[ProviderIdentityFlag.Binance], icon: walletIcons.binance, - platforms: ['desktop'], - connector: new InjectedConnector(), -}; +}); -const coinbase: Wallet = { +const coinbase: Wallet = new InjectedConnector({ name: 'Coinbase', installed: ({ provider }) => provider?.[ProviderIdentityFlag.Coinbase] || provider?.providers?.[0]?.[ProviderIdentityFlag.CoinbaseExtension], icon: walletIcons.coinbase, +}); - platforms: ['all'], - connector: new InjectedConnector(), -}; - -const detected: Wallet = { +const detected: Wallet = new InjectedConnector({ name: 'Detected', installed: ({ provider }) => provider?.[ProviderIdentityFlag.Detected], icon: walletIcons.detected, - platforms: ['all'], - connector: new InjectedConnector(), -}; +}); -const trust: Wallet = { +const trust: Wallet = new InjectedConnector({ name: 'Trust', installed: ({ provider }) => provider?.[ProviderIdentityFlag.Trust] && !provider[ProviderIdentityFlag.TokenPocket], icon: walletIcons.trust, - platforms: ['mobile'], - connector: new InjectedConnector(), -}; +}); -const status: Wallet = { +const status: Wallet = new InjectedConnector({ name: 'Status', installed: ({ provider }) => provider?.[ProviderIdentityFlag.Status], icon: walletIcons.status, - platforms: ['mobile'], - connector: new InjectedConnector(), -}; +}); -const alphawallet: Wallet = { +const alphawallet: Wallet = new InjectedConnector({ name: 'AlphaWallet', installed: ({ provider }) => provider?.[ProviderIdentityFlag.AlphaWallet], icon: walletIcons.alphawallet, - platforms: ['mobile'], - connector: new InjectedConnector(), -}; +}); -const atoken: Wallet = { +const atoken: Wallet = new InjectedConnector({ name: 'AToken', installed: ({ provider }) => provider?.[ProviderIdentityFlag.AToken], icon: walletIcons.atoken, - platforms: ['mobile'], - connector: new InjectedConnector(), -}; +}); -const bitpie: Wallet = { +const bitpie: Wallet = new InjectedConnector({ name: 'Bitpie', installed: () => (window as any).Bitpie, icon: walletIcons.bitpie, - platforms: ['mobile'], - connector: new InjectedConnector(), -}; +}); -const dcent: Wallet = { +const dcent: Wallet = new InjectedConnector({ name: 'Dcent', installed: ({ provider }) => provider?.[ProviderIdentityFlag.Dcent], icon: walletIcons.dcent, - platforms: ['mobile'], - connector: new InjectedConnector(), -}; +}); -const frame: Wallet = { +const frame: Wallet = new InjectedConnector({ name: 'Frame', installed: ({ provider }) => provider?.[ProviderIdentityFlag.Frame], icon: walletIcons.frame, - platforms: ['desktop'], - connector: new InjectedConnector(), -}; +}); -const huobiwallet: Wallet = { +const huobiwallet: Wallet = new InjectedConnector({ name: 'HuobiWallet', installed: ({ provider }) => provider?.[ProviderIdentityFlag.HuobiWallet], icon: walletIcons.huobiwallet, - platforms: ['mobile'], - connector: new InjectedConnector(), -}; +}); -const hyperpay: Wallet = { +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).hiWallet, icon: walletIcons.hyperpay, - platforms: ['mobile'], - connector: new InjectedConnector(), -}; +}); -const imtoken: Wallet = { +const imtoken: Wallet = new InjectedConnector({ name: 'ImToken', installed: ({ provider }) => provider?.[ProviderIdentityFlag.ImToken], icon: walletIcons.imtoken, - platforms: ['mobile'], - connector: new InjectedConnector(), -}; +}); -const liquality: Wallet = { +const liquality: Wallet = new InjectedConnector({ name: 'Liquality', installed: ({ provider }) => provider?.[ProviderIdentityFlag.Liquality], icon: walletIcons.liquality, - platforms: ['desktop'], - connector: new InjectedConnector(), -}; +}); -const meetone: Wallet = { +const meetone: Wallet = new InjectedConnector({ name: 'MeetOne', installed: ({ provider }) => provider?.[ProviderIdentityFlag.MeetOne] === 'MEETONE', icon: walletIcons.meetone, - platforms: ['mobile'], - connector: new InjectedConnector(), -}; +}); -const mykey: Wallet = { +const mykey: Wallet = new InjectedConnector({ name: 'MyKey', installed: ({ provider }) => provider?.[ProviderIdentityFlag.MyKey], icon: walletIcons.mykey, - platforms: ['mobile'], - connector: new InjectedConnector(), -}; +}); -const ownbit: Wallet = { +const ownbit: Wallet = new InjectedConnector({ name: 'OwnBit', installed: ({ provider }) => provider?.[ProviderIdentityFlag.OwnBit], icon: walletIcons.ownbit, - platforms: ['mobile'], - connector: new InjectedConnector(), -}; +}); -const tokenpocket: Wallet = { +const tokenpocket: Wallet = new InjectedConnector({ name: 'TokenPocket', installed: ({ provider }) => provider?.[ProviderIdentityFlag.TokenPocket] && !provider[ProviderIdentityFlag.TP], icon: walletIcons.tokenpocket, - platforms: ['all'], - connector: new InjectedConnector(), -}; +}); -const tp: Wallet = { +const tp: Wallet = new InjectedConnector({ name: 'TP', installed: ({ provider }) => provider?.[ProviderIdentityFlag.TP], icon: walletIcons.tp, - platforms: ['mobile'], - connector: new InjectedConnector(), -}; +}); -const xdefi: Wallet = { +const xdefi: Wallet = new InjectedConnector({ name: 'XDEFI', // eslint-disable-next-line dot-notation installed: ({ provider }) => true, icon: walletIcons.xdefi, - platforms: ['all'], - connector: new InjectedConnector(), -}; +}); -const oneInch: Wallet = { +const oneInch: Wallet = new InjectedConnector({ name: 'OneInch', installed: ({ provider }) => provider?.[ProviderIdentityFlag.OneInch], icon: walletIcons.oneInch, - platforms: ['mobile'], - connector: new InjectedConnector(), -}; +}); -const tokenary: Wallet = { +const tokenary: Wallet = new InjectedConnector({ name: 'Tokenary', installed: ({ provider }) => provider?.[ProviderIdentityFlag.Tokenary], icon: walletIcons.tokenary, - platforms: ['mobile'], - connector: new InjectedConnector(), -}; +}); export const supportedWallets = [ metamask, - walletConnect, + // walletConnect, tallyho, binance, coinbase, diff --git a/packages/widget/src/providers/WalletProvider/WalletProvider.tsx b/packages/widget/src/providers/WalletProvider/WalletProvider.tsx index 96194be7f..eec777dff 100644 --- a/packages/widget/src/providers/WalletProvider/WalletProvider.tsx +++ b/packages/widget/src/providers/WalletProvider/WalletProvider.tsx @@ -1,7 +1,7 @@ import type { Signer } from '@ethersproject/abstract-signer'; import type { Token } from '@lifi/sdk'; -import type { Wallet } from '@lifi/wallet-management'; import { LiFiWalletManagement } from '@lifi/wallet-management'; +import type { Wallet } from '@lifi/wallet-management/types'; import type { FC, PropsWithChildren } from 'react'; import { @@ -15,6 +15,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}>.`, @@ -34,31 +36,18 @@ const WalletContext = createContext(initialContext); export const useWallet = (): WalletContextProps => useContext(WalletContext); -const liFiWalletManagement = new LiFiWalletManagement(); - export const WalletProvider: FC = ({ children }) => { const { walletManagement } = useWidgetConfig(); const [account, setAccount] = useState({}); const [currentWallet, setCurrentWallet] = useState( liFiWalletManagement.connectedWallets[0], ); - const testCurrentWallet = - liFiWalletManagement.connectedWallets[0] || undefined; - console.log(testCurrentWallet); - useEffect(() => { - const sync = async () => { - const account = await extractAccountFromSigner( - liFiWalletManagement.connectedWallets[0].connector.account?.signer, - ); - setAccount(account); - }; - sync(); - }, [ - liFiWalletManagement.connectedWallets[0]?.connector.account?.address, - liFiWalletManagement.connectedWallets[0]?.connector.account?.chainId, - liFiWalletManagement.connectedWallets[0]?.connector.account?.signer, - ]); + const handleWalletUpdate = async (wallet: Wallet) => { + setCurrentWallet(wallet); + const account = await extractAccountFromSigner(wallet.account?.signer); + setAccount(account); + }; const connect = useCallback( async (wallet: Wallet) => { @@ -69,10 +58,11 @@ export const WalletProvider: FC = ({ children }) => { return; } await liFiWalletManagement.connect(wallet); + wallet.addListener('walletAccountChanged', handleWalletUpdate); const activeWallet = liFiWalletManagement.connectedWallets[0]; setCurrentWallet(activeWallet); const account = await extractAccountFromSigner( - activeWallet.connector.account?.signer, + activeWallet.account?.signer, ); setAccount(account); }, @@ -88,6 +78,7 @@ export const WalletProvider: FC = ({ children }) => { if (currentWallet) { await liFiWalletManagement.disconnect(currentWallet); setCurrentWallet(undefined); + currentWallet.removeAllListeners(); setAccount({} as WalletAccount); } }, [walletManagement, currentWallet]); @@ -101,10 +92,10 @@ export const WalletProvider: FC = ({ children }) => { return true; } try { - await currentWallet?.connector.switchChain(chainId); + await currentWallet?.switchChain(chainId); setCurrentWallet(() => currentWallet); const account = await extractAccountFromSigner( - currentWallet?.connector.account?.signer, + currentWallet?.account?.signer, ); setAccount(account); return true; @@ -121,10 +112,10 @@ export const WalletProvider: FC = ({ children }) => { return walletManagement.addChain(chainId); } try { - await currentWallet?.connector.addChain(chainId); + await currentWallet?.addChain(chainId); setCurrentWallet(() => currentWallet); const account = await extractAccountFromSigner( - currentWallet?.connector.account?.signer, + currentWallet?.account?.signer, ); setAccount(account); return true; @@ -140,10 +131,10 @@ export const WalletProvider: FC = ({ children }) => { if (walletManagement?.addToken) { return walletManagement.addToken(token, chainId); } - await currentWallet?.connector.addToken(chainId, token); + await currentWallet?.addToken(chainId, token); setCurrentWallet(() => currentWallet); const account = await extractAccountFromSigner( - currentWallet?.connector.account?.signer, + currentWallet?.account?.signer, ); setAccount(account); return; @@ -151,23 +142,6 @@ export const WalletProvider: FC = ({ children }) => { [walletManagement, currentWallet], ); - // // keep account information up to date - // useEffect(() => { - // const updateAccount = async () => { - // let account; - // if (walletManagement) { - // account = await extractAccountFromSigner(walletManagement?.signer); - // } else { - // account = await extractAccountFromSigner( - // currentWallet?.connector.account?.signer, - // ); - // } - - // setAccount(account); - // }; - // updateAccount(); - // }, [walletManagement, currentWallet]); - const value = useMemo( () => ({ connect, @@ -176,7 +150,7 @@ export const WalletProvider: FC = ({ children }) => { addChain, addToken, account, - provider: currentWallet?.connector.account?.provider || undefined, + provider: currentWallet?.account?.provider || undefined, }), [ account, From 6ca396eed3a9d695c6ac58a284df9b12aa2c52d3 Mon Sep 17 00:00:00 2001 From: Addminus Date: Tue, 21 Mar 2023 17:16:00 +0100 Subject: [PATCH 03/32] fix: external disconnect behavior --- .../src/connectors/injectedConnector.ts | 2 ++ .../WalletProvider/WalletProvider.tsx | 36 ++++++------------- 2 files changed, 12 insertions(+), 26 deletions(-) diff --git a/packages/wallet-management/src/connectors/injectedConnector.ts b/packages/wallet-management/src/connectors/injectedConnector.ts index 3befee600..bbee3e562 100644 --- a/packages/wallet-management/src/connectors/injectedConnector.ts +++ b/packages/wallet-management/src/connectors/injectedConnector.ts @@ -70,6 +70,8 @@ export class InjectedConnector extends events.EventEmitter implements Wallet { console.log('on accountsChanged'); if (!accounts.length) { this.account = undefined; + this.emit('walletAccountChanged', this); + return; } await this.calcAccountData(); }, diff --git a/packages/widget/src/providers/WalletProvider/WalletProvider.tsx b/packages/widget/src/providers/WalletProvider/WalletProvider.tsx index eec777dff..f27883e70 100644 --- a/packages/widget/src/providers/WalletProvider/WalletProvider.tsx +++ b/packages/widget/src/providers/WalletProvider/WalletProvider.tsx @@ -43,9 +43,9 @@ export const WalletProvider: FC = ({ children }) => { liFiWalletManagement.connectedWallets[0], ); - const handleWalletUpdate = async (wallet: Wallet) => { - setCurrentWallet(wallet); - const account = await extractAccountFromSigner(wallet.account?.signer); + const handleWalletUpdate = async (wallet?: Wallet) => { + setCurrentWallet(() => wallet); + const account = await extractAccountFromSigner(wallet?.account?.signer); setAccount(account); }; @@ -59,12 +59,7 @@ export const WalletProvider: FC = ({ children }) => { } await liFiWalletManagement.connect(wallet); wallet.addListener('walletAccountChanged', handleWalletUpdate); - const activeWallet = liFiWalletManagement.connectedWallets[0]; - setCurrentWallet(activeWallet); - const account = await extractAccountFromSigner( - activeWallet.account?.signer, - ); - setAccount(account); + handleWalletUpdate(liFiWalletManagement.connectedWallets[0]); }, [walletManagement], ); @@ -77,9 +72,8 @@ export const WalletProvider: FC = ({ children }) => { } if (currentWallet) { await liFiWalletManagement.disconnect(currentWallet); - setCurrentWallet(undefined); currentWallet.removeAllListeners(); - setAccount({} as WalletAccount); + handleWalletUpdate(undefined); } }, [walletManagement, currentWallet]); @@ -93,11 +87,7 @@ export const WalletProvider: FC = ({ children }) => { } try { await currentWallet?.switchChain(chainId); - setCurrentWallet(() => currentWallet); - const account = await extractAccountFromSigner( - currentWallet?.account?.signer, - ); - setAccount(account); + handleWalletUpdate(currentWallet); return true; } catch { return false; @@ -113,11 +103,8 @@ export const WalletProvider: FC = ({ children }) => { } try { await currentWallet?.addChain(chainId); - setCurrentWallet(() => currentWallet); - const account = await extractAccountFromSigner( - currentWallet?.account?.signer, - ); - setAccount(account); + handleWalletUpdate(currentWallet); + return true; } catch { return false; @@ -132,11 +119,8 @@ export const WalletProvider: FC = ({ children }) => { return walletManagement.addToken(token, chainId); } await currentWallet?.addToken(chainId, token); - setCurrentWallet(() => currentWallet); - const account = await extractAccountFromSigner( - currentWallet?.account?.signer, - ); - setAccount(account); + handleWalletUpdate(currentWallet); + return; }, [walletManagement, currentWallet], From c07c217fc4a47c0ad0e6fc310dbe8ecedb2c847c Mon Sep 17 00:00:00 2001 From: Addminus Date: Tue, 21 Mar 2023 17:19:29 +0100 Subject: [PATCH 04/32] refactor: cleanup unnecessary files --- packages/wallet-management/src/index.ts | 2 +- .../wallet-management/src/walletProviders.ts | 219 ----------- packages/wallet-management/src/wallets.ts | 339 +++++++++++------- 3 files changed, 218 insertions(+), 342 deletions(-) delete mode 100644 packages/wallet-management/src/walletProviders.ts diff --git a/packages/wallet-management/src/index.ts b/packages/wallet-management/src/index.ts index e70cc4e49..8bae84ddb 100644 --- a/packages/wallet-management/src/index.ts +++ b/packages/wallet-management/src/index.ts @@ -1,5 +1,5 @@ export * from './LiFiWalletManagement'; export * from './walletAutomation'; export * from './walletIcons'; -export * from './walletProviders'; +export * from './wallets'; export * from './wallets'; diff --git a/packages/wallet-management/src/walletProviders.ts b/packages/wallet-management/src/walletProviders.ts deleted file mode 100644 index cfdb97ecf..000000000 --- a/packages/wallet-management/src/walletProviders.ts +++ /dev/null @@ -1,219 +0,0 @@ -import { InjectedConnector } from './connectors/injectedConnector'; -import type { Wallet } from './types'; -import { ProviderIdentityFlag } from './types'; -import { walletIcons } from './walletIcons'; - -const metamask: Wallet = new InjectedConnector({ - name: 'MetaMask', - installed: ({ provider }) => - !!provider && !!provider[ProviderIdentityFlag.MetaMask], - icon: walletIcons.metamask, -}); - -// const walletConnect: Wallet = { -// name: 'Wallet Connect', -// installed: ({ provider }) => true, -// icon: walletIcons.walletConnect, -// platforms: ['all'], -// connector: new InjectedConnector(), -// }; - -const brave: Wallet = new InjectedConnector({ - name: 'Brave', - installed: ({ provider }) => - // eslint-disable-next-line no-underscore-dangle - (navigator as any).brave && provider?._web3Ref, - icon: walletIcons.brave, -}); - -const mathWallet: Wallet = new InjectedConnector({ - name: 'MathWallet', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.MathWallet], - icon: walletIcons.mathwallet, -}); - -const tallyho: Wallet = new InjectedConnector({ - name: 'Tally Ho', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.TallyHo], - icon: walletIcons.tallyho, -}); - -const blockWallet: Wallet = new InjectedConnector({ - name: 'BlockWallet', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.BlockWallet], - icon: walletIcons.blockwallet, -}); - -const binance: Wallet = new InjectedConnector({ - name: 'Binance', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.Binance], - icon: walletIcons.binance, -}); - -const coinbase: Wallet = new InjectedConnector({ - name: 'Coinbase', - installed: ({ provider }) => - provider?.[ProviderIdentityFlag.Coinbase] || - provider?.providers?.[0]?.[ProviderIdentityFlag.CoinbaseExtension], - icon: walletIcons.coinbase, -}); - -const detected: Wallet = new InjectedConnector({ - name: 'Detected', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.Detected], - icon: walletIcons.detected, -}); - -const trust: Wallet = new InjectedConnector({ - name: 'Trust', - installed: ({ provider }) => - provider?.[ProviderIdentityFlag.Trust] && - !provider[ProviderIdentityFlag.TokenPocket], - icon: walletIcons.trust, -}); - -const status: Wallet = new InjectedConnector({ - name: 'Status', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.Status], - icon: walletIcons.status, -}); - -const alphawallet: Wallet = new InjectedConnector({ - name: 'AlphaWallet', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.AlphaWallet], - icon: walletIcons.alphawallet, -}); - -const atoken: Wallet = new InjectedConnector({ - name: 'AToken', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.AToken], - icon: walletIcons.atoken, -}); - -const bitpie: Wallet = new InjectedConnector({ - name: 'Bitpie', - installed: () => (window as any).Bitpie, - icon: walletIcons.bitpie, -}); - -const dcent: Wallet = new InjectedConnector({ - name: 'Dcent', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.Dcent], - icon: walletIcons.dcent, -}); - -const frame: Wallet = new InjectedConnector({ - name: 'Frame', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.Frame], - icon: walletIcons.frame, -}); - -const huobiwallet: Wallet = new InjectedConnector({ - name: 'HuobiWallet', - installed: ({ provider }) => provider?.[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).hiWallet, - icon: walletIcons.hyperpay, -}); - -const imtoken: Wallet = new InjectedConnector({ - name: 'ImToken', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.ImToken], - icon: walletIcons.imtoken, -}); - -const liquality: Wallet = new InjectedConnector({ - name: 'Liquality', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.Liquality], - icon: walletIcons.liquality, -}); - -const meetone: Wallet = new InjectedConnector({ - name: 'MeetOne', - installed: ({ provider }) => - provider?.[ProviderIdentityFlag.MeetOne] === 'MEETONE', - icon: walletIcons.meetone, -}); - -const mykey: Wallet = new InjectedConnector({ - name: 'MyKey', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.MyKey], - icon: walletIcons.mykey, -}); - -const ownbit: Wallet = new InjectedConnector({ - name: 'OwnBit', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.OwnBit], - icon: walletIcons.ownbit, -}); - -const tokenpocket: Wallet = new InjectedConnector({ - name: 'TokenPocket', - installed: ({ provider }) => - provider?.[ProviderIdentityFlag.TokenPocket] && - !provider[ProviderIdentityFlag.TP], - icon: walletIcons.tokenpocket, -}); - -const tp: Wallet = new InjectedConnector({ - name: 'TP', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.TP], - icon: walletIcons.tp, -}); - -const xdefi: Wallet = new InjectedConnector({ - name: 'XDEFI', - // eslint-disable-next-line dot-notation - installed: ({ provider }) => true, - icon: walletIcons.xdefi, -}); - -const oneInch: Wallet = new InjectedConnector({ - name: 'OneInch', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.OneInch], - icon: walletIcons.oneInch, -}); - -const tokenary: Wallet = new InjectedConnector({ - name: 'Tokenary', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.Tokenary], - icon: walletIcons.tokenary, -}); - -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..cfdb97ecf 100644 --- a/packages/wallet-management/src/wallets.ts +++ b/packages/wallet-management/src/wallets.ts @@ -1,124 +1,219 @@ +import { InjectedConnector } from './connectors/injectedConnector'; +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, - }, - binance: { - name: 'Binance', - icon: walletIcons.binance, - }, - bitpie: { - name: 'Bitpie', - icon: walletIcons.bitpie, - }, - blockwallet: { - name: 'BlockWallet', - icon: walletIcons.blockwallet, - }, - brave: { - name: 'Brave', - icon: walletIcons.brave, - }, - coinbase: { - name: 'Coinbase', - icon: walletIcons.coinbase, - }, - dcent: { - name: 'Dcent', - icon: walletIcons.dcent, - }, - detected: { - name: 'Detected', - icon: walletIcons.detected, - }, - frame: { - name: 'Frame', - icon: walletIcons.frame, - }, - huobiwallet: { - name: 'HuobiWallet', - icon: walletIcons.huobiwallet, - }, - hyperpay: { - name: 'HyperPay', - icon: walletIcons.hyperpay, - }, - imtoken: { - name: 'ImToken', - icon: walletIcons.imtoken, - }, - liquality: { - name: '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, - }, -}; +const metamask: Wallet = new InjectedConnector({ + name: 'MetaMask', + installed: ({ provider }) => + !!provider && !!provider[ProviderIdentityFlag.MetaMask], + icon: walletIcons.metamask, +}); + +// const walletConnect: Wallet = { +// name: 'Wallet Connect', +// installed: ({ provider }) => true, +// icon: walletIcons.walletConnect, +// platforms: ['all'], +// connector: new InjectedConnector(), +// }; + +const brave: Wallet = new InjectedConnector({ + name: 'Brave', + installed: ({ provider }) => + // eslint-disable-next-line no-underscore-dangle + (navigator as any).brave && provider?._web3Ref, + icon: walletIcons.brave, +}); + +const mathWallet: Wallet = new InjectedConnector({ + name: 'MathWallet', + installed: ({ provider }) => provider?.[ProviderIdentityFlag.MathWallet], + icon: walletIcons.mathwallet, +}); + +const tallyho: Wallet = new InjectedConnector({ + name: 'Tally Ho', + installed: ({ provider }) => provider?.[ProviderIdentityFlag.TallyHo], + icon: walletIcons.tallyho, +}); + +const blockWallet: Wallet = new InjectedConnector({ + name: 'BlockWallet', + installed: ({ provider }) => provider?.[ProviderIdentityFlag.BlockWallet], + icon: walletIcons.blockwallet, +}); + +const binance: Wallet = new InjectedConnector({ + name: 'Binance', + installed: ({ provider }) => provider?.[ProviderIdentityFlag.Binance], + icon: walletIcons.binance, +}); + +const coinbase: Wallet = new InjectedConnector({ + name: 'Coinbase', + installed: ({ provider }) => + provider?.[ProviderIdentityFlag.Coinbase] || + provider?.providers?.[0]?.[ProviderIdentityFlag.CoinbaseExtension], + icon: walletIcons.coinbase, +}); + +const detected: Wallet = new InjectedConnector({ + name: 'Detected', + installed: ({ provider }) => provider?.[ProviderIdentityFlag.Detected], + icon: walletIcons.detected, +}); + +const trust: Wallet = new InjectedConnector({ + name: 'Trust', + installed: ({ provider }) => + provider?.[ProviderIdentityFlag.Trust] && + !provider[ProviderIdentityFlag.TokenPocket], + icon: walletIcons.trust, +}); + +const status: Wallet = new InjectedConnector({ + name: 'Status', + installed: ({ provider }) => provider?.[ProviderIdentityFlag.Status], + icon: walletIcons.status, +}); + +const alphawallet: Wallet = new InjectedConnector({ + name: 'AlphaWallet', + installed: ({ provider }) => provider?.[ProviderIdentityFlag.AlphaWallet], + icon: walletIcons.alphawallet, +}); + +const atoken: Wallet = new InjectedConnector({ + name: 'AToken', + installed: ({ provider }) => provider?.[ProviderIdentityFlag.AToken], + icon: walletIcons.atoken, +}); + +const bitpie: Wallet = new InjectedConnector({ + name: 'Bitpie', + installed: () => (window as any).Bitpie, + icon: walletIcons.bitpie, +}); + +const dcent: Wallet = new InjectedConnector({ + name: 'Dcent', + installed: ({ provider }) => provider?.[ProviderIdentityFlag.Dcent], + icon: walletIcons.dcent, +}); + +const frame: Wallet = new InjectedConnector({ + name: 'Frame', + installed: ({ provider }) => provider?.[ProviderIdentityFlag.Frame], + icon: walletIcons.frame, +}); + +const huobiwallet: Wallet = new InjectedConnector({ + name: 'HuobiWallet', + installed: ({ provider }) => provider?.[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).hiWallet, + icon: walletIcons.hyperpay, +}); + +const imtoken: Wallet = new InjectedConnector({ + name: 'ImToken', + installed: ({ provider }) => provider?.[ProviderIdentityFlag.ImToken], + icon: walletIcons.imtoken, +}); + +const liquality: Wallet = new InjectedConnector({ + name: 'Liquality', + installed: ({ provider }) => provider?.[ProviderIdentityFlag.Liquality], + icon: walletIcons.liquality, +}); + +const meetone: Wallet = new InjectedConnector({ + name: 'MeetOne', + installed: ({ provider }) => + provider?.[ProviderIdentityFlag.MeetOne] === 'MEETONE', + icon: walletIcons.meetone, +}); + +const mykey: Wallet = new InjectedConnector({ + name: 'MyKey', + installed: ({ provider }) => provider?.[ProviderIdentityFlag.MyKey], + icon: walletIcons.mykey, +}); + +const ownbit: Wallet = new InjectedConnector({ + name: 'OwnBit', + installed: ({ provider }) => provider?.[ProviderIdentityFlag.OwnBit], + icon: walletIcons.ownbit, +}); + +const tokenpocket: Wallet = new InjectedConnector({ + name: 'TokenPocket', + installed: ({ provider }) => + provider?.[ProviderIdentityFlag.TokenPocket] && + !provider[ProviderIdentityFlag.TP], + icon: walletIcons.tokenpocket, +}); + +const tp: Wallet = new InjectedConnector({ + name: 'TP', + installed: ({ provider }) => provider?.[ProviderIdentityFlag.TP], + icon: walletIcons.tp, +}); + +const xdefi: Wallet = new InjectedConnector({ + name: 'XDEFI', + // eslint-disable-next-line dot-notation + installed: ({ provider }) => true, + icon: walletIcons.xdefi, +}); + +const oneInch: Wallet = new InjectedConnector({ + name: 'OneInch', + installed: ({ provider }) => provider?.[ProviderIdentityFlag.OneInch], + icon: walletIcons.oneInch, +}); + +const tokenary: Wallet = new InjectedConnector({ + name: 'Tokenary', + installed: ({ provider }) => provider?.[ProviderIdentityFlag.Tokenary], + icon: walletIcons.tokenary, +}); + +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, +]; From bbf58a4ab27e57a21728036deb8eb38b12671304 Mon Sep 17 00:00:00 2001 From: Addminus Date: Tue, 21 Mar 2023 17:19:56 +0100 Subject: [PATCH 05/32] chore: cleanup unused code --- .../wallet-management/src/injectedData.ts | 21 ------------------- 1 file changed, 21 deletions(-) delete mode 100644 packages/wallet-management/src/injectedData.ts 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; -}; From c6987c9d9ec67722839aeee160d59420d7cfdc4c Mon Sep 17 00:00:00 2001 From: Addminus Date: Tue, 21 Mar 2023 17:34:20 +0100 Subject: [PATCH 06/32] feat: add autoConnect --- .../src/LiFiWalletManagement.ts | 150 ++---------------- .../src/connectors/injectedConnector.ts | 24 +++ packages/wallet-management/src/types/index.ts | 3 +- .../WalletProvider/WalletProvider.tsx | 20 ++- 4 files changed, 58 insertions(+), 139 deletions(-) diff --git a/packages/wallet-management/src/LiFiWalletManagement.ts b/packages/wallet-management/src/LiFiWalletManagement.ts index 5ca192042..924a28040 100644 --- a/packages/wallet-management/src/LiFiWalletManagement.ts +++ b/packages/wallet-management/src/LiFiWalletManagement.ts @@ -3,7 +3,6 @@ import type { Wallet } from './types'; import { addToActiveWallets, addToDeactivatedWallets, - // isWalletDeactivated, removeFromActiveWallets, removeFromDeactivatedWallets, } from './walletPersistance'; @@ -11,7 +10,7 @@ import { export class LiFiWalletManagement extends events.EventEmitter { connectedWallets: Wallet[] = []; - connect = async (wallet: Wallet) => { + public connect = async (wallet: Wallet) => { try { await wallet.connect(); wallet.addListener('walletAccountChanged', this.handleAccountDataChange); @@ -23,7 +22,20 @@ export class LiFiWalletManagement extends events.EventEmitter { } }; - disconnect = async (wallet: Wallet) => { + public async autoConnect(wallets: Wallet[]) { + for (const wallet of wallets) { + if (wallet.autoConnect) { + await wallet.autoConnect(); + wallet.addListener( + 'walletAccountChanged', + this.handleAccountDataChange, + ); + this.connectedWallets.push(wallet); // TODO: add new wallet as first element + } + } + } + + public disconnect = async (wallet: Wallet) => { const selectedAddress = wallet.account?.address; wallet.removeAllListeners(); removeFromActiveWallets(selectedAddress); @@ -36,135 +48,3 @@ export class LiFiWalletManagement extends events.EventEmitter { this.emit('walletChanged', this.connectedWallets); } } - -// 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?.()); -// } -// }; - -// // 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); -// // } -// // const selectedAddress = getInjectedAddress(wallet); -// // removeFromDeactivatedWallets(selectedAddress); -// // addToActiveWallets(selectedAddress); -// // }, -// // [calcWalletData, priorityConnector], -// // ); - -// const connect = useCallback(async (wallet?: Wallet) => { -// console.log('in new connect function'); -// wallet = undefined; -// try { -// if (wallet) { -// console.log(wallet); -// } else { -// const metaMask = supportedWallets.find( -// (wallet) => wallet.name === 'MetaMask', -// ); -// await metaMask?.connector?.activate(); -// console.log(metaMask?.connector); -// } -// } catch (e) { -// console.log(e); -// } -// // const selectedAddress = getInjectedAddress(wallet); -// // removeFromDeactivatedWallets(selectedAddress); -// // addToActiveWallets(selectedAddress); -// }, []); - -// 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(); -// // } -// }, []); - -// // 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, -// }; -// }; diff --git a/packages/wallet-management/src/connectors/injectedConnector.ts b/packages/wallet-management/src/connectors/injectedConnector.ts index bbee3e562..17b52715e 100644 --- a/packages/wallet-management/src/connectors/injectedConnector.ts +++ b/packages/wallet-management/src/connectors/injectedConnector.ts @@ -14,6 +14,7 @@ import { switchChain, switchChainAndAddToken, } from '../walletAutomation'; +import { isWalletDeactivated } from '../walletPersistance'; export class InjectedConnector extends events.EventEmitter implements Wallet { private windowProvider: Provider | undefined; @@ -26,6 +27,7 @@ export class InjectedConnector extends events.EventEmitter implements Wallet { constructor( constructorArgs: InjectedConnectorConstructorArgs, connectorWindowProperty = 'ethereum', + autoConnect = false, ) { super(); this.initializeProvider(connectorWindowProperty); @@ -77,6 +79,28 @@ export class InjectedConnector extends events.EventEmitter implements Wallet { }, ); } + 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(selectedAddress?.[0])) { + await this.calcAccountData(); + } + } catch (e) { + throw e; + } + } public async connect() { if (window === undefined) { diff --git a/packages/wallet-management/src/types/index.ts b/packages/wallet-management/src/types/index.ts index 148d97e68..71d3a91d1 100644 --- a/packages/wallet-management/src/types/index.ts +++ b/packages/wallet-management/src/types/index.ts @@ -21,7 +21,7 @@ export interface RequestArguments { export interface Provider extends EventEmitter { request(args: RequestArguments): Promise; - selectedAddress?: any[]; + selectedAddress?: string[]; chainId?: any; } @@ -44,6 +44,7 @@ export interface Wallet extends events.EventEmitter { account: AccountData | undefined; installed: (helpers: { provider: any }) => boolean; connect: () => Promise; + autoConnect?: () => Promise; disconnect: () => void; switchChain: (chainId: number) => Promise; addChain: (chainId: number) => Promise; diff --git a/packages/widget/src/providers/WalletProvider/WalletProvider.tsx b/packages/widget/src/providers/WalletProvider/WalletProvider.tsx index f27883e70..6d267177c 100644 --- a/packages/widget/src/providers/WalletProvider/WalletProvider.tsx +++ b/packages/widget/src/providers/WalletProvider/WalletProvider.tsx @@ -1,14 +1,16 @@ import type { Signer } from '@ethersproject/abstract-signer'; import type { Token } from '@lifi/sdk'; -import { LiFiWalletManagement } from '@lifi/wallet-management'; +import { + LiFiWalletManagement, + supportedWallets, +} from '@lifi/wallet-management'; import type { Wallet } from '@lifi/wallet-management/types'; -import type { FC, PropsWithChildren } from 'react'; +import { FC, PropsWithChildren, useEffect } from 'react'; import { createContext, useCallback, useContext, - useEffect, useMemo, useState, } from 'react'; @@ -43,6 +45,18 @@ export const WalletProvider: FC = ({ children }) => { liFiWalletManagement.connectedWallets[0], ); + useEffect(() => { + const autoConnect = async () => { + const metaMask = supportedWallets.filter( + (wallet) => wallet.name === 'MetaMask', + ); + await liFiWalletManagement.autoConnect(metaMask); + metaMask[0].addListener('walletAccountChanged', handleWalletUpdate); + handleWalletUpdate(metaMask[0]); + }; + autoConnect(); + }, []); + const handleWalletUpdate = async (wallet?: Wallet) => { setCurrentWallet(() => wallet); const account = await extractAccountFromSigner(wallet?.account?.signer); From 77707f3d072b7e4b945699046a1929623f1ea3b2 Mon Sep 17 00:00:00 2001 From: Addminus Date: Wed, 22 Mar 2023 10:29:03 +0100 Subject: [PATCH 07/32] fix: auto connect --- .../src/connectors/injectedConnector.ts | 2 +- packages/wallet-management/src/types/index.ts | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/wallet-management/src/connectors/injectedConnector.ts b/packages/wallet-management/src/connectors/injectedConnector.ts index 17b52715e..504afbc5d 100644 --- a/packages/wallet-management/src/connectors/injectedConnector.ts +++ b/packages/wallet-management/src/connectors/injectedConnector.ts @@ -94,7 +94,7 @@ export class InjectedConnector extends events.EventEmitter implements Wallet { try { const selectedAddress = this.windowProvider.selectedAddress; - if (!isWalletDeactivated(selectedAddress?.[0])) { + if (!isWalletDeactivated(selectedAddress)) { await this.calcAccountData(); } } catch (e) { diff --git a/packages/wallet-management/src/types/index.ts b/packages/wallet-management/src/types/index.ts index 71d3a91d1..ce3622dd4 100644 --- a/packages/wallet-management/src/types/index.ts +++ b/packages/wallet-management/src/types/index.ts @@ -21,7 +21,7 @@ export interface RequestArguments { export interface Provider extends EventEmitter { request(args: RequestArguments): Promise; - selectedAddress?: string[]; + selectedAddress?: string; chainId?: any; } @@ -36,6 +36,14 @@ export interface InjectedConnectorConstructorArgs { icon: string; installed: (helpers: { provider: any }) => boolean; } +export interface WalletConnectConnectorConstructorArgs { + name: string; + icon: string; + installed: (helpers: { provider: any }) => boolean; + rpc: { + [chainId: number]: string; + }; +} export interface Wallet extends events.EventEmitter { name: string; From 597bb98ee3d3855aca69b4da3131a19cf58f78c3 Mon Sep 17 00:00:00 2001 From: Addminus Date: Wed, 22 Mar 2023 11:51:39 +0100 Subject: [PATCH 08/32] fix: walletconnect --- .../src/connectors/injectedConnector.ts | 7 +- .../src/connectors/walletConnect.ts | 105 ------------- .../src/connectors/walletConnectConnector.ts | 145 ++++++++++++++++++ packages/wallet-management/src/wallets.ts | 21 ++- .../WalletProvider/WalletProvider.tsx | 9 +- 5 files changed, 165 insertions(+), 122 deletions(-) delete mode 100644 packages/wallet-management/src/connectors/walletConnect.ts create mode 100644 packages/wallet-management/src/connectors/walletConnectConnector.ts diff --git a/packages/wallet-management/src/connectors/injectedConnector.ts b/packages/wallet-management/src/connectors/injectedConnector.ts index 504afbc5d..24ccfadba 100644 --- a/packages/wallet-management/src/connectors/injectedConnector.ts +++ b/packages/wallet-management/src/connectors/injectedConnector.ts @@ -48,30 +48,27 @@ export class InjectedConnector extends events.EventEmitter implements Wallet { this.windowProvider?.on( 'connect', async ({ chainId }: ProviderConnectInfo): Promise => { - console.log('on connect'); await this.calcAccountData(); }, ); this.windowProvider?.on( 'disconnect', async (error: ProviderRpcError): Promise => { - console.log('on disconnect'); await this.calcAccountData(); }, ); this.windowProvider?.on( 'chainChanged', async (chainId: string): Promise => { - console.log('on chainChanged'); await this.calcAccountData(); }, ); this.windowProvider?.on( 'accountsChanged', async (accounts: string[]): Promise => { - console.log('on accountsChanged'); if (!accounts.length) { this.account = undefined; + this.emit('walletAccountChanged', this); return; } @@ -91,7 +88,6 @@ export class InjectedConnector extends events.EventEmitter implements Wallet { if (this.isActivationInProgress) { return; } - try { const selectedAddress = this.windowProvider.selectedAddress; if (!isWalletDeactivated(selectedAddress)) { @@ -171,6 +167,7 @@ export class InjectedConnector extends events.EventEmitter implements Wallet { if (!this.windowProvider) { throw new Error('provider is not defined.'); } + const provider = new ethers.providers.Web3Provider( this.windowProvider, 'any', 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..79161ca29 --- /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: (helpers: { provider: any }) => 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/wallets.ts b/packages/wallet-management/src/wallets.ts index cfdb97ecf..20ca974a9 100644 --- a/packages/wallet-management/src/wallets.ts +++ b/packages/wallet-management/src/wallets.ts @@ -2,6 +2,8 @@ import { InjectedConnector } from './connectors/injectedConnector'; import type { Wallet } from './types'; import { ProviderIdentityFlag } from './types'; import { walletIcons } from './walletIcons'; +import { WalletConnectConnector } from './connectors/walletConnectConnector'; +import { supportedChains } from '@lifi/sdk'; const metamask: Wallet = new InjectedConnector({ name: 'MetaMask', @@ -10,13 +12,16 @@ const metamask: Wallet = new InjectedConnector({ icon: walletIcons.metamask, }); -// const walletConnect: Wallet = { -// name: 'Wallet Connect', -// installed: ({ provider }) => true, -// icon: walletIcons.walletConnect, -// platforms: ['all'], -// connector: new InjectedConnector(), -// }; +const walletConnect: Wallet = new WalletConnectConnector({ + name: 'Wallet Connect', + installed: ({ provider }) => true, + icon: walletIcons.walletConnect, + rpc: Object.fromEntries( + supportedChains.map((chain) => { + return [chain.id, chain.metamask.rpcUrls[0] || '']; + }), + ), +}); const brave: Wallet = new InjectedConnector({ name: 'Brave', @@ -189,7 +194,7 @@ const tokenary: Wallet = new InjectedConnector({ export const supportedWallets = [ metamask, - // walletConnect, + walletConnect, tallyho, binance, coinbase, diff --git a/packages/widget/src/providers/WalletProvider/WalletProvider.tsx b/packages/widget/src/providers/WalletProvider/WalletProvider.tsx index 6d267177c..0b2aaf63d 100644 --- a/packages/widget/src/providers/WalletProvider/WalletProvider.tsx +++ b/packages/widget/src/providers/WalletProvider/WalletProvider.tsx @@ -51,7 +51,7 @@ export const WalletProvider: FC = ({ children }) => { (wallet) => wallet.name === 'MetaMask', ); await liFiWalletManagement.autoConnect(metaMask); - metaMask[0].addListener('walletAccountChanged', handleWalletUpdate); + metaMask[0].on('walletAccountChanged', handleWalletUpdate); handleWalletUpdate(metaMask[0]); }; autoConnect(); @@ -72,8 +72,9 @@ export const WalletProvider: FC = ({ children }) => { return; } await liFiWalletManagement.connect(wallet); - wallet.addListener('walletAccountChanged', handleWalletUpdate); - handleWalletUpdate(liFiWalletManagement.connectedWallets[0]); + wallet.on('walletAccountChanged', handleWalletUpdate); + + handleWalletUpdate(wallet); }, [walletManagement], ); @@ -175,7 +176,7 @@ export const extractAccountFromSigner = async (signer?: Signer) => { chainId: await signer?.getChainId(), }; } catch (error) { - console.log(error); + console.error(error); return {}; } }; From 2d5ce2796bce01daec79395222b9acfdb498fe64 Mon Sep 17 00:00:00 2001 From: Addminus Date: Wed, 22 Mar 2023 12:23:00 +0100 Subject: [PATCH 09/32] feat: re-enable tally --- packages/wallet-management/src/wallets.ts | 15 ++++++++++----- .../providers/WalletProvider/WalletProvider.tsx | 4 +--- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/packages/wallet-management/src/wallets.ts b/packages/wallet-management/src/wallets.ts index 20ca974a9..16bfd7451 100644 --- a/packages/wallet-management/src/wallets.ts +++ b/packages/wallet-management/src/wallets.ts @@ -37,11 +37,16 @@ const mathWallet: Wallet = new InjectedConnector({ icon: walletIcons.mathwallet, }); -const tallyho: Wallet = new InjectedConnector({ - name: 'Tally Ho', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.TallyHo], - icon: walletIcons.tallyho, -}); +const tallyho: Wallet = new InjectedConnector( + { + name: 'Tally Ho', + installed: ({ provider }) => + (window as any).tally && + (window as any).tally[ProviderIdentityFlag.TallyHo], + icon: walletIcons.tallyho, + }, + 'tally', +); const blockWallet: Wallet = new InjectedConnector({ name: 'BlockWallet', diff --git a/packages/widget/src/providers/WalletProvider/WalletProvider.tsx b/packages/widget/src/providers/WalletProvider/WalletProvider.tsx index 0b2aaf63d..e499cbcce 100644 --- a/packages/widget/src/providers/WalletProvider/WalletProvider.tsx +++ b/packages/widget/src/providers/WalletProvider/WalletProvider.tsx @@ -41,9 +41,7 @@ export const useWallet = (): WalletContextProps => useContext(WalletContext); export const WalletProvider: FC = ({ children }) => { const { walletManagement } = useWidgetConfig(); const [account, setAccount] = useState({}); - const [currentWallet, setCurrentWallet] = useState( - liFiWalletManagement.connectedWallets[0], - ); + const [currentWallet, setCurrentWallet] = useState(); useEffect(() => { const autoConnect = async () => { From b4e8d89e17e0c3806edf41d8e3bf8ab456e93890 Mon Sep 17 00:00:00 2001 From: Addminus Date: Wed, 22 Mar 2023 12:24:00 +0100 Subject: [PATCH 10/32] fix: type export --- packages/wallet-management/src/index.ts | 2 +- packages/widget/src/pages/SelectWalletPage/SelectWalletPage.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/wallet-management/src/index.ts b/packages/wallet-management/src/index.ts index 8bae84ddb..61482bb58 100644 --- a/packages/wallet-management/src/index.ts +++ b/packages/wallet-management/src/index.ts @@ -2,4 +2,4 @@ export * from './LiFiWalletManagement'; export * from './walletAutomation'; export * from './walletIcons'; export * from './wallets'; -export * from './wallets'; +export * from './types'; diff --git a/packages/widget/src/pages/SelectWalletPage/SelectWalletPage.tsx b/packages/widget/src/pages/SelectWalletPage/SelectWalletPage.tsx index 8c3b7dee6..3f0d73856 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, From 4b8d67ef43b9a406af1af8dc3e0c85702303db1a Mon Sep 17 00:00:00 2001 From: Addminus Date: Wed, 22 Mar 2023 12:26:16 +0100 Subject: [PATCH 11/32] fix: type import --- packages/wallet-management/src/types/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wallet-management/src/types/index.ts b/packages/wallet-management/src/types/index.ts index ce3622dd4..16a1c3484 100644 --- a/packages/wallet-management/src/types/index.ts +++ b/packages/wallet-management/src/types/index.ts @@ -1,7 +1,7 @@ import type { Signer } from '@ethersproject/abstract-signer'; import type { Token } from '@lifi/sdk'; import type { ethers } from 'ethers'; -import events from 'events'; +import type events from 'events'; import type EventEmitter from 'node:events'; From f7a5bf8bf2ad4642b941181928621b0c800fb7d9 Mon Sep 17 00:00:00 2001 From: Addminus Date: Wed, 22 Mar 2023 12:27:54 +0100 Subject: [PATCH 12/32] chore: remove unused files --- packages/wallet-management/package.json | 8 -------- 1 file changed, 8 deletions(-) diff --git a/packages/wallet-management/package.json b/packages/wallet-management/package.json index feafbbf19..67a4c3e68 100644 --- a/packages/wallet-management/package.json +++ b/packages/wallet-management/package.json @@ -55,14 +55,6 @@ "@lifi/sdk": "^1.7.2", "@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": { From d0ec46fa9e3aa35a2e794ba0db5197178605d203 Mon Sep 17 00:00:00 2001 From: Addminus Date: Wed, 22 Mar 2023 12:28:07 +0100 Subject: [PATCH 13/32] chore: remove unused files --- .../src/connectors/coinbaseWallet.ts | 12 -- .../src/connectors/eip1193.ts | 68 ------ .../wallet-management/src/connectors/empty.ts | 5 - .../src/connectors/metaMask.ts | 23 -- .../src/connectors/network.ts | 10 - .../src/connectors/tallyho.ts | 203 ------------------ .../wallet-management/src/connectors/url.ts | 10 - 7 files changed, 331 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 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 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/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 8db35351e..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 {}; From 09ec03ed7a8b4815a7b16d6ebcb29741445feffb Mon Sep 17 00:00:00 2001 From: Addminus Date: Wed, 22 Mar 2023 12:31:20 +0100 Subject: [PATCH 14/32] refactor: playground wallet provider --- .../src/providers/WalletProvider.tsx | 97 ++++++++++++------- 1 file changed, 62 insertions(+), 35 deletions(-) diff --git a/packages/widget-playground/src/providers/WalletProvider.tsx b/packages/widget-playground/src/providers/WalletProvider.tsx index 05efee40d..6802b8574 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 { supportedWallets, Wallet } from '@lifi/wallet-management'; import { LiFiWalletManagement } from '@lifi/wallet-management'; -import { - addChain as walletAddChain, - switchChain as walletSwitchChain, - switchChainAndAddToken, -} from '@lifi/wallet-management'; import type { WalletAccount, WalletContextProps } from '@lifi/widget/providers'; import type { FC, PropsWithChildren } from 'react'; import { @@ -40,45 +35,77 @@ const liFiWalletManagement = new LiFiWalletManagement(); export const WalletProvider: FC> = ({ children }) => { const [account, setAccount] = useState({}); - const [currentWallet, setCurrentWallet] = useState( - liFiWalletManagement.connectedWallets[0], - ); + const [currentWallet, setCurrentWallet] = useState(); + + useEffect(() => { + const autoConnect = async () => { + const metaMask = supportedWallets.filter( + (wallet) => wallet.name === 'MetaMask', + ); + await liFiWalletManagement.autoConnect(metaMask); + metaMask[0].on('walletAccountChanged', handleWalletUpdate); + handleWalletUpdate(metaMask[0]); + }; + autoConnect(); + }, []); + + const handleWalletUpdate = async (wallet?: Wallet) => { + setCurrentWallet(() => wallet); + const account = await extractAccountFromSigner(wallet?.account?.signer); + setAccount(account); + }; const connect = useCallback(async (wallet: Wallet) => { await liFiWalletManagement.connect(wallet); - }, []); + wallet.on('walletAccountChanged', handleWalletUpdate); - const disconnect = useCallback(async (wallet?: Wallet) => { - await liFiWalletManagement.disconnect(wallet!); + handleWalletUpdate(wallet); }, []); - // only for injected wallets - const switchChain = useCallback(async (chainId: number) => { - return walletSwitchChain(chainId); - }, []); + const disconnect = useCallback(async () => { + if (currentWallet) { + await liFiWalletManagement.disconnect(currentWallet); + currentWallet.removeAllListeners(); + handleWalletUpdate(undefined); + } + }, [currentWallet]); - const addChain = useCallback(async (chainId: number) => { - return walletAddChain(chainId); - }, []); + const switchChain = useCallback( + async (chainId: number) => { + try { + await currentWallet?.switchChain(chainId); + handleWalletUpdate(currentWallet); + return true; + } catch { + return false; + } + }, + [currentWallet], + ); - const addToken = useCallback(async (chainId: number, token: Token) => { - return switchChainAndAddToken(chainId, token); - }, []); + const addChain = useCallback( + async (chainId: number) => { + try { + await currentWallet?.addChain(chainId); + handleWalletUpdate(currentWallet); - // keep account information up to date - useEffect(() => { - const updateAccount = async () => { - const account = await extractAccountFromSigner( - currentWallet?.connector.account?.signer, - ); - setAccount(account); - }; + return true; + } catch { + return false; + } + }, + [currentWallet], + ); - updateAccount(); - }, [ - currentWallet?.connector?.account?.chainId, - currentWallet?.connector.account?.signer, - ]); + const addToken = useCallback( + async (chainId: number, token: Token) => { + await currentWallet?.addToken(chainId, token); + handleWalletUpdate(currentWallet); + + return; + }, + [currentWallet], + ); const value = useMemo( () => ({ From 631a14e87be9bff94de2838db0baacb041aedc73 Mon Sep 17 00:00:00 2001 From: Addminus Date: Wed, 22 Mar 2023 12:32:12 +0100 Subject: [PATCH 15/32] fix: import --- packages/widget-playground/src/providers/WalletProvider.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/widget-playground/src/providers/WalletProvider.tsx b/packages/widget-playground/src/providers/WalletProvider.tsx index 6802b8574..40bafefb4 100644 --- a/packages/widget-playground/src/providers/WalletProvider.tsx +++ b/packages/widget-playground/src/providers/WalletProvider.tsx @@ -1,6 +1,7 @@ import type { Signer } from '@ethersproject/abstract-signer'; import type { Token } from '@lifi/sdk'; -import { supportedWallets, Wallet } from '@lifi/wallet-management'; +import type { Wallet } from '@lifi/wallet-management'; +import { supportedWallets } from '@lifi/wallet-management'; import { LiFiWalletManagement } from '@lifi/wallet-management'; import type { WalletAccount, WalletContextProps } from '@lifi/widget/providers'; import type { FC, PropsWithChildren } from 'react'; From 495f0ad48083a08099df2f87da2ce0faa160e7a7 Mon Sep 17 00:00:00 2001 From: Addminus Date: Wed, 22 Mar 2023 16:28:34 +0100 Subject: [PATCH 16/32] feat: add frontier --- .../src/connectors/injectedConnector.ts | 16 ++++++---------- packages/wallet-management/src/types/index.ts | 1 + packages/wallet-management/src/wallets.ts | 12 +++++++++++- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/packages/wallet-management/src/connectors/injectedConnector.ts b/packages/wallet-management/src/connectors/injectedConnector.ts index 24ccfadba..15d713108 100644 --- a/packages/wallet-management/src/connectors/injectedConnector.ts +++ b/packages/wallet-management/src/connectors/injectedConnector.ts @@ -26,25 +26,21 @@ export class InjectedConnector extends events.EventEmitter implements Wallet { constructor( constructorArgs: InjectedConnectorConstructorArgs, - connectorWindowProperty = 'ethereum', + windowConnector = (window as any).ethereum as Provider, autoConnect = false, ) { super(); - this.initializeProvider(connectorWindowProperty); + this.initializeProvider(windowConnector); this.name = constructorArgs.name; this.icon = constructorArgs.icon; this.installed = constructorArgs.installed; } - private initializeProvider(connectorWindowProperty: string) { - if (!window[connectorWindowProperty as any]) { - throw new Error( - `window.${connectorWindowProperty} is not a valid connector`, - ); + private initializeProvider(connectorWindowProperty: Provider) { + if (window === undefined) { + throw new Error('window is not defined. This should not have happened.'); } - this.windowProvider = window[ - connectorWindowProperty as any - ] as unknown as Provider; + this.windowProvider = connectorWindowProperty; this.windowProvider?.on( 'connect', async ({ chainId }: ProviderConnectInfo): Promise => { diff --git a/packages/wallet-management/src/types/index.ts b/packages/wallet-management/src/types/index.ts index 16a1c3484..8ccf33346 100644 --- a/packages/wallet-management/src/types/index.ts +++ b/packages/wallet-management/src/types/index.ts @@ -88,4 +88,5 @@ export enum ProviderIdentityFlag { OneInch = 'isOneInchIOSWallet', Tokenary = 'isTokenary', MathWallet = 'isMathWallet', + Frontier = 'isFrontier', } diff --git a/packages/wallet-management/src/wallets.ts b/packages/wallet-management/src/wallets.ts index 16bfd7451..1a4e83516 100644 --- a/packages/wallet-management/src/wallets.ts +++ b/packages/wallet-management/src/wallets.ts @@ -23,6 +23,15 @@ const walletConnect: Wallet = new WalletConnectConnector({ ), }); +const frontier: Wallet = new InjectedConnector( + { + name: 'Frontier', + installed: ({ provider }) => (window as any).frontier, + icon: walletIcons.mathwallet, + }, + (window as any).frontier.ethereum, +); + const brave: Wallet = new InjectedConnector({ name: 'Brave', installed: ({ provider }) => @@ -45,7 +54,7 @@ const tallyho: Wallet = new InjectedConnector( (window as any).tally[ProviderIdentityFlag.TallyHo], icon: walletIcons.tallyho, }, - 'tally', + (window as any).tally, ); const blockWallet: Wallet = new InjectedConnector({ @@ -202,6 +211,7 @@ export const supportedWallets = [ walletConnect, tallyho, binance, + frontier, coinbase, detected, trust, From 50ab8495f9a3f236070f82db92580c1b2de72306 Mon Sep 17 00:00:00 2001 From: Addminus Date: Wed, 22 Mar 2023 16:57:09 +0100 Subject: [PATCH 17/32] feat: frontier logo --- .../src/walletIcons/frontier.svg | 20 +++++ .../src/walletIcons/index.ts | 2 + packages/wallet-management/src/wallets.ts | 73 +++++++++---------- 3 files changed, 58 insertions(+), 37 deletions(-) create mode 100644 packages/wallet-management/src/walletIcons/frontier.svg 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..1e0aeab4c 100644 --- a/packages/wallet-management/src/walletIcons/index.ts +++ b/packages/wallet-management/src/walletIcons/index.ts @@ -28,12 +28,14 @@ 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'; export const walletIcons = { mathwallet, walletConnect, alphawallet, atoken, + frontier, blockwallet, binance, bitpie, diff --git a/packages/wallet-management/src/wallets.ts b/packages/wallet-management/src/wallets.ts index 1a4e83516..16d2a326b 100644 --- a/packages/wallet-management/src/wallets.ts +++ b/packages/wallet-management/src/wallets.ts @@ -7,14 +7,14 @@ import { supportedChains } from '@lifi/sdk'; const metamask: Wallet = new InjectedConnector({ name: 'MetaMask', - installed: ({ provider }) => - !!provider && !!provider[ProviderIdentityFlag.MetaMask], + installed: () => + !!(window as any) && !!(window as any)[ProviderIdentityFlag.MetaMask], icon: walletIcons.metamask, }); const walletConnect: Wallet = new WalletConnectConnector({ name: 'Wallet Connect', - installed: ({ provider }) => true, + installed: () => true, icon: walletIcons.walletConnect, rpc: Object.fromEntries( supportedChains.map((chain) => { @@ -26,30 +26,30 @@ const walletConnect: Wallet = new WalletConnectConnector({ const frontier: Wallet = new InjectedConnector( { name: 'Frontier', - installed: ({ provider }) => (window as any).frontier, - icon: walletIcons.mathwallet, + installed: () => (window as any).frontier, + icon: walletIcons.frontier, }, (window as any).frontier.ethereum, ); const brave: Wallet = new InjectedConnector({ name: 'Brave', - installed: ({ provider }) => + installed: () => // eslint-disable-next-line no-underscore-dangle - (navigator as any).brave && provider?._web3Ref, + (navigator as any).brave && (window as any)._web3Ref, icon: walletIcons.brave, }); const mathWallet: Wallet = new InjectedConnector({ name: 'MathWallet', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.MathWallet], + installed: () => (window as any)[ProviderIdentityFlag.MathWallet], icon: walletIcons.mathwallet, }); const tallyho: Wallet = new InjectedConnector( { name: 'Tally Ho', - installed: ({ provider }) => + installed: () => (window as any).tally && (window as any).tally[ProviderIdentityFlag.TallyHo], icon: walletIcons.tallyho, @@ -59,53 +59,53 @@ const tallyho: Wallet = new InjectedConnector( const blockWallet: Wallet = new InjectedConnector({ name: 'BlockWallet', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.BlockWallet], + installed: () => (window as any)[ProviderIdentityFlag.BlockWallet], icon: walletIcons.blockwallet, }); const binance: Wallet = new InjectedConnector({ name: 'Binance', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.Binance], + installed: () => (window as any)[ProviderIdentityFlag.Binance], icon: walletIcons.binance, }); const coinbase: Wallet = new InjectedConnector({ name: 'Coinbase', - installed: ({ provider }) => - provider?.[ProviderIdentityFlag.Coinbase] || - provider?.providers?.[0]?.[ProviderIdentityFlag.CoinbaseExtension], + installed: () => + (window as any)[ProviderIdentityFlag.Coinbase] || + (window as any).providers?.[0]?.[ProviderIdentityFlag.CoinbaseExtension], icon: walletIcons.coinbase, }); const detected: Wallet = new InjectedConnector({ name: 'Detected', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.Detected], + installed: () => (window as any)[ProviderIdentityFlag.Detected], icon: walletIcons.detected, }); const trust: Wallet = new InjectedConnector({ name: 'Trust', - installed: ({ provider }) => - provider?.[ProviderIdentityFlag.Trust] && - !provider[ProviderIdentityFlag.TokenPocket], + installed: () => + (window as any)[ProviderIdentityFlag.Trust] && + !(window as any)[ProviderIdentityFlag.TokenPocket], icon: walletIcons.trust, }); const status: Wallet = new InjectedConnector({ name: 'Status', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.Status], + installed: () => (window as any)[ProviderIdentityFlag.Status], icon: walletIcons.status, }); const alphawallet: Wallet = new InjectedConnector({ name: 'AlphaWallet', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.AlphaWallet], + installed: () => (window as any)[ProviderIdentityFlag.AlphaWallet], icon: walletIcons.alphawallet, }); const atoken: Wallet = new InjectedConnector({ name: 'AToken', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.AToken], + installed: () => (window as any)[ProviderIdentityFlag.AToken], icon: walletIcons.atoken, }); @@ -117,19 +117,19 @@ const bitpie: Wallet = new InjectedConnector({ const dcent: Wallet = new InjectedConnector({ name: 'Dcent', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.Dcent], + installed: () => (window as any)[ProviderIdentityFlag.Dcent], icon: walletIcons.dcent, }); const frame: Wallet = new InjectedConnector({ name: 'Frame', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.Frame], + installed: () => (window as any)[ProviderIdentityFlag.Frame], icon: walletIcons.frame, }); const huobiwallet: Wallet = new InjectedConnector({ name: 'HuobiWallet', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.HuobiWallet], + installed: () => (window as any)[ProviderIdentityFlag.HuobiWallet], icon: walletIcons.huobiwallet, }); @@ -144,65 +144,64 @@ const hyperpay: Wallet = new InjectedConnector({ const imtoken: Wallet = new InjectedConnector({ name: 'ImToken', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.ImToken], + installed: () => (window as any)[ProviderIdentityFlag.ImToken], icon: walletIcons.imtoken, }); const liquality: Wallet = new InjectedConnector({ name: 'Liquality', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.Liquality], + installed: () => (window as any)[ProviderIdentityFlag.Liquality], icon: walletIcons.liquality, }); const meetone: Wallet = new InjectedConnector({ name: 'MeetOne', - installed: ({ provider }) => - provider?.[ProviderIdentityFlag.MeetOne] === 'MEETONE', + installed: () => (window as any)[ProviderIdentityFlag.MeetOne] === 'MEETONE', icon: walletIcons.meetone, }); const mykey: Wallet = new InjectedConnector({ name: 'MyKey', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.MyKey], + installed: () => (window as any)[ProviderIdentityFlag.MyKey], icon: walletIcons.mykey, }); const ownbit: Wallet = new InjectedConnector({ name: 'OwnBit', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.OwnBit], + installed: () => (window as any)[ProviderIdentityFlag.OwnBit], icon: walletIcons.ownbit, }); const tokenpocket: Wallet = new InjectedConnector({ name: 'TokenPocket', - installed: ({ provider }) => - provider?.[ProviderIdentityFlag.TokenPocket] && - !provider[ProviderIdentityFlag.TP], + installed: () => + (window as any)[ProviderIdentityFlag.TokenPocket] && + !(window as any)[ProviderIdentityFlag.TP], icon: walletIcons.tokenpocket, }); const tp: Wallet = new InjectedConnector({ name: 'TP', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.TP], + installed: () => (window as any)[ProviderIdentityFlag.TP], icon: walletIcons.tp, }); const xdefi: Wallet = new InjectedConnector({ name: 'XDEFI', // eslint-disable-next-line dot-notation - installed: ({ provider }) => true, + installed: () => true, icon: walletIcons.xdefi, }); const oneInch: Wallet = new InjectedConnector({ name: 'OneInch', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.OneInch], + installed: () => (window as any)[ProviderIdentityFlag.OneInch], icon: walletIcons.oneInch, }); const tokenary: Wallet = new InjectedConnector({ name: 'Tokenary', - installed: ({ provider }) => provider?.[ProviderIdentityFlag.Tokenary], + installed: () => (window as any)[ProviderIdentityFlag.Tokenary], icon: walletIcons.tokenary, }); From d530a3650599bdce47b4d83332613c3fbe7ce8b4 Mon Sep 17 00:00:00 2001 From: Addminus Date: Thu, 23 Mar 2023 16:11:15 +0100 Subject: [PATCH 18/32] feat: add apex wallet, optimize connectors --- packages/wallet-management/src/types/index.ts | 1 + .../src/walletIcons/index.ts | 4 +- .../src/walletIcons/placeholder.svg | 1 + .../wallet-management/src/walletIcons/tp.svg | 11 -- packages/wallet-management/src/wallets.ts | 135 ++++++++++-------- 5 files changed, 80 insertions(+), 72 deletions(-) create mode 100644 packages/wallet-management/src/walletIcons/placeholder.svg delete mode 100644 packages/wallet-management/src/walletIcons/tp.svg diff --git a/packages/wallet-management/src/types/index.ts b/packages/wallet-management/src/types/index.ts index 8ccf33346..f025e1618 100644 --- a/packages/wallet-management/src/types/index.ts +++ b/packages/wallet-management/src/types/index.ts @@ -89,4 +89,5 @@ export enum ProviderIdentityFlag { Tokenary = 'isTokenary', MathWallet = 'isMathWallet', Frontier = 'isFrontier', + ApexWallet = 'isApexWallet', } diff --git a/packages/wallet-management/src/walletIcons/index.ts b/packages/wallet-management/src/walletIcons/index.ts index 1e0aeab4c..f2d69534f 100644 --- a/packages/wallet-management/src/walletIcons/index.ts +++ b/packages/wallet-management/src/walletIcons/index.ts @@ -23,12 +23,12 @@ 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, @@ -38,6 +38,7 @@ export const walletIcons = { frontier, blockwallet, binance, + placeholder, bitpie, brave, coinbase, @@ -58,7 +59,6 @@ export const walletIcons = { tallyho, tokenary, tokenpocket, - tp, trust, walletio, xdefi, diff --git a/packages/wallet-management/src/walletIcons/placeholder.svg b/packages/wallet-management/src/walletIcons/placeholder.svg new file mode 100644 index 000000000..db170de79 --- /dev/null +++ b/packages/wallet-management/src/walletIcons/placeholder.svg @@ -0,0 +1 @@ + \ No newline at end of file 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/wallets.ts b/packages/wallet-management/src/wallets.ts index 16d2a326b..8d75a67f6 100644 --- a/packages/wallet-management/src/wallets.ts +++ b/packages/wallet-management/src/wallets.ts @@ -5,10 +5,15 @@ import { walletIcons } from './walletIcons'; import { WalletConnectConnector } from './connectors/walletConnectConnector'; import { supportedChains } from '@lifi/sdk'; +const defaultWallet: Wallet = new InjectedConnector({ + name: 'Your Default Wallet', + installed: () => !!(window as any).ethereum, + icon: walletIcons.metamask, +}); + const metamask: Wallet = new InjectedConnector({ name: 'MetaMask', - installed: () => - !!(window as any) && !!(window as any)[ProviderIdentityFlag.MetaMask], + installed: () => !!(window as any).ethereum[ProviderIdentityFlag.MetaMask], icon: walletIcons.metamask, }); @@ -29,7 +34,7 @@ const frontier: Wallet = new InjectedConnector( installed: () => (window as any).frontier, icon: walletIcons.frontier, }, - (window as any).frontier.ethereum, + (window as any).frontier?.ethereum, ); const brave: Wallet = new InjectedConnector({ @@ -42,13 +47,13 @@ const brave: Wallet = new InjectedConnector({ const mathWallet: Wallet = new InjectedConnector({ name: 'MathWallet', - installed: () => (window as any)[ProviderIdentityFlag.MathWallet], + installed: () => (window as any).ethereum[ProviderIdentityFlag.MathWallet], icon: walletIcons.mathwallet, }); const tallyho: Wallet = new InjectedConnector( { - name: 'Tally Ho', + name: 'Taho', installed: () => (window as any).tally && (window as any).tally[ProviderIdentityFlag.TallyHo], @@ -59,77 +64,91 @@ const tallyho: Wallet = new InjectedConnector( const blockWallet: Wallet = new InjectedConnector({ name: 'BlockWallet', - installed: () => (window as any)[ProviderIdentityFlag.BlockWallet], + installed: () => (window as any).ethereum[ProviderIdentityFlag.BlockWallet], icon: walletIcons.blockwallet, }); -const binance: Wallet = new InjectedConnector({ - name: 'Binance', - installed: () => (window as any)[ProviderIdentityFlag.Binance], - icon: walletIcons.binance, -}); +const binance: Wallet = new InjectedConnector( + { + name: 'Binance', + installed: () => (window as any).BinanceChain, + icon: walletIcons.binance, + }, + (window as any).BinanceChain, +); -const coinbase: Wallet = new InjectedConnector({ - name: 'Coinbase', - installed: () => - (window as any)[ProviderIdentityFlag.Coinbase] || - (window as any).providers?.[0]?.[ProviderIdentityFlag.CoinbaseExtension], - icon: walletIcons.coinbase, -}); +const coinbase: Wallet = new InjectedConnector( + { + name: 'Coinbase', + installed: () => (window as any).coinbaseWalletExtension, + icon: walletIcons.coinbase, + }, + (window as any).coinbaseWalletExtension, +); const detected: Wallet = new InjectedConnector({ name: 'Detected', - installed: () => (window as any)[ProviderIdentityFlag.Detected], + installed: () => (window as any).ethereum[ProviderIdentityFlag.Detected], icon: walletIcons.detected, }); -const trust: Wallet = new InjectedConnector({ - name: 'Trust', - installed: () => - (window as any)[ProviderIdentityFlag.Trust] && - !(window as any)[ProviderIdentityFlag.TokenPocket], - icon: walletIcons.trust, -}); +const trust: Wallet = new InjectedConnector( + { + name: 'Trust', + installed: () => (window as any).trustWallet, + icon: walletIcons.trust, + }, + (window as any).trustWallet, +); const status: Wallet = new InjectedConnector({ name: 'Status', - installed: () => (window as any)[ProviderIdentityFlag.Status], + installed: () => (window as any).ethereum[ProviderIdentityFlag.Status], icon: walletIcons.status, }); const alphawallet: Wallet = new InjectedConnector({ name: 'AlphaWallet', - installed: () => (window as any)[ProviderIdentityFlag.AlphaWallet], + installed: () => (window as any).ethereum[ProviderIdentityFlag.AlphaWallet], icon: walletIcons.alphawallet, }); const atoken: Wallet = new InjectedConnector({ name: 'AToken', - installed: () => (window as any)[ProviderIdentityFlag.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).Bitpie, + installed: () => (window as any).ethereum.Bitpie, icon: walletIcons.bitpie, }); const dcent: Wallet = new InjectedConnector({ name: 'Dcent', - installed: () => (window as any)[ProviderIdentityFlag.Dcent], + installed: () => (window as any).ethereum[ProviderIdentityFlag.Dcent], icon: walletIcons.dcent, }); -const frame: Wallet = new InjectedConnector({ - name: 'Frame', - installed: () => (window as any)[ProviderIdentityFlag.Frame], - icon: walletIcons.frame, -}); +const frame: Wallet = new InjectedConnector( + { + name: 'Frame', + installed: () => (window as any).frame, + icon: walletIcons.frame, + }, + (window as any).frame, +); const huobiwallet: Wallet = new InjectedConnector({ name: 'HuobiWallet', - installed: () => (window as any)[ProviderIdentityFlag.HuobiWallet], + installed: () => (window as any).ethereum[ProviderIdentityFlag.HuobiWallet], icon: walletIcons.huobiwallet, }); @@ -138,70 +157,68 @@ const hyperpay: Wallet = new InjectedConnector({ // 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).hiWallet, + installed: () => (window as any).ethereum.hiWallet, icon: walletIcons.hyperpay, }); const imtoken: Wallet = new InjectedConnector({ name: 'ImToken', - installed: () => (window as any)[ProviderIdentityFlag.ImToken], + installed: () => (window as any).ethereum[ProviderIdentityFlag.ImToken], icon: walletIcons.imtoken, }); -const liquality: Wallet = new InjectedConnector({ - name: 'Liquality', - installed: () => (window as any)[ProviderIdentityFlag.Liquality], - icon: walletIcons.liquality, -}); +const liquality: Wallet = new InjectedConnector( + { + name: 'Liquality', + installed: () => (window as any).liquality, + icon: walletIcons.liquality, + }, + (window as any).liquality, +); const meetone: Wallet = new InjectedConnector({ name: 'MeetOne', - installed: () => (window as any)[ProviderIdentityFlag.MeetOne] === 'MEETONE', + installed: () => + (window as any).ethereum[ProviderIdentityFlag.MeetOne] === 'MEETONE', icon: walletIcons.meetone, }); const mykey: Wallet = new InjectedConnector({ name: 'MyKey', - installed: () => (window as any)[ProviderIdentityFlag.MyKey], + installed: () => (window as any).ethereum[ProviderIdentityFlag.MyKey], icon: walletIcons.mykey, }); const ownbit: Wallet = new InjectedConnector({ name: 'OwnBit', - installed: () => (window as any)[ProviderIdentityFlag.OwnBit], + installed: () => (window as any).ethereum[ProviderIdentityFlag.OwnBit], icon: walletIcons.ownbit, }); const tokenpocket: Wallet = new InjectedConnector({ name: 'TokenPocket', installed: () => - (window as any)[ProviderIdentityFlag.TokenPocket] && - !(window as any)[ProviderIdentityFlag.TP], + (window as any).ethereum[ProviderIdentityFlag.TokenPocket] && + !(window as any).ethereum[ProviderIdentityFlag.TP], icon: walletIcons.tokenpocket, }); -const tp: Wallet = new InjectedConnector({ - name: 'TP', - installed: () => (window as any)[ProviderIdentityFlag.TP], - icon: walletIcons.tp, -}); - const xdefi: Wallet = new InjectedConnector({ name: 'XDEFI', // eslint-disable-next-line dot-notation - installed: () => true, + installed: () => (window as any).ethereum[ProviderIdentityFlag.XDEFI], icon: walletIcons.xdefi, }); const oneInch: Wallet = new InjectedConnector({ name: 'OneInch', - installed: () => (window as any)[ProviderIdentityFlag.OneInch], + installed: () => (window as any).ethereum[ProviderIdentityFlag.OneInch], icon: walletIcons.oneInch, }); const tokenary: Wallet = new InjectedConnector({ name: 'Tokenary', - installed: () => (window as any)[ProviderIdentityFlag.Tokenary], + installed: () => (window as any).ethereum[ProviderIdentityFlag.Tokenary], icon: walletIcons.tokenary, }); @@ -220,6 +237,7 @@ export const supportedWallets = [ blockWallet, bitpie, brave, + apex, dcent, frame, huobiwallet, @@ -230,7 +248,6 @@ export const supportedWallets = [ mykey, ownbit, tokenpocket, - tp, xdefi, oneInch, tokenary, From 7996939b812016e3a8204d01d617355d30a38f59 Mon Sep 17 00:00:00 2001 From: Eugene Chybisov Date: Wed, 12 Apr 2023 13:36:18 +0800 Subject: [PATCH 19/32] refactor: cleanup --- packages/wallet-management/src/index.ts | 2 +- packages/wallet-management/src/types/index.ts | 1 - .../src/walletPersistance.ts | 20 ++++++++++++++----- packages/wallet-management/src/wallets.ts | 4 ++-- .../src/providers/WalletProvider.tsx | 4 ++-- .../src/providers/WalletProvider.tsx | 6 ++++-- .../WalletProvider/WalletProvider.tsx | 4 ++-- .../src/providers/WalletProvider/index.ts | 2 +- 8 files changed, 27 insertions(+), 16 deletions(-) diff --git a/packages/wallet-management/src/index.ts b/packages/wallet-management/src/index.ts index 61482bb58..b64f7b852 100644 --- a/packages/wallet-management/src/index.ts +++ b/packages/wallet-management/src/index.ts @@ -1,5 +1,5 @@ export * from './LiFiWalletManagement'; +export * from './types'; export * from './walletAutomation'; export * from './walletIcons'; export * from './wallets'; -export * from './types'; diff --git a/packages/wallet-management/src/types/index.ts b/packages/wallet-management/src/types/index.ts index f025e1618..79c28c050 100644 --- a/packages/wallet-management/src/types/index.ts +++ b/packages/wallet-management/src/types/index.ts @@ -2,7 +2,6 @@ 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 { diff --git a/packages/wallet-management/src/walletPersistance.ts b/packages/wallet-management/src/walletPersistance.ts index c271de7e4..7e2b95e33 100644 --- a/packages/wallet-management/src/walletPersistance.ts +++ b/packages/wallet-management/src/walletPersistance.ts @@ -41,7 +41,9 @@ const readDeactivatedWallets = (): Array => { }; const removeFromActiveWallets = (address?: string | null) => { - if (!address) return; + if (!address) { + return; + } const lowerCaseAddress = address.toLowerCase(); const wallets = readWallets(); const filteredWallets = wallets.filter( @@ -51,7 +53,9 @@ const removeFromActiveWallets = (address?: string | null) => { }; const addToDeactivatedWallets = (address?: string | null) => { - if (!address) return; + if (!address) { + return; + } const lowerCaseAddress = address.toLowerCase(); const deactivatedWallets = readDeactivatedWallets(); deactivatedWallets.push(lowerCaseAddress); @@ -59,7 +63,9 @@ const addToDeactivatedWallets = (address?: string | null) => { }; const addToActiveWallets = (address?: string | null) => { - if (!address) return; + if (!address) { + return; + } const lowerCaseAddress = address.toLowerCase(); const activeWallets = readWallets(); activeWallets.push(lowerCaseAddress); @@ -67,7 +73,9 @@ const addToActiveWallets = (address?: string | null) => { }; const removeFromDeactivatedWallets = (address?: string | null) => { - if (!address) return; + if (!address) { + return; + } const lowerCaseAddress = address.toLowerCase(); const deactivatedWallets = readDeactivatedWallets(); const deactivatedWalletsWithoutAccount = deactivatedWallets.filter( @@ -77,7 +85,9 @@ const removeFromDeactivatedWallets = (address?: string | null) => { }; const isWalletDeactivated = (address?: string | null): boolean => { - if (!address) return true; + if (!address) { + return true; + } const lowerCaseAddress = address.toLowerCase(); const deactivatedWallets = readDeactivatedWallets(); const deactivatedAddresses = deactivatedWallets.map((address) => diff --git a/packages/wallet-management/src/wallets.ts b/packages/wallet-management/src/wallets.ts index 8d75a67f6..d64a6260d 100644 --- a/packages/wallet-management/src/wallets.ts +++ b/packages/wallet-management/src/wallets.ts @@ -1,9 +1,9 @@ +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'; -import { WalletConnectConnector } from './connectors/walletConnectConnector'; -import { supportedChains } from '@lifi/sdk'; const defaultWallet: Wallet = new InjectedConnector({ name: 'Your Default Wallet', diff --git a/packages/widget-embedded/src/providers/WalletProvider.tsx b/packages/widget-embedded/src/providers/WalletProvider.tsx index c205f485e..b6d592bf8 100644 --- a/packages/widget-embedded/src/providers/WalletProvider.tsx +++ b/packages/widget-embedded/src/providers/WalletProvider.tsx @@ -1,11 +1,11 @@ import type { Signer } from '@ethersproject/abstract-signer'; import type { Token } from '@lifi/sdk'; import type { Wallet } from '@lifi/wallet-management'; -import { LiFiWalletManagement } from '@lifi/wallet-management'; import { + LiFiWalletManagement, + switchChainAndAddToken, addChain as walletAddChain, switchChain as walletSwitchChain, - switchChainAndAddToken, } from '@lifi/wallet-management'; import type { WalletAccount, WalletContextProps } from '@lifi/widget/providers'; import type { FC, PropsWithChildren } from 'react'; diff --git a/packages/widget-playground/src/providers/WalletProvider.tsx b/packages/widget-playground/src/providers/WalletProvider.tsx index 40bafefb4..f9568da3e 100644 --- a/packages/widget-playground/src/providers/WalletProvider.tsx +++ b/packages/widget-playground/src/providers/WalletProvider.tsx @@ -1,8 +1,10 @@ import type { Signer } from '@ethersproject/abstract-signer'; import type { Token } from '@lifi/sdk'; import type { Wallet } from '@lifi/wallet-management'; -import { supportedWallets } from '@lifi/wallet-management'; -import { LiFiWalletManagement } from '@lifi/wallet-management'; +import { + LiFiWalletManagement, + supportedWallets, +} from '@lifi/wallet-management'; import type { WalletAccount, WalletContextProps } from '@lifi/widget/providers'; import type { FC, PropsWithChildren } from 'react'; import { diff --git a/packages/widget/src/providers/WalletProvider/WalletProvider.tsx b/packages/widget/src/providers/WalletProvider/WalletProvider.tsx index e499cbcce..3cd1ffa14 100644 --- a/packages/widget/src/providers/WalletProvider/WalletProvider.tsx +++ b/packages/widget/src/providers/WalletProvider/WalletProvider.tsx @@ -5,12 +5,12 @@ import { supportedWallets, } from '@lifi/wallet-management'; import type { Wallet } from '@lifi/wallet-management/types'; - -import { FC, PropsWithChildren, useEffect } from 'react'; +import type { FC, PropsWithChildren } from 'react'; import { createContext, useCallback, useContext, + useEffect, useMemo, useState, } from 'react'; 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'; From bc66578cbb3d3872edf2642cf0939442ad6fcb57 Mon Sep 17 00:00:00 2001 From: Addminus Date: Mon, 17 Apr 2023 18:03:54 +0200 Subject: [PATCH 20/32] refactor: unshift wallets into back of connected wallets array --- packages/wallet-management/src/LiFiWalletManagement.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wallet-management/src/LiFiWalletManagement.ts b/packages/wallet-management/src/LiFiWalletManagement.ts index 924a28040..7941acf38 100644 --- a/packages/wallet-management/src/LiFiWalletManagement.ts +++ b/packages/wallet-management/src/LiFiWalletManagement.ts @@ -14,7 +14,7 @@ export class LiFiWalletManagement extends events.EventEmitter { try { await wallet.connect(); wallet.addListener('walletAccountChanged', this.handleAccountDataChange); - this.connectedWallets.push(wallet); // TODO: add new wallet as first element + this.connectedWallets.unshift(wallet); removeFromDeactivatedWallets(wallet.account?.address); addToActiveWallets(wallet.account?.address); } catch (e) { From 2af7d62de8403f0ccbc9f03c99ea9c2270614b77 Mon Sep 17 00:00:00 2001 From: Addminus Date: Mon, 17 Apr 2023 18:08:20 +0200 Subject: [PATCH 21/32] chore: clean widget walletprovider --- .../widget/src/providers/WalletProvider/WalletProvider.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/widget/src/providers/WalletProvider/WalletProvider.tsx b/packages/widget/src/providers/WalletProvider/WalletProvider.tsx index 3cd1ffa14..6ad37862a 100644 --- a/packages/widget/src/providers/WalletProvider/WalletProvider.tsx +++ b/packages/widget/src/providers/WalletProvider/WalletProvider.tsx @@ -56,7 +56,7 @@ export const WalletProvider: FC = ({ children }) => { }, []); const handleWalletUpdate = async (wallet?: Wallet) => { - setCurrentWallet(() => wallet); + setCurrentWallet(wallet); const account = await extractAccountFromSigner(wallet?.account?.signer); setAccount(account); }; @@ -147,7 +147,7 @@ export const WalletProvider: FC = ({ children }) => { addChain, addToken, account, - provider: currentWallet?.account?.provider || undefined, + provider: currentWallet?.account?.provider, }), [ account, From 6664a301ba38b987ff99cee620e7222aac451774 Mon Sep 17 00:00:00 2001 From: Addminus Date: Mon, 17 Apr 2023 18:19:53 +0200 Subject: [PATCH 22/32] feat: add default wallet --- packages/wallet-management/src/wallets.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/wallet-management/src/wallets.ts b/packages/wallet-management/src/wallets.ts index d64a6260d..a78bbc2e4 100644 --- a/packages/wallet-management/src/wallets.ts +++ b/packages/wallet-management/src/wallets.ts @@ -223,6 +223,7 @@ const tokenary: Wallet = new InjectedConnector({ }); export const supportedWallets = [ + defaultWallet, metamask, walletConnect, tallyho, From ed79275d59b4135d46100509dc352d8b9a7457c4 Mon Sep 17 00:00:00 2001 From: Addminus Date: Mon, 17 Apr 2023 18:20:04 +0200 Subject: [PATCH 23/32] fix: walletautomation --- packages/widget-playground/src/App.tsx | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/packages/widget-playground/src/App.tsx b/packages/widget-playground/src/App.tsx index 3a2efabd7..38bc0e777 100644 --- a/packages/widget-playground/src/App.tsx +++ b/packages/widget-playground/src/App.tsx @@ -33,6 +33,10 @@ import { WidgetVariants, widgetBaseConfig, widgetConfig } from './config'; import './index.css'; import { useWallet } from './providers/WalletProvider'; +const METAMASK_WALLET = supportedWallets.find( + (wallet) => wallet.name === 'MetaMask', +); + export const App = () => { const { connect, disconnect, account } = useWallet(); const [searchParams] = useState(() => @@ -127,30 +131,24 @@ export const App = () => { walletManagement: { signer: account.signer, connect: async () => { - const metamask = supportedWallets.find( - (wallet) => wallet.name === 'MetaMask', - ); - await connect(metamask); + await connect(METAMASK_WALLET); return account.signer!; }, disconnect: async () => { - const metamask = supportedWallets.find( - (wallet) => wallet.name === 'MetaMask', - ); - disconnect(metamask); + 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); }, }, })); From fd167bdbc37a733b7c169a20d56a08bef58f3cf4 Mon Sep 17 00:00:00 2001 From: Addminus Date: Mon, 17 Apr 2023 18:37:19 +0200 Subject: [PATCH 24/32] fix: playground wallet connect --- packages/widget-playground/src/App.tsx | 27 ++++++++++--------- .../src/components/WalletButtons.tsx | 5 ++-- packages/widget-playground/src/config.ts | 5 ++++ .../src/providers/WalletProvider.tsx | 21 +++------------ 4 files changed, 27 insertions(+), 31 deletions(-) diff --git a/packages/widget-playground/src/App.tsx b/packages/widget-playground/src/App.tsx index 38bc0e777..eab5a9090 100644 --- a/packages/widget-playground/src/App.tsx +++ b/packages/widget-playground/src/App.tsx @@ -1,10 +1,5 @@ import type { Token } from '@lifi/sdk'; -import { - addChain, - supportedWallets, - switchChain, - switchChainAndAddToken, -} from '@lifi/wallet-management'; + import type { WidgetVariant } from '@lifi/widget'; import { LiFiWidget } from '@lifi/widget'; import { @@ -29,16 +24,18 @@ 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'; -const METAMASK_WALLET = supportedWallets.find( - (wallet) => wallet.name === 'MetaMask', -); - export const App = () => { const { connect, disconnect, account } = useWallet(); + console.log(account); const [searchParams] = useState(() => Object.fromEntries(new URLSearchParams(window?.location.search)), ); @@ -155,7 +152,13 @@ export const App = () => { } 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 f9568da3e..2ef969cd8 100644 --- a/packages/widget-playground/src/providers/WalletProvider.tsx +++ b/packages/widget-playground/src/providers/WalletProvider.tsx @@ -1,10 +1,7 @@ import type { Signer } from '@ethersproject/abstract-signer'; import type { Token } from '@lifi/sdk'; import type { Wallet } from '@lifi/wallet-management'; -import { - LiFiWalletManagement, - supportedWallets, -} 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 { @@ -15,6 +12,7 @@ import { useMemo, useState, } from 'react'; +import { METAMASK_WALLET } from '../config'; const stub = (): never => { throw new Error( @@ -40,18 +38,6 @@ export const WalletProvider: FC> = ({ children }) => { const [account, setAccount] = useState({}); const [currentWallet, setCurrentWallet] = useState(); - useEffect(() => { - const autoConnect = async () => { - const metaMask = supportedWallets.filter( - (wallet) => wallet.name === 'MetaMask', - ); - await liFiWalletManagement.autoConnect(metaMask); - metaMask[0].on('walletAccountChanged', handleWalletUpdate); - handleWalletUpdate(metaMask[0]); - }; - autoConnect(); - }, []); - const handleWalletUpdate = async (wallet?: Wallet) => { setCurrentWallet(() => wallet); const account = await extractAccountFromSigner(wallet?.account?.signer); @@ -67,6 +53,7 @@ export const WalletProvider: FC> = ({ children }) => { const disconnect = useCallback(async () => { if (currentWallet) { + console.log('in disco'); await liFiWalletManagement.disconnect(currentWallet); currentWallet.removeAllListeners(); handleWalletUpdate(undefined); @@ -119,7 +106,7 @@ export const WalletProvider: FC> = ({ children }) => { addToken, account, }), - [account, addChain, addToken, connect, disconnect, switchChain], + [account.address, addChain, addToken, connect, disconnect, switchChain], ); return ( From 23a5846aab8120e5f134cc5689d304cad8217e9f Mon Sep 17 00:00:00 2001 From: Addminus Date: Mon, 17 Apr 2023 18:39:23 +0200 Subject: [PATCH 25/32] chore: remove logs --- packages/widget-playground/src/App.tsx | 1 - packages/widget-playground/src/providers/WalletProvider.tsx | 1 - 2 files changed, 2 deletions(-) diff --git a/packages/widget-playground/src/App.tsx b/packages/widget-playground/src/App.tsx index eab5a9090..915572ed4 100644 --- a/packages/widget-playground/src/App.tsx +++ b/packages/widget-playground/src/App.tsx @@ -35,7 +35,6 @@ import { useWallet } from './providers/WalletProvider'; export const App = () => { const { connect, disconnect, account } = useWallet(); - console.log(account); const [searchParams] = useState(() => Object.fromEntries(new URLSearchParams(window?.location.search)), ); diff --git a/packages/widget-playground/src/providers/WalletProvider.tsx b/packages/widget-playground/src/providers/WalletProvider.tsx index 2ef969cd8..80c1ead49 100644 --- a/packages/widget-playground/src/providers/WalletProvider.tsx +++ b/packages/widget-playground/src/providers/WalletProvider.tsx @@ -53,7 +53,6 @@ export const WalletProvider: FC> = ({ children }) => { const disconnect = useCallback(async () => { if (currentWallet) { - console.log('in disco'); await liFiWalletManagement.disconnect(currentWallet); currentWallet.removeAllListeners(); handleWalletUpdate(undefined); From c55ae7e5e69c2a9d1ea40b8cb79a49d7ea0d5a09 Mon Sep 17 00:00:00 2001 From: Addminus Date: Mon, 17 Apr 2023 18:47:14 +0200 Subject: [PATCH 26/32] fix: external disconnet sync --- .../src/providers/WalletProvider/WalletProvider.tsx | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/widget/src/providers/WalletProvider/WalletProvider.tsx b/packages/widget/src/providers/WalletProvider/WalletProvider.tsx index 6ad37862a..8c04e1e0f 100644 --- a/packages/widget/src/providers/WalletProvider/WalletProvider.tsx +++ b/packages/widget/src/providers/WalletProvider/WalletProvider.tsx @@ -139,6 +139,19 @@ export const WalletProvider: FC = ({ children }) => { [walletManagement, currentWallet], ); + // keep widget in sync with changing external signer object + useEffect(() => { + if (walletManagement) { + const updateAccount = async () => { + const account = await extractAccountFromSigner( + walletManagement?.signer, + ); + setAccount(account); + }; + updateAccount(); + } + }, [walletManagement, walletManagement?.signer]); + const value = useMemo( () => ({ connect, From fefd24897f91ec788c1d11f027d86cf174061a3e Mon Sep 17 00:00:00 2001 From: Addminus Date: Mon, 17 Apr 2023 18:52:54 +0200 Subject: [PATCH 27/32] refactor: widget-embedded walletprovider --- .../src/providers/WalletProvider.tsx | 74 +++++++++++-------- 1 file changed, 45 insertions(+), 29 deletions(-) diff --git a/packages/widget-embedded/src/providers/WalletProvider.tsx b/packages/widget-embedded/src/providers/WalletProvider.tsx index b6d592bf8..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 { - LiFiWalletManagement, - switchChainAndAddToken, - 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 { @@ -44,42 +39,63 @@ export const WalletProvider: FC> = ({ children }) => { liFiWalletManagement.connectedWallets[0], ); + const handleWalletUpdate = async (wallet?: Wallet) => { + setCurrentWallet(() => wallet); + const account = await extractAccountFromSigner(wallet?.account?.signer); + setAccount(account); + }; + const connect = useCallback(async (wallet: Wallet) => { await liFiWalletManagement.connect(wallet); - setCurrentWallet(wallet); + wallet.on('walletAccountChanged', handleWalletUpdate); + + handleWalletUpdate(wallet); }, []); const disconnect = useCallback(async () => { if (currentWallet) { await liFiWalletManagement.disconnect(currentWallet); + currentWallet.removeAllListeners(); + handleWalletUpdate(undefined); } - setCurrentWallet(undefined); }, [currentWallet]); - // only for injected wallets - const switchChain = useCallback(async (chainId: number) => { - return walletSwitchChain(chainId); - }, []); + 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) => { - return walletAddChain(chainId); - }, []); + const addChain = useCallback( + async (chainId: number) => { + try { + await currentWallet?.addChain(chainId); + handleWalletUpdate(currentWallet); - const addToken = useCallback(async (chainId: number, token: Token) => { - return switchChainAndAddToken(chainId, token); - }, []); + return true; + } catch { + return false; + } + }, + [currentWallet], + ); - // keep account information up to date - useEffect(() => { - const updateAccount = async () => { - let account; - account = await extractAccountFromSigner( - currentWallet?.connector.account?.signer, - ); - setAccount(account); - }; - updateAccount(); - }, [account.signer, currentWallet]); + const addToken = useCallback( + async (chainId: number, token: Token) => { + await currentWallet?.addToken(chainId, token); + handleWalletUpdate(currentWallet); + + return; + }, + [currentWallet], + ); const value = useMemo( () => ({ From 3a8170eff1face78adcd80d3314f53735fa44d0e Mon Sep 17 00:00:00 2001 From: Addminus Date: Tue, 18 Apr 2023 14:54:40 +0200 Subject: [PATCH 28/32] feat: improve default wallet handling --- .../src/connectors/injectedConnector.ts | 2 +- .../src/connectors/walletConnectConnector.ts | 2 +- packages/wallet-management/src/types/index.ts | 6 +- .../src/walletIcons/detected.svg | 4 -- .../src/walletIcons/index.ts | 2 - .../src/walletIcons/placeholder.svg | 5 +- packages/wallet-management/src/wallets.ts | 58 +++++++++---------- .../SelectWalletPage/SelectWalletPage.tsx | 33 +++++++++-- 8 files changed, 64 insertions(+), 48 deletions(-) delete mode 100644 packages/wallet-management/src/walletIcons/detected.svg diff --git a/packages/wallet-management/src/connectors/injectedConnector.ts b/packages/wallet-management/src/connectors/injectedConnector.ts index 15d713108..1ce0de0f7 100644 --- a/packages/wallet-management/src/connectors/injectedConnector.ts +++ b/packages/wallet-management/src/connectors/injectedConnector.ts @@ -22,7 +22,7 @@ export class InjectedConnector extends events.EventEmitter implements Wallet { public account: AccountData | undefined; public name: string; public icon: string; - public installed: (helpers: { provider: any }) => boolean; + public installed: () => boolean; constructor( constructorArgs: InjectedConnectorConstructorArgs, diff --git a/packages/wallet-management/src/connectors/walletConnectConnector.ts b/packages/wallet-management/src/connectors/walletConnectConnector.ts index 79161ca29..67843e8ea 100644 --- a/packages/wallet-management/src/connectors/walletConnectConnector.ts +++ b/packages/wallet-management/src/connectors/walletConnectConnector.ts @@ -34,7 +34,7 @@ export class WalletConnectConnector public account: AccountData | undefined; public name: string; public icon: string; - public installed: (helpers: { provider: any }) => boolean; + public installed: () => boolean; constructor(constructorArgs: WalletConnectConnectorConstructorArgs) { super(); diff --git a/packages/wallet-management/src/types/index.ts b/packages/wallet-management/src/types/index.ts index 79c28c050..9a358f6f6 100644 --- a/packages/wallet-management/src/types/index.ts +++ b/packages/wallet-management/src/types/index.ts @@ -33,12 +33,12 @@ export interface AccountData { export interface InjectedConnectorConstructorArgs { name: string; icon: string; - installed: (helpers: { provider: any }) => boolean; + installed: () => boolean; } export interface WalletConnectConnectorConstructorArgs { name: string; icon: string; - installed: (helpers: { provider: any }) => boolean; + installed: () => boolean; rpc: { [chainId: number]: string; }; @@ -49,7 +49,7 @@ export interface Wallet extends events.EventEmitter { icon: string; isActivationInProgress: boolean; account: AccountData | undefined; - installed: (helpers: { provider: any }) => boolean; + installed: () => boolean; connect: () => Promise; autoConnect?: () => Promise; disconnect: () => void; diff --git a/packages/wallet-management/src/walletIcons/detected.svg b/packages/wallet-management/src/walletIcons/detected.svg deleted file mode 100644 index fe0456c2c..000000000 --- a/packages/wallet-management/src/walletIcons/detected.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - diff --git a/packages/wallet-management/src/walletIcons/index.ts b/packages/wallet-management/src/walletIcons/index.ts index f2d69534f..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'; @@ -43,7 +42,6 @@ export const walletIcons = { brave, coinbase, dcent, - detected, frame, huobiwallet, hyperpay, diff --git a/packages/wallet-management/src/walletIcons/placeholder.svg b/packages/wallet-management/src/walletIcons/placeholder.svg index db170de79..fe0456c2c 100644 --- a/packages/wallet-management/src/walletIcons/placeholder.svg +++ b/packages/wallet-management/src/walletIcons/placeholder.svg @@ -1 +1,4 @@ - \ No newline at end of file + + + diff --git a/packages/wallet-management/src/wallets.ts b/packages/wallet-management/src/wallets.ts index a78bbc2e4..74067a50f 100644 --- a/packages/wallet-management/src/wallets.ts +++ b/packages/wallet-management/src/wallets.ts @@ -6,14 +6,17 @@ import { ProviderIdentityFlag } from './types'; import { walletIcons } from './walletIcons'; const defaultWallet: Wallet = new InjectedConnector({ - name: 'Your Default Wallet', - installed: () => !!(window as any).ethereum, - icon: walletIcons.metamask, + // 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], + installed: () => !!(window as any)?.ethereum?.[ProviderIdentityFlag.MetaMask], icon: walletIcons.metamask, }); @@ -47,7 +50,7 @@ const brave: Wallet = new InjectedConnector({ const mathWallet: Wallet = new InjectedConnector({ name: 'MathWallet', - installed: () => (window as any).ethereum[ProviderIdentityFlag.MathWallet], + installed: () => (window as any).ethereum?.[ProviderIdentityFlag.MathWallet], icon: walletIcons.mathwallet, }); @@ -56,7 +59,7 @@ const tallyho: Wallet = new InjectedConnector( name: 'Taho', installed: () => (window as any).tally && - (window as any).tally[ProviderIdentityFlag.TallyHo], + (window as any).tally?.[ProviderIdentityFlag.TallyHo], icon: walletIcons.tallyho, }, (window as any).tally, @@ -64,7 +67,7 @@ const tallyho: Wallet = new InjectedConnector( const blockWallet: Wallet = new InjectedConnector({ name: 'BlockWallet', - installed: () => (window as any).ethereum[ProviderIdentityFlag.BlockWallet], + installed: () => (window as any).ethereum?.[ProviderIdentityFlag.BlockWallet], icon: walletIcons.blockwallet, }); @@ -86,12 +89,6 @@ const coinbase: Wallet = new InjectedConnector( (window as any).coinbaseWalletExtension, ); -const detected: Wallet = new InjectedConnector({ - name: 'Detected', - installed: () => (window as any).ethereum[ProviderIdentityFlag.Detected], - icon: walletIcons.detected, -}); - const trust: Wallet = new InjectedConnector( { name: 'Trust', @@ -103,37 +100,37 @@ const trust: Wallet = new InjectedConnector( const status: Wallet = new InjectedConnector({ name: 'Status', - installed: () => (window as any).ethereum[ProviderIdentityFlag.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], + installed: () => (window as any).ethereum?.[ProviderIdentityFlag.AlphaWallet], icon: walletIcons.alphawallet, }); const atoken: Wallet = new InjectedConnector({ name: 'AToken', - installed: () => (window as any).ethereum[ProviderIdentityFlag.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], + installed: () => (window as any).ethereum?.[ProviderIdentityFlag.ApexWallet], icon: walletIcons.placeholder, }); const bitpie: Wallet = new InjectedConnector({ name: 'Bitpie', - installed: () => (window as any).ethereum.Bitpie, + installed: () => (window as any).ethereum?.Bitpie, icon: walletIcons.bitpie, }); const dcent: Wallet = new InjectedConnector({ name: 'Dcent', - installed: () => (window as any).ethereum[ProviderIdentityFlag.Dcent], + installed: () => (window as any).ethereum?.[ProviderIdentityFlag.Dcent], icon: walletIcons.dcent, }); @@ -148,7 +145,7 @@ const frame: Wallet = new InjectedConnector( const huobiwallet: Wallet = new InjectedConnector({ name: 'HuobiWallet', - installed: () => (window as any).ethereum[ProviderIdentityFlag.HuobiWallet], + installed: () => (window as any).ethereum?.[ProviderIdentityFlag.HuobiWallet], icon: walletIcons.huobiwallet, }); @@ -157,13 +154,13 @@ const hyperpay: Wallet = new InjectedConnector({ // 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, + installed: () => (window as any).ethereum?.hiWallet, icon: walletIcons.hyperpay, }); const imtoken: Wallet = new InjectedConnector({ name: 'ImToken', - installed: () => (window as any).ethereum[ProviderIdentityFlag.ImToken], + installed: () => (window as any).ethereum?.[ProviderIdentityFlag.ImToken], icon: walletIcons.imtoken, }); @@ -179,46 +176,46 @@ const liquality: Wallet = new InjectedConnector( const meetone: Wallet = new InjectedConnector({ name: 'MeetOne', installed: () => - (window as any).ethereum[ProviderIdentityFlag.MeetOne] === 'MEETONE', + (window as any).ethereum?.[ProviderIdentityFlag.MeetOne] === 'MEETONE', icon: walletIcons.meetone, }); const mykey: Wallet = new InjectedConnector({ name: 'MyKey', - installed: () => (window as any).ethereum[ProviderIdentityFlag.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], + 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], + (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], + installed: () => (window as any).ethereum?.[ProviderIdentityFlag.XDEFI], icon: walletIcons.xdefi, }); const oneInch: Wallet = new InjectedConnector({ name: 'OneInch', - installed: () => (window as any).ethereum[ProviderIdentityFlag.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], + installed: () => (window as any).ethereum?.[ProviderIdentityFlag.Tokenary], icon: walletIcons.tokenary, }); @@ -230,7 +227,6 @@ export const supportedWallets = [ binance, frontier, coinbase, - detected, trust, status, alphawallet, diff --git a/packages/widget/src/pages/SelectWalletPage/SelectWalletPage.tsx b/packages/widget/src/pages/SelectWalletPage/SelectWalletPage.tsx index f3d747f5c..7d19576d7 100644 --- a/packages/widget/src/pages/SelectWalletPage/SelectWalletPage.tsx +++ b/packages/widget/src/pages/SelectWalletPage/SelectWalletPage.tsx @@ -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.installed({ - provider: ethereum, - }); + const identityCheckPassed = wallet.installed(); if (!identityCheckPassed) { setWalletIdentity({ show: true, @@ -61,7 +67,24 @@ export const SelectWalletPage = () => { paddingRight: 1.5, }} > - {supportedWallets.map((wallet: Wallet) => ( + {installedWallets.map((wallet: Wallet) => ( + handleConnect(wallet)} + > + + + {wallet.name[0]} + + + + + ))} + + {notInstalledWallets.map((wallet: Wallet) => ( handleConnect(wallet)} From 89d9f8e7d3b9af768f5696a783b6ff123282c5df Mon Sep 17 00:00:00 2001 From: Addminus Date: Tue, 18 Apr 2023 15:02:16 +0200 Subject: [PATCH 29/32] chore: simplify wallet select page --- .../SelectWalletPage/SelectWalletPage.tsx | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/packages/widget/src/pages/SelectWalletPage/SelectWalletPage.tsx b/packages/widget/src/pages/SelectWalletPage/SelectWalletPage.tsx index 7d19576d7..2be5b24d9 100644 --- a/packages/widget/src/pages/SelectWalletPage/SelectWalletPage.tsx +++ b/packages/widget/src/pages/SelectWalletPage/SelectWalletPage.tsx @@ -67,24 +67,7 @@ export const SelectWalletPage = () => { paddingRight: 1.5, }} > - {installedWallets.map((wallet: Wallet) => ( - handleConnect(wallet)} - > - - - {wallet.name[0]} - - - - - ))} - - {notInstalledWallets.map((wallet: Wallet) => ( + {[...installedWallets, ...notInstalledWallets].map((wallet: Wallet) => ( handleConnect(wallet)} From e3b35eab0005450df70864da4a4fca054e530c9d Mon Sep 17 00:00:00 2001 From: Addminus Date: Tue, 18 Apr 2023 16:59:47 +0200 Subject: [PATCH 30/32] feat: autoconnect based on specific wallets --- .../src/LiFiWalletManagement.ts | 24 +++- .../src/connectors/injectedConnector.ts | 7 +- packages/wallet-management/src/index.ts | 1 + .../src/walletPersistance.ts | 109 ++++++++++++------ .../WalletProvider/WalletProvider.tsx | 17 ++- 5 files changed, 112 insertions(+), 46 deletions(-) diff --git a/packages/wallet-management/src/LiFiWalletManagement.ts b/packages/wallet-management/src/LiFiWalletManagement.ts index 7941acf38..44551f04f 100644 --- a/packages/wallet-management/src/LiFiWalletManagement.ts +++ b/packages/wallet-management/src/LiFiWalletManagement.ts @@ -3,6 +3,7 @@ import type { Wallet } from './types'; import { addToActiveWallets, addToDeactivatedWallets, + isWalletDeactivated, removeFromActiveWallets, removeFromDeactivatedWallets, } from './walletPersistance'; @@ -15,8 +16,14 @@ export class LiFiWalletManagement extends events.EventEmitter { await wallet.connect(); wallet.addListener('walletAccountChanged', this.handleAccountDataChange); this.connectedWallets.unshift(wallet); - removeFromDeactivatedWallets(wallet.account?.address); - addToActiveWallets(wallet.account?.address); + removeFromDeactivatedWallets({ + address: wallet.account?.address || '', + name: wallet.name, + }); + addToActiveWallets({ + address: wallet.account?.address || '', + name: wallet.name, + }); } catch (e) { throw e; } @@ -30,16 +37,21 @@ export class LiFiWalletManagement extends events.EventEmitter { 'walletAccountChanged', this.handleAccountDataChange, ); - this.connectedWallets.push(wallet); // TODO: add new wallet as first element + this.connectedWallets.unshift(wallet); } } } public disconnect = async (wallet: Wallet) => { - const selectedAddress = wallet.account?.address; wallet.removeAllListeners(); - removeFromActiveWallets(selectedAddress); - addToDeactivatedWallets(selectedAddress); + removeFromActiveWallets({ + address: wallet.account?.address || '', + name: wallet.name, + }); + addToDeactivatedWallets({ + address: wallet.account?.address || '', + name: wallet.name, + }); wallet.disconnect(); }; diff --git a/packages/wallet-management/src/connectors/injectedConnector.ts b/packages/wallet-management/src/connectors/injectedConnector.ts index 1ce0de0f7..77ecb0bf0 100644 --- a/packages/wallet-management/src/connectors/injectedConnector.ts +++ b/packages/wallet-management/src/connectors/injectedConnector.ts @@ -86,7 +86,12 @@ export class InjectedConnector extends events.EventEmitter implements Wallet { } try { const selectedAddress = this.windowProvider.selectedAddress; - if (!isWalletDeactivated(selectedAddress)) { + if ( + !isWalletDeactivated({ + address: selectedAddress || '', + name: this.name, + }) + ) { await this.calcAccountData(); } } catch (e) { diff --git a/packages/wallet-management/src/index.ts b/packages/wallet-management/src/index.ts index b64f7b852..5eb3d94dd 100644 --- a/packages/wallet-management/src/index.ts +++ b/packages/wallet-management/src/index.ts @@ -3,3 +3,4 @@ export * from './types'; export * from './walletAutomation'; export * from './walletIcons'; export * from './wallets'; +export * from './walletPersistance'; diff --git a/packages/wallet-management/src/walletPersistance.ts b/packages/wallet-management/src/walletPersistance.ts index 7e2b95e33..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,60 +81,59 @@ const readDeactivatedWallets = (): Array => { } }; -const removeFromActiveWallets = (address?: string | null) => { - if (!address) { +const removeFromActiveWallets = (wallet?: PersistedWallet | null) => { + if (!wallet) { return; } - const lowerCaseAddress = address.toLowerCase(); - const wallets = readWallets(); + 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) { +const addToDeactivatedWallets = (wallet?: PersistedWallet | null) => { + if (!wallet) { return; } - const lowerCaseAddress = address.toLowerCase(); + const normalizedWallet = normalizeWallets([wallet])[0]; const deactivatedWallets = readDeactivatedWallets(); - deactivatedWallets.push(lowerCaseAddress); + deactivatedWallets.push(normalizedWallet); storeDeactivatedWallets(deactivatedWallets); }; -const addToActiveWallets = (address?: string | null) => { - if (!address) { +const addToActiveWallets = (wallet?: PersistedWallet | null) => { + if (!wallet) { return; } - const lowerCaseAddress = address.toLowerCase(); - const activeWallets = readWallets(); - activeWallets.push(lowerCaseAddress); + const normalizedWallet = normalizeWallets([wallet])[0]; + const activeWallets = readActiveWallets(); + activeWallets.push(normalizedWallet); storeWallets(activeWallets); }; -const removeFromDeactivatedWallets = (address?: string | null) => { - if (!address) { +const removeFromDeactivatedWallets = (wallet?: PersistedWallet | null) => { + if (!wallet) { return; } - const lowerCaseAddress = address.toLowerCase(); + 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) { +const isWalletDeactivated = (wallet?: PersistedWallet | null): boolean => { + if (!wallet) { return true; } - const lowerCaseAddress = address.toLowerCase(); + 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 { @@ -102,4 +142,5 @@ export { addToActiveWallets, removeFromDeactivatedWallets, isWalletDeactivated, + readActiveWallets, }; diff --git a/packages/widget/src/providers/WalletProvider/WalletProvider.tsx b/packages/widget/src/providers/WalletProvider/WalletProvider.tsx index 8c04e1e0f..cbd20ccdd 100644 --- a/packages/widget/src/providers/WalletProvider/WalletProvider.tsx +++ b/packages/widget/src/providers/WalletProvider/WalletProvider.tsx @@ -3,6 +3,7 @@ import type { Token } from '@lifi/sdk'; import { LiFiWalletManagement, supportedWallets, + readActiveWallets, } from '@lifi/wallet-management'; import type { Wallet } from '@lifi/wallet-management/types'; import type { FC, PropsWithChildren } from 'react'; @@ -45,12 +46,18 @@ export const WalletProvider: FC = ({ children }) => { useEffect(() => { const autoConnect = async () => { - const metaMask = supportedWallets.filter( - (wallet) => wallet.name === 'MetaMask', + const persistedActiveWallets = readActiveWallets(); + const activeWallets = supportedWallets.filter((wallet) => + persistedActiveWallets.some( + (perstistedWallet) => perstistedWallet.name === wallet.name, + ), ); - await liFiWalletManagement.autoConnect(metaMask); - metaMask[0].on('walletAccountChanged', handleWalletUpdate); - handleWalletUpdate(metaMask[0]); + if (!activeWallets.length) { + return; + } + await liFiWalletManagement.autoConnect(activeWallets); + activeWallets[0].on('walletAccountChanged', handleWalletUpdate); + handleWalletUpdate(activeWallets[0]); }; autoConnect(); }, []); From b4734e9b0fd4ee2eab49c2cba9a8f8b83263116a Mon Sep 17 00:00:00 2001 From: Eugene Chybisov Date: Wed, 19 Apr 2023 13:02:51 +0700 Subject: [PATCH 31/32] chore: cleanup --- packages/wallet-management/src/LiFiWalletManagement.ts | 1 - packages/wallet-management/src/index.ts | 2 +- .../widget-embedded/src/components/NFTOpenSea/NFTOpenSea.tsx | 5 ++--- packages/widget/src/components/ActiveSwaps/index.ts | 1 - .../widget/src/providers/WalletProvider/WalletProvider.tsx | 2 +- 5 files changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/wallet-management/src/LiFiWalletManagement.ts b/packages/wallet-management/src/LiFiWalletManagement.ts index 44551f04f..28f512a97 100644 --- a/packages/wallet-management/src/LiFiWalletManagement.ts +++ b/packages/wallet-management/src/LiFiWalletManagement.ts @@ -3,7 +3,6 @@ import type { Wallet } from './types'; import { addToActiveWallets, addToDeactivatedWallets, - isWalletDeactivated, removeFromActiveWallets, removeFromDeactivatedWallets, } from './walletPersistance'; diff --git a/packages/wallet-management/src/index.ts b/packages/wallet-management/src/index.ts index 5eb3d94dd..cc36aa1b9 100644 --- a/packages/wallet-management/src/index.ts +++ b/packages/wallet-management/src/index.ts @@ -2,5 +2,5 @@ export * from './LiFiWalletManagement'; export * from './types'; export * from './walletAutomation'; export * from './walletIcons'; -export * from './wallets'; export * from './walletPersistance'; +export * from './wallets'; 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/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/providers/WalletProvider/WalletProvider.tsx b/packages/widget/src/providers/WalletProvider/WalletProvider.tsx index cbd20ccdd..732a75a82 100644 --- a/packages/widget/src/providers/WalletProvider/WalletProvider.tsx +++ b/packages/widget/src/providers/WalletProvider/WalletProvider.tsx @@ -2,8 +2,8 @@ import type { Signer } from '@ethersproject/abstract-signer'; import type { Token } from '@lifi/sdk'; import { LiFiWalletManagement, - supportedWallets, readActiveWallets, + supportedWallets, } from '@lifi/wallet-management'; import type { Wallet } from '@lifi/wallet-management/types'; import type { FC, PropsWithChildren } from 'react'; From 51fff61f98540562931538523af9fa0997b22989 Mon Sep 17 00:00:00 2001 From: Eugene Chybisov Date: Wed, 19 Apr 2023 13:02:53 +0700 Subject: [PATCH 32/32] chore: bump packages --- packages/wallet-management/package.json | 2 +- packages/widget-embedded/package.json | 6 +- packages/widget-playground/package.json | 2 +- yarn.lock | 711 ++++-------------------- 4 files changed, 124 insertions(+), 597 deletions(-) diff --git a/packages/wallet-management/package.json b/packages/wallet-management/package.json index aed0f1754..11252ec14 100644 --- a/packages/wallet-management/package.json +++ b/packages/wallet-management/package.json @@ -48,7 +48,7 @@ "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", 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-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/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: