From a341dadc3f4c66e6e85519bdff3a7845e8139341 Mon Sep 17 00:00:00 2001 From: guanbinrui Date: Wed, 15 Dec 2021 12:58:53 +0800 Subject: [PATCH 1/6] fix: more timeout duration for request accounts --- .../EthereumServices/providers/Fortmatic.ts | 5 +- .../EthereumServices/providers/Injected.ts | 7 ++- .../Wallet/services/transaction/helpers.ts | 57 ++++++++++++++++++- 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/packages/mask/src/extension/background-script/EthereumServices/providers/Fortmatic.ts b/packages/mask/src/extension/background-script/EthereumServices/providers/Fortmatic.ts index 520a6dacf9cf..8a3665eb9282 100644 --- a/packages/mask/src/extension/background-script/EthereumServices/providers/Fortmatic.ts +++ b/packages/mask/src/extension/background-script/EthereumServices/providers/Fortmatic.ts @@ -20,7 +20,10 @@ async function request(requestArguments: RequestArguments) { else resolve(result) } - setTimeout(() => reject(new Error('The request is timeout.')), 45 * 1000) + setTimeout( + () => reject(new Error('The request is timeout.')), + requestArguments.method === EthereumMethodType.MASK_LOGIN_FORTMATIC ? 3 * 60 * 1000 : 45 * 1000, + ) EVM_Messages.events.FORTMATIC_PROVIDER_RPC_RESPONSE.on(onResponse) EVM_Messages.events.FORTMATIC_PROVIDER_RPC_REQUEST.sendToVisiblePages({ payload: { diff --git a/packages/mask/src/extension/background-script/EthereumServices/providers/Injected.ts b/packages/mask/src/extension/background-script/EthereumServices/providers/Injected.ts index def98ceedcd8..6a6fce664b01 100644 --- a/packages/mask/src/extension/background-script/EthereumServices/providers/Injected.ts +++ b/packages/mask/src/extension/background-script/EthereumServices/providers/Injected.ts @@ -3,7 +3,7 @@ import { defer } from '@masknet/shared-base' import Web3 from 'web3' import type { RequestArguments } from 'web3-core' import type { JsonRpcPayload, JsonRpcResponse } from 'web3-core-helpers' -import { ChainId, ProviderType } from '@masknet/web3-shared-evm' +import { ChainId, EthereumMethodType, ProviderType } from '@masknet/web3-shared-evm' import { EVM_Messages } from '../../../../plugins/EVM/messages' import { currentChainIdSettings, currentProviderSettings } from '../../../../plugins/Wallet/settings' import { updateAccount } from '../../../../plugins/Wallet/services' @@ -22,7 +22,10 @@ async function request(requestArguments: RequestArguments) { else resolve(result) } - setTimeout(() => reject(new Error('The request is timeout.')), 45 * 1000) + setTimeout( + () => reject(new Error('The request is timeout.')), + requestArguments.method === EthereumMethodType.ETH_REQUEST_ACCOUNTS ? 3 * 60 * 1000 : 45 * 1000, + ) EVM_Messages.events.INJECTED_PROVIDER_RPC_RESPONSE.on(onResponse) EVM_Messages.events.INJECTED_PROVIDER_RPC_REQUEST.sendToVisiblePages({ payload: { diff --git a/packages/mask/src/plugins/Wallet/services/transaction/helpers.ts b/packages/mask/src/plugins/Wallet/services/transaction/helpers.ts index f717bf6f449c..52ca2695b749 100644 --- a/packages/mask/src/plugins/Wallet/services/transaction/helpers.ts +++ b/packages/mask/src/plugins/Wallet/services/transaction/helpers.ts @@ -1,6 +1,6 @@ -import { sha3 } from 'web3-utils' -import type { Transaction, TransactionConfig, TransactionReceipt } from 'web3-core' +import { sha3, toHex } from 'web3-utils' import type { JsonRpcPayload } from 'web3-core-helpers' +import type { Transaction, TransactionConfig, TransactionReceipt } from 'web3-core' import { isSameAddress, TransactionState, @@ -10,6 +10,57 @@ import { } from '@masknet/web3-shared-evm' import { unreachable } from '@dimensiondev/kit' +export function toReceipt(status: '0' | '1', transaction: Transaction): TransactionReceipt { + return { + status: status === '1', + transactionHash: transaction.hash, + transactionIndex: transaction.transactionIndex ?? 0, + blockHash: transaction.blockHash ?? '', + blockNumber: transaction.blockNumber ?? 0, + from: transaction.from, + to: transaction.to ?? '', + cumulativeGasUsed: 0, + gasUsed: 0, + logs: [], + logsBloom: '', + } +} + +export function toPayload(transaction: Transaction): JsonRpcPayload { + return { + jsonrpc: '2.0', + id: '0', + method: EthereumMethodType.ETH_SEND_TRANSACTION, + params: [ + { + from: transaction.from, + to: transaction.to, + value: transaction.value, + gas: transaction.gas, + gasPrice: transaction.gasPrice, + data: transaction.input, + nonce: transaction.nonce, + }, + ], + } +} + +export function getPayloadConfig(payload: JsonRpcPayload) { + if (!payload.id || payload.method !== EthereumMethodType.ETH_SEND_TRANSACTION) return + const [config] = payload.params as [TransactionConfig] + return config +} + +export function getPayloadFrom(payload: JsonRpcPayload) { + const config = getPayloadConfig(payload) + return config?.from as string | undefined +} + +export function getPayloadTo(payload: JsonRpcPayload) { + const config = getPayloadConfig(payload) + return config?.to as string | undefined +} + export function getPayloadId(payload: JsonRpcPayload) { if (!payload.id || payload.method !== EthereumMethodType.ETH_SEND_TRANSACTION) return '' const [config] = payload.params as [TransactionConfig] @@ -21,7 +72,7 @@ export function getPayloadId(payload: JsonRpcPayload) { export function getTransactionId(transaction: Transaction | null) { if (!transaction) return '' const { from, to, input, value } = transaction - return sha3([from, to, input || '0x0', value || '0x0'].join('_')) ?? '' + return sha3([from, to, input || '0x0', toHex(value) || '0x0'].join('_')) ?? '' } export function getReceiptStatus(receipt: TransactionReceipt | null) { From 20b933bafc5507b88728c1c2b5eaae6c02ab107b Mon Sep 17 00:00:00 2001 From: guanbinrui Date: Thu, 16 Dec 2021 00:40:00 +0800 Subject: [PATCH 2/6] fix: the fixed bridged provider --- .../src/plugins/Wallet/services/transaction/helpers.ts | 8 ++++---- packages/mask/src/web3/context.ts | 6 ++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/mask/src/plugins/Wallet/services/transaction/helpers.ts b/packages/mask/src/plugins/Wallet/services/transaction/helpers.ts index 52ca2695b749..331f36b491cc 100644 --- a/packages/mask/src/plugins/Wallet/services/transaction/helpers.ts +++ b/packages/mask/src/plugins/Wallet/services/transaction/helpers.ts @@ -10,9 +10,9 @@ import { } from '@masknet/web3-shared-evm' import { unreachable } from '@dimensiondev/kit' -export function toReceipt(status: '0' | '1', transaction: Transaction): TransactionReceipt { +export function toReceipt(status: true | string, transaction: Transaction): TransactionReceipt { return { - status: status === '1', + status: ['1', '0x1', true].includes(status), transactionHash: transaction.hash, transactionIndex: transaction.transactionIndex ?? 0, blockHash: transaction.blockHash ?? '', @@ -62,8 +62,8 @@ export function getPayloadTo(payload: JsonRpcPayload) { } export function getPayloadId(payload: JsonRpcPayload) { - if (!payload.id || payload.method !== EthereumMethodType.ETH_SEND_TRANSACTION) return '' - const [config] = payload.params as [TransactionConfig] + const config = getPayloadConfig(payload) + if (!config) return '' const { from, to, data = '0x0', value = '0x0' } = config if (!from || !to) return '' return sha3([from, to, data, value].join('_')) ?? '' diff --git a/packages/mask/src/web3/context.ts b/packages/mask/src/web3/context.ts index 3b9ff9d392b7..ae80a7c7e220 100644 --- a/packages/mask/src/web3/context.ts +++ b/packages/mask/src/web3/context.ts @@ -10,8 +10,8 @@ import { resolveProviderInjectedKey, isInjectedProvider, } from '@masknet/web3-shared-evm' -import { bridgedEthereumProvider } from '@masknet/injected-script' import { isPopupPage } from '@masknet/shared-base' +import { bridgedCoin98Provider, bridgedEthereumProvider } from '@masknet/injected-script' import { currentBlockNumberSettings, currentBalanceSettings, @@ -74,9 +74,11 @@ function createWeb3Context(disablePopup = false, isMask = false): Web3ProviderTy if (!isInjectedProvider(providerType)) return account try { + const bridgedProvider = + providerType === ProviderType.Coin98 ? bridgedCoin98Provider : bridgedEthereumProvider const injectedKey = resolveProviderInjectedKey(providerType) if (!injectedKey) return '' - const propertyValue = await bridgedEthereumProvider.getProperty(injectedKey) + const propertyValue = await bridgedProvider.getProperty(injectedKey) if (propertyValue === true) return account return '' } catch (error) { From 9d458ced04bad466ee3eb715a17f7d483e767c6a Mon Sep 17 00:00:00 2001 From: guanbinrui Date: Thu, 16 Dec 2021 01:05:35 +0800 Subject: [PATCH 3/6] fix: coin98 handle add/switch rpc provider in the wrong way --- .../SNSAdaptor/ConnectWalletDialog/index.tsx | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/packages/mask/src/plugins/Wallet/SNSAdaptor/ConnectWalletDialog/index.tsx b/packages/mask/src/plugins/Wallet/SNSAdaptor/ConnectWalletDialog/index.tsx index 700fd2952f25..c7e20ba39b49 100644 --- a/packages/mask/src/plugins/Wallet/SNSAdaptor/ConnectWalletDialog/index.tsx +++ b/packages/mask/src/plugins/Wallet/SNSAdaptor/ConnectWalletDialog/index.tsx @@ -110,15 +110,20 @@ export function ConnectWalletDialog(props: ConnectWalletDialogProps) { chainId: expectedChainId, providerType, } - await Promise.race([ - (async () => { - await delay(30 /* seconds */ * 1000 /* milliseconds */) - throw new Error('Timeout!') - })(), - networkType === NetworkType.Ethereum - ? Services.Ethereum.switchEthereumChain(ChainId.Mainnet, overrides) - : Services.Ethereum.addEthereumChain(chainDetailedCAIP, account, overrides), - ]) + + // the coin98 wallet cannot handle add/switch RPC provider correctly + // it will always add a new RPC provider even if the network exists + if (providerType !== ProviderType.Coin98) { + await Promise.race([ + (async () => { + await delay(30 /* seconds */ * 1000 /* milliseconds */) + throw new Error('Timeout!') + })(), + networkType === NetworkType.Ethereum + ? Services.Ethereum.switchEthereumChain(ChainId.Mainnet, overrides) + : Services.Ethereum.addEthereumChain(chainDetailedCAIP, account, overrides), + ]) + } // recheck const chainIdHex = await Services.Ethereum.getChainId(overrides) From 10eb65cadbc409b0ecffb0b3c765d53940479623 Mon Sep 17 00:00:00 2001 From: guanbinrui Date: Thu, 16 Dec 2021 01:45:49 +0800 Subject: [PATCH 4/6] refactor: remove unused settings --- .../background-script/SettingsService.ts | 2 - packages/mask/src/plugins/Wallet/settings.ts | 85 ++++--------------- 2 files changed, 16 insertions(+), 71 deletions(-) diff --git a/packages/mask/src/extension/background-script/SettingsService.ts b/packages/mask/src/extension/background-script/SettingsService.ts index 96e3ce634232..19ffb06bad95 100644 --- a/packages/mask/src/extension/background-script/SettingsService.ts +++ b/packages/mask/src/extension/background-script/SettingsService.ts @@ -27,7 +27,6 @@ import { currentFungibleAssetDataProviderSettings, currentNonFungibleAssetDataProviderSettings, currentGasOptionsSettings, - currentEtherPriceSettings, currentTokenPricesSettings, currentMaskWalletLockStatusSettings, currentMaskWalletAccountSettings, @@ -56,7 +55,6 @@ export const [getChainId, setChainId] = create(currentChainIdSettings) export const [getBalance, setBalance] = create(currentBalanceSettings) export const [getBalances, setBalances] = create(currentBalancesSettings) export const [getBlockNumber, setBlockNumber] = create(currentBlockNumberSettings) -export const [getEtherPrice, setEtherPrice] = create(currentEtherPriceSettings) export const [getTokenPrices, setTokenPrices] = create(currentTokenPricesSettings) export const [getGasOptions, setGasOptions] = create(currentGasOptionsSettings) export const [getGasPrice, setGasPrice] = create(currentGasOptionsSettings) diff --git a/packages/mask/src/plugins/Wallet/settings.ts b/packages/mask/src/plugins/Wallet/settings.ts index b0fe8b2dc852..2198147cf8c1 100644 --- a/packages/mask/src/plugins/Wallet/settings.ts +++ b/packages/mask/src/plugins/Wallet/settings.ts @@ -14,10 +14,6 @@ import { import { PLUGIN_IDENTIFIER } from './constants' import { isEqual } from 'lodash-unified' -export const currentAccountSettings = createGlobalSettings(`${PLUGIN_IDENTIFIER}+selectedWalletAddress`, '', { - primary: () => 'DO NOT DISPLAY IT IN UI', -}) - export const currentMaskWalletAccountSettings = createGlobalSettings( `${PLUGIN_IDENTIFIER}+selectedMaskWalletAddress`, '', @@ -44,28 +40,34 @@ export const currentMaskWalletBalanceSettings = createGlobalSettings( }, ) -/** - * The network type of the selected wallet - */ -export const currentNetworkSettings = createGlobalSettings( - `${PLUGIN_IDENTIFIER}+selectedWalletNetwork`, +export const currentMaskWalletNetworkSettings = createGlobalSettings( + `${PLUGIN_IDENTIFIER}+selectedMaskWalletNetwork`, NetworkType.Ethereum, { primary: () => 'DO NOT DISPLAY IT IN UI', }, ) -export const currentMaskWalletNetworkSettings = createGlobalSettings( - `${PLUGIN_IDENTIFIER}+selectedMaskWalletNetwork`, +export const currentMaskWalletLockStatusSettings = createGlobalSettings( + `${PLUGIN_IDENTIFIER}+maskWalletLockStatus`, + LockStatus.INIT, + { + primary: () => 'DO NOT DISPLAY IT IN UI', + }, +) + +export const currentAccountSettings = createGlobalSettings(`${PLUGIN_IDENTIFIER}+selectedWalletAddress`, '', { + primary: () => 'DO NOT DISPLAY IT IN UI', +}) + +export const currentNetworkSettings = createGlobalSettings( + `${PLUGIN_IDENTIFIER}+selectedWalletNetwork`, NetworkType.Ethereum, { primary: () => 'DO NOT DISPLAY IT IN UI', }, ) -/** - * The provider type of the selected wallet - */ export const currentProviderSettings = createGlobalSettings( `${PLUGIN_IDENTIFIER}+selectedWalletProvider`, ProviderType.MaskWallet, @@ -74,9 +76,6 @@ export const currentProviderSettings = createGlobalSettings( }, ) -/** - * The default asset data provider - */ export const currentFungibleAssetDataProviderSettings = createGlobalSettings( `${PLUGIN_IDENTIFIER}+fungibleAssetProvider`, FungibleAssetProvider.DEBANK, @@ -86,9 +85,6 @@ export const currentFungibleAssetDataProviderSettings = createGlobalSettings( `${PLUGIN_IDENTIFIER}+nonFungibleAssetProvider`, NonFungibleAssetProvider.OPENSEA, @@ -98,61 +94,19 @@ export const currentNonFungibleAssetDataProviderSettings = createGlobalSettings< }, ) -/** - * Is the current selected wallet has been locked? - */ -export const currentMaskWalletLockStatusSettings = createGlobalSettings( - `${PLUGIN_IDENTIFIER}+maskWalletLockStatus`, - LockStatus.INIT, - { - primary: () => 'DO NOT DISPLAY IT IN UI', - }, -) - -/** - * Chain Id - */ export const currentChainIdSettings = createGlobalSettings(`${PLUGIN_IDENTIFIER}+chainId`, ChainId.Mainnet, { primary: () => i18n.t('settings_choose_eth_network'), secondary: () => 'This only affects the built-in wallet.', }) -/** - * Block number - */ export const currentBlockNumberSettings = createGlobalSettings(`${PLUGIN_IDENTIFIER}+blockNumber`, 0, { primary: () => 'DO NOT DISPLAY IT IN UI', }) -/** - * Balance - */ export const currentBalanceSettings = createGlobalSettings(`${PLUGIN_IDENTIFIER}+balance`, '0', { primary: () => 'DO NOT DISPLAY IT IN UI', }) -/** - * Nonce - */ -export const currentNonceSettings = createGlobalSettings(`${PLUGIN_IDENTIFIER}+nonce`, 0, { - primary: () => 'DO NOT DISPLAY IT IN UI', -}) - -/** - * Gas Price - */ -export const currentGasPriceSettings = createGlobalSettings( - `${PLUGIN_IDENTIFIER}+gasPrice`, - 0, - { - primary: () => 'DO NOT DISPLAY IT IN UI', - }, - (a: number, b: number) => isEqual(a, b), -) - -/** - * Gas Options - */ export const currentGasOptionsSettings = createGlobalSettings( `${PLUGIN_IDENTIFIER}+gasOptions`, null, @@ -162,13 +116,6 @@ export const currentGasOptionsSettings = createGlobalSettings (a: GasOptions | null, b: GasOptions | null) => isEqual(a, b), ) -/** - * Ether Price in USD - */ -export const currentEtherPriceSettings = createGlobalSettings(`${PLUGIN_IDENTIFIER}+etherPriceUSD`, 0, { - primary: () => 'DO NOT DISPLAY IT IN UI', -}) - /** * ERC20 Token prices or native token prices */ From e9acd8c789b4044191c29d5cebc427f01b0f4dbe Mon Sep 17 00:00:00 2001 From: guanbinrui Date: Thu, 16 Dec 2021 11:26:56 +0800 Subject: [PATCH 5/6] chore: switch between network plugins --- .../SNSAdaptor/ConnectWalletDialog/index.tsx | 27 ++- .../src/web3/UI/EthereumChainBoundary.tsx | 187 ++++++++++++------ 2 files changed, 138 insertions(+), 76 deletions(-) diff --git a/packages/mask/src/plugins/Wallet/SNSAdaptor/ConnectWalletDialog/index.tsx b/packages/mask/src/plugins/Wallet/SNSAdaptor/ConnectWalletDialog/index.tsx index c7e20ba39b49..bdea5d7062fa 100644 --- a/packages/mask/src/plugins/Wallet/SNSAdaptor/ConnectWalletDialog/index.tsx +++ b/packages/mask/src/plugins/Wallet/SNSAdaptor/ConnectWalletDialog/index.tsx @@ -103,27 +103,24 @@ export function ConnectWalletDialog(props: ConnectWalletDialogProps) { // connection failed if (!account || !networkType) throw new Error(`Failed to connect to ${resolveProviderName(providerType)}.`) - // need to switch chain - if (chainId !== expectedChainId) { + // the coin98 wallet cannot handle add/switch RPC provider correctly + // it will always add a new RPC provider even if the network exists + if (chainId !== expectedChainId && providerType !== ProviderType.Coin98) { try { const overrides = { chainId: expectedChainId, providerType, } - // the coin98 wallet cannot handle add/switch RPC provider correctly - // it will always add a new RPC provider even if the network exists - if (providerType !== ProviderType.Coin98) { - await Promise.race([ - (async () => { - await delay(30 /* seconds */ * 1000 /* milliseconds */) - throw new Error('Timeout!') - })(), - networkType === NetworkType.Ethereum - ? Services.Ethereum.switchEthereumChain(ChainId.Mainnet, overrides) - : Services.Ethereum.addEthereumChain(chainDetailedCAIP, account, overrides), - ]) - } + await Promise.race([ + (async () => { + await delay(30 /* seconds */ * 1000 /* milliseconds */) + throw new Error('Timeout!') + })(), + networkType === NetworkType.Ethereum + ? Services.Ethereum.switchEthereumChain(ChainId.Mainnet, overrides) + : Services.Ethereum.addEthereumChain(chainDetailedCAIP, account, overrides), + ]) // recheck const chainIdHex = await Services.Ethereum.getChainId(overrides) diff --git a/packages/mask/src/web3/UI/EthereumChainBoundary.tsx b/packages/mask/src/web3/UI/EthereumChainBoundary.tsx index 0b05b35ddc79..32f0f38d865d 100644 --- a/packages/mask/src/web3/UI/EthereumChainBoundary.tsx +++ b/packages/mask/src/web3/UI/EthereumChainBoundary.tsx @@ -1,7 +1,8 @@ -import { useCallback } from 'react' +import React, { useCallback } from 'react' import { Box, Typography, Theme } from '@mui/material' import { makeStyles, useStylesExtends } from '@masknet/theme' import type { SxProps } from '@mui/system' +import { NetworkPluginID, useActivatedPlugin, usePluginIDContext } from '@masknet/plugin-infra' import { ChainId, getChainDetailedCAIP, @@ -25,6 +26,7 @@ import { currentProviderSettings } from '../../plugins/Wallet/settings' import { useI18N } from '../../utils' import { WalletMessages, WalletRPC } from '../../plugins/Wallet/messages' import Services from '../../extension/service' +import { pluginIDSettings } from '../../settings/settings' const useStyles = makeStyles()(() => ({})) @@ -40,6 +42,10 @@ export interface EthereumChainBoundaryProps extends withClasses<'switchButton'> export function EthereumChainBoundary(props: EthereumChainBoundaryProps) { const { t } = useI18N() + + const pluginID = usePluginIDContext() + const plugin = useActivatedPlugin(pluginID) + const account = useAccount() const chainId = useChainId() const allowTestnet = useAllowTestnet() @@ -48,66 +54,89 @@ export function EthereumChainBoundary(props: EthereumChainBoundaryProps) { const { noSwitchNetworkTip = false } = props const classes = useStylesExtends(useStyles(), props) const expectedChainId = props.chainId - const expectedNetwork = expectedChainId === ChainId.BSC ? 'BSC' : getChainName(expectedChainId) + const expectedNetwork = getChainName(expectedChainId) + const actualChainId = chainId - const actualNetwork = actualChainId === ChainId.BSC ? 'BSC' : getChainName(actualChainId) + const actualNetwork = getChainName(actualChainId) // if false then it will not guide the user to switch the network - const isAllowed = isChainIdValid(expectedChainId, allowTestnet) && !!account + const isAllowed = isChainIdValid(expectedChainId, allowTestnet) && !!account && providerType !== ProviderType.Coin98 + + // is the actual chain id matched with the expected one? + const isChainMatched = actualChainId === expectedChainId + const isPluginMatched = pluginID === NetworkPluginID.PLUGIN_EVM - const onSwitch = useCallback(async () => { + // is the actual chain id a valid one even if it does not match with the expected one? + const isValid = props?.isValidChainId?.(actualChainId, expectedChainId) ?? false + + const onSwitchChain = useCallback(async () => { // a short time loading makes the user fells better await delay(1000) if (!isAllowed) return - // read the chain detailed from the built-in chain list - const chainDetailedCAIP = getChainDetailedCAIP(expectedChainId) - if (!chainDetailedCAIP) throw new Error('Unknown network type.') + const switchToChain = async () => { + // read the chain detailed from the built-in chain list + const chainDetailedCAIP = getChainDetailedCAIP(expectedChainId) + if (!chainDetailedCAIP) throw new Error('Unknown network type.') + + // if mask wallet was used it can switch network automatically + if (providerType === ProviderType.MaskWallet) { + await WalletRPC.updateAccount({ + chainId: expectedChainId, + }) + return + } - // if mask wallet was used it can switch network automatically - if (providerType === ProviderType.MaskWallet) { - await WalletRPC.updateAccount({ - chainId: expectedChainId, - }) - return + // request ethereum-compatible network + const networkType = getNetworkTypeFromChainId(expectedChainId) + if (!networkType) return + try { + const overrides = { + chainId: expectedChainId, + providerType, + } + await Promise.race([ + (async () => { + await delay(30 /* seconds */ * 1000 /* milliseconds */) + throw new Error('Timeout!') + })(), + networkType === NetworkType.Ethereum + ? Services.Ethereum.switchEthereumChain(expectedChainId, overrides) + : Services.Ethereum.addEthereumChain(chainDetailedCAIP, account, overrides), + ]) + } catch { + throw new Error(`Make sure your wallet is on the ${resolveNetworkName(networkType)} network.`) + } } - // request ethereum-compatible network - const networkType = getNetworkTypeFromChainId(expectedChainId) - if (!networkType) return - try { - const overrides = { - chainId: expectedChainId, - providerType, - } - await Promise.race([ - (async () => { - await delay(30 /* seconds */ * 1000 /* milliseconds */) - throw new Error('Timeout!') - })(), - networkType === NetworkType.Ethereum - ? Services.Ethereum.switchEthereumChain(expectedChainId, overrides) - : Services.Ethereum.addEthereumChain(chainDetailedCAIP, account, overrides), - ]) - } catch { - throw new Error(`Make sure your wallet is on the ${resolveNetworkName(networkType)} network.`) + const switchToPlugin = async () => { + pluginIDSettings.value = NetworkPluginID.PLUGIN_EVM } - }, [account, isAllowed, providerType, expectedChainId]) + + if (!isChainMatched) await switchToChain() + if (!isPluginMatched) await switchToPlugin() + }, [account, isAllowed, isChainMatched, isPluginMatched, providerType, expectedChainId]) const { openDialog: openSelectProviderDialog } = useRemoteControlledDialog( WalletMessages.events.selectProviderDialogUpdated, ) - // is the actual chain id matched with the expected one? - const isMatched = actualChainId === expectedChainId - - // is the actual chain id a valid one even if it does not match with the expected one? - const isValid = props?.isValidChainId?.(actualChainId, expectedChainId) ?? false + const renderBox = (children?: React.ReactNode) => { + return ( + + {children} + + ) + } if (!account) - return ( - + return renderBox( + <> {t('plugin_wallet_connect_wallet_tip')} @@ -118,30 +147,66 @@ export function EthereumChainBoundary(props: EthereumChainBoundaryProps) { onClick={openSelectProviderDialog}> {t('plugin_wallet_connect_wallet')} - + , ) - if (isMatched || isValid) return <>{props.children} + if ((isChainMatched && isPluginMatched) || isValid) return <>{props.children} if (!isAllowed) - return ( - - - - {t('plugin_wallet_not_available_on', { - network: actualNetwork, + return renderBox( + + + {t('plugin_wallet_not_available_on', { + network: actualNetwork, + })} + + , + ) + + if (pluginID !== NetworkPluginID.PLUGIN_EVM) { + return renderBox( + <> + {!noSwitchNetworkTip ? ( + + + {t('plugin_wallet_not_available_on', { + network: plugin?.name?.fallback ?? 'Unknown Plugin', + })} + + + ) : null} + {isAllowed ? ( + + {t('plugin_wallet_switch_network', { + network: expectedNetwork, + })} + + } + waiting={t('plugin_wallet_switch_network_under_going', { + network: expectedNetwork, })} - - - + complete={t('plugin_wallet_switch_network', { + network: expectedNetwork, + })} + failed={t('retry')} + executor={onSwitchChain} + completeOnClick={onSwitchChain} + failedOnClick="use executor" + {...props.ActionButtonPromiseProps} + /> + ) : null} + , ) + } - return ( - + return renderBox( + <> {!noSwitchNetworkTip ? ( @@ -171,12 +236,12 @@ export function EthereumChainBoundary(props: EthereumChainBoundaryProps) { network: expectedNetwork, })} failed={t('retry')} - executor={onSwitch} - completeOnClick={onSwitch} + executor={onSwitchChain} + completeOnClick={onSwitchChain} failedOnClick="use executor" {...props.ActionButtonPromiseProps} /> ) : null} - + , ) } From ca56228e31025cf72c8112abb171b0cd3b2bc43c Mon Sep 17 00:00:00 2001 From: guanbinrui Date: Thu, 16 Dec 2021 11:51:39 +0800 Subject: [PATCH 6/6] fix: disable fortmatic on dashboard --- packages/dashboard/src/web3/context.ts | 2 +- .../src/plugins/EVM/UI/components/FortmaticProviderBridge.tsx | 2 ++ .../src/plugins/EVM/UI/components/InjectedProviderBridge.tsx | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/dashboard/src/web3/context.ts b/packages/dashboard/src/web3/context.ts index c2a354e85d12..e1d4d70b5824 100644 --- a/packages/dashboard/src/web3/context.ts +++ b/packages/dashboard/src/web3/context.ts @@ -30,7 +30,7 @@ export const Web3Context: Web3ProviderType = { account: createSubscriptionFromAsync( async () => { const providerType = await Services.Settings.getCurrentSelectedWalletProvider() - if (isInjectedProvider(providerType)) return '' + if (isInjectedProvider(providerType) || providerType === ProviderType.Fortmatic) return '' return Services.Settings.getSelectedWalletAddress() }, '', diff --git a/packages/mask/src/plugins/EVM/UI/components/FortmaticProviderBridge.tsx b/packages/mask/src/plugins/EVM/UI/components/FortmaticProviderBridge.tsx index e99e345af6eb..d6ff50a07c25 100644 --- a/packages/mask/src/plugins/EVM/UI/components/FortmaticProviderBridge.tsx +++ b/packages/mask/src/plugins/EVM/UI/components/FortmaticProviderBridge.tsx @@ -4,6 +4,7 @@ import { first } from 'lodash-unified' import { ChainId, EthereumMethodType, isFortmaticSupported, ProviderType } from '@masknet/web3-shared-evm' import * as Fortmatic from '@masknet/web3-shared-evm/providers/Fortmatic' import { NetworkPluginID, useChainId, useProviderType } from '@masknet/plugin-infra' +import { isDashboardPage, isPopupPage } from '@masknet/shared-base' import { EVM_Messages } from '../../messages' import { WalletRPC } from '../../../Wallet/messages' import Services from '../../../../extension/service' @@ -15,6 +16,7 @@ export function FortmaticProviderBridge(props: FortmaticProviderBridgeProps) { const providerType = useProviderType(NetworkPluginID.PLUGIN_EVM) const onMounted = useCallback(async () => { + if (isDashboardPage() || isPopupPage()) return if (providerType !== ProviderType.Fortmatic) return const connected = await Services.Ethereum.connectFortmatic( isFortmaticSupported(chainId) ? chainId : ChainId.Mainnet, diff --git a/packages/mask/src/plugins/EVM/UI/components/InjectedProviderBridge.tsx b/packages/mask/src/plugins/EVM/UI/components/InjectedProviderBridge.tsx index 09a1cffaed8d..9369c686b701 100644 --- a/packages/mask/src/plugins/EVM/UI/components/InjectedProviderBridge.tsx +++ b/packages/mask/src/plugins/EVM/UI/components/InjectedProviderBridge.tsx @@ -2,6 +2,7 @@ import { useEffect, useCallback } from 'react' import { useMount } from 'react-use' import { ProviderType, isInjectedProvider, ChainId } from '@masknet/web3-shared-evm' import { NetworkPluginID, useChainId, useProviderType } from '@masknet/plugin-infra' +import { isDashboardPage, isPopupPage } from '@masknet/shared-base' import { EVM_Messages } from '../../messages' import Services from '../../../../extension/service' import { WalletRPC } from '../../../Wallet/messages' @@ -17,6 +18,7 @@ export function InjectedProviderBridge(props: InjectedProviderBridgeProps) { const bridgedProvider = useBridgedProvider(props.type) const onMounted = useCallback(async () => { + if (isDashboardPage() || isPopupPage()) return if (providerType !== ProviderType.Coin98) return const connected = await Services.Ethereum.connectInjected() await WalletRPC.updateAccount({