From 325e7bc695193368e69220414c656ee3a5860af0 Mon Sep 17 00:00:00 2001 From: Sharon Sheah <37326128+sharonsheah@users.noreply.github.com> Date: Fri, 1 Mar 2024 11:42:08 +1100 Subject: [PATCH 1/2] feat: WT-2157 Handle add new network and switch network functionality (#1544) --- packages/checkout/sdk/src/network/network.ts | 2 +- packages/checkout/sdk/src/sdk.ts | 18 ++++++ packages/checkout/sdk/src/types/network.ts | 10 +++ .../widgets-lib/src/lib/walletConnect.ts | 20 +++--- .../checkout/widgets-lib/src/locales/en.json | 1 + .../checkout/widgets-lib/src/locales/ja.json | 1 + .../checkout/widgets-lib/src/locales/ko.json | 1 + .../checkout/widgets-lib/src/locales/zh.json | 1 + .../connect/views/SwitchNetworkZkEVM.tsx | 63 ++++++++++++++++++- .../ui/marketplace-orchestrator/MainPage.tsx | 2 +- 10 files changed, 109 insertions(+), 10 deletions(-) diff --git a/packages/checkout/sdk/src/network/network.ts b/packages/checkout/sdk/src/network/network.ts index 34773c8903..aed1b958b8 100644 --- a/packages/checkout/sdk/src/network/network.ts +++ b/packages/checkout/sdk/src/network/network.ts @@ -38,7 +38,7 @@ async function switchNetworkInWallet( } // eslint-disable-next-line consistent-return -async function addNetworkToWallet( +export async function addNetworkToWallet( networkMap: NetworkMap, web3Provider: Web3Provider, chainId: ChainId, diff --git a/packages/checkout/sdk/src/sdk.ts b/packages/checkout/sdk/src/sdk.ts index 4eced07e19..b094966362 100644 --- a/packages/checkout/sdk/src/sdk.ts +++ b/packages/checkout/sdk/src/sdk.ts @@ -56,6 +56,7 @@ import { SellResult, TokenInfo, GetTokenInfoParams, + AddNetworkParams, } from './types'; import { CheckoutConfiguration } from './config'; import { createReadOnlyProviders } from './readOnlyProviders/readOnlyProvider'; @@ -281,6 +282,23 @@ export class Checkout { return { provider: web3Provider }; } + /** + * Adds the network for the current wallet provider. + * @param {AddNetworkParams} params - The parameters for adding the network. + * @returns {Promise} - A promise that resolves to the result of adding the network. + */ + public async addNetwork( + params: AddNetworkParams, + ): Promise { + const addNetworkRes = await network.addNetworkToWallet( + this.config.networkMap, + params.provider, + params.chainId, + ); + + return addNetworkRes; + } + /** * Switches the network for the current wallet provider. * @param {SwitchNetworkParams} params - The parameters for switching the network. diff --git a/packages/checkout/sdk/src/types/network.ts b/packages/checkout/sdk/src/types/network.ts index 7be96f2692..2ea382e38f 100644 --- a/packages/checkout/sdk/src/types/network.ts +++ b/packages/checkout/sdk/src/types/network.ts @@ -3,6 +3,16 @@ import { ChainId } from './chains'; import { NetworkInfo } from './networkInfo'; import { TokenInfo } from './tokenInfo'; +/** + * Interface representing the parameters for {@link Checkout.addNetwork}. + * @property {Web3Provider} provider - The provider to connect to the network. + * @property {ChainId} chainId - The ID of the network to add. We only support adding Immutable zkEVM and Immutable zkEVM Testnet. + */ +export interface AddNetworkParams { + provider: Web3Provider; + chainId: ChainId; +} + /** * Interface representing the parameters for {@link Checkout.switchNetwork}. * @property {Web3Provider} provider - The provider to connect to the network. diff --git a/packages/checkout/widgets-lib/src/lib/walletConnect.ts b/packages/checkout/widgets-lib/src/lib/walletConnect.ts index aea4b8a5c9..abc4049810 100644 --- a/packages/checkout/widgets-lib/src/lib/walletConnect.ts +++ b/packages/checkout/widgets-lib/src/lib/walletConnect.ts @@ -45,10 +45,14 @@ const lightThemeVariables = { // Whitelisted wallet ids on WalletConnect explorer API const metamaskId = 'c57ca95b47569778a828d19178114f4db188b89b763c899ba0be274e97267d96'; const frontierId = '85db431492aa2e8672e93f4ea7acf10c88b97b867b0d373107af63dc4880f041'; -const coinbaseId = 'fd20dc426fb37566d803205b19bbc1d4096b248ac04548e3cfb6b3a38bd033aa'; +const ledgerLiveId = '19177a98252e07ddfc9af2083ba8e07ef627cb6103467ffebb3f8f4205fd7927'; +// const coinbaseId = 'fd20dc426fb37566d803205b19bbc1d4096b248ac04548e3cfb6b3a38bd033aa'; // const phantomId = 'a797aa35c0fadbfc1a53e7f675162ed5226968b44a19ee3d24385c64d1d3c393'; // const rainbowId = '1ae92b26df02f0abca6304df07debccd18262fdf5fe82daa81593582dac9a369'; +const productionWalletWhitelist = [metamaskId, frontierId, ledgerLiveId]; +const sandboxWalletWhitelist = [metamaskId]; + export class WalletConnectManager { private static instance: WalletConnectManager; @@ -112,11 +116,8 @@ export class WalletConnectManager { const modal = new WalletConnectModal({ projectId: this.walletConnectConfig.projectId, chains: this.environment === Environment.PRODUCTION ? productionModalChains : testnetModalChains, - explorerRecommendedWalletIds: [ - metamaskId, - frontierId, - coinbaseId, - ], + explorerRecommendedWalletIds: this.environment === Environment.PRODUCTION + ? productionWalletWhitelist : sandboxWalletWhitelist, explorerExcludedWalletIds: 'ALL', themeMode: this.theme, themeVariables: this.theme === WidgetTheme.DARK ? darkThemeVariables : lightThemeVariables, @@ -163,8 +164,13 @@ export class WalletConnectManager { } private async loadWalletListings(): Promise { + const whitelistedWallets = this.environment === Environment.PRODUCTION + ? productionWalletWhitelist : sandboxWalletWhitelist; + + const whitelistedWalletIds = whitelistedWallets.map((walletId) => `${walletId}`).join(','); // eslint-disable-next-line max-len - const walletListingsApi = `https://explorer-api.walletconnect.com/v3/wallets?projectId=${this.walletConnectConfig.projectId}&ids=${metamaskId},${frontierId},${coinbaseId}`; + const walletListingsApi = `https://explorer-api.walletconnect.com/v3/wallets?projectId=${this.walletConnectConfig.projectId}&ids=${whitelistedWalletIds}`; + try { const response = await fetch(walletListingsApi); const data = await response.json(); diff --git a/packages/checkout/widgets-lib/src/locales/en.json b/packages/checkout/widgets-lib/src/locales/en.json index 145737c8ef..56885d3f42 100644 --- a/packages/checkout/widgets-lib/src/locales/en.json +++ b/packages/checkout/widgets-lib/src/locales/en.json @@ -47,6 +47,7 @@ "zkEVM": { "heading": "You’ll be asked to switch to the Immutable zkEVM network", "body": "Check for the pop-up from MetaMask and 'Approve' to switch. If this is the first time, MetaMask will also ask you to add the network.", + "bodyWalletConnect": "Check for the pop-up from your wallet to switch. If this is the first time, your wallet will also ask you to add the network.", "button": { "text": "Ready to Switch", "retryText": "Try Again" diff --git a/packages/checkout/widgets-lib/src/locales/ja.json b/packages/checkout/widgets-lib/src/locales/ja.json index c93e92f9ba..bcfcd8047d 100644 --- a/packages/checkout/widgets-lib/src/locales/ja.json +++ b/packages/checkout/widgets-lib/src/locales/ja.json @@ -47,6 +47,7 @@ "zkEVM": { "heading": "Immutable zkEVMネットワークに切り替えるように求められます", "body": "MetaMaskからのポップアップを確認し、「承認」して切り替えてください。これが初めての場合、MetaMaskはネットワークを追加するように求めることもあります。", + "bodyWalletConnect": "ウォレットからのポップアップを確認して切り替えます。これが初めての場合、ウォレットはネットワークの追加を求めます。", "button": { "text": "切り替えの準備ができました", "retryText": "再試行する" diff --git a/packages/checkout/widgets-lib/src/locales/ko.json b/packages/checkout/widgets-lib/src/locales/ko.json index 7943cd41ae..443a30220b 100644 --- a/packages/checkout/widgets-lib/src/locales/ko.json +++ b/packages/checkout/widgets-lib/src/locales/ko.json @@ -47,6 +47,7 @@ "zkEVM": { "heading": "Immutable zkEVM 네트워크로 전환하라는 요청을 받게 됩니다", "body": "MetaMask 팝업에서 '승인'을 선택하고 전환하세요. 처음이라면 MetaMask에서 네트워크 추가를 요구할 수도 있습니다.", + "bodyWalletConnect": "지갑에서 팝업을 확인하여 전환하십시오. 처음이라면 지갑에서 네트워크 추가를 요청합니다.", "button": { "text": "전환 준비됨", "retryText": "다시 시도" diff --git a/packages/checkout/widgets-lib/src/locales/zh.json b/packages/checkout/widgets-lib/src/locales/zh.json index 2e4c5b1689..5a60390e93 100644 --- a/packages/checkout/widgets-lib/src/locales/zh.json +++ b/packages/checkout/widgets-lib/src/locales/zh.json @@ -47,6 +47,7 @@ "zkEVM": { "heading": "将要求您切换到Immutable zkEVM网络", "body": "检查MetaMask的弹窗并选择'批准'以切换。如果这是第一次,MetaMask还会要求您添加网络。", + "bodyWalletConnect": "请检查您的钱包弹出窗口以进行切换。如果这是第一次,您的钱包还会要求您添加网络。", "button": { "text": "准备切换", "retryText": "再试一次" diff --git a/packages/checkout/widgets-lib/src/widgets/connect/views/SwitchNetworkZkEVM.tsx b/packages/checkout/widgets-lib/src/widgets/connect/views/SwitchNetworkZkEVM.tsx index b566cd86f9..9b9981311c 100644 --- a/packages/checkout/widgets-lib/src/widgets/connect/views/SwitchNetworkZkEVM.tsx +++ b/packages/checkout/widgets-lib/src/widgets/connect/views/SwitchNetworkZkEVM.tsx @@ -2,6 +2,7 @@ import { useCallback, useContext, useEffect, useState, } from 'react'; import { useTranslation } from 'react-i18next'; +import { isWalletConnectProvider } from 'lib/providerUtils'; import { SimpleTextBody } from '../../../components/Body/SimpleTextBody'; import { FooterButton } from '../../../components/Footer/FooterButton'; import { HeaderNavigation } from '../../../components/Header/HeaderNavigation'; @@ -38,7 +39,65 @@ export function SwitchNetworkZkEVM() { controlType: 'Button', }); + if (!provider.provider.request) return; + + const currentChainId = provider.provider.request({ method: 'eth_chainId', params: [] }); + // eslint-disable-next-line radix + const parsedChainId = parseInt(currentChainId.toString()); + + if (parsedChainId === getL2ChainId(checkout.config)) { + connectDispatch({ + payload: { + type: ConnectActions.SET_PROVIDER, + provider, + }, + }); + + viewDispatch({ + payload: { + type: ViewActions.UPDATE_VIEW, + view: { + type: ConnectWidgetViews.SUCCESS, + }, + }, + }); + + return; + } + try { + let walletName = ''; + if (isWalletConnectProvider(provider)) { + walletName = (provider.provider as any)?.session?.peer?.metadata?.name.toLowerCase(); + } + if (walletName === 'metamask') { + try { + await checkout.addNetwork({ + provider, + chainId: getL2ChainId(checkout.config), + }); + connectDispatch({ + payload: { + type: ConnectActions.SET_PROVIDER, + provider, + }, + }); + + viewDispatch({ + payload: { + type: ViewActions.UPDATE_VIEW, + view: { + type: ConnectWidgetViews.SUCCESS, + }, + }, + }); + return; + } catch { + // eslint-disable-next-line no-console + console.warn('Failed to add network to wallet, skipping add network'); + } + } + const switchRes = await checkout.switchNetwork({ provider, chainId: getL2ChainId(checkout.config), @@ -84,7 +143,9 @@ export function SwitchNetworkZkEVM() { - {t('views.SWITCH_NETWORK.zkEVM.body')} + {isWalletConnectProvider(provider) ? ( + t('views.SWITCH_NETWORK.zkEVM.bodyWalletConnect')) : ( + t('views.SWITCH_NETWORK.zkEVM.body'))} ); diff --git a/packages/checkout/widgets-sample-app/src/components/ui/marketplace-orchestrator/MainPage.tsx b/packages/checkout/widgets-sample-app/src/components/ui/marketplace-orchestrator/MainPage.tsx index 95e9c55399..1d691aed9d 100644 --- a/packages/checkout/widgets-sample-app/src/components/ui/marketplace-orchestrator/MainPage.tsx +++ b/packages/checkout/widgets-sample-app/src/components/ui/marketplace-orchestrator/MainPage.tsx @@ -15,7 +15,7 @@ import { SwapEventType, WalletEventType, WalletNetworkSwitch, - WidgetTheme, WidgetType, ProviderEventType, ProviderUpdated, WidgetConfiguration, WidgetProperties + WidgetTheme, WidgetType, ProviderEventType, ProviderUpdated, WidgetProperties } from '@imtbl/checkout-sdk'; import { Environment } from '@imtbl/config'; import { passport } from './passport'; From 6c041d4a1f04be945ebffbdbeddf4b228d4195c3 Mon Sep 17 00:00:00 2001 From: Mikhala <122326421+imx-mikhala@users.noreply.github.com> Date: Fri, 1 Mar 2024 08:56:31 +0800 Subject: [PATCH 2/2] chore: Add visualizer plugin and script (#1550) --- packages/checkout/widgets-lib/.gitignore | 2 ++ packages/checkout/widgets-lib/package.json | 2 ++ yarn.lock | 24 ++++++++++++++++++++-- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/packages/checkout/widgets-lib/.gitignore b/packages/checkout/widgets-lib/.gitignore index 8bec29d3ee..80af08115b 100644 --- a/packages/checkout/widgets-lib/.gitignore +++ b/packages/checkout/widgets-lib/.gitignore @@ -24,3 +24,5 @@ yarn-error.log* cypress/videos/* +# visualizer +stats.html \ No newline at end of file diff --git a/packages/checkout/widgets-lib/package.json b/packages/checkout/widgets-lib/package.json index 60552e530e..219cb056fe 100644 --- a/packages/checkout/widgets-lib/package.json +++ b/packages/checkout/widgets-lib/package.json @@ -64,6 +64,7 @@ "react-scripts": "5.0.1", "rollup": "^3.17.2", "rollup-plugin-svg": "^2.0.0", + "rollup-plugin-visualizer": "^5.12.0", "ts-jest": "^29.1.0", "typescript": "^4.9.5", "web-vitals": "^2.1.4" @@ -78,6 +79,7 @@ "private": true, "scripts": { "build": "yarn clean && rollup --config rollup.config.js", + "build:analyse": "yarn build --plugin visualizer", "build:local": "yarn clean && yarn build && mkdir -p ../widgets-sample-app/public/lib/js && cp dist/*.js ../widgets-sample-app/public/lib/js/", "clean": "rm -rf ./dist", "lint": "eslint ./src --ext .ts,.jsx,.tsx --max-warnings=0", diff --git a/yarn.lock b/yarn.lock index e73b254bf2..8a205f9729 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3444,6 +3444,7 @@ __metadata: react-scripts: 5.0.1 rollup: ^3.17.2 rollup-plugin-svg: ^2.0.0 + rollup-plugin-visualizer: ^5.12.0 stream-browserify: ^3.0.0 stream-http: ^3.2.0 ts-jest: ^29.1.0 @@ -25351,6 +25352,25 @@ __metadata: languageName: node linkType: hard +"rollup-plugin-visualizer@npm:^5.12.0": + version: 5.12.0 + resolution: "rollup-plugin-visualizer@npm:5.12.0" + dependencies: + open: ^8.4.0 + picomatch: ^2.3.1 + source-map: ^0.7.4 + yargs: ^17.5.1 + peerDependencies: + rollup: 2.x || 3.x || 4.x + peerDependenciesMeta: + rollup: + optional: true + bin: + rollup-plugin-visualizer: dist/bin/cli.js + checksum: 17dc10a93d4bd457c8bb7796a57c284487fb00f4b9703a33a1a954f5d40c66a89b24aca98564569922456f4fa8f72281c3ef96a95502195e6930b3fac62fce8e + languageName: node + linkType: hard + "rollup-pluginutils@npm:^1.3.1": version: 1.5.2 resolution: "rollup-pluginutils@npm:1.5.2" @@ -26205,7 +26225,7 @@ __metadata: languageName: node linkType: hard -"source-map@npm:^0.7.3": +"source-map@npm:^0.7.3, source-map@npm:^0.7.4": version: 0.7.4 resolution: "source-map@npm:0.7.4" checksum: 01cc5a74b1f0e1d626a58d36ad6898ea820567e87f18dfc9d24a9843a351aaa2ec09b87422589906d6ff1deed29693e176194dc88bcae7c9a852dc74b311dbf5 @@ -29845,7 +29865,7 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^17.3.1": +"yargs@npm:^17.3.1, yargs@npm:^17.5.1": version: 17.7.2 resolution: "yargs@npm:17.7.2" dependencies: