diff --git a/packages/synapse-interface/components/StateManagedBridge/DestinationAddressInput.tsx b/packages/synapse-interface/components/StateManagedBridge/DestinationAddressInput.tsx index 345a76dc4e..a88965cf7a 100644 --- a/packages/synapse-interface/components/StateManagedBridge/DestinationAddressInput.tsx +++ b/packages/synapse-interface/components/StateManagedBridge/DestinationAddressInput.tsx @@ -220,6 +220,8 @@ export const DestinationAddressInput = ({ const adjustInputSize = () => { const addressInput: HTMLElement = document.getElementById('address-input') + if (!addressInput) return + if (isInputFocused || isInputInvalid) { addressInput.style.width = '12rem' } else if (inputValue.length > 0) { diff --git a/packages/synapse-interface/contexts/SegmentAnalyticsProvider.tsx b/packages/synapse-interface/contexts/SegmentAnalyticsProvider.tsx index ff069ef3f9..34977c8605 100644 --- a/packages/synapse-interface/contexts/SegmentAnalyticsProvider.tsx +++ b/packages/synapse-interface/contexts/SegmentAnalyticsProvider.tsx @@ -2,7 +2,6 @@ import { AnalyticsBrowser } from '@segment/analytics-next' import { getAccount } from '@wagmi/core' import { createContext, useContext } from 'react' -import { isBlacklisted } from '@/utils/isBlacklisted' import { screenAddress } from '@/utils/screenAddress' import { wagmiConfig } from '@/wagmiConfig' @@ -24,12 +23,10 @@ export const segmentAnalyticsEvent = ( const { address } = getAccount(wagmiConfig) - if (isBlacklisted(address)) { - document.body = document.createElement('body') - } else { - if (screen) { - screenAddress(address) - } + if (screen && address) { + screenAddress(address).catch((error) => { + console.error('Error screening address:', error) + }) } const enrichedEventData = { diff --git a/packages/synapse-interface/contexts/UserProvider.tsx b/packages/synapse-interface/contexts/UserProvider.tsx index 769b7b0e02..6476d8e19e 100644 --- a/packages/synapse-interface/contexts/UserProvider.tsx +++ b/packages/synapse-interface/contexts/UserProvider.tsx @@ -8,7 +8,6 @@ import { setSwapChainId } from '@/slices/swap/reducer' import { fetchAndStorePortfolioBalances } from '@/slices/portfolio/hooks' import { useAppDispatch } from '@/store/hooks' import { resetPortfolioState } from '@/slices/portfolio/actions' -import { isBlacklisted } from '@/utils/isBlacklisted' import { screenAddress } from '@/utils/screenAddress' const WalletStatusContext = createContext(undefined) @@ -85,11 +84,12 @@ export const UserProvider = ({ children }) => { useEffect(() => { if (address) { - if (!isBlacklisted(address)) { - screenAddress(address) - } else { - document.body = document.createElement('body') - } + ;(async () => { + const isRisky = await screenAddress(address) + if (isRisky) { + return + } + })() } }, [address]) diff --git a/packages/synapse-interface/pages/state-managed-bridge/index.tsx b/packages/synapse-interface/pages/state-managed-bridge/index.tsx index 46befb6311..99183e76da 100644 --- a/packages/synapse-interface/pages/state-managed-bridge/index.tsx +++ b/packages/synapse-interface/pages/state-managed-bridge/index.tsx @@ -73,6 +73,7 @@ import { } from '@/components/Maintenance/Maintenance' import { wagmiConfig } from '@/wagmiConfig' import { useStaleQuoteUpdater } from '@/utils/hooks/useStaleQuoteUpdater' +import { screenAddress } from '@/utils/screenAddress' const StateManagedBridge = () => { const { address } = useAccount() @@ -349,6 +350,14 @@ const StateManagedBridge = () => { const executeBridge = async () => { let pendingPopup: any + + if (destinationAddress) { + const isRisky = await screenAddress(destinationAddress) + if (isRisky) { + return + } + } + segmentAnalyticsEvent( `[Bridge] initiates bridge`, { diff --git a/packages/synapse-interface/store/destinationAddressMiddleware.ts b/packages/synapse-interface/store/destinationAddressMiddleware.ts new file mode 100644 index 0000000000..0b412f8b25 --- /dev/null +++ b/packages/synapse-interface/store/destinationAddressMiddleware.ts @@ -0,0 +1,15 @@ +import { Middleware } from '@reduxjs/toolkit' + +import { screenAddress } from '@/utils/screenAddress' +import { setDestinationAddress } from '@/slices/bridge/reducer' + +export const destinationAddressMiddleware: Middleware = + (_store) => (next) => async (action) => { + if (setDestinationAddress.match(action) && action.payload !== null) { + const isRisky = await screenAddress(action.payload) + if (isRisky) { + return + } + } + return next(action) + } diff --git a/packages/synapse-interface/store/store.ts b/packages/synapse-interface/store/store.ts index 33606768e3..28a84a9ccc 100644 --- a/packages/synapse-interface/store/store.ts +++ b/packages/synapse-interface/store/store.ts @@ -6,6 +6,7 @@ import { api } from '@/slices/api/slice' import { segmentAnalyticsEvent } from '@/contexts/SegmentAnalyticsProvider' import { storageKey, persistConfig, persistedReducer } from './reducer' import { resetReduxCache } from '@/slices/application/actions' +import { destinationAddressMiddleware } from '@/store/destinationAddressMiddleware' const checkVersionAndResetCache = (): boolean => { if (typeof window !== 'undefined') { @@ -27,7 +28,7 @@ export const store = configureStore({ middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: false, - }).concat(api.middleware), + }).concat(api.middleware, destinationAddressMiddleware), }) if (checkVersionAndResetCache()) { diff --git a/packages/synapse-interface/utils/screenAddress.ts b/packages/synapse-interface/utils/screenAddress.ts index c849571fd6..571d574ca5 100644 --- a/packages/synapse-interface/utils/screenAddress.ts +++ b/packages/synapse-interface/utils/screenAddress.ts @@ -1,25 +1,42 @@ import { Address } from 'viem' -import { GlobalEventEmitter } from '@/utils/globalEventEmitter' import { DISCORD_URL } from '@/constants/urls' +import { GlobalEventEmitter } from '@/utils/globalEventEmitter' +import { isBlacklisted } from '@/utils/isBlacklisted' + +const createRiskDetectedEvent = (address: Address | string) => { + return new CustomEvent('riskDetected', { + detail: { + message: `This address ${address} has been flagged for being associated with illicit activities. If you think this is a mistake, please contact support.`, + }, + }) +} -export const screenAddress = (address: Address | string) => { +export const screenAddress = async ( + address: Address | string +): Promise => { const url = `https://screener.omnirpc.io/fe/address/${address}` - fetch(url, { - method: 'GET', - }) - .then((response) => response.json()) - .then(({ risk }) => { - if (risk) { - const event = new CustomEvent('riskDetected', { - detail: { - message: `This address has been flagged for being associated with illicit activities. If you think this is a mistake, please contact support.`, - }, - }) - - GlobalEventEmitter.dispatchEvent(event) - } - }) - .catch((error) => console.error('Error:', error)) + if (isBlacklisted(address)) { + const event = createRiskDetectedEvent(address) + + GlobalEventEmitter.dispatchEvent(event) + return true + } + + try { + const response = await fetch(url, { method: 'GET' }) + const { risk } = await response.json() + + if (risk) { + const event = createRiskDetectedEvent(address) + + GlobalEventEmitter.dispatchEvent(event) + return true + } + return false + } catch (error) { + console.error('Error:', error) + return false + } }