From 57bfb049756c31536f28b536d4024fee3bb5477c Mon Sep 17 00:00:00 2001 From: Hodor Date: Tue, 14 Jan 2025 18:36:41 +0800 Subject: [PATCH] feat: reflector page provider (#2718) * feat: reflector page provider * feat: udpate provider * fix: provider * chore: fix some ui bugs * chore: fix some bugs * fix: metamaskModeService * feat: update provider * fix: conflict with rainbow * feat: update page-provider --------- Co-authored-by: vvvvvv1vvvvvv --- _raw/locales/en/messages.json | 24 +- package.json | 2 +- .../controller/provider/controller.ts | 3 +- src/background/controller/provider/index.ts | 6 +- .../controller/provider/internalMethod.ts | 19 +- src/background/controller/provider/rpcFlow.ts | 5 +- src/background/controller/wallet.ts | 66 +++- src/background/index.ts | 2 + src/background/service/contextMenu.ts | 143 -------- src/background/service/index.ts | 1 - src/background/service/metamaskModeService.ts | 124 +++++++ src/background/service/permission.ts | 17 +- src/background/service/session.ts | 12 +- src/background/utils/alarms.ts | 1 + src/background/utils/index.ts | 4 +- .../assets/dashboard/icon-metamask-yellow.svg | 4 + src/ui/assets/dashboard/question-cc.svg | 12 + .../assets/metamask-mode-dapps/delete-cc.svg | 7 + .../icon-metamask-mode-dark.svg | 86 +++++ .../icon-metamask-mode.svg | 86 +++++ .../components/Connect/SelectWallet.tsx | 68 ++++ .../Approval/components/Connect/index.tsx | 317 ++++++++++-------- .../components/CurrentConnection/index.tsx | 179 +++++----- .../components/DefaultWalletSetting/index.tsx | 80 ----- .../DefaultWalletSetting/style.less | 98 ------ .../components/MetamaskModePopup/index.tsx | 101 ++++++ .../Dashboard/components/Settings/index.tsx | 8 +- src/ui/views/Dashboard/components/index.tsx | 1 - src/ui/views/Dashboard/index.tsx | 2 - src/ui/views/MainRoute.tsx | 6 +- src/ui/views/MetamaskModeDapps/index.tsx | 92 +++++ src/ui/views/MetamaskModeDapps/style.less | 119 +++++++ src/utils/message/broadcastChannelMessage.ts | 16 +- yarn.lock | 8 +- 34 files changed, 1137 insertions(+), 582 deletions(-) delete mode 100644 src/background/service/contextMenu.ts create mode 100644 src/background/service/metamaskModeService.ts create mode 100644 src/ui/assets/dashboard/icon-metamask-yellow.svg create mode 100644 src/ui/assets/dashboard/question-cc.svg create mode 100644 src/ui/assets/metamask-mode-dapps/delete-cc.svg create mode 100644 src/ui/assets/metamask-mode-dapps/icon-metamask-mode-dark.svg create mode 100644 src/ui/assets/metamask-mode-dapps/icon-metamask-mode.svg create mode 100644 src/ui/views/Approval/components/Connect/SelectWallet.tsx delete mode 100644 src/ui/views/Dashboard/components/DefaultWalletSetting/index.tsx delete mode 100644 src/ui/views/Dashboard/components/DefaultWalletSetting/style.less create mode 100644 src/ui/views/Dashboard/components/MetamaskModePopup/index.tsx create mode 100644 src/ui/views/MetamaskModeDapps/index.tsx create mode 100644 src/ui/views/MetamaskModeDapps/style.less diff --git a/_raw/locales/en/messages.json b/_raw/locales/en/messages.json index 48ecfdd5443..d2f0dbbc1e6 100644 --- a/_raw/locales/en/messages.json +++ b/_raw/locales/en/messages.json @@ -1151,7 +1151,8 @@ "recentlyConnected": "Recently connected", "noRecentlyConnectedDapps": "No recently connected Dapps", "noConnectedDapps": "No connected Dapps", - "dapps": "Dapps" + "dapps": "Dapps", + "metamaskModeTooltip": "Can’t connect Rabby on this Dapp? Try enabling <1>MetaMask Mode" }, "feedback": { "directMessage": { @@ -1268,7 +1269,8 @@ "enableTestnets": "Enable Testnets", "toggleThemeMode": "Theme Mode", "themeMode": "Theme Mode", - "customTestnet": "Add Custom Network" + "customTestnet": "Add Custom Network", + "metamaskMode": "MetaMask Mode" }, "aboutUs": "About us", "currentVersion": "Current Version", @@ -1403,6 +1405,13 @@ }, "echologyPopup": { "title": "Ecosystem" + }, + "MetamaskModePopup": { + "title": "MetaMask Mode", + "desc": "If you can’t connect Rabby on a Dapp, enable MetaMask Mode and connect by selecting the MetaMask option.", + "footerText": "Add more Dapps to MetaMask Mode in More > MetaMask Mode", + "enableDesc": "Enable if Dapp only works with MetaMask", + "toastSuccess": "Enabled. Refresh the page to reconnect." } }, "nft": { @@ -1842,7 +1851,12 @@ "SignTestnetPermission": { "title": "Signing permission" }, - "ignoreAll": "Ignore all" + "ignoreAll": "Ignore all", + "otherWalletBtn": "Connect with Another Wallet", + "SelectWallet": { + "title": "Select a Wallet to Connect", + "desc": "Choose from the wallets you have installed" + } }, "addressDetail": { "add-to-whitelist": "Add to Whitelist", @@ -2466,6 +2480,10 @@ "loading": "Searching the deployed chain of this address" } }, + "metamaskModeDapps": { + "title": "MetaMask Mode", + "desc": "MetaMask Mode enabled for the following Dapps. You can connect Rabby by selecting the MetaMask option." + }, "forgotPassword": { "home": { "title": "Forgot Password", diff --git a/package.json b/package.json index 86e609f506c..35c37ca8a95 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "@rabby-wallet/eth-walletconnect-keyring": "2.1.5", "@rabby-wallet/eth-watch-keyring": "1.0.0", "@rabby-wallet/gnosis-sdk": "1.3.10", - "@rabby-wallet/page-provider": "0.4.2", + "@rabby-wallet/page-provider": "0.4.3", "@rabby-wallet/rabby-action": "0.1.8", "@rabby-wallet/rabby-api": "0.9.9", "@rabby-wallet/rabby-security-engine": "2.0.7", diff --git a/src/background/controller/provider/controller.ts b/src/background/controller/provider/controller.ts index 00b0fb42cef..708406565a2 100644 --- a/src/background/controller/provider/controller.ts +++ b/src/background/controller/provider/controller.ts @@ -266,6 +266,7 @@ class ProviderController extends BaseController { }; ethRequestAccounts = async ({ session: { origin } }) => { + console.log('ethRequestAccounts'); if (!permissionService.hasPermission(origin)) { throw ethErrors.provider.unauthorized(); } @@ -1257,7 +1258,7 @@ class ProviderController extends BaseController { */ @Reflect.metadata('SAFE', true) walletRevokePermissions = ({ session: { origin }, data: { params } }) => { - if (Wallet.isUnlocked() && Wallet.getConnectedSite(origin)) { + if (Wallet.isUnlocked() && Wallet.getSite(origin)) { if (params?.[0] && 'eth_accounts' in params[0]) { Wallet.removeConnectedSite(origin); } diff --git a/src/background/controller/provider/index.ts b/src/background/controller/provider/index.ts index 5f67cd31952..116d0a02801 100644 --- a/src/background/controller/provider/index.ts +++ b/src/background/controller/provider/index.ts @@ -2,11 +2,7 @@ import { ProviderRequest } from './type'; import { ethErrors } from 'eth-rpc-errors'; import { tab } from 'background/webapi'; -import { - sessionService, - keyringService, - contextMenuService, -} from 'background/service'; +import { sessionService, keyringService } from 'background/service'; import rpcFlow from './rpcFlow'; import internalMethod from './internalMethod'; diff --git a/src/background/controller/provider/internalMethod.ts b/src/background/controller/provider/internalMethod.ts index 770f6f33028..11c055b191c 100644 --- a/src/background/controller/provider/internalMethod.ts +++ b/src/background/controller/provider/internalMethod.ts @@ -4,7 +4,6 @@ import { permissionService, keyringService, preferenceService, - contextMenuService, } from 'background/service'; import providerController from './controller'; import { findChainByEnum } from '@/utils/chain'; @@ -23,7 +22,6 @@ const tabCheckin = ({ origin, }) => { session.setProp({ origin, name, icon }); - contextMenuService.createOrUpdate(origin); const site = permissionService.getSite(origin); if (site) { permissionService.updateConnectSite(origin, { ...site, icon, name }, true); @@ -79,12 +77,8 @@ const providerOverwrite = ({ }; const hasOtherProvider = () => { - const prev = preferenceService.getHasOtherProvider(); preferenceService.setHasOtherProvider(true); const isRabby = preferenceService.getIsDefaultWallet(); - if (!prev) { - contextMenuService.init(); - } if (wallet.isUnlocked()) { setPopupIcon(isRabby ? 'rabby' : 'metamask'); } @@ -95,10 +89,23 @@ const isDefaultWallet = ({ origin }) => { return preferenceService.getIsDefaultWallet(origin); }; +const getProvider = ({ origin }: { origin: string }) => { + return permissionService.getSite(origin)?.rdns; +}; + +const resetProvider = ({ origin }: { origin: string }) => { + const site = permissionService.getSite(origin); + if (site) { + permissionService.setSite({ ...site, rdns: undefined }); + } +}; + export default { tabCheckin, getProviderState, providerOverwrite, hasOtherProvider, isDefaultWallet, + 'rabby:getProvider': getProvider, + 'rabby:resetProvider': resetProvider, }; diff --git a/src/background/controller/provider/rpcFlow.ts b/src/background/controller/provider/rpcFlow.ts index fb4c4cdb93c..c059dc21882 100644 --- a/src/background/controller/provider/rpcFlow.ts +++ b/src/background/controller/provider/rpcFlow.ts @@ -104,9 +104,11 @@ const flowContext = flow const { request: { session: { origin, name, icon }, + data, }, mapMethod, } = ctx; + console.log(ctx); if (!Reflect.getMetadata('SAFE', providerController, mapMethod)) { if (!permissionService.hasPermission(origin)) { if (connectOrigins.has(origin)) { @@ -119,12 +121,13 @@ const flowContext = flow try { const { defaultChain } = await notificationService.requestApproval( { - params: { origin, name, icon }, + params: { origin, name, icon, $ctx: data.$ctx }, approvalComponent: 'Connect', }, { height: 800 } ); connectOrigins.delete(origin); + console.log('xxxxx'); permissionService.addConnectedSiteV2({ origin, name, diff --git a/src/background/controller/wallet.ts b/src/background/controller/wallet.ts index 35879b4da3c..bbed540c122 100644 --- a/src/background/controller/wallet.ts +++ b/src/background/controller/wallet.ts @@ -1,7 +1,7 @@ import * as ethUtil from 'ethereumjs-util'; import { ethErrors } from 'eth-rpc-errors'; import { ethers, Contract } from 'ethers'; -import { groupBy, isEqual, sortBy, uniq } from 'lodash'; +import { groupBy, isEqual, sortBy, truncate, uniq } from 'lodash'; import abiCoder, { AbiCoder } from 'web3-eth-abi'; import { keyringService, @@ -18,7 +18,6 @@ import { swapService, RPCService, unTriggerTxCounter, - contextMenuService, securityEngineService, transactionBroadcastWatchService, RabbyPointsService, @@ -133,6 +132,7 @@ import pRetry from 'p-retry'; import Browser from 'webextension-polyfill'; import { hashSafeMessage } from '@safe-global/protocol-kit'; import { userGuideService } from '../service/userGuide'; +import { metamaskModeService } from '../service/metamaskModeService'; const stashKeyrings: Record = {}; @@ -1935,7 +1935,6 @@ export class WalletController extends BaseController { ); site.preferMetamask = false; permissionService.setSite(site); - contextMenuService.createOrUpdate(site.origin); const currentIsDefaultWallet = preferenceService.getIsDefaultWallet(origin); const hasOtherProvider = preferenceService.getHasOtherProvider(); if (prevIsDefaultWallet !== currentIsDefaultWallet && hasOtherProvider) { @@ -1976,7 +1975,29 @@ export class WalletController extends BaseController { permissionService.removeConnectedSite(origin); }; getSitesByDefaultChain = permissionService.getSitesByDefaultChain; + /** + * @deprecated + */ getPreferMetamaskSites = permissionService.getPreferMetamaskSites; + getMetamaskModeSites = permissionService.getMetamaskModeSites; + addMetamaskModeSite = (site: ConnectedSite) => { + permissionService.setSite({ + ...site, + isMetamaskMode: true, + }); + metamaskModeService.localSites.push( + site.origin.replace(/^https?:\/\//, '') + ); + }; + removeMetamaskModeSite = (site: ConnectedSite) => { + permissionService.setSite({ + ...site, + isMetamaskMode: false, + }); + metamaskModeService.localSites = metamaskModeService.localSites.filter( + (item) => item !== site.origin.replace(/^https?:\/\//, '') + ); + }; topConnectedSite = (origin: string) => permissionService.topConnectedSite(origin); unpinConnectedSite = (origin: string) => @@ -5051,6 +5072,45 @@ export class WalletController extends BaseController { }); }; + changeDappProvider = ({ + origin, + name, + icon, + rdns, + }: { + origin: string; + name: string; + icon: string; + rdns: string; + }) => { + const site = permissionService.getSite(origin); + if (site) { + permissionService.setSite({ + ...site, + rdns, + isConnected: false, + }); + } else { + permissionService.setSite({ + origin, + name, + icon, + chain: CHAINS_ENUM.ETH, + isSigned: false, + isConnected: false, + isTop: false, + rdns, + }); + } + sessionService.broadcastEvent( + 'rabby:providerChanged', + { + rdns, + }, + origin, + true + ); + }; savedUnencryptedKeyringData = async () => keyringService.savedUnencryptedKeyringData(); diff --git a/src/background/index.ts b/src/background/index.ts index f6784aafa9d..6c20043ede1 100644 --- a/src/background/index.ts +++ b/src/background/index.ts @@ -53,6 +53,7 @@ import { userGuideService } from './service/userGuide'; import { isSameAddress } from './utils'; import rpcCache from './utils/rpcCache'; import { storage } from './webapi'; +import { metamaskModeService } from './service/metamaskModeService'; Safe.adapter = fetchAdapter as any; @@ -104,6 +105,7 @@ async function restoreAppState() { await bridgeService.init(); await gasAccountService.init(); await uninstalledService.init(); + await metamaskModeService.init(); await walletController.tryUnlock(); diff --git a/src/background/service/contextMenu.ts b/src/background/service/contextMenu.ts deleted file mode 100644 index ef5c23566f4..00000000000 --- a/src/background/service/contextMenu.ts +++ /dev/null @@ -1,143 +0,0 @@ -import { CHAINS_ENUM } from '@debank/common'; -import { - permissionService, - preferenceService, - sessionService, -} from 'background/service'; -import Browser, { Menus, Tabs } from 'webextension-polyfill'; - -const getTabsOriginList = () => { - const res: string[] = []; - for (const session of sessionService.getSessionMap().values()) { - if (session?.origin) { - res.push(session.origin); - } - } - return res; -}; - -const getContextMenuTitle = (origin: string | number) => { - const site = permissionService.getSite(origin); - const title = site?.preferMetamask - ? 'Do not prefer to use MetaMask on this dapp' - : 'Prefer to use MetaMask on this dapp'; - return title; -}; - -export class ContextMenu { - store = new Set(); - - constructor() { - Browser.contextMenus.onClicked.addListener(this.listener); - } - - create(origin: string) { - if (this.store.has(origin) || !preferenceService.getHasOtherProvider()) { - return; - } - - Browser.contextMenus.create( - { - id: origin, - title: getContextMenuTitle(origin), - documentUrlPatterns: [`${origin}/*`], - }, - () => {} - ); - this.store.add(origin); - } - createOrUpdate(origin: string) { - if (this.store.has(origin)) { - this.update(origin); - } else { - this.create(origin); - } - } - update(origin: string | number) { - const _origin = origin.toString(); - if (!this.store.has(_origin)) { - return; - } - - Browser.contextMenus.update(origin, { - title: getContextMenuTitle(origin), - }); - } - remove(origin: string) { - if (!this.store.has(origin)) { - return; - } - Browser.contextMenus.remove(origin).then(() => { - this.store.delete(origin); - }); - } - removeAll() { - this.store.clear(); - Browser.contextMenus.removeAll(); - } - - async sync() { - const originList = await getTabsOriginList(); - this.store.forEach((origin) => { - if (!originList.includes(origin)) { - this.remove(origin); - } - }); - originList.forEach((origin) => { - if (!this.store.has(origin)) { - this.create(origin); - } - }); - } - - async init() { - this.removeAll(); - const originList = await getTabsOriginList(); - originList.forEach((origin) => { - this.create(origin); - }); - } - - private listener = (info: Menus.OnClickData, tab: Tabs.Tab | undefined) => { - if (!info.menuItemId) { - return; - } - - let site = permissionService.getSite(info.menuItemId); - if (!site && tab) { - site = { - origin: info.menuItemId.toString(), - icon: tab.favIconUrl || '', - name: tab.title || '', - isSigned: false, - isConnected: false, - isTop: false, - chain: CHAINS_ENUM.ETH, - }; - } - if (!site) { - return; - } - const prevIsDefaultWallet = preferenceService.getIsDefaultWallet( - site.origin - ); - site.preferMetamask = !site.preferMetamask; - permissionService.setSite(site); - this.update(info.menuItemId); - const currentIsDefaultWallet = preferenceService.getIsDefaultWallet( - site.origin - ); - if ( - prevIsDefaultWallet !== currentIsDefaultWallet && - preferenceService.getHasOtherProvider() - ) { - sessionService.broadcastEvent( - 'defaultWalletChanged', - currentIsDefaultWallet ? 'rabby' : 'metamask', - site.origin - ); - } - }; -} - -export const contextMenuService = new ContextMenu(); diff --git a/src/background/service/index.ts b/src/background/service/index.ts index fa3c24a9a90..798423c9ae7 100644 --- a/src/background/service/index.ts +++ b/src/background/service/index.ts @@ -14,7 +14,6 @@ export { default as swapService } from './swap'; export { default as RPCService } from './rpc'; export { default as i18n } from './i18n'; export { default as unTriggerTxCounter } from './unTriggerTxCounter'; -export * from './contextMenu'; export { default as securityEngineService } from './securityEngine'; export * from './transactionBroadcastWatcher'; export { default as RabbyPointsService } from './rabbyPoints'; diff --git a/src/background/service/metamaskModeService.ts b/src/background/service/metamaskModeService.ts new file mode 100644 index 00000000000..0789d7e3309 --- /dev/null +++ b/src/background/service/metamaskModeService.ts @@ -0,0 +1,124 @@ +import { isManifestV3 } from '@/utils/env'; +import browser from 'webextension-polyfill'; +import { createPersistStore } from '../utils'; +import { ALARMS_SYNC_METAMASK_DAPPS } from '../utils/alarms'; +import { http } from '../utils/http'; +import permissionService from './permission'; + +interface MetamaskModeServiceStore { + sites: string[]; +} +class MetamaskModeService { + timer: ReturnType | null = null; + + store: MetamaskModeServiceStore = { + sites: [], + }; + + localSites: string[] = []; + + init = async () => { + const storageCache = await createPersistStore({ + name: 'metamaskMode', + template: { + sites: [], + }, + }); + this.store = storageCache || this.store; + + this.syncMetamaskModeList(); + this.resetTimer(); + this.localSites = permissionService.getMetamaskModeSites().map((item) => { + return item.origin.replace(/^https?:\/\//, ''); + }); + + this.registerEvent(); + }; + + syncMetamaskModeList = async () => { + try { + const sites = await http + .get('https://static.debank.com/fake_mm_dapps.json') + .then((res) => { + return res.data as string[]; + }); + this.store.sites = sites; + } catch (e) { + console.error('fetch metamask list error: ', e); + } + }; + + resetTimer = () => { + const periodInMinutes = 30; + if (this.timer) { + clearInterval(this.timer); + } else if (isManifestV3) { + browser.alarms.clear(ALARMS_SYNC_METAMASK_DAPPS); + } + + if (isManifestV3) { + browser.alarms.create(ALARMS_SYNC_METAMASK_DAPPS, { + delayInMinutes: periodInMinutes, + periodInMinutes: periodInMinutes, + }); + browser.alarms.onAlarm.addListener((alarm) => { + if (alarm.name === ALARMS_SYNC_METAMASK_DAPPS) { + this.syncMetamaskModeList(); + } + }); + } else { + this.timer = setInterval(() => { + this.syncMetamaskModeList(); + }, periodInMinutes * 60 * 1000); + } + }; + + defineMetamaskMode = () => { + (function () { + console.log('inject by executeScript'); + (window as any).__rabby__inject__ = { + isMetamaskMode: true, + }; + if ((window as any).rabbyWalletRouter) { + (window as any).rabbyWalletRouter.rabbyProvider.isMetaMask = true; + delete (window as any).rabbyWalletRouter.rabbyProvider.isRabby; + (window as any).rabbyWalletRouter.rabbyEthereumProvider.isMetaMask = true; + delete (window as any).rabbyWalletRouter.rabbyEthereumProvider.isRabby; + window.dispatchEvent(new Event('eip6963:requestProvider')); + } + })(); + }; + + handleInject = (tabId: number) => { + const sites = new Set([...this.store.sites, ...this.localSites]); + browser.tabs.get(tabId).then((tab) => { + if (tab.url?.startsWith('http') && sites.has(new URL(tab.url).hostname)) + browser.scripting.executeScript({ + target: { + tabId, + }, + func: this.defineMetamaskMode, + injectImmediately: true, + // Inject as soon as possible + // todo ts + world: 'MAIN' as any, + }); + }); + }; + registerEvent = () => { + browser.tabs.onCreated.addListener((tab) => { + tab.id && this.handleInject(tab.id); + }); + browser.tabs.onActivated.addListener((tab) => { + this.handleInject(tab.tabId); + }); + browser.tabs.onReplaced.addListener((tabId) => { + this.handleInject(tabId); + }); + browser.tabs.onUpdated.addListener((tabId) => { + this.handleInject(tabId); + }); + }; +} + +export const metamaskModeService = new MetamaskModeService(); diff --git a/src/background/service/permission.ts b/src/background/service/permission.ts index b09a8ca7f1d..739fad10b4f 100644 --- a/src/background/service/permission.ts +++ b/src/background/service/permission.ts @@ -16,9 +16,17 @@ export interface ConnectedSite { isTop: boolean; order?: number; isConnected: boolean; + /** + * @deprecated + */ preferMetamask?: boolean; isFavorite?: boolean; info?: BasicDappInfo; + /** + * eip6963 rdns + */ + rdns?: string; + isMetamaskMode?: boolean; } export type PermissionStore = { @@ -240,6 +248,12 @@ class PermissionService { ); }; + getMetamaskModeSites = () => { + return (this.lruCache?.values() || []).filter( + (item) => item.isMetamaskMode + ); + }; + getConnectedSite = (key: string) => { const site = this._getSite(key); if (site && site.isConnected) { @@ -293,12 +307,13 @@ class PermissionService { removeConnectedSite = (origin: string) => { if (!this.lruCache) return; - const site = this.getConnectedSite(origin); + const site = this.getSite(origin); if (!site) { return; } this.setSite({ ...site, + rdns: undefined, isConnected: false, }); this.sync(); diff --git a/src/background/service/session.ts b/src/background/service/session.ts index 79dc395020c..a8cc73f9364 100644 --- a/src/background/service/session.ts +++ b/src/background/service/session.ts @@ -78,10 +78,18 @@ const deleteSession = (key: string) => { sessionMap.delete(key); }; -const broadcastEvent = (ev, data?, origin?: string) => { +const broadcastEvent = ( + ev, + data?, + origin?: string, + ignorePermission?: boolean +) => { let sessions: { key: string; data: Session }[] = []; sessionMap.forEach((session, key) => { - if (session && permissionService.hasPermission(session.origin)) { + if ( + session && + (permissionService.hasPermission(session.origin) || ignorePermission) + ) { sessions.push({ key, data: session, diff --git a/src/background/utils/alarms.ts b/src/background/utils/alarms.ts index f4565aa18d3..5422d3cb09a 100644 --- a/src/background/utils/alarms.ts +++ b/src/background/utils/alarms.ts @@ -1 +1,2 @@ export const ALARMS_SYNC_CHAINS = 'ALARMS_SYNC_CHAINS'; +export const ALARMS_SYNC_METAMASK_DAPPS = 'ALARMS_SYNC_METAMASK_DAPPS'; diff --git a/src/background/utils/index.ts b/src/background/utils/index.ts index 7f40cbbfa6b..740f3c93fa5 100644 --- a/src/background/utils/index.ts +++ b/src/background/utils/index.ts @@ -86,9 +86,7 @@ export const setPopupIcon = ( type: 'default' | 'rabby' | 'metamask' | 'locked' ) => { const icons = [16, 19, 32, 48, 128].reduce((res, size) => { - if (type === 'rabby' || type === 'metamask') { - res[size] = `images/icon-default-${type}-${size}.png`; - } else if (type === 'locked') { + if (type === 'locked') { res[size] = `images/icon-lock-${size}.png`; } else { res[size] = `images/icon-${size}.png`; diff --git a/src/ui/assets/dashboard/icon-metamask-yellow.svg b/src/ui/assets/dashboard/icon-metamask-yellow.svg new file mode 100644 index 00000000000..9ae1c6933b4 --- /dev/null +++ b/src/ui/assets/dashboard/icon-metamask-yellow.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/ui/assets/dashboard/question-cc.svg b/src/ui/assets/dashboard/question-cc.svg new file mode 100644 index 00000000000..69ce57f5925 --- /dev/null +++ b/src/ui/assets/dashboard/question-cc.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/ui/assets/metamask-mode-dapps/delete-cc.svg b/src/ui/assets/metamask-mode-dapps/delete-cc.svg new file mode 100644 index 00000000000..655eee96b01 --- /dev/null +++ b/src/ui/assets/metamask-mode-dapps/delete-cc.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/ui/assets/metamask-mode-dapps/icon-metamask-mode-dark.svg b/src/ui/assets/metamask-mode-dapps/icon-metamask-mode-dark.svg new file mode 100644 index 00000000000..ee71d22ec44 --- /dev/null +++ b/src/ui/assets/metamask-mode-dapps/icon-metamask-mode-dark.svg @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ui/assets/metamask-mode-dapps/icon-metamask-mode.svg b/src/ui/assets/metamask-mode-dapps/icon-metamask-mode.svg new file mode 100644 index 00000000000..8da4ae215ea --- /dev/null +++ b/src/ui/assets/metamask-mode-dapps/icon-metamask-mode.svg @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ui/views/Approval/components/Connect/SelectWallet.tsx b/src/ui/views/Approval/components/Connect/SelectWallet.tsx new file mode 100644 index 00000000000..560ca796b13 --- /dev/null +++ b/src/ui/views/Approval/components/Connect/SelectWallet.tsx @@ -0,0 +1,68 @@ +import clsx from 'clsx'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { ReactComponent as RcIconBack } from 'ui/assets/icon-back-cc.svg'; + +export interface EIP6963ProviderInfo { + uuid: string; + name: string; + icon: string; + rdns: string; +} + +interface Props { + onBack(): void; + providers?: EIP6963ProviderInfo[]; + onSelect?(info: EIP6963ProviderInfo): void; +} +export const SelectWallet: React.FC = ({ + onBack, + providers, + onSelect, +}) => { + const { t } = useTranslation(); + return ( +
+
+
+ +
+
+

+ {t('page.connect.SelectWallet.title')} +

+

+ {t('page.connect.SelectWallet.desc')} +

+
+
+
+ {providers?.map((item) => { + return ( +
{ + onSelect?.(item); + }} + > + +
+ {item.name} +
+
+ ); + })} +
+
+ ); +}; diff --git a/src/ui/views/Approval/components/Connect/index.tsx b/src/ui/views/Approval/components/Connect/index.tsx index 5b0908326af..33d57ec2957 100644 --- a/src/ui/views/Approval/components/Connect/index.tsx +++ b/src/ui/views/Approval/components/Connect/index.tsx @@ -18,11 +18,12 @@ import { useLocation } from 'react-router-dom'; import styled from 'styled-components'; import IconSuccess from 'ui/assets/success.svg'; import { ChainSelector, FallbackSiteLogo, Spin } from 'ui/component'; -import { useApproval, useCommonPopupView, useWallet } from 'ui/utils'; +import { sleep, useApproval, useCommonPopupView, useWallet } from 'ui/utils'; import { useSecurityEngine } from 'ui/utils/securityEngine'; import RuleDrawer from '../SecurityEngine/RuleDrawer'; import RuleResult from './RuleResult'; import UserListDrawer from './UserListDrawer'; +import { EIP6963ProviderInfo, SelectWallet } from './SelectWallet'; interface ConnectProps { params: any; @@ -191,7 +192,11 @@ const SecurityLevelTipColor = { }, }; -const Connect = ({ params: { icon, origin } }: ConnectProps) => { +const Connect = (props: ConnectProps) => { + const { + params: { icon, origin, name, $ctx }, + } = props; + console.log(props); const { state } = useLocation<{ showChainsModal?: boolean; }>(); @@ -221,6 +226,11 @@ const Connect = ({ params: { icon, origin } }: ConnectProps) => { ignored: boolean; } | null>(null); + const [isShowSelectWallet, setIsShowSelectWallet] = useState(false); + const [providerInfo, setProviderInfo] = useState( + null + ); + const userListResult = useMemo(() => { const originBlacklist = engineResults.find( (result) => result.id === '1006' @@ -605,58 +615,60 @@ const Connect = ({ params: { icon, origin } }: ConnectProps) => { return ( - -
-
-
{t('page.connect.title')}
- -
- {t('page.connect.selectChainToConnect')} + {isShowSelectWallet ? ( + { + setIsShowSelectWallet(false); + }} + onSelect={async (info) => { + await wallet.changeDappProvider({ + origin, + icon, + name, + rdns: info.rdns, + }); + await sleep(150); + rejectApproval(); + }} + providers={$ctx?.providers || []} + /> + ) : ( + +
+
+
{t('page.connect.title')}
+ +
+ {t('page.connect.selectChainToConnect')} +
+
{origin}
-
{origin}
-
- } - value={defaultChain} - onChange={handleChainChange} - connection - showModal={showModal} - modalHeight={540} - /> -
-
- -

{origin}

+ } + value={defaultChain} + onChange={handleChainChange} + connection + showModal={showModal} + modalHeight={540} + /> +
+
+ +

{origin}

+
-
- -
- {RuleDesc.map((rule) => { - if (rule.id === '1006') { - return ( - - ); - } else { - if (sortRules.find((item) => item.id === rule.id) || rule.fixed) { + +
+ {RuleDesc.map((rule) => { + if (rule.id === '1006') { return ( item.id === rule.id)!} - key={rule.id} + rule={{ + id: '1006', + desc: t('page.connect.markRuleText'), + result: userListResult || null, + }} onSelect={handleSelectRule} collectList={collectList} popularLevel={originPopularLevel} @@ -668,97 +680,136 @@ const Connect = ({ params: { icon, origin } }: ConnectProps) => { /> ); } else { - return null; + if ( + sortRules.find((item) => item.id === rule.id) || + rule.fixed + ) { + return ( + item.id === rule.id)!} + key={rule.id} + onSelect={handleSelectRule} + collectList={collectList} + popularLevel={originPopularLevel} + userListResult={userListResult} + ignored={processedRules.includes(rule.id)} + hasSafe={hasSafe} + hasForbidden={hasForbidden} + onEditUserList={handleEditUserDataList} + /> + ); + } else { + return null; + } } - } - })} -
-
-
-
- - {connectBtnStatus.text && ( -
+
+
+
+ +
+ {$ctx?.providers?.length ? ( +
+
{ + setIsShowSelectWallet(true); }} - onClick={onIgnoreAllRules} > - {t('page.connect.ignoreAll')} - + {t('page.connect.otherWalletBtn')} +
- )} - -
-
-
- - setListDrawerVisible(false)} - /> - + ) : null} + +
+ + setListDrawerVisible(false)} + /> +
+ )}
); }; diff --git a/src/ui/views/Dashboard/components/CurrentConnection/index.tsx b/src/ui/views/Dashboard/components/CurrentConnection/index.tsx index 511cea83169..b3e78d48fcc 100644 --- a/src/ui/views/Dashboard/components/CurrentConnection/index.tsx +++ b/src/ui/views/Dashboard/components/CurrentConnection/index.tsx @@ -1,20 +1,19 @@ +import { getOriginFromUrl } from '@/utils'; +import { matomoRequestEvent } from '@/utils/matomo-request'; import { message, Tooltip } from 'antd'; import { ConnectedSite } from 'background/service/permission'; import clsx from 'clsx'; import { CHAINS_ENUM } from 'consts'; import React, { memo, useCallback, useEffect, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import IconDisconnect from 'ui/assets/icon-disconnect.svg'; -import { ReactComponent as RCIconDisconnectCC } from 'ui/assets/dashboard/current-connection/cc-disconnect.svg'; +import { Trans, useTranslation } from 'react-i18next'; +import { useLocation } from 'react-router-dom'; import IconDapps from 'ui/assets/dapps.svg'; +import { ReactComponent as RCIconDisconnectCC } from 'ui/assets/dashboard/current-connection/cc-disconnect.svg'; +import { ReactComponent as RCIconQuestionCC } from 'ui/assets/dashboard/question-cc.svg'; import { ChainSelector, FallbackSiteLogo } from 'ui/component'; import { getCurrentTab, useWallet } from 'ui/utils'; +import { MetamaskModePopup } from '../MetamaskModePopup'; import './style.less'; -import { useLocation } from 'react-router-dom'; -import { getOriginFromUrl } from '@/utils'; -import IconMetamaskBadge from 'ui/assets/dashboard/icon-metamask-badge.svg'; -import { useRequest } from 'ahooks'; -import { matomoRequestEvent } from '@/utils/matomo-request'; interface CurrentConnectionProps { onChainChange?: (chain: CHAINS_ENUM) => void; @@ -29,15 +28,14 @@ export const CurrentConnection = memo((props: CurrentConnectionProps) => { showChainsModal?: boolean; }>(); const { showChainsModal = false, trigger } = state ?? {}; - - const { data: hasOtherProvider } = useRequest(() => - wallet.getHasOtherProvider() - ); + const [isShowMetamaskModePopup, setIsShowMetamaskModePopup] = useState(false); const [visible, setVisible] = useState( trigger === 'current-connection' && showChainsModal ); + const [isShowTooltip, setIsShowTooltip] = useState(false); + const getCurrentSite = useCallback(async () => { const tab = await getCurrentTab(); if (!tab.id || !tab.url) return; @@ -81,80 +79,81 @@ export const CurrentConnection = memo((props: CurrentConnectionProps) => { getCurrentSite(); }, []); - const Content = site && ( -
- {site?.preferMetamask && hasOtherProvider ? ( - + {site ? ( +
{ + setIsShowTooltip(true); + }} + onMouseLeave={() => { + setIsShowTooltip(false); }} - title={t('page.dashboard.recentConnection.metamaskTooltip')} > -
- - + +
+
+ {site?.origin} +
+
+ {site?.isConnected + ? t('page.dashboard.recentConnection.connected') + : t('page.dashboard.recentConnection.notConnected')} + {!site?.isConnected ? ( + <> + + Can’t connect Rabby on this Dapp? Try enabling + { + e.preventDefault(); + e.stopPropagation(); + setIsShowTooltip(false); + setIsShowMetamaskModePopup(true); + }} + > + MetaMask Mode + + + } + > +
+ +
+
+ + ) : null} + handleRemove(site!.origin)} + /> +
- - ) : ( - - )} -
-
- {site?.origin} -
-
- {site?.isConnected - ? t('page.dashboard.recentConnection.connected') - : t('page.dashboard.recentConnection.notConnected')} - - handleRemove(site!.origin)} - />
-
-
- ); - - return ( -
- {site ? ( - site.isConnected || (site.preferMetamask && hasOtherProvider) ? ( - Content - ) : ( - - {Content} - - ) ) : (
@@ -164,9 +163,7 @@ export const CurrentConnection = memo((props: CurrentConnectionProps) => {
)} { }} showRPCStatus /> + {site ? ( + { + setIsShowMetamaskModePopup(false); + }} + onChangeMetamaskMode={(v) => { + getCurrentSite(); + }} + /> + ) : null}
); }); diff --git a/src/ui/views/Dashboard/components/DefaultWalletSetting/index.tsx b/src/ui/views/Dashboard/components/DefaultWalletSetting/index.tsx deleted file mode 100644 index cbb1158ce2f..00000000000 --- a/src/ui/views/Dashboard/components/DefaultWalletSetting/index.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import { useWallet } from '@/ui/utils'; -import { message } from 'antd'; -import React, { useEffect, useState } from 'react'; -import IconDefaultMetamask from 'ui/assets/icon-default-metamask.png'; -import IconDefaultRabby from 'ui/assets/icon-default-rabby.png'; -import './style.less'; -import { useTranslation } from 'react-i18next'; - -const DefaultWalletSetting = () => { - const [isConflict, setIsConflict] = useState(false); - const [isDefault, setIsDefault] = useState(true); - const wallet = useWallet(); - const { t } = useTranslation(); - - const init = () => { - wallet.isDefaultWallet().then(setIsDefault); - wallet.getHasOtherProvider().then(setIsConflict); - }; - - const handleFlip = async (e: React.MouseEvent) => { - e.preventDefault(); - handleSubmit(); - }; - - const handleSubmit = async () => { - await wallet.setIsDefaultWallet(!isDefault); - setIsDefault(!isDefault); - message.success({ - icon: , - content: ( - - {t('page.dashboard.home.refreshTheWebPageToTakeEffect')} - - ), - duration: 2, - }); - }; - - useEffect(() => { - init(); - }, []); - - if (!isConflict) { - return null; - } - if (isDefault) { - return ( - <> -
- - {t('page.dashboard.home.rabbyIsInUseAndMetamaskIsBanned')} - - {t('page.dashboard.home.flip')} - -
- - ); - } - return ( - <> -
- - {t('page.dashboard.home.metamaskIsInUseAndRabbyIsBanned')} - - {t('page.dashboard.home.flip')} - -
- - ); -}; - -export default DefaultWalletSetting; diff --git a/src/ui/views/Dashboard/components/DefaultWalletSetting/style.less b/src/ui/views/Dashboard/components/DefaultWalletSetting/style.less deleted file mode 100644 index 70e2dd724a5..00000000000 --- a/src/ui/views/Dashboard/components/DefaultWalletSetting/style.less +++ /dev/null @@ -1,98 +0,0 @@ -.rabby-default-wallet-setting { - position: fixed; - bottom: 28px; - left: 100%; - width: 303px; - width: max-content; - padding-left: 12px; - height: 36px; - - display: flex; - align-items: center; - - font-size: 12px; - line-height: 14px; - color: @color-title; - transform: translateX(-42px); - background: linear-gradient( - 0deg, - rgba(134, 151, 255, 0.2), - rgba(134, 151, 255, 0.2) - ), - #ffffff; - - border-width: 1px 0px 1px 1px; - border-style: solid; - border-color: var(--r-blue-default, #7084ff); - box-shadow: 0px 8px 16px rgba(134, 151, 255, 0.2); - border-radius: 90px 0px 0px 90px; - - &:hover { - transform: translateX(-100%); - } - transition: 0.3s; - - a { - font-weight: 500; - margin-left: 8px; - padding: 10px 10px 10px 0; - } - - &.is-metamask { - transform: translateX(-100%); - background: linear-gradient( - 0deg, - rgba(245, 132, 31, 0.2), - rgba(245, 132, 31, 0.2) - ), - #ffffff; - border-color: #f5841f; - box-shadow: 0px 8px 16px rgba(245, 132, 31, 0.2); - - a { - color: #f5841f; - } - } - - &-modal { - .ant-drawer-header { - padding-bottom: 8px; - background: linear-gradient( - 180deg, - rgba(245, 132, 31, 0.12) 0%, - rgba(245, 132, 31, 0) 100% - ); - border-radius: 16px 16px 0px 0px; - } - &.is-flip-to-rabby .ant-drawer-header { - background: linear-gradient( - 180deg, - rgba(134, 151, 255, 0.12) 0%, - rgba(134, 151, 255, 0) 100% - ); - } - .ant-drawer-body { - padding-top: 12px; - display: flex; - flex-direction: column; - } - .desc { - font-size: 14px; - line-height: 20px; - color: #4b4d59; - flex: 1; - margin-bottom: 8px; - } - .checkbox { - margin-bottom: 32px; - text-align: center; - .rabby-checkbox__label { - color: @color-comment-1; - } - } - .footer { - display: flex; - gap: 16px; - } - } -} diff --git a/src/ui/views/Dashboard/components/MetamaskModePopup/index.tsx b/src/ui/views/Dashboard/components/MetamaskModePopup/index.tsx new file mode 100644 index 00000000000..422f1914f05 --- /dev/null +++ b/src/ui/views/Dashboard/components/MetamaskModePopup/index.tsx @@ -0,0 +1,101 @@ +import { ConnectedSite } from '@/background/service/permission'; +import { FallbackSiteLogo, Popup } from '@/ui/component'; +import { useWallet } from '@/ui/utils'; +import { message, Switch } from 'antd'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { createGlobalStyle } from 'styled-components'; +import IconMetamask from 'ui/assets/dashboard/icon-metamask-yellow.svg'; + +const GlobalStyle = createGlobalStyle` + .metamask-mode-popup { + .ant-drawer-content { + background: var(--r-neutral-bg2, #F2F4F7); + } + .ant-drawer-body { + padding: 16px 20px 20px 20px; + } + .ant-switch-checked { + background-color: var(--r-blue-default, #7084FF); + } + } +`; + +interface Props { + visible?: boolean; + site: ConnectedSite; + onChangeMetamaskMode?(v: boolean): void; + onClose?(): void; +} +export const MetamaskModePopup = ({ + visible, + onClose, + site, + onChangeMetamaskMode, +}: Props) => { + const { t } = useTranslation(); + const wallet = useWallet(); + + return ( + <> + + + + {t('page.dashboard.MetamaskModePopup.title')} +
+ } + > +
+
+ {t('page.dashboard.MetamaskModePopup.desc')} +
+ +
+ +
+
+ {site.origin} +
+
+ {t('page.dashboard.MetamaskModePopup.enableDesc')} +
+
+
+ { + if (v) { + await wallet.addMetamaskModeSite(site); + message.success( + t('page.dashboard.MetamaskModePopup.toastSuccess') + ); + } else { + await wallet.removeMetamaskModeSite(site); + } + onChangeMetamaskMode?.(v); + }} + > +
+
+ +
+ {t('page.dashboard.MetamaskModePopup.footerText')} +
+
+ + + ); +}; diff --git a/src/ui/views/Dashboard/components/Settings/index.tsx b/src/ui/views/Dashboard/components/Settings/index.tsx index 6bba049539c..f858d4513ce 100644 --- a/src/ui/views/Dashboard/components/Settings/index.tsx +++ b/src/ui/views/Dashboard/components/Settings/index.tsx @@ -822,15 +822,15 @@ const SettingsInner = ({ }, { leftIcon: RcIconPreferMetamask, - content: t('page.dashboard.settings.settings.metamaskPreferredDapps'), + content: t('page.dashboard.settings.settings.metamaskMode'), onClick: () => { - history.push('/prefer-metamask-dapps'); + history.push('/metamask-mode-dapps'); matomoRequestEvent({ category: 'Setting', action: 'clickToUse', - label: 'MetaMask Preferred Dapps', + label: 'MetaMask Mode Dapps', }); - reportSettings('MetaMask Preferred Dapps'); + reportSettings('MetaMask Mode Dapps'); }, }, { diff --git a/src/ui/views/Dashboard/components/index.tsx b/src/ui/views/Dashboard/components/index.tsx index a8c92684530..78b150def0e 100644 --- a/src/ui/views/Dashboard/components/index.tsx +++ b/src/ui/views/Dashboard/components/index.tsx @@ -4,4 +4,3 @@ export { default as GnosisWrongChainAlertBar } from './GnosisWrongChainAlertBar' export { default as ChainAndSiteSelector } from './ChainAndSiteSelector'; export { default as Settings } from './Settings'; export { default as Contacts } from './Contacts'; -export { default as DefaultWalletSetting } from './DefaultWalletSetting'; diff --git a/src/ui/views/Dashboard/index.tsx b/src/ui/views/Dashboard/index.tsx index b64423f5cff..57d4132f3ed 100644 --- a/src/ui/views/Dashboard/index.tsx +++ b/src/ui/views/Dashboard/index.tsx @@ -37,7 +37,6 @@ import { BalanceView, ChainAndSiteSelector, GnosisWrongChainAlertBar, - DefaultWalletSetting, } from './components'; import './style.less'; @@ -538,7 +537,6 @@ const Dashboard = () => {
- {!(showToken || showAssets || showNFT) && } {pendingApprovalCount > 0 && ( { diff --git a/src/ui/views/MainRoute.tsx b/src/ui/views/MainRoute.tsx index 0c38d1df843..0e4f9d1979b 100644 --- a/src/ui/views/MainRoute.tsx +++ b/src/ui/views/MainRoute.tsx @@ -37,7 +37,6 @@ import { getUiType, useWallet } from '../utils'; import CustomRPC from './CustomRPC'; import { ImportMyMetaMaskAccount } from './ImportMyMetaMaskAccount'; import { matomoRequestEvent } from '@/utils/matomo-request'; -import { PreferMetamaskDapps } from './PreferMetamaskDapps'; import { CommonPopup } from './CommonPopup'; import ManageAddress from './ManageAddress'; import { NFTView } from './NFTView'; @@ -72,6 +71,7 @@ import { ReadyToUse } from './NewUserImport/ReadyToUse'; import { ImportSeedPhrase } from './NewUserImport/ImportSeedPhrase'; import { NewUserImportHardware } from './NewUserImport/ImportHardWare'; import { KEYRING_CLASS } from '@/constant'; +import { MetamaskModeDapps } from './MetamaskModeDapps'; declare global { interface Window { @@ -327,8 +327,8 @@ const Main = () => { - - + + diff --git a/src/ui/views/MetamaskModeDapps/index.tsx b/src/ui/views/MetamaskModeDapps/index.tsx new file mode 100644 index 00000000000..1e4c28bd430 --- /dev/null +++ b/src/ui/views/MetamaskModeDapps/index.tsx @@ -0,0 +1,92 @@ +import { useThemeMode } from '@/ui/hooks/usePreference'; +import { useRequest } from 'ahooks'; +import { message } from 'antd'; +import { ConnectedSite } from 'background/service/permission'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { ReactComponent as RcIconDelete } from 'ui/assets/metamask-mode-dapps/delete-cc.svg'; +import IconMetamaskModeDark from 'ui/assets/metamask-mode-dapps/icon-metamask-mode-dark.svg'; +import IconMetamaskMode from 'ui/assets/metamask-mode-dapps/icon-metamask-mode.svg'; +import { Empty, FallbackSiteLogo, PageHeader } from 'ui/component'; +import { useWallet } from 'ui/utils'; +import './style.less'; + +const DappCard = (props: { + data: ConnectedSite; + onRemove: (site: ConnectedSite) => void; +}) => { + const { data, onRemove } = props; + return ( +
+ +
{data.origin}
+
+ { + onRemove(data); + }} + > +
+
+ ); +}; + +export const MetamaskModeDapps = () => { + const wallet = useWallet(); + const { t } = useTranslation(); + const { isDarkTheme } = useThemeMode(); + + const { data: sites, runAsync } = useRequest(() => + wallet.getMetamaskModeSites() + ); + const handleRemoveMetamaskMode = async (site: ConnectedSite) => { + await wallet.removeMetamaskModeSite(site); + runAsync(); + message.success(t('global.Deleted')); + }; + + return ( +
+
+ + {t('page.metamaskModeDapps.title')} + +
+
+ +
+ {t('page.metamaskModeDapps.desc')} +
+
+ {sites?.length ? ( +
+ {(sites || []).map((item) => { + return ( + + ); + })} +
+ ) : ( + + )} +
+ ); +}; diff --git a/src/ui/views/MetamaskModeDapps/style.less b/src/ui/views/MetamaskModeDapps/style.less new file mode 100644 index 00000000000..721af711844 --- /dev/null +++ b/src/ui/views/MetamaskModeDapps/style.less @@ -0,0 +1,119 @@ +@import '../../style/var.less'; + +.page-metamask-mode-dapps { + .page(); + display: flex; + flex-direction: column; + padding: 0 20px 20px; + font-size: 12px; + line-height: 14px; + height: 100vh; + overflow: auto; + background: var(--r-neutral-bg-2, #3d4251); + position: relative; + + .header { + .desc { + font-weight: 400; + font-size: 14px; + line-height: 18px; + color: var(--r-neutral-body, #d3d8e0); + margin-top: 18px; + margin-bottom: 18px; + } + } + .content { + flex: 1; + overflow: overlay; + padding-bottom: 80px; + } + + .dapp-card { + display: flex; + align-items: center; + background: var(--r-neutral-card-1, rgba(255, 255, 255, 0.06)); + border-radius: 6px; + padding: 10px 16px; + gap: 12px; + &:not(:last-child) { + margin-bottom: 8px; + } + + &-icon { + width: 24px; + height: 24px; + flex-shrink: 0; + } + + &-content { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + flex: 1; + + font-weight: 400; + font-size: 13px; + line-height: 15px; + color: var(--r-neutral-body, #d3d8e0); + } + + &-action { + margin-right: auto; + flex-shrink: 0; + + &-delete { + width: 16px; + height: 16px; + color: var(--r-neutral-foot, #6a7587); + + cursor: pointer; + &:hover { + color: var(--r-neutral-red-default, #e34935); + } + } + } + } + + .footer { + position: absolute; + bottom: 0; + left: 0; + right: 0; + padding: 20px; + display: flex; + align-items: center; + justify-content: center; + border-top: 1px solid var(--r-neutral-line, rgba(255, 255, 255, 0.1)); + border-top: 0.5px solid var(--r-neutral-line, rgba(255, 255, 255, 0.1)); + background: var(--r-neutral-bg1, rgba(255, 255, 255, 0.06)); + + .ant-btn { + height: 44px; + font-weight: 500; + font-size: 15px; + line-height: 18px; + border-radius: 6px; + } + } +} + +.prefer-metamask-popup { + .content { + text-align: center; + border-radius: 6px; + + .info { + font-weight: 500; + font-size: 15px; + line-height: 18px; + color: var(--r-neutral-body, #d3d8e0); + margin-bottom: 16px; + } + + img { + width: 267px; + display: block; + margin: 0 auto; + } + } +} diff --git a/src/utils/message/broadcastChannelMessage.ts b/src/utils/message/broadcastChannelMessage.ts index 19e5b8db594..d3bb24605c3 100644 --- a/src/utils/message/broadcastChannelMessage.ts +++ b/src/utils/message/broadcastChannelMessage.ts @@ -17,7 +17,13 @@ export default class BroadcastChannelMessage extends Message { } connect = () => { - this._channel.on('data', ({ data: { type, data } }) => { + this._channel.on('data', (res) => { + if (!res.data) { + return; + } + const { + data: { type, data }, + } = res; if (type === 'message') { this.emit('message', data); } else if (type === 'response') { @@ -31,7 +37,13 @@ export default class BroadcastChannelMessage extends Message { listen = (listenCallback) => { this.listenCallback = listenCallback; - this._channel.on('data', ({ data: { type, data } }) => { + this._channel.on('data', (res) => { + if (!res.data) { + return; + } + const { + data: { type, data }, + } = res; if (type === 'request') { this.onRequest(data); } diff --git a/yarn.lock b/yarn.lock index 74837d47ac2..571c7b77fc7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4851,10 +4851,10 @@ typescript "^4.4.4" web3-core "^1.6.0" -"@rabby-wallet/page-provider@0.4.2": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@rabby-wallet/page-provider/-/page-provider-0.4.2.tgz#32f58df1bac847baa0ac8c6aeaba0751d2a522f4" - integrity sha512-QTgLnw6JpArofBtUj2Ve9vwB/S2Kfyz5KUeekYqA02DFyBCJRhCTbFtY+2FoqS8NlZM9TWf46Yau2p6NIJdf1w== +"@rabby-wallet/page-provider@0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@rabby-wallet/page-provider/-/page-provider-0.4.3.tgz#25fd2ec0cb57883997b1bf2c326a764ae8a3da34" + integrity sha512-QISfQucW60wa2kmQkb4DSuBuXUD/HkWjHJvzhwS1Mqf3vv6MnivnnBwDVT+VC1UeVOn3SxZKyITUrx1XjGrLvA== dependencies: "@ledgerhq/devices" "^6.27.1" "@metamask/post-message-stream" "8.1.0"