From 5086c28f63d246979305d6f2506f3820467d6754 Mon Sep 17 00:00:00 2001 From: guanbinrui Date: Mon, 11 Jul 2022 23:04:36 +0800 Subject: [PATCH] fix: switch chain with fortmatic --- packages/mask/src/web3/UI/ChainBoundary.tsx | 13 ++++---- .../SNSAdaptor/components/ConsoleContent.tsx | 4 +-- .../state/Connection/providers/Fortmatic.ts | 30 +++++++++++++++++-- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/packages/mask/src/web3/UI/ChainBoundary.tsx b/packages/mask/src/web3/UI/ChainBoundary.tsx index 2b6ca3010826..9d1db522a87a 100644 --- a/packages/mask/src/web3/UI/ChainBoundary.tsx +++ b/packages/mask/src/web3/UI/ChainBoundary.tsx @@ -12,6 +12,7 @@ import { useWeb3State, useWeb3Connection, useChainIdValid, + useProviderDescriptor, } from '@masknet/plugin-infra/web3' import { ChainId, ProviderType } from '@masknet/web3-shared-evm' import { useRemoteControlledDialog } from '@masknet/shared-base-ui' @@ -83,6 +84,7 @@ export function ChainBoundary(props: ChainBoundaryPro const { Others: actualOthers } = useWeb3State(actualPluginID) const actualChainId = useChainId(actualPluginID) const actualProviderType = useProviderType(actualPluginID) + const actualProviderDescriptor = useProviderDescriptor(actualPluginID) const actualChainName = actualOthers?.chainResolver.chainName(actualChainId) const account = useAccount(actualPluginID) @@ -135,10 +137,9 @@ export function ChainBoundary(props: ChainBoundaryPro openSelectProviderDialog, ]) - const fortmaticDisabled = useMemo(() => { - if (actualProviderType !== ProviderType.Fortmatic) return false - return !(expectedChainId === ChainId.Mainnet || expectedChainId === ChainId.BSC) - }, [actualProviderType, expectedChainId]) + const switchButtonDisabled = useMemo(() => { + return !(actualProviderDescriptor.enableRequirements?.supportedChainIds?.includes(expectedChainId) ?? false) + }, [expectedChainId, actualProviderDescriptor]) const renderBox = (children?: React.ReactNode, tips?: string) => { return ( @@ -251,7 +252,7 @@ export function ChainBoundary(props: ChainBoundaryPro size={18} /> } - disabled={actualProviderType === ProviderType.WalletConnect || fortmaticDisabled} + disabled={actualProviderType === ProviderType.WalletConnect || switchButtonDisabled} sx={props.ActionButtonPromiseProps?.sx} init={{t('plugin_wallet_switch_network', { network: expectedChainName })}} waiting={t('plugin_wallet_switch_network_under_going', { @@ -268,7 +269,7 @@ export function ChainBoundary(props: ChainBoundaryPro , actualProviderType === ProviderType.WalletConnect ? t('plugin_wallet_connect_tips') - : fortmaticDisabled + : switchButtonDisabled ? t('plugin_wallet_not_support_network') : '', ) diff --git a/packages/plugins/Debugger/src/SNSAdaptor/components/ConsoleContent.tsx b/packages/plugins/Debugger/src/SNSAdaptor/components/ConsoleContent.tsx index fe36f6c370e7..c9e158ea9ec3 100644 --- a/packages/plugins/Debugger/src/SNSAdaptor/components/ConsoleContent.tsx +++ b/packages/plugins/Debugger/src/SNSAdaptor/components/ConsoleContent.tsx @@ -268,9 +268,7 @@ export function ConsoleContent(props: ConsoleContentProps) { switch (pluginID) { case NetworkPluginID.PLUGIN_EVM: await onSwitchChain( - chainId === EVM_ChainId.Mainnet - ? EVM_ChainId.Matic - : EVM_ChainId.Mainnet, + chainId === EVM_ChainId.Mainnet ? EVM_ChainId.BSC : EVM_ChainId.Mainnet, ) break default: diff --git a/packages/plugins/EVM/src/state/Connection/providers/Fortmatic.ts b/packages/plugins/EVM/src/state/Connection/providers/Fortmatic.ts index 5db1b1dc093e..868d5ba3d1c0 100644 --- a/packages/plugins/EVM/src/state/Connection/providers/Fortmatic.ts +++ b/packages/plugins/EVM/src/state/Connection/providers/Fortmatic.ts @@ -1,8 +1,9 @@ import Fortmatic from 'fortmatic' +import { toHex } from 'web3-utils' import type { RequestArguments } from 'web3-core' import { first } from 'lodash-unified' import type { FmProvider } from 'fortmatic/dist/cjs/src/core/fm-provider' -import { ChainId, chainResolver, getRPCConstants } from '@masknet/web3-shared-evm' +import { ChainId, chainResolver, getRPCConstants, ProviderType } from '@masknet/web3-shared-evm' import { createLookupTableResolver } from '@masknet/web3-shared-base' import type { EVM_Provider } from '../types' import { BaseProvider } from './Base' @@ -50,16 +51,28 @@ export default class FortmaticProvider extends BaseProvider implements EVM_Provi private get chainId(): ChainIdFortmatic { const chainId = this.chainId_ if (!chainId) throw new Error('No connection.') - if (!isFortmaticSupported(chainId)) throw new Error(`Chain id ${chainId} is not supported.`) + if (!isFortmaticSupported(chainId)) throw new Error(`The chain id ${chainId} is not supported.`) return chainId } private set chainId(newChainId: ChainId) { const chainId = newChainId - if (!isFortmaticSupported(chainId)) throw new Error(`Chain id ${chainId} is not supported.`) + if (!isFortmaticSupported(chainId)) throw new Error(`The chain id ${chainId} is not supported.`) this.chainId_ = chainId } + protected onAccountsChanged(accounts: string[]) { + this.emitter.emit('accounts', accounts) + } + + protected onChainChanged(chainId: string) { + this.emitter.emit('chainId', chainId) + } + + protected onDisconnect() { + this.emitter.emit('disconnect', ProviderType.Fortmatic) + } + private createFortmatic(chainId: ChainIdFortmatic) { const rpcUrl = first(getRPCConstants(chainId).RPC_URLS) if (!rpcUrl) throw new Error('Failed to create provider.') @@ -85,11 +98,21 @@ export default class FortmaticProvider extends BaseProvider implements EVM_Provi return fm.user.logout() } + override async switchChain(chainId?: ChainId): Promise { + if (chainId) { + await this.connect(chainId) + return + } + throw new Error(`Failed to switch to ${chainResolver.chainFullName(chainId)}.`) + } + override async connect(chainId: ChainId) { try { this.chainId = chainId const accounts = await this.login() if (!accounts.length) throw new Error(`Failed to connect to ${chainResolver.chainFullName(this.chainId)}.`) + this.onAccountsChanged(accounts) + this.onChainChanged(toHex(chainId)) return { account: first(accounts)!, chainId, @@ -103,6 +126,7 @@ export default class FortmaticProvider extends BaseProvider implements EVM_Provi override async disconnect() { await this.logout() this.chainId_ = null + this.onDisconnect() } override request(requestArguments: RequestArguments) {