diff --git a/packages/checkout/widgets-lib/src/context/view-context/BridgeViewContextTypes.ts b/packages/checkout/widgets-lib/src/context/view-context/BridgeViewContextTypes.ts index 0a45e18724..6921d8adcf 100644 --- a/packages/checkout/widgets-lib/src/context/view-context/BridgeViewContextTypes.ts +++ b/packages/checkout/widgets-lib/src/context/view-context/BridgeViewContextTypes.ts @@ -15,6 +15,7 @@ export enum BridgeWidgetViews { CLAIM_WITHDRAWAL_IN_PROGRESS = 'CLAIM_WITHDRAWAL_IN_PROGRESS', CLAIM_WITHDRAWAL_SUCCESS = 'CLAIM_WITHDRAWAL_SUCCESS', CLAIM_WITHDRAWAL_FAILURE = 'CLAIM_WITHDRAWAL_FAILURE', + SERVICE_UNAVAILABLE = 'SERVICE_UNAVAILABLE', } export type BridgeWidgetView = @@ -28,7 +29,8 @@ export type BridgeWidgetView = | BridgeClaimWithdrawal | BridgeClaimWithdrawalInProgress | BridgeClaimWithdrawalSuccess - | BridgeClaimWithdrawalFailure; + | BridgeClaimWithdrawalFailure + | BridgeServiceUnavailableView; interface BridgeCrossWalletSelection extends ViewType { type: BridgeWidgetViews.WALLET_NETWORK_SELECTION, @@ -83,3 +85,7 @@ export interface BridgeClaimWithdrawalFailure extends ViewType { transactionHash: string; reason: string; } + +export interface BridgeServiceUnavailableView extends ViewType { + type: BridgeWidgetViews.SERVICE_UNAVAILABLE; +} diff --git a/packages/checkout/widgets-lib/src/widgets/bridge/BridgeWidget.tsx b/packages/checkout/widgets-lib/src/widgets/bridge/BridgeWidget.tsx index f8f92e33d1..eaa2172adf 100644 --- a/packages/checkout/widgets-lib/src/widgets/bridge/BridgeWidget.tsx +++ b/packages/checkout/widgets-lib/src/widgets/bridge/BridgeWidget.tsx @@ -339,7 +339,7 @@ export default function BridgeWidget({ testId="claim-withdrawal-fail-view" /> )} - {viewState.view.type === SharedViews.SERVICE_UNAVAILABLE_ERROR_VIEW && ( + {viewState.view.type === BridgeWidgetViews.SERVICE_UNAVAILABLE && ( sendBridgeWidgetCloseEvent(eventTarget)} onBackButtonClick={() => { diff --git a/packages/checkout/widgets-lib/src/widgets/bridge/components/BridgeForm.tsx b/packages/checkout/widgets-lib/src/widgets/bridge/components/BridgeForm.tsx index 55d1653c67..4c60aeb38c 100644 --- a/packages/checkout/widgets-lib/src/widgets/bridge/components/BridgeForm.tsx +++ b/packages/checkout/widgets-lib/src/widgets/bridge/components/BridgeForm.tsx @@ -5,6 +5,7 @@ import { OptionKey, } from '@biom3/react'; import { + fetchRiskAssessment, GetBalanceResult, WidgetTheme, } from '@imtbl/checkout-sdk'; import { @@ -176,6 +177,27 @@ export function BridgeForm(props: BridgeFormProps) { [formToken, tokenBalances, cryptoFiatState.conversions, formatTokenOptionsId], ); + useEffect(() => { + if (!checkout || !from || !to) { + return; + } + + (async () => { + const addresses = [from.walletAddress]; + if (to.walletAddress.toLowerCase() !== from.walletAddress.toLowerCase()) { + addresses.push(to.walletAddress); + } + + const assessment = await fetchRiskAssessment(addresses, checkout.config); + bridgeDispatch({ + payload: { + type: BridgeActions.SET_RISK_ASSESSMENT, + riskAssessment: assessment, + }, + }); + })(); + }, [checkout, from, to]); + const canFetchEstimates = (silently: boolean): boolean => { if (Number.isNaN(parseFloat(formAmount))) return false; if (parseFloat(formAmount) <= 0) return false; 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 6e86b34e60..4e42922d7f 100644 --- a/packages/checkout/widgets-lib/src/widgets/bridge/components/BridgeReviewSummary.tsx +++ b/packages/checkout/widgets-lib/src/widgets/bridge/components/BridgeReviewSummary.tsx @@ -7,6 +7,7 @@ import { import { GasEstimateBridgeToL2Result, GasEstimateType, + isAddressSanctioned, } from '@imtbl/checkout-sdk'; import { ApproveBridgeResponse, BridgeTxResponse } from '@imtbl/bridge-sdk'; import { BigNumber, utils } from 'ethers'; @@ -76,7 +77,7 @@ export function BridgeReviewSummary() { const { bridgeState: { - checkout, tokenBridge, from, to, token, amount, tokenBalances, + checkout, tokenBridge, from, to, token, amount, tokenBalances, riskAssessment, }, bridgeDispatch, } = useContext(BridgeContext); @@ -363,6 +364,19 @@ export function BridgeReviewSummary() { const submitBridge = useCallback(async () => { if (!isTransfer && (!approveTransaction || !transaction)) return; + if (!from || !to) return; + if (riskAssessment && isAddressSanctioned(riskAssessment)) { + viewDispatch({ + payload: { + type: ViewActions.UPDATE_VIEW, + view: { + type: BridgeWidgetViews.SERVICE_UNAVAILABLE, + }, + }, + }); + + return; + } if (insufficientFundsForGas) { setShowNotEnoughGasDrawer(true); 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 7cc6f61d44..1c4cbabea4 100644 --- a/packages/checkout/widgets-lib/src/widgets/bridge/components/WalletAndNetworkSelector.tsx +++ b/packages/checkout/widgets-lib/src/widgets/bridge/components/WalletAndNetworkSelector.tsx @@ -13,8 +13,6 @@ import { } from 'react'; import { ChainId, - fetchRiskAssessment, - isAddressSanctioned, WalletProviderName, WalletProviderRdns, } from '@imtbl/checkout-sdk'; @@ -30,7 +28,7 @@ import { } from '../../../lib/provider'; import { getL1ChainId, getL2ChainId } from '../../../lib'; import { getChainNameById } from '../../../lib/chains'; -import { SharedViews, ViewActions, ViewContext } from '../../../context/view-context/ViewContext'; +import { ViewActions, ViewContext } from '../../../context/view-context/ViewContext'; import { abbreviateAddress } from '../../../lib/addressUtils'; import { useAnalytics, @@ -213,22 +211,6 @@ export function WalletAndNetworkSelector() { const web3Provider = new Web3Provider(event.provider as any); const connectedProvider = await connectToProvider(checkout, web3Provider, changeAccount); - // CM-793 Check for sanctioned address - const address = await connectedProvider.getSigner().getAddress(); - const sanctions = await fetchRiskAssessment([address], checkout.config); - if (isAddressSanctioned(sanctions, address)) { - viewDispatch({ - payload: { - type: ViewActions.UPDATE_VIEW, - view: { - type: SharedViews.SERVICE_UNAVAILABLE_ERROR_VIEW, - error: new Error('Sanctioned address'), - }, - }, - }); - return; - } - await handleFromWalletConnectionSuccess(connectedProvider); }, [checkout], @@ -325,6 +307,7 @@ export function WalletAndNetworkSelector() { setToWalletWeb3Provider(fromWalletWeb3Provider); setToWallet(event); const address = await fromWalletWeb3Provider!.getSigner().getAddress(); + setToWalletAddress(address.toLowerCase()); handleSettingToNetwork(address.toLowerCase()); @@ -345,21 +328,7 @@ export function WalletAndNetworkSelector() { const web3Provider = new Web3Provider(event.provider as any); const connectedProvider = await connectToProvider(checkout, web3Provider, false); - // CM-793 Check for sanctioned address const address = await connectedProvider.getSigner().getAddress(); - const sanctions = await fetchRiskAssessment([address], checkout.config); - if (isAddressSanctioned(sanctions, address)) { - viewDispatch({ - payload: { - type: ViewActions.UPDATE_VIEW, - view: { - type: SharedViews.SERVICE_UNAVAILABLE_ERROR_VIEW, - error: new Error('Sanctioned address'), - }, - }, - }); - return; - } if (isWalletConnectProvider(connectedProvider)) { handleWalletConnectToWalletConnection(connectedProvider); diff --git a/packages/checkout/widgets-lib/src/widgets/bridge/context/BridgeContext.ts b/packages/checkout/widgets-lib/src/widgets/bridge/context/BridgeContext.ts index d06326cf96..1f93d8196e 100644 --- a/packages/checkout/widgets-lib/src/widgets/bridge/context/BridgeContext.ts +++ b/packages/checkout/widgets-lib/src/widgets/bridge/context/BridgeContext.ts @@ -7,6 +7,7 @@ import { Checkout, ChainId, EIP6963ProviderInfo, + AssessmentResult, } from '@imtbl/checkout-sdk'; import { createContext } from 'react'; @@ -28,6 +29,7 @@ export interface BridgeState { allowedTokens: TokenInfo[]; token: TokenInfo | null; amount: string; + riskAssessment: AssessmentResult | undefined; } export const initialBridgeState: Omit = { @@ -40,6 +42,7 @@ export const initialBridgeState: Omit = { allowedTokens: [], token: null, amount: '0', + riskAssessment: undefined, }; export interface BridgeContextState { @@ -58,7 +61,8 @@ type ActionPayload = | SetTokenBalancesPayload | SetAllowedTokensPayload | SetTokenAndAmountPayload - | SetWalletsAndNetworksPayload; + | SetWalletsAndNetworksPayload + | SetRiskAssessmentPayload; export enum BridgeActions { SET_WALLETS_AND_NETWORKS = 'SET_WALLETS_AND_NETWORKS', @@ -68,6 +72,7 @@ export enum BridgeActions { SET_TOKEN_BALANCES = 'SET_TOKEN_BALANCES', SET_ALLOWED_TOKENS = 'SET_ALLOWED_TOKENS', SET_TOKEN_AND_AMOUNT = 'SET_TOKEN_AND_AMOUNT', + SET_RISK_ASSESSMENT = 'SET_RISK_ASSESSMENT', } export interface SetWalletProviderNamePayload { @@ -107,6 +112,11 @@ export interface SetTokenAndAmountPayload { amount: string; } +export interface SetRiskAssessmentPayload { + type: BridgeActions.SET_RISK_ASSESSMENT; + riskAssessment: AssessmentResult; +} + // eslint-disable-next-line @typescript-eslint/naming-convention export const BridgeContext = createContext({ bridgeState: { ...initialBridgeState, checkout: {} as Checkout }, @@ -159,6 +169,11 @@ export const bridgeReducer: Reducer = ( token: action.payload.token, amount: action.payload.amount, }; + case BridgeActions.SET_RISK_ASSESSMENT: + return { + ...state, + riskAssessment: action.payload.riskAssessment, + }; default: return state; }