diff --git a/packages/checkout/widgets-lib/src/components/NetworkSwitchDrawer/NetworkSwitchDrawer.tsx b/packages/checkout/widgets-lib/src/components/NetworkSwitchDrawer/NetworkSwitchDrawer.tsx
new file mode 100644
index 0000000000..1190b629f0
--- /dev/null
+++ b/packages/checkout/widgets-lib/src/components/NetworkSwitchDrawer/NetworkSwitchDrawer.tsx
@@ -0,0 +1,148 @@
+import {
+ Body, Box, Button, CloudImage, Drawer, Heading, Logo,
+} from '@biom3/react';
+import { Web3Provider } from '@ethersproject/providers';
+import { ChainId, Checkout } from '@imtbl/checkout-sdk';
+import { Environment } from '@imtbl/config';
+import { FooterLogo } from 'components/Footer/FooterLogo';
+import { getL1ChainId } from 'lib';
+import { getChainNameById } from 'lib/chains';
+import {
+ isMetaMaskProvider,
+ isWalletConnectProvider,
+} from 'lib/providerUtils';
+import { getRemoteImage } from 'lib/utils';
+import { useCallback, useMemo } from 'react';
+import { useTranslation } from 'react-i18next';
+
+export interface NetworkSwitchDrawerProps {
+ visible: boolean;
+ targetChainId: ChainId;
+ provider: Web3Provider;
+ checkout: Checkout;
+ onCloseDrawer: () => void;
+ onNetworkSwitch?: (provider: Web3Provider) => void;
+}
+export function NetworkSwitchDrawer({
+ visible,
+ targetChainId,
+ provider,
+ checkout,
+ onCloseDrawer,
+ onNetworkSwitch,
+}: NetworkSwitchDrawerProps) {
+ const { t } = useTranslation();
+
+ const targetChainName = getChainNameById(targetChainId);
+ const networkSwitchImage = useMemo(() => {
+ if (targetChainId === getL1ChainId(checkout.config)) {
+ const ethNetworkImageUrl = getRemoteImage(Environment.SANDBOX, '/switchnetworkethereum.svg');
+ return ;
+ }
+ return ;
+ }, [targetChainId]);
+
+ const handleSwitchNetwork = useCallback(async () => {
+ if (!checkout) return;
+ const switchNetworkResult = await checkout.switchNetwork({
+ provider,
+ chainId: targetChainId,
+ });
+ if (onNetworkSwitch) {
+ onNetworkSwitch(switchNetworkResult.provider);
+ }
+ }, [checkout, provider, onNetworkSwitch, targetChainId]);
+
+ const isWalletConnect = isWalletConnectProvider(provider);
+
+ const walletConnectPeerName = useMemo(() => {
+ if (!isWalletConnect) return '';
+ return (provider.provider as any)?.session?.peer?.metadata?.name as string;
+ }, [provider, isWalletConnect]);
+
+ const isMetaMaskMobileWalletPeer = useMemo(
+ () => walletConnectPeerName?.toLowerCase().includes('metamask'),
+ [walletConnectPeerName],
+ );
+
+ const walletDisplayName = useMemo(() => {
+ if (isMetaMaskProvider(provider)) return 'MetaMask wallet';
+ if (isWalletConnect && walletConnectPeerName) return walletConnectPeerName;
+ return 'wallet';
+ }, [provider, isWalletConnect, walletConnectPeerName]);
+
+ const requireManualSwitch = isWalletConnect && isMetaMaskMobileWalletPeer;
+
+ return (
+
+
+
+ {networkSwitchImage}
+
+ {t('drawers.networkSwitch.heading', {
+ wallet: walletDisplayName,
+ })}
+
+ {/** MetaMask mobile requires manual switch */}
+ {requireManualSwitch && (
+
+ {t('drawers.networkSwitch.manualSwitch.body', {
+ chain: targetChainName,
+ })}
+
+ )}
+ {!requireManualSwitch && (
+
+ {t('drawers.networkSwitch.controlledSwitch.body', {
+ chain: targetChainName,
+ })}
+
+ )}
+
+
+
+
+ {!requireManualSwitch && (
+
+ )}
+
+
+
+
+ );
+}
diff --git a/packages/checkout/widgets-lib/src/components/Transactions/ChangeWallet.tsx b/packages/checkout/widgets-lib/src/components/Transactions/ChangeWallet.tsx
index c0df6e7ea5..8c1341b886 100644
--- a/packages/checkout/widgets-lib/src/components/Transactions/ChangeWallet.tsx
+++ b/packages/checkout/widgets-lib/src/components/Transactions/ChangeWallet.tsx
@@ -1,9 +1,9 @@
import {
- Box, Button, EllipsizedText, Logo,
+ Box, Button, EllipsizedText, FramedImage, Logo,
} from '@biom3/react';
-import { useContext } from 'react';
+import { useContext, useEffect, useState } from 'react';
import { BridgeContext } from 'widgets/bridge/context/BridgeContext';
-import { getWalletProviderNameByProvider } from 'lib/providerUtils';
+import { getWalletProviderNameByProvider, isWalletConnectProvider } from 'lib/providerUtils';
import {
UserJourney,
useAnalytics,
@@ -11,7 +11,10 @@ import {
import { BridgeWidgetViews } from 'context/view-context/BridgeViewContextTypes';
import { useTranslation } from 'react-i18next';
import { getWalletLogoByName } from 'lib/logoUtils';
-import { headingStyles } from './ChangeWalletStyles';
+import { useWalletConnect } from 'lib/hooks/useWalletConnect';
+import {
+ headingStyles, wcStickerLogoStyles, wcWalletLogoStyles, wcWalletLogoWrapperStyles,
+} from './ChangeWalletStyles';
export interface ChangeWalletProps {
onChangeWalletClick: () => void;
@@ -20,8 +23,15 @@ export interface ChangeWalletProps {
export function ChangeWallet({ onChangeWalletClick }: ChangeWalletProps) {
const { t } = useTranslation();
const {
- bridgeState: { from },
+ bridgeState: { checkout, from },
} = useContext(BridgeContext);
+ const [walletLogoUrl, setWalletLogoUrl] = useState(
+ undefined,
+ );
+ const [isWalletConnect, setIsWalletConnect] = useState(false);
+ const { isWalletConnectEnabled, getWalletLogoUrl } = useWalletConnect({
+ checkout,
+ });
const { track } = useAnalytics();
const walletAddress = from?.walletAddress || '';
@@ -39,18 +49,38 @@ export function ChangeWallet({ onChangeWalletClick }: ChangeWalletProps) {
onChangeWalletClick();
};
+ useEffect(() => {
+ if (isWalletConnectEnabled) {
+ setIsWalletConnect(isWalletConnectProvider(from?.web3Provider));
+ (async () => {
+ setWalletLogoUrl(await getWalletLogoUrl());
+ })();
+ }
+ }, [isWalletConnectEnabled, from]);
+
return (
-
+ {isWalletConnect && walletLogoUrl ? (
+
+
+
+
+ ) : (
+
+ )}
{
// eslint-disable-next-line no-console
console.log('activate succeeded but there is no connected session');
}
- // eslint-disable-next-line no-console
+ // eslint-disable-next-line no-console
}).catch((err) => console.log('activate existing pairing error', err));
}
} catch (err) {
@@ -140,11 +140,14 @@ export const useWalletConnect = ({ checkout }: UseWalletConnectParams) => {
})
), [ethereumProvider, walletConnectModal]);
+ const getWalletLogoUrl = useCallback(async () => await WalletConnectManager.getInstance().getWalletLogoUrl(), []);
+
return {
isWalletConnectEnabled,
ethereumProvider,
walletConnectBusy,
walletConnectModal,
openWalletConnectModal,
+ getWalletLogoUrl,
};
};
diff --git a/packages/checkout/widgets-lib/src/lib/walletConnect.ts b/packages/checkout/widgets-lib/src/lib/walletConnect.ts
index d0acb67970..aea4b8a5c9 100644
--- a/packages/checkout/widgets-lib/src/lib/walletConnect.ts
+++ b/packages/checkout/widgets-lib/src/lib/walletConnect.ts
@@ -25,6 +25,8 @@ const darkThemeVariables = {
'--wcm-container-border-radius': '8px',
// eslint-disable-next-line @typescript-eslint/naming-convention
'--wcm-wallet-icon-border-radius': '8px',
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ '--wcm-overlay-background-color': 'rgba(255, 255, 255, 0.1)',
};
const lightThemeVariables = {
@@ -36,8 +38,17 @@ const lightThemeVariables = {
'--wcm-container-border-radius': '8px',
// eslint-disable-next-line @typescript-eslint/naming-convention
'--wcm-wallet-icon-border-radius': '8px',
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ '--wcm-overlay-background-color': 'rgba(255, 255, 255, 0.1)',
};
+// Whitelisted wallet ids on WalletConnect explorer API
+const metamaskId = 'c57ca95b47569778a828d19178114f4db188b89b763c899ba0be274e97267d96';
+const frontierId = '85db431492aa2e8672e93f4ea7acf10c88b97b867b0d373107af63dc4880f041';
+const coinbaseId = 'fd20dc426fb37566d803205b19bbc1d4096b248ac04548e3cfb6b3a38bd033aa';
+// const phantomId = 'a797aa35c0fadbfc1a53e7f675162ed5226968b44a19ee3d24385c64d1d3c393';
+// const rainbowId = '1ae92b26df02f0abca6304df07debccd18262fdf5fe82daa81593582dac9a369';
+
export class WalletConnectManager {
private static instance: WalletConnectManager;
@@ -53,6 +64,8 @@ export class WalletConnectManager {
private ethereumProvider!: EthereumProvider;
+ private walletListings!: any;
+
private validateConfig(config: WalletConnectConfiguration): boolean {
if (!config.projectId || config.projectId === '') {
// eslint-disable-next-line no-console
@@ -100,10 +113,9 @@ export class WalletConnectManager {
projectId: this.walletConnectConfig.projectId,
chains: this.environment === Environment.PRODUCTION ? productionModalChains : testnetModalChains,
explorerRecommendedWalletIds: [
- 'c57ca95b47569778a828d19178114f4db188b89b763c899ba0be274e97267d96', // MetaMask
- '85db431492aa2e8672e93f4ea7acf10c88b97b867b0d373107af63dc4880f041', // Frontier
- // 'a797aa35c0fadbfc1a53e7f675162ed5226968b44a19ee3d24385c64d1d3c393', // Phantom
- // '1ae92b26df02f0abca6304df07debccd18262fdf5fe82daa81593582dac9a369', // Rainbow
+ metamaskId,
+ frontierId,
+ coinbaseId,
],
explorerExcludedWalletIds: 'ALL',
themeMode: this.theme,
@@ -149,4 +161,34 @@ export class WalletConnectManager {
}
});
}
+
+ private async loadWalletListings(): Promise {
+ // eslint-disable-next-line max-len
+ const walletListingsApi = `https://explorer-api.walletconnect.com/v3/wallets?projectId=${this.walletConnectConfig.projectId}&ids=${metamaskId},${frontierId},${coinbaseId}`;
+ try {
+ const response = await fetch(walletListingsApi);
+ const data = await response.json();
+ return data;
+ } catch (error) {
+ // eslint-disable-next-line no-console
+ console.error('Error fetching wallet listings', error);
+ }
+ return undefined;
+ }
+
+ public async getWalletLogoUrl(): Promise {
+ if (!this.walletListings) {
+ this.walletListings = await this.loadWalletListings();
+ }
+ const walletName = this.ethereumProvider?.session?.peer.metadata.name;
+
+ if (!this.walletListings || !walletName) {
+ return undefined;
+ }
+
+ const matchedWallet = Object.values(this.walletListings.listings)
+ .find((wallet: any) => walletName.toLowerCase().includes(wallet.slug)) as any;
+
+ return matchedWallet.image_url.md;
+ }
}
diff --git a/packages/checkout/widgets-lib/src/locales/en.json b/packages/checkout/widgets-lib/src/locales/en.json
index b7cb68146c..145737c8ef 100644
--- a/packages/checkout/widgets-lib/src/locales/en.json
+++ b/packages/checkout/widgets-lib/src/locales/en.json
@@ -632,6 +632,16 @@
"buttons": {
"cancel": "Dismiss"
}
+ },
+ "networkSwitch": {
+ "heading": "Switch network in your {{wallet}}",
+ "manualSwitch": {
+ "body": "You'll need to open your mobile wallet and switch to the {{chain}} network to proceed"
+ },
+ "controlledSwitch": {
+ "body": "You'll need to switch to the {{chain}} network to proceed"
+ },
+ "switchButton": "Switch to {{chain}}"
}
}
-}
+}
\ No newline at end of file
diff --git a/packages/checkout/widgets-lib/src/locales/ja.json b/packages/checkout/widgets-lib/src/locales/ja.json
index bc634a2e37..c93e92f9ba 100644
--- a/packages/checkout/widgets-lib/src/locales/ja.json
+++ b/packages/checkout/widgets-lib/src/locales/ja.json
@@ -625,6 +625,16 @@
"buttons": {
"cancel": "閉じる"
}
+ },
+ "networkSwitch": {
+ "heading": "あなたの{{wallet}}でネットワークを切り替える",
+ "manualSwitch": {
+ "body": "続行するにはモバイルウォレットを開き、{{chain}}ネットワークに切り替える必要があります"
+ },
+ "controlledSwitch": {
+ "body": "{{chain}}ネットワークに切り替える必要があります"
+ },
+ "switchButton": "{{chain}}に切り替える"
}
}
-}
+}
\ No newline at end of file
diff --git a/packages/checkout/widgets-lib/src/locales/ko.json b/packages/checkout/widgets-lib/src/locales/ko.json
index fcaaa85084..7943cd41ae 100644
--- a/packages/checkout/widgets-lib/src/locales/ko.json
+++ b/packages/checkout/widgets-lib/src/locales/ko.json
@@ -622,6 +622,16 @@
"buttons": {
"cancel": "취소"
}
+ },
+ "networkSwitch": {
+ "heading": "귀하의 {{wallet}}에서 네트워크를 전환하세요",
+ "manualSwitch": {
+ "body": "계속하려면 모바일 지갑을 열고 {{chain}} 네트워크로 전환해야 합니다"
+ },
+ "controlledSwitch": {
+ "body": "{{chain}} 네트워크로 전환해야 합니다"
+ },
+ "switchButton": "{{chain}}로 전환하기"
}
}
-}
+}
\ No newline at end of file
diff --git a/packages/checkout/widgets-lib/src/locales/zh.json b/packages/checkout/widgets-lib/src/locales/zh.json
index 39cc45fba7..2e4c5b1689 100644
--- a/packages/checkout/widgets-lib/src/locales/zh.json
+++ b/packages/checkout/widgets-lib/src/locales/zh.json
@@ -622,6 +622,16 @@
"buttons": {
"cancel": "关闭"
}
+ },
+ "networkSwitch": {
+ "heading": "在您的{{wallet}}中切换网络",
+ "manualSwitch": {
+ "body": "您需要打开您的移动钱包并切换到{{chain}}网络才能继续进行"
+ },
+ "controlledSwitch": {
+ "body": "您需要切换到{{chain}}网络才能继续进行"
+ },
+ "switchButton": "切换到{{chain}}"
}
}
-}
+}
\ No newline at end of file
diff --git a/packages/checkout/widgets-lib/src/widgets/bridge/components/BridgeReviewSummary.tsx b/packages/checkout/widgets-lib/src/widgets/bridge/components/BridgeReviewSummary.tsx
index 64e9c71c8f..e94e279f2a 100644
--- a/packages/checkout/widgets-lib/src/widgets/bridge/components/BridgeReviewSummary.tsx
+++ b/packages/checkout/widgets-lib/src/widgets/bridge/components/BridgeReviewSummary.tsx
@@ -3,7 +3,7 @@ import {
} from 'react';
import { BridgeWidgetViews } from 'context/view-context/BridgeViewContextTypes';
import {
- Body, Box, Button, Heading, Icon, MenuItem,
+ Body, Box, Button, Heading, Icon, Logo, MenuItem,
} from '@biom3/react';
import {
GasEstimateBridgeToL2Result,
@@ -15,13 +15,16 @@ import {
getWalletProviderNameByProvider,
isMetaMaskProvider,
isPassportProvider,
+ isWalletConnectProvider,
} from 'lib/providerUtils';
import { calculateCryptoToFiat } from 'lib/utils';
import {
DEFAULT_QUOTE_REFRESH_INTERVAL,
DEFAULT_TOKEN_DECIMALS,
NATIVE,
+ addChainChangedListener,
networkIcon,
+ removeChainChangedListener,
} from 'lib';
import { useInterval } from 'lib/hooks/useInterval';
import { ApproveBridgeResponse, BridgeTxResponse } from '@imtbl/bridge-sdk';
@@ -32,6 +35,9 @@ import {
} from 'context/analytics-provider/SegmentAnalyticsProvider';
import { useTranslation } from 'react-i18next';
import { getWalletLogoByName } from 'lib/logoUtils';
+import { NetworkSwitchDrawer } from 'components/NetworkSwitchDrawer/NetworkSwitchDrawer';
+import { Web3Provider } from '@ethersproject/providers';
+import { useWalletConnect } from 'lib/hooks/useWalletConnect';
import { networkIconStyles } from './WalletNetworkButtonStyles';
import {
arrowIconStyles,
@@ -41,8 +47,10 @@ import {
bridgeReviewHeadingStyles,
bridgeReviewWrapperStyles,
topMenuItemStyles,
+ wcStickerLogoStyles,
+ wcWalletLogoStyles,
} from './BridgeReviewSummaryStyles';
-import { BridgeContext } from '../context/BridgeContext';
+import { BridgeActions, BridgeContext } from '../context/BridgeContext';
import {
ViewActions,
ViewContext,
@@ -60,6 +68,7 @@ export function BridgeReviewSummary() {
bridgeState: {
checkout, tokenBridge, from, to, token, amount,
},
+ bridgeDispatch,
} = useContext(BridgeContext);
const { track } = useAnalytics();
@@ -75,6 +84,19 @@ export function BridgeReviewSummary() {
const [transaction, setTransaction] = useState(
undefined,
);
+ const [showSwitchNetworkDrawer, setShowSwitchNetworkDrawer] = useState(false);
+
+ const [fromWalletLogoUrl, setFromWalletLogoUrl] = useState(
+ undefined,
+ );
+ const [toWalletLogoUrl, setToWalletLogoUrl] = useState(
+ undefined,
+ );
+ const [fromWalletIsWalletConnect, setFromWalletIsWalletConnect] = useState(false);
+ const [toWalletIsWalletConnect, setToWalletIsWalletConnect] = useState(false);
+ const { isWalletConnectEnabled, getWalletLogoUrl } = useWalletConnect({
+ checkout,
+ });
const displayAmount = useMemo(
() => (token?.symbol ? `${token?.symbol} ${amount}` : `${amount}`),
@@ -189,9 +211,67 @@ export function BridgeReviewSummary() {
})();
}, []);
+ const handleNetworkSwitch = useCallback((provider: Web3Provider) => {
+ bridgeDispatch({
+ payload: {
+ type: BridgeActions.SET_WALLETS_AND_NETWORKS,
+ from: {
+ web3Provider: provider,
+ walletAddress: from?.walletAddress!,
+ network: from?.network!,
+ },
+ to: {
+ web3Provider: to?.web3Provider!,
+ walletAddress: to?.walletAddress!,
+ network: to?.network!,
+ },
+ },
+ });
+ }, [from?.web3Provider, from?.network, to?.web3Provider, to?.network]);
+
+ useEffect(() => {
+ if (!from?.web3Provider) return;
+
+ const handleChainChanged = () => {
+ const newProvider = new Web3Provider(from?.web3Provider.provider);
+ handleNetworkSwitch(newProvider);
+ setShowSwitchNetworkDrawer(false);
+ };
+ addChainChangedListener(from?.web3Provider, handleChainChanged);
+
+ // eslint-disable-next-line consistent-return
+ return () => {
+ removeChainChangedListener(from?.web3Provider, handleChainChanged);
+ };
+ }, [from?.web3Provider]);
+
+ useEffect(() => {
+ if (isWalletConnectEnabled) {
+ setFromWalletIsWalletConnect(isWalletConnectProvider(from?.web3Provider));
+ setToWalletIsWalletConnect(isWalletConnectProvider(to?.web3Provider));
+ (async () => {
+ setFromWalletLogoUrl(await getWalletLogoUrl());
+ setToWalletLogoUrl(await getWalletLogoUrl());
+ })();
+ }
+ }, [isWalletConnectEnabled, from, to]);
+
const submitBridge = useCallback(async () => {
if (!approveTransaction || !transaction) return;
+ try {
+ const currentChainId = await (from?.web3Provider.provider as any).request({ method: 'eth_chainId', params: [] });
+ // eslint-disable-next-line radix
+ const parsedChainId = parseInt(currentChainId.toString());
+ if (parsedChainId !== from?.network) {
+ setShowSwitchNetworkDrawer(true);
+ return;
+ }
+ } catch (err) {
+ // eslint-disable-next-line no-console
+ console.error('Current network check failed', err);
+ }
+
track({
userJourney: UserJourney.BRIDGE,
screen: 'Summary',
@@ -228,7 +308,7 @@ export function BridgeReviewSummary() {
},
},
});
- }, [viewDispatch, approveTransaction, transaction]);
+ }, [viewDispatch, approveTransaction, transaction, from?.web3Provider, from?.network]);
return (
@@ -269,7 +349,17 @@ export function BridgeReviewSummary() {
emphasized
sx={bottomMenuItemStyles}
>
- {fromWalletProviderName && (
+ {fromWalletIsWalletConnect && fromWalletLogoUrl && (
+ <>
+
+
+ >
+ )}
+ {fromWalletProviderName && !fromWalletIsWalletConnect && (
- {toWalletProviderName && (
+ {toWalletProviderName && toWalletIsWalletConnect && toWalletLogoUrl && (
+ <>
+
+
+ >
+ )}
+ {toWalletProviderName && !toWalletIsWalletConnect && (
+ setShowSwitchNetworkDrawer(false)}
+ onNetworkSwitch={handleNetworkSwitch}
+ />
);
}
diff --git a/packages/checkout/widgets-lib/src/widgets/bridge/components/BridgeReviewSummaryStyles.ts b/packages/checkout/widgets-lib/src/widgets/bridge/components/BridgeReviewSummaryStyles.ts
index 6ddda47693..3cc9f7c3c3 100644
--- a/packages/checkout/widgets-lib/src/widgets/bridge/components/BridgeReviewSummaryStyles.ts
+++ b/packages/checkout/widgets-lib/src/widgets/bridge/components/BridgeReviewSummaryStyles.ts
@@ -2,12 +2,28 @@ export const topMenuItemStyles = {
borderBottomLeftRadius: '0px',
borderBottomRightRadius: '0px',
marginBottom: '2px',
+ position: 'relative',
};
export const bottomMenuItemStyles = {
borderTopLeftRadius: '0px',
borderTopRightRadius: '0px',
backgroundColor: 'base.color.translucent.emphasis.100',
+ position: 'relative',
+};
+
+export const wcWalletLogoStyles = {
+ width: 'base.icon.size.400',
+};
+
+export const wcStickerLogoStyles = {
+ position: 'absolute',
+ top: '2px',
+ left: '26px',
+ width: '20px',
+ padding: '2px',
+ backgroundColor: 'base.color.translucent.inverse.900',
+ borderRadius: 'base.borderRadius.x2',
};
export const bridgeReviewWrapperStyles = {
diff --git a/packages/checkout/widgets-lib/src/widgets/bridge/components/WalletAndNetworkSelector.tsx b/packages/checkout/widgets-lib/src/widgets/bridge/components/WalletAndNetworkSelector.tsx
index d555843097..8a0afc845f 100644
--- a/packages/checkout/widgets-lib/src/widgets/bridge/components/WalletAndNetworkSelector.tsx
+++ b/packages/checkout/widgets-lib/src/widgets/bridge/components/WalletAndNetworkSelector.tsx
@@ -279,35 +279,10 @@ export function WalletAndNetworkSelector() {
if (!fromWalletWeb3Provider) return;
clearToWalletSelections();
-
- if (isPassportProvider(fromWalletWeb3Provider)) {
- setFromNetworkDrawerOpen(false);
- setFromNetwork(chainId);
- return;
- }
-
- const currentNetwork = await fromWalletWeb3Provider?.getNetwork();
- if (currentNetwork?.chainId === chainId) {
- setFromNetworkDrawerOpen(false);
- setFromNetwork(chainId);
- return;
- }
-
- let switchNetwork;
- try {
- switchNetwork = await checkout.switchNetwork({
- provider: fromWalletWeb3Provider,
- chainId,
- });
- setFromWalletWeb3Provider(switchNetwork.provider);
- setFromNetworkDrawerOpen(false);
- setFromNetwork(switchNetwork.network.chainId);
- } catch (err) {
- // eslint-disable-next-line no-console
- console.error(err);
- }
+ setFromNetworkDrawerOpen(false);
+ setFromNetwork(chainId);
},
- [checkout, fromWalletWeb3Provider, fromWalletProviderName, fromNetwork],
+ [checkout, fromWalletWeb3Provider],
);
const handleSettingToNetwork = useCallback(() => {
@@ -504,6 +479,7 @@ export function WalletAndNetworkSelector() {
>
(
+ undefined,
+ );
+ const [isWalletConnect, setIsWalletConnect] = useState(false);
+ const {
+ bridgeState: { checkout },
+ } = useContext(BridgeContext);
+ const { isWalletConnectEnabled, getWalletLogoUrl } = useWalletConnect({
+ checkout,
+ });
+
+ useEffect(() => {
+ if (isWalletConnectEnabled) {
+ setIsWalletConnect(isWalletConnectProvider(walletProvider));
+ (async () => {
+ setWalletLogoUrl(await getWalletLogoUrl());
+ })();
+ }
+ }, [isWalletConnectEnabled, walletProvider]);
return (
-
+ {isWalletConnect && walletLogoUrl ? (
+ <>
+
+
+ >
+ ) : (
+
+ )}
({
width: 'base.icon.size.500',
- padding: walletName === WalletProviderName.PASSPORT ? 'base.spacing.x1' : '',
+ padding:
+ // eslint-disable-next-line no-constant-condition
+ walletName === WalletProviderName.PASSPORT || 'walletconnect'
+ ? 'base.spacing.x1'
+ : '',
backgroundColor: 'base.color.translucent.standard.200',
borderRadius: 'base.borderRadius.x2',
});
@@ -39,11 +60,10 @@ export const networkButtonStyles = {
borderRadius: 'base.borderRadius.x18',
};
-export const networkIconStyles = (chainId:ChainId) => ({
+export const networkIconStyles = (chainId: ChainId) => ({
fill: 'base.color.brand.2',
width: 'base.icon.size.300',
backgroundColor: logoColour[chainId],
borderRadius: '100%',
padding: 'base.spacing.x1',
-}
-);
+});
diff --git a/packages/checkout/widgets-lib/src/widgets/bridge/views/Bridge.tsx b/packages/checkout/widgets-lib/src/widgets/bridge/views/Bridge.tsx
index d516f4c722..52855922d7 100644
--- a/packages/checkout/widgets-lib/src/widgets/bridge/views/Bridge.tsx
+++ b/packages/checkout/widgets-lib/src/widgets/bridge/views/Bridge.tsx
@@ -57,6 +57,7 @@ export function Bridge({ amount, tokenAddress, defaultTokenImage }: BridgeProps)
const tokensAndBalances = await getAllowedBalances({
checkout,
provider: from.web3Provider,
+ chainId: from?.network,
allowTokenListType: TokenFilterTypes.BRIDGE,
// Skip retry given that in this case it is not needed;
// refreshBalances will be, automatically, called again
@@ -87,7 +88,7 @@ export function Bridge({ amount, tokenAddress, defaultTokenImage }: BridgeProps)
// eslint-disable-next-line no-console
console.debug(e);
}
- }, [checkout, from?.web3Provider]);
+ }, [checkout, from?.web3Provider, from?.network]);
useInterval(refreshBalances, REFRESH_TOKENS_INTERVAL_MS);
useEffect(() => {
diff --git a/packages/checkout/widgets-lib/src/widgets/swap/SwapWidget.tsx b/packages/checkout/widgets-lib/src/widgets/swap/SwapWidget.tsx
index c64e3ffc03..ac2f84a8c7 100644
--- a/packages/checkout/widgets-lib/src/widgets/swap/SwapWidget.tsx
+++ b/packages/checkout/widgets-lib/src/widgets/swap/SwapWidget.tsx
@@ -202,7 +202,9 @@ export default function SwapWidget({
if (!(await loadBalances())) return;
- showSwapView();
+ if (viewState.view.type === SharedViews.LOADING_VIEW) {
+ showSwapView();
+ }
})();
}, [checkout, provider]);
diff --git a/packages/checkout/widgets-lib/src/widgets/swap/components/SwapButton.tsx b/packages/checkout/widgets-lib/src/widgets/swap/components/SwapButton.tsx
index 7ce9ae15e0..24571c428d 100644
--- a/packages/checkout/widgets-lib/src/widgets/swap/components/SwapButton.tsx
+++ b/packages/checkout/widgets-lib/src/widgets/swap/components/SwapButton.tsx
@@ -3,6 +3,7 @@ import { useContext, useState } from 'react';
import { TransactionResponse } from '@imtbl/dex-sdk';
import { CheckoutErrorType } from '@imtbl/checkout-sdk';
import { useTranslation } from 'react-i18next';
+import { getL2ChainId } from 'lib';
import { PrefilledSwapForm, SwapWidgetViews } from '../../../context/view-context/SwapViewContextTypes';
import {
ViewContext,
@@ -26,10 +27,18 @@ export interface SwapButtonProps {
data?: SwapFormData;
insufficientFundsForGas: boolean;
openNotEnoughImxDrawer: () => void;
+ openNetworkSwitchDrawer: () => void;
}
export function SwapButton({
- loading, updateLoading, validator, transaction, data, insufficientFundsForGas, openNotEnoughImxDrawer,
+ loading,
+ updateLoading,
+ validator,
+ transaction,
+ data,
+ insufficientFundsForGas,
+ openNotEnoughImxDrawer,
+ openNetworkSwitchDrawer,
}: SwapButtonProps) {
const { t } = useTranslation();
const [showTxnRejectedState, setShowTxnRejectedState] = useState(false);
@@ -63,6 +72,20 @@ export function SwapButton({
return;
}
+ try {
+ // check for switch network here
+ const currentChainId = await (provider.provider as any).request({ method: 'eth_chainId', params: [] });
+ // eslint-disable-next-line radix
+ const parsedChainId = parseInt(currentChainId.toString());
+ if (parsedChainId !== getL2ChainId(checkout.config)) {
+ openNetworkSwitchDrawer();
+ return;
+ }
+ } catch (err) {
+ // eslint-disable-next-line no-console
+ console.error('Current network check failed', err);
+ }
+
if (!transaction) return;
try {
updateLoading(true);
diff --git a/packages/checkout/widgets-lib/src/widgets/swap/components/SwapForm.tsx b/packages/checkout/widgets-lib/src/widgets/swap/components/SwapForm.tsx
index 0792ce1015..c2ffeef347 100644
--- a/packages/checkout/widgets-lib/src/widgets/swap/components/SwapForm.tsx
+++ b/packages/checkout/widgets-lib/src/widgets/swap/components/SwapForm.tsx
@@ -11,6 +11,7 @@ import { TransactionResponse } from '@imtbl/dex-sdk';
import { UserJourney, useAnalytics } from 'context/analytics-provider/SegmentAnalyticsProvider';
import { useTranslation } from 'react-i18next';
import { Environment } from '@imtbl/config';
+import { NetworkSwitchDrawer } from 'components/NetworkSwitchDrawer/NetworkSwitchDrawer';
import { amountInputValidation as textInputValidator } from '../../../lib/validations/amountInputValidations';
import { SwapContext } from '../context/SwapContext';
import { CryptoFiatActions, CryptoFiatContext } from '../../../context/crypto-fiat-context/CryptoFiatContext';
@@ -23,6 +24,7 @@ import {
NATIVE,
DEFAULT_TOKEN_VALIDATION_DECIMALS,
ESTIMATE_DEBOUNCE,
+ getL2ChainId,
} from '../../../lib';
import { quotesProcessor } from '../functions/FetchQuote';
import { SelectInput } from '../../../components/FormComponents/SelectInput/SelectInput';
@@ -152,6 +154,7 @@ export function SwapForm({ data, theme }: SwapFromProps) {
// Drawers
const [showNotEnoughImxDrawer, setShowNotEnoughImxDrawer] = useState(false);
const [showUnableToSwapDrawer, setShowUnableToSwapDrawer] = useState(false);
+ const [showNetworkSwitchDrawer, setShowNetworkSwitchDrawer] = useState(false);
useEffect(() => {
if (tokenBalances.length === 0) return;
@@ -836,6 +839,7 @@ export function SwapForm({ data, theme }: SwapFromProps) {
}}
insufficientFundsForGas={insufficientFundsForGas}
openNotEnoughImxDrawer={openNotEnoughImxDrawer}
+ openNetworkSwitchDrawer={() => setShowNetworkSwitchDrawer(true)}
/>
+ setShowNetworkSwitchDrawer(false)}
+ />
>
);
}
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 11ca880071..95e9c55399 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
@@ -24,7 +24,7 @@ import { LanguageSelector } from './LanguageSelector';
// Create one instance of Checkout and inject Passport
const checkout = new Checkout({
baseConfig: {
- environment: Environment.SANDBOX,
+ environment: Environment.PRODUCTION,
publishableKey: 'pk_imapik-test-pCHFU0GpQImZx9UzSnU3',
},
passport,
@@ -44,8 +44,8 @@ export const MainPage = () => {
walletConnect: {
projectId: '938b553484e344b1e0b4bb80edf8c362',
metadata: {
- name: 'Marketplace Orchestrator',
- description: '',
+ name: 'Checkout Marketplace',
+ description: 'Checkout Marketplace',
url: 'http://localhost:3000/marketplace-orchestrator',
icons: []
}
@@ -156,9 +156,9 @@ export const MainPage = () => {
return (
-
+
Immutable Checkout Marketplace
-
+