From 3664383c87bb941cd34b67c8f9747af5627ae093 Mon Sep 17 00:00:00 2001 From: Felix Leupold <1200333+fleupold@users.noreply.github.com> Date: Wed, 15 Jul 2026 14:45:08 +0200 Subject: [PATCH 1/4] chore(cow-amm): remove CoW AMM/MEV Blocker landing cards and CoW AMM nav link Part of the CoW AMM deprecation. Two small, self-contained removals: - cow.fi: drop the CoW AMM and MEV Blocker product cards from the homepage product grid (leaving CoW Protocol + CoW Swap). - CoW Swap: remove the "CoW AMM" link from the nav "More" menu. The full Yield-tab / CoW AMM feature removal is deferred to a follow-up commit. Co-Authored-By: Claude Opus 4.8 (1M context) --- apps/cow-fi/data/home/const.tsx | 30 ------------------- .../application/containers/App/menuConsts.tsx | 5 ---- 2 files changed, 35 deletions(-) diff --git a/apps/cow-fi/data/home/const.tsx b/apps/cow-fi/data/home/const.tsx index 83ebaa85403..2cbbc79b49a 100644 --- a/apps/cow-fi/data/home/const.tsx +++ b/apps/cow-fi/data/home/const.tsx @@ -3,9 +3,7 @@ import svgBitsSrc from '@cowprotocol/assets/images/image-bits.svg' import svgCoinsSrc from '@cowprotocol/assets/images/image-coins.svg' import svgDiscordSrc from '@cowprotocol/assets/images/image-discord.svg' import svgForumSrc from '@cowprotocol/assets/images/image-forum.svg' -import svgGreenWavesSrc from '@cowprotocol/assets/images/image-green-waves.svg' import svgSnapshotSrc from '@cowprotocol/assets/images/image-snapshot.svg' -import svgTubeSrc from '@cowprotocol/assets/images/image-tube.svg' import { Color, ProductVariant, UI } from '@cowprotocol/ui' import SVG from 'react-inlinesvg' @@ -59,34 +57,6 @@ export const PRODUCT_LIST = [ productVariant: ProductVariant.CowDao, iconImage: svgCoinsSrc, }, - { - title: 'CoW AMM', - description: 'The first MEV-capturing AMM', - linkHref: '/cow-amm', - linkText: 'Deposit liquidity', - linkEvent: 'click-deploy-liquidity', - bgColor: Color.cowamm_dark_green, - textColor: Color.cowamm_green, - descriptionColor: Color.cowamm_green, - linkBgColor: Color.cowamm_green, - linkColor: Color.cowamm_dark_green, - productVariant: ProductVariant.CowDao, - iconImage: svgGreenWavesSrc, - }, - { - title: 'MEV Blocker', - description: 'The best MEV protection RPC under the sun', - linkHref: '/mevblocker', - linkText: 'Get protected', - linkEvent: 'click-get-protected', - bgColor: Color.cowfi_orange_pale, - textColor: Color.cowfi_orange_bright, - descriptionColor: Color.cowfi_orange_bright, - linkBgColor: Color.cowfi_orange_bright, - linkColor: Color.cowfi_orange_pale, - productVariant: ProductVariant.MevBlocker, - iconImage: svgTubeSrc, - }, ] export const CHANNEL_LIST = [ diff --git a/apps/cowswap-frontend/src/modules/application/containers/App/menuConsts.tsx b/apps/cowswap-frontend/src/modules/application/containers/App/menuConsts.tsx index 87d38239b9a..b79532b71cb 100644 --- a/apps/cowswap-frontend/src/modules/application/containers/App/menuConsts.tsx +++ b/apps/cowswap-frontend/src/modules/application/containers/App/menuConsts.tsx @@ -109,11 +109,6 @@ const MORE_ITEM = (isSolversEnabled: boolean): UntranslatedMenuItem => ({ label: msg`CoW Protocol`, external: true, }, - { - href: 'https://cow.fi/cow-amm', - label: msg`CoW AMM`, - external: true, - }, { href: 'https://cow.fi/careers', label: msg`Careers`, From f7ebf8b0b561754d0958df96a34777d4ca2ff55f Mon Sep 17 00:00:00 2001 From: "cowswap-release-sync[bot]" <274575433+cowswap-release-sync[bot]@users.noreply.github.com> Date: Wed, 15 Jul 2026 12:55:30 +0000 Subject: [PATCH 2/4] chore(i18n): extract i18n strings [automatic] --- apps/cowswap-frontend/src/locales/en-US.po | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/cowswap-frontend/src/locales/en-US.po b/apps/cowswap-frontend/src/locales/en-US.po index b2bd90eba4a..2271d57390d 100644 --- a/apps/cowswap-frontend/src/locales/en-US.po +++ b/apps/cowswap-frontend/src/locales/en-US.po @@ -1671,7 +1671,6 @@ msgid "Please contact CoW Swap support!" msgstr "Please contact CoW Swap support!" #: apps/cowswap-frontend/src/common/containers/CoWAmmBanner/index.tsx -#: apps/cowswap-frontend/src/modules/application/containers/App/menuConsts.tsx msgid "CoW AMM" msgstr "CoW AMM" From 12cfe88048985c2b8ab7a6b8f4d784cfff74f471 Mon Sep 17 00:00:00 2001 From: Felix Leupold <1200333+fleupold@users.noreply.github.com> Date: Wed, 15 Jul 2026 16:56:09 +0200 Subject: [PATCH 3/4] fix: remove other links and CTA button for MEVBlocker --- apps/cow-fi/components/AddRpcButton/index.tsx | 113 ----- apps/cow-fi/components/Layout/const.ts | 8 - apps/cow-fi/data/mev-blocker/const.tsx | 457 ------------------ apps/cow-fi/lib/hooks/useAddRpcEndpoint.ts | 65 --- apps/cow-fi/lib/hooks/useAddRpcWithTimeout.ts | 81 ---- apps/cow-fi/lib/hooks/useConnect.ts | 62 --- .../lib/hooks/useConnectAndAddToWallet.ts | 163 ------- apps/cow-fi/util/handleRpcError.ts | 72 --- .../src/modules/orderProgressBar/constants.ts | 1 - .../src/containers/Footer/footer.constants.ts | 21 - libs/ui/src/pure/MenuBar/index.tsx | 16 - 11 files changed, 1059 deletions(-) delete mode 100644 apps/cow-fi/components/AddRpcButton/index.tsx delete mode 100644 apps/cow-fi/data/mev-blocker/const.tsx delete mode 100644 apps/cow-fi/lib/hooks/useAddRpcEndpoint.ts delete mode 100644 apps/cow-fi/lib/hooks/useAddRpcWithTimeout.ts delete mode 100644 apps/cow-fi/lib/hooks/useConnect.ts delete mode 100644 apps/cow-fi/lib/hooks/useConnectAndAddToWallet.ts delete mode 100644 apps/cow-fi/util/handleRpcError.ts diff --git a/apps/cow-fi/components/AddRpcButton/index.tsx b/apps/cow-fi/components/AddRpcButton/index.tsx deleted file mode 100644 index fcfff43c29a..00000000000 --- a/apps/cow-fi/components/AddRpcButton/index.tsx +++ /dev/null @@ -1,113 +0,0 @@ -import { useAccount } from 'wagmi' - -import { useCowAnalytics } from '@cowprotocol/analytics' -import { Confetti, Color, UI } from '@cowprotocol/ui' - -import { darken, transparentize } from 'polished' -import { CowFiCategory, toCowFiGtmEvent } from 'src/common/analytics/types' -import styled from 'styled-components/macro' - -import { useConnectAndAddToWallet } from '../../lib/hooks/useConnectAndAddToWallet' -import { AddToWalletStateValues } from '../../types/addToWalletState' - -import { Link, LinkType } from '@/components/Link' - -const Message = styled.p<{ state: AddToWalletStateValues }>` - color: ${({ state }) => (state === 'added' ? darken(0.5, Color.cowfi_green) : Color.cowfi_orange_bright)}; - font-weight: bold; - width: 100%; - margin: 2.4rem 0 0; - background: ${({ state }) => - state === 'added' ? transparentize(0.8, Color.cowfi_green) : transparentize(0.9, Color.cowfi_orange_bright)}; - padding: 1rem; - border-radius: 1.2rem; - text-align: center; -` - -export function AddRpcButton() { - const { addWalletState, connectAndAddToWallet, disconnectWallet } = useConnectAndAddToWallet() - const { errorMessage, state } = addWalletState - const { isConnected } = useAccount() - const cowAnalytics = useCowAnalytics() - - const handleClick = async () => { - // We keep direct analytics for error tracking as it needs more context - try { - if (connectAndAddToWallet) { - // Start the connection process - const connectionPromise = connectAndAddToWallet() - - // Wait for the connection process to complete - await connectionPromise - } else { - throw new Error('connectAndAddToWallet is not defined') - } - } catch (error) { - // Use direct analytics for error tracking to include more context - cowAnalytics.sendEvent({ - category: CowFiCategory.MEVBLOCKER, - action: 'Error Add RPC', - label: error instanceof Error ? error.message : 'Unknown error', - }) - } - } - - // Get the label and enable state of button - const isAdding = state === 'adding' - const isConnecting = state === 'connecting' - const disabledButton = isConnecting || isAdding || !connectAndAddToWallet - const buttonLabel = isConnecting - ? 'Connecting Wallet...' - : isAdding - ? 'Adding to Wallet...' - : isConnected - ? 'Add MEV Blocker RPC' - : 'Get protected' - - return ( - <> - {state === 'added' ? ( - <> - - Added to your wallet! You are now safe! - - ) : ( - <> - - {buttonLabel} - - {errorMessage && {errorMessage}} - {disconnectWallet && ( - - Disconnect - - )} - - )} - - ) -} diff --git a/apps/cow-fi/components/Layout/const.ts b/apps/cow-fi/components/Layout/const.ts index 2a57756b06d..56d26bd69ef 100644 --- a/apps/cow-fi/components/Layout/const.ts +++ b/apps/cow-fi/components/Layout/const.ts @@ -67,14 +67,6 @@ function getProductsNavItem(isSolversEnabled: boolean): MenuItem { label: 'CoW Protocol', href: '/cow-protocol', }, - { - label: 'CoW AMM', - href: '/cow-amm', - }, - { - label: 'MEV Blocker', - href: '/mev-blocker', - }, { label: 'More', children: [ diff --git a/apps/cow-fi/data/mev-blocker/const.tsx b/apps/cow-fi/data/mev-blocker/const.tsx deleted file mode 100644 index 6cf388245c0..00000000000 --- a/apps/cow-fi/data/mev-blocker/const.tsx +++ /dev/null @@ -1,457 +0,0 @@ -import svgFastfreeSrc from '@cowprotocol/assets/images/image-fastfree.svg' -import svgFullprotectionSrc from '@cowprotocol/assets/images/image-fullprotection.svg' -import svgMevblockerReview1Src from '@cowprotocol/assets/images/image-mevblocker-review-1.svg' -import svgMevblockerReview2Src from '@cowprotocol/assets/images/image-mevblocker-review-2.svg' -import svgMevblockerReview3Src from '@cowprotocol/assets/images/image-mevblocker-review-3.svg' -import svgMevblockerReview4Src from '@cowprotocol/assets/images/image-mevblocker-review-4.svg' -import svgMevblockerReview5Src from '@cowprotocol/assets/images/image-mevblocker-review-5.svg' -import svgMevblockerReview6Src from '@cowprotocol/assets/images/image-mevblocker-review-6.svg' -import svgProfitSrc from '@cowprotocol/assets/images/image-profit.svg' -import svgAmbireSrc from '@cowprotocol/assets/images/logo-ambire.svg' -import svgBlocknativeSrc from '@cowprotocol/assets/images/logo-blocknative.svg' -import svgCryptoComSrc from '@cowprotocol/assets/images/logo-crypto-com.svg' -import svgKarpatkeySrc from '@cowprotocol/assets/images/logo-karpatkey.svg' -import svgKeepkeySrc from '@cowprotocol/assets/images/logo-keepkey.svg' -import svgRabbySrc from '@cowprotocol/assets/images/logo-rabby.svg' -import svgSafeSrc from '@cowprotocol/assets/images/logo-safe.svg' -import svgUniswapSrc from '@cowprotocol/assets/images/logo-uniswap.svg' -import { Color, ProductLogo, ProductVariant, UI } from '@cowprotocol/ui' - -import { CowFiCategory, toCowFiGtmEvent } from 'src/common/analytics/types' - -import { Link } from '@/components/Link' - -export const MEV_BLOCKER_LIST = [ - { - id: 'fullprotection', - description: 'Protection from frontrunning and sandwich attacks on all types of transactions', - iconImage: svgFullprotectionSrc, - bgColor: Color.cowfi_orange_bright, - textColor: Color.cowfi_orange_pale, - }, - { - id: 'profit', - description: 'Profit from any backrunning opportunities your transactions create', - iconImage: svgProfitSrc, - bgColor: Color.cowfi_peach, - textColor: Color.cowfi_orange_bright, - }, - { - id: 'fastfree', - description: 'A fast, free, censorship-resistant solution open to all searchers and builders', - iconImage: svgFastfreeSrc, - bgColor: Color.cowfi_lightBlue4, - textColor: `var(${UI.COLOR_BLUE_900_PRIMARY})`, - }, -] - -export const TRUSTED_BY_CONTENT = [ - { - href: 'https://uniswap.org/', - src: svgUniswapSrc, - }, - { - href: 'https://rabby.io/', - src: svgRabbySrc, - }, - { - href: 'https://crypto.com/', - src: svgCryptoComSrc, - }, - { - href: 'https://swap.cow.fi/', - component: , - }, - { - href: 'https://safe.global/', - src: svgSafeSrc, - }, - { - href: 'https://www.karpatkey.com/', - src: svgKarpatkeySrc, - }, - { - href: 'https://www.keepkey.com/', - src: svgKeepkeySrc, - }, - { - href: 'https://www.ambire.com/', - src: svgAmbireSrc, - }, - { - href: 'https://www.blocknative.com/', - src: svgBlocknativeSrc, - }, -] - -export const TESTIMONIAL_LIST = [ - { - title: 'MEV Blocker fixed my marriage!', - description: '– Anon', - bgColor: `var(${UI.COLOR_BLUE_400_PRIMARY})`, - textColor: `var(${UI.COLOR_NEUTRAL_0})`, - iconImage: svgMevblockerReview1Src, - }, - { - title: "If I'd known about MEV Blocker sooner, I could've had a lambo by now", - description: '– Anon', - bgColor: Color.cowfi_orange_bright, - textColor: Color.cowfi_orange_pale, - iconImage: svgMevblockerReview2Src, - }, - { - title: 'I was tired of getting rekt, so I started using MEV Blocker', - description: '– Anon', - bgColor: `var(${UI.COLOR_NEUTRAL_100})`, - textColor: Color.cowfi_orange_bright, - iconImage: svgMevblockerReview3Src, - }, - { - title: 'Robots should work for me, not against me', - description: '– Anon', - bgColor: `var(${UI.COLOR_NEUTRAL_100})`, - textColor: Color.cowfi_orange_bright, - iconImage: svgMevblockerReview4Src, - }, - { - title: "Nobody's stolen my lunch money since I started using MEV Blocker", - description: '– Anon', - bgColor: Color.cowfi_yellow, - textColor: Color.cowfi_orange_bright, - iconImage: svgMevblockerReview5Src, - }, - { - title: 'I used MEV Blocker and I instantly went up a tax bracket', - description: '– Anon', - bgColor: Color.cowfi_orange_bright, - textColor: Color.cowfi_yellow, - iconImage: svgMevblockerReview6Src, - }, -] - -export const FAQ_DATA = [ - { - question: 'What is MEV?', - answer: ( - <> - MEV or "maximal extractable value" is a method used by savvy actors (known as "searchers") - to exploit your transactions at your expense.
-
- Any time you make a transaction that carries value, searchers can "frontrun" it by submitting the - exact same transaction before you and keeping the profits for themselves. After getting frontrun, you can also - get "backrun", which is where the searcher cleans up any price slippage your trade caused, again - keeping the profits for themselves. Both a frontrun and a backrun together are known as a "sandwich - attack" — the worst type of MEV. -
-
- MEV gives you a worse price for your transactions and can cause you to lose out on hundreds or even thousands of - dollars. MEV Blocker is an easy solution - an RPC endpoint that protects all types of transactions from MEV. - - ), - }, - { - question: 'What is an RPC endpoint?', - answer: ( - <> - An RPC (remote procedure call) endpoint is used to connect applications like wallets to the blockchain.
-
- MEV Blocker is a special RPC endpoint that ensures your trades are protected from MEV. It does this by sending - your transaction to a network of searchers that scan for backrunning opportunities, but cannot frontrun or - sandwich your trades.
-
- You can add RPC endpoints like MEV Blocker by changing the selected network in your crypto wallet. Some DeFi - trading apps will also be able to integrate the MEV Blocker RPC endpoint directly — making it a default for all - users.{' '} - - Get in touch - {' '} - if you're interested in doing this! - - ), - }, - { - question: 'What kinds of MEV does MEV Blocker protect from?', - answer: ( - <> - MEV blocker protects from most kinds of frontrunning, but especially from trade sandwiching, which is when a - searcher trades just before and just after your transaction to make a profit. - - ), - }, - { - question: 'How does MEV Blocker RPC give you a rebate and when?', - answer: ( - <> - MEV Blocker also lets you benefit from backrunning. It does this by allowing searchers to "bid" in an - auction to win the right to backrun your trade. When this happens, users of MEV Blocker receive 90% of the - profit their backrunning opportunity creates (compared with 0% when not using MEV Blocker). The rebate is paid - to the user that sent the transaction (tx.origin), immediately in the same block. -
-
- In return for benefitting from backrunning your trade, these searchers are not allowed to frontrun or sandwich - you — thus protecting you from the worst types of MEV. - - ), - }, - { - question: 'When and where should I use MEV Blocker?', - answer: ( - <> - You should use MEV Blocker as often as possible! -
-
- While some DEXs like{' '} - - CoW Swap - {' '} - offer MEV protection for your DeFi trades, most DeFi venues and NFT marketplaces do not provide any type of MEV - protection. -
-
- This is where MEV Blocker comes in: any user or dApp can implement it and it protects all types of transactions - from MEV. -
-
- See a chance to mint the next Cryptopunks but don't want anyone to snatch the opportunity from you? Use MEV - Blocker. -
-
- Want to trade directly on an AMM that doesn't protect you from MEV? Use MEV Blocker. -
-
- And more! - - ), - }, - { - question: 'How do I install MEV Blocker?', - answer: ( - <> - To use MEV Blocker, you will need to add the MEV Blocker RPC endpoint to your wallet. You can do that easily by - following the instructions{' '} - - here - - . (Note that once your MEV Blocker is added to your wallet, you might need to check that it is your selected - network from time to time.) -
-
- If your wallet does not support adding custom RPC endpoints, you may have to contact your wallet developer to - get MEV Blocker included as a supported RPC. - - ), - }, - { - question: 'How does MEV Blocker work?', - answer: ( - <> - MEV Blocker facilitates an auction between a network of "searchers" who are given the opportunity to - backrun your transactions. In return, they protect you from frontrunning and sandwich attacks - the nasty types - of MEV that exploit Ethereum users every day. -
-
- When searchers submit winning bids through the orderflow auction, MEV Blocker sends the full amount of the bid - to users and validators at a 90/10 split. Validators keep the 10% as a reward, and users pocket the other 90% as - profit they'd miss out on if they weren't using MEV Blocker. -
-
- As long as you have MEV Blocker set as the RPC in your wallet (as if it were another network), you are protected - from frontrunning and sandwiching when using any Ethereum dApp. And the profit share from backrunning is - deposited automatically into your wallet. - - ), - }, - { - question: 'Which block builders does MEV Blocker submit to?', - answer: ( - <> - MEV Blocker submits to all major block builders, including Builder0x69, f1b, Flashbots, rsync builder, Titan - Builder, Gambit labs and Beaver Build. - - ), - }, - { - question: 'Does this RPC offer revert protection?', - answer: ( - <> - No, this RPC focuses on fast execution, however, we are offering another endpoint which offers revert - protection. -
-
- This separate endpoint focuses on providing revert protection first, at the expense of possibly slower inclusion - time. You can use this second endpoint by using{' '} - - https://rpc.mevblocker.io/noreverts - {' '} - as the url instead. - - ), - }, - { - question: 'Does this RPC offer a secure & private RPC endpoint?', - answer: ( - <> - Yes! if you want your transactions to be completely private, and you don't care about the refund, you need - to connect to the following endpoint:{' '} - - https://rpc.mevblocker.io/norefunds - {' '} - as the url instead. -
-
- This endpoint focuses on privacy for users that want to perform transactions and it will not share TX data over - WS. It prevents transactions failures (same as /noreverts). -
-
- Note: This endpoint is intended for sophisticated users who can unstuck transactions themselves. - - ), - }, - { - question: 'While using MEV Blocker RPC, is it safe to ignore slippage control?', - answer: ( - <> - NO, you should ALWAYS set slippage control to have multiple protections in place. -
-
- The goal of RPC is to prevent 99% of sandwiches but no existing solution can provide full 100% protection. Due - to reorgs/forked blocks 0.1% of transactions might become publicly available before on-chain confirmation. - - ), - }, - { - question: 'Who made MEV Blocker?', - answer: ( - <> - MEV Blocker is jointly formulated and maintained by{' '} - - CoW Protocol - - ,{' '} - - Agnostic Relay - - , and{' '} - - Beaver Build - - . It is open to all searchers and block builders. -
-
- This collaboration represents our commitment to providing a trusted, neutral product available to all Ethereum - users. We invite additional contributors - please get in touch if you're interested in supporting the - project. - - ), - }, - { - question: 'How do I participate as a searcher?', - answer: ( - <> - If you are a searcher that is interested in collaborating with MEV Blocker RPC, please check out the{' '} - - documentation - {' '} - for searchers and{' '} - - join the community - - . - - ), - }, - { - question: 'How can I get in touch?', - answer: ( - <> - If you are a searcher or a dApp developer, or if you're a user that has questions about MEV Blocker, please - reach out via{' '} - - Telegram - - . - - ), - }, -] diff --git a/apps/cow-fi/lib/hooks/useAddRpcEndpoint.ts b/apps/cow-fi/lib/hooks/useAddRpcEndpoint.ts deleted file mode 100644 index ae33c8484a5..00000000000 --- a/apps/cow-fi/lib/hooks/useAddRpcEndpoint.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { useCallback } from 'react' - -import { WalletClient, toHex } from 'viem' - -import { useConnect } from './useConnect' - -const CONFIG = { - rpc: { - url: 'https://rpc.mevblocker.io', - chainId: 1, - chainName: 'MEV Blocker (Ethereum Mainnet)', - nativeSymbol: 'ETH', - nativeDecimals: 18, - blockExplorerUrl: 'https://etherscan.io', - }, -} - -export interface UseAddRpcEndpointResult { - isConnected: boolean - addRpcEndpoint: () => Promise -} - -export function useAddRpcEndpoint(walletClient: WalletClient | undefined): UseAddRpcEndpointResult { - const { isConnected } = useConnect() - - const addRpcEndpoint = useCallback(async () => { - if (!walletClient || !isConnected) { - return false - } - - const { - chainName, - nativeSymbol, - nativeDecimals, - url: rpcUrl, - chainId, - blockExplorerUrl: blockExplorerUrls, - } = CONFIG.rpc - - console.debug('[addRpcEndpoint] Do RPC call "wallet_addEthereumChain" with URL:', rpcUrl) - return walletClient - .request({ - method: 'wallet_addEthereumChain', - params: [ - { - chainId: toHex(chainId), - rpcUrls: [rpcUrl], - chainName, - nativeCurrency: { - name: '', - symbol: nativeSymbol, - decimals: nativeDecimals, - }, - blockExplorerUrls: [blockExplorerUrls], - }, - ], - }) - .then(() => true) - }, [isConnected, walletClient]) - - return { - addRpcEndpoint, - isConnected, - } -} diff --git a/apps/cow-fi/lib/hooks/useAddRpcWithTimeout.ts b/apps/cow-fi/lib/hooks/useAddRpcWithTimeout.ts deleted file mode 100644 index 88c943610b8..00000000000 --- a/apps/cow-fi/lib/hooks/useAddRpcWithTimeout.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { useCallback } from 'react' - -import { WalletClient } from 'viem' - -import { useAddRpcEndpoint } from './useAddRpcEndpoint' - -import { AddToWalletStateValues } from '../../types/addToWalletState' - -import { ERROR_ADD_MANUALLY_MESSAGE } from '@/util/handleRpcError' - -const TAKING_TOO_LONG_TIME = 15000 // 15s -const TIMEOUT_TIME = 90000 // 1.5min - -interface UseAddToWalletProps { - isAdding: boolean - onAdding: (promise: Promise) => void - onAdded: () => void - walletClient: WalletClient | undefined - addingPromise: Promise | null - handleError: (error: any) => void - onTimeout: ( - errorMessage: string, - newState: AddToWalletStateValues, - // event: AddRpcUrlActionType - ) => void -} - -export function useAddRpcWithTimeout(props: UseAddToWalletProps) { - const { isAdding, walletClient, addingPromise: addRpcPromise, onAdding, onAdded, handleError, onTimeout } = props - const { addRpcEndpoint } = useAddRpcEndpoint(walletClient ?? undefined) - - return useCallback(() => { - if (isAdding || !walletClient) { - // No action if we are already adding or we are not yet connected - return undefined - } - - // Show a message if it takes long to connect/add-network - const delayMessage = ( - errorMessage: string, - newState: AddToWalletStateValues, - delay: number, - // event: AddRpcUrlActionType - ) => - setTimeout(() => { - onTimeout( - errorMessage, - newState, - // event - ) - }, delay) - - // Gives some feedback if it takes long, plus add some timeout (some wallets don't have great support to add RPC endpoints) - const timeoutSlow = delayMessage( - 'Adding the new network to your wallet is taking too long. Please verify your wallet', - 'adding', - TAKING_TOO_LONG_TIME, - // 'adding_is_taking_too_long' - ) - const timeoutTimeout = delayMessage( - ERROR_ADD_MANUALLY_MESSAGE.errorMessage, - 'error', - TIMEOUT_TIME, - // 'timeout_add_rpc' - ) - const clearTimeouts = () => [timeoutSlow, timeoutTimeout].forEach(clearTimeout) - - const newAddRpcPromise = addRpcPromise ? addRpcPromise : addRpcEndpoint() - onAdding(newAddRpcPromise) - newAddRpcPromise - .then((success) => { - if (success) { - onAdded() - } - }) - .catch(handleError) - .finally(clearTimeouts) - - return clearTimeouts - }, [addRpcEndpoint, isAdding, onAdding, onAdded, onTimeout, handleError, addRpcPromise, walletClient]) -} diff --git a/apps/cow-fi/lib/hooks/useConnect.ts b/apps/cow-fi/lib/hooks/useConnect.ts deleted file mode 100644 index b1319bc4dd4..00000000000 --- a/apps/cow-fi/lib/hooks/useConnect.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { useCallback, useEffect, useState } from 'react' - -import { useAccount, useConnectors, useConnect as useConnectWagmi } from 'wagmi' - -import { useCowAnalytics } from '@cowprotocol/analytics' - -import { useConnectModal } from '@rainbow-me/rainbowkit' -import { ConnectReturnType } from '@wagmi/core' -import { CowFiCategory } from 'src/common/analytics/types' - -export function useConnect() { - const { isConnected } = useAccount() - const { openConnectModal } = useConnectModal() - const connectors = useConnectors() - const { mutateAsync: connectAsync } = useConnectWagmi() - const cowAnalytics = useCowAnalytics() - const [connectionPromise, setConnectionPromise] = useState | null>(null) - - const injectedConnector = connectors.find((c) => c.id === 'injected') - - useEffect(() => { - if (isConnected && connectionPromise) { - // Track successful connection - cowAnalytics.sendEvent({ - category: CowFiCategory.MEVBLOCKER, - action: 'Wallet Connected', - }) - setConnectionPromise(null) - } - }, [isConnected, connectionPromise, cowAnalytics]) - - const connect = useCallback((): Promise => { - console.debug('[useConnect] Initiating connection') - - const promise = new Promise((resolve, reject) => { - if (openConnectModal) { - console.debug('[useConnect] Showing connect modal') - openConnectModal() - } - - const checkConnection = setInterval(async () => { - if (isConnected && injectedConnector) { - clearInterval(checkConnection) - try { - const result = await connectAsync({ connector: injectedConnector }) - resolve(result) - } catch (error) { - reject(error) - } - } - }, 500) - }) - - setConnectionPromise(promise) - return promise - }, [connectAsync, injectedConnector, openConnectModal, isConnected]) - - return { - isConnected, - connect, - } -} diff --git a/apps/cow-fi/lib/hooks/useConnectAndAddToWallet.ts b/apps/cow-fi/lib/hooks/useConnectAndAddToWallet.ts deleted file mode 100644 index 1228438cd3a..00000000000 --- a/apps/cow-fi/lib/hooks/useConnectAndAddToWallet.ts +++ /dev/null @@ -1,163 +0,0 @@ -import { useCallback, useState } from 'react' - -import { useDisconnect, useWalletClient } from 'wagmi' - -import { useCowAnalytics } from '@cowprotocol/analytics' - -import { CowFiCategory } from 'src/common/analytics/types' - -import { useAddRpcWithTimeout } from './useAddRpcWithTimeout' -import { useConnect } from './useConnect' - -import { AddToWalletState, AddToWalletStateValues } from '../../types/addToWalletState' - -import { handleRpcError } from '@/util/handleRpcError' - -const DEFAULT_STATE: AddToWalletState = { state: 'unknown', autoConnect: false } -const ADDING_STATE: AddToWalletState = { state: 'adding', autoConnect: false } -const ADDED_STATE: AddToWalletState = { state: 'added', autoConnect: false } - -export interface UseConnectAndAddToWalletProps { - addWalletState: AddToWalletState - connectAndAddToWallet: (() => Promise) | null - disconnectWallet: (() => void) | null -} - -export function useConnectAndAddToWallet(): UseConnectAndAddToWalletProps { - const { connect, isConnected = false } = useConnect() - const { disconnect } = useDisconnect() - const { data: walletClient } = useWalletClient() - const cowAnalytics = useCowAnalytics() - const [addWalletState, setState] = useState(DEFAULT_STATE) - const [addingPromise, setAddRpcPromise] = useState | null>(null) - - const handleError = useCallback( - (error: unknown) => { - console.error(`[connectAndAddToWallet] handleError`, error) - const { errorMessage: message, isError, isUserRejection } = handleRpcError(error) - if (isUserRejection) { - cowAnalytics.sendEvent({ - category: CowFiCategory.MEVBLOCKER, - action: 'Add RPC Error', - label: 'User Rejected', - }) - setState({ state: 'unknown', errorMessage: 'User rejected the request', autoConnect: false }) - } else if (isError) { - cowAnalytics.sendEvent({ - category: CowFiCategory.MEVBLOCKER, - action: 'Add RPC Error', - label: error instanceof Error ? error.message : 'Unknown error', - }) - setState({ state: 'error', errorMessage: message || undefined, autoConnect: false }) - } else { - setState(DEFAULT_STATE) - } - setAddRpcPromise(null) - }, - [setState, cowAnalytics], - ) - - const addToWallet = useAddRpcWithTimeout({ - isAdding: addWalletState.state === 'adding', - addingPromise, - onAdding(newAddRpcPromise) { - console.debug('[connectAndAddToWallet] Adding RPC...') - cowAnalytics.sendEvent({ - category: CowFiCategory.MEVBLOCKER, - action: 'Add RPC', - label: 'Adding', - }) - setAddRpcPromise(newAddRpcPromise) - setState(ADDING_STATE) - }, - onAdded() { - console.debug('[connectAndAddToWallet] 🎉 RPC has been added!') - cowAnalytics.sendEvent({ - category: CowFiCategory.MEVBLOCKER, - action: 'Add RPC', - label: 'Success', - }) - setState(ADDED_STATE) - setAddRpcPromise(null) - }, - onTimeout(errorMessage: string, newState: AddToWalletStateValues) { - console.debug(`[connectAndAddToWallet] New State: ${newState}. Message`, errorMessage) - cowAnalytics.sendEvent({ - category: CowFiCategory.MEVBLOCKER, - action: 'Add RPC Error', - label: 'Timeout', - value: errorMessage ? 1 : 0, - }) - setState({ - state: newState, - errorMessage: errorMessage || undefined, - autoConnect: addWalletState.autoConnect, - }) - }, - walletClient: walletClient ?? undefined, - handleError, - }) - - const connectAndAddToWallet = useCallback((): Promise => { - if (!walletClient && isConnected) { - return Promise.reject(new Error('Connection not allowed')) - } - - return new Promise((resolve, reject) => { - if (!isConnected) { - console.debug('[useConnectAndAddToWallet] Connecting...') - cowAnalytics.sendEvent({ - category: CowFiCategory.MEVBLOCKER, - action: 'Attempt Connect Wallet', - }) - connect() - .then((result) => { - if (result) { - console.debug('[useConnectAndAddToWallet] 🔌 Connected!') - cowAnalytics.sendEvent({ - category: CowFiCategory.MEVBLOCKER, - action: 'Wallet Connected', - }) - cowAnalytics.sendEvent({ - category: CowFiCategory.MEVBLOCKER, - action: 'Attempt Add RPC', - }) - addToWallet() - resolve() - } else { - console.debug('[useConnectAndAddToWallet] Connection process incomplete') - setState(DEFAULT_STATE) - resolve() - } - }) - .catch((error: unknown) => { - handleError(error) - reject(error) - }) - } else { - console.debug('[useConnectAndAddToWallet] Already connected. Adding RPC endpoint...') - cowAnalytics.sendEvent({ - category: CowFiCategory.MEVBLOCKER, - action: 'Attempt Add RPC', - }) - addToWallet() - resolve() - } - }) - }, [isConnected, connect, addToWallet, handleError, walletClient, cowAnalytics]) - - const disconnectWallet = useCallback(() => { - cowAnalytics.sendEvent({ - category: CowFiCategory.MEVBLOCKER, - action: 'Wallet Disconnected', - }) - disconnect() - setState(DEFAULT_STATE) - }, [disconnect, cowAnalytics]) - - return { - connectAndAddToWallet: walletClient || !isConnected ? connectAndAddToWallet : null, - disconnectWallet: isConnected ? disconnectWallet : null, - addWalletState, - } -} diff --git a/apps/cow-fi/util/handleRpcError.ts b/apps/cow-fi/util/handleRpcError.ts deleted file mode 100644 index 8ad586edb9e..00000000000 --- a/apps/cow-fi/util/handleRpcError.ts +++ /dev/null @@ -1,72 +0,0 @@ -const ERROR_USER_REJECTED = { - errorMessage: `MEV Blocker was not added. User rejected.`, - isUserRejection: true, - isError: false, -} -export const ERROR_ADD_MANUALLY_MESSAGE = { - errorMessage: 'There was an error adding the RPC automatically to your wallet. Please add manually', - isUserRejection: false, - isError: true, -} -const ERROR_NETWORK_ADDING_UNSUPPORTED = { - errorMessage: `Oh no! 😢 It looks like your wallet doesn't support automatic RPC changes to help protect you. You might be able to make the change manually, though. If you could let your wallet provider know about this, that would be awesome! Thanks for considering it!`, - isUserRejection: false, - isError: true, -} -const ERROR_NETWORK_ALREADY_ADDED = { - errorMessage: `Your wallet has a pending request to add the network. Please review your wallet.`, - isUserRejection: false, - isError: true, -} - -export function handleRpcError(error: any): { - errorMessage: string | null - isUserRejection: boolean - isError: boolean -} { - let actualError = error - - // viem wraps the actual error, we need to get the actual error (not their wrapper) - - if (error.details && typeof error.details === 'string') { - try { - actualError = JSON.parse(error.details) - } catch { - if (error.details === 'Missing or invalid. request() method: wallet_addEthereumChain') { - return ERROR_NETWORK_ADDING_UNSUPPORTED - } - } - } - - const errorCode = actualError?.code - if (errorCode === 4001) { - return ERROR_USER_REJECTED - } - - // -------- Uncomment to debug - // if (error) { - // return { errorMessage: JSON.stringify(error, null, 2), isUserRejection: false, isError: true } - // } - // ----------------- - - const message = error?.details.message || error?.message - if (errorCode === -32002 && message?.includes('already pending')) { - return ERROR_NETWORK_ALREADY_ADDED - } - - if ( - errorCode === -32000 && - (message?.includes('May not specify default') || // i.e. IOS Metamask (over Wallet Connect) - message?.includes('Chain ID already exists. Received')) // i.e. Im token - ) { - return ERROR_NETWORK_ADDING_UNSUPPORTED - } - - if (errorCode === -32602 && message?.includes('May not specify default')) { - // Metakas IOS don't allow you to replace your RPC Endpoint - // https://community.metamask.io/t/allow-to-add-switch-between-ethereum-networks-using-api/23595 - return ERROR_NETWORK_ADDING_UNSUPPORTED - } - - return ERROR_ADD_MANUALLY_MESSAGE -} diff --git a/apps/cowswap-frontend/src/modules/orderProgressBar/constants.ts b/apps/cowswap-frontend/src/modules/orderProgressBar/constants.ts index 40bc763768a..ee8958f8a6c 100644 --- a/apps/cowswap-frontend/src/modules/orderProgressBar/constants.ts +++ b/apps/cowswap-frontend/src/modules/orderProgressBar/constants.ts @@ -85,7 +85,6 @@ export const COW_SWAP_BENEFITS = [ msg`Limit orders on CoW Swap capture surplus - so if the price moves in your favor, you're likely to get more than you asked for.`, msg`On CoW Swap, you can set limit orders for balances you don't have yet.`, msg`Limit orders on CoW Swap are free to place and cancel. That's unique in DeFi!`, - msg`You can protect all your Ethereum transactions from MEV - not just trades on CoW Swap - by installing MEV Blocker.`, msg`Liquidity pools on CoW AMM grow faster than on other AMMs because they don't lose money to arbitrage bots.`, msg`CoW Swap has over 20 active solvers - more than any other exchange.`, msg`CoW Swap's robust solver competition protects your slippage from being exploited by MEV bots.`, diff --git a/libs/ui/src/containers/Footer/footer.constants.ts b/libs/ui/src/containers/Footer/footer.constants.ts index 4b62d0c09a4..451e8469552 100644 --- a/libs/ui/src/containers/Footer/footer.constants.ts +++ b/libs/ui/src/containers/Footer/footer.constants.ts @@ -63,20 +63,6 @@ export const PRODUCT_LOGO_LINKS = [ external: true, utmContent: 'product-cow-protocol', }, - { - href: 'https://cow.fi/mev-blocker', - label: 'MEV Blocker', - productVariant: ProductVariant.MevBlocker, - external: true, - utmContent: 'product-mev-blocker', - }, - { - href: 'https://cow.fi/cow-amm', - label: 'CoW AMM', - productVariant: ProductVariant.CowAmm, - external: true, - utmContent: 'product-cow-amm', - }, ] as const satisfies NavItemChildrenProps[] export const GLOBAL_FOOTER_DESCRIPTION = @@ -97,13 +83,6 @@ const FOOTER_NAV_GROUP_PRODUCTS = { external: true, utmContent: 'footer-products-cow-protocol', }, - { label: 'CoW AMM', href: 'https://cow.fi/cow-amm', external: true, utmContent: 'footer-products-cow-amm' }, - { - label: 'MEV Blocker', - href: 'https://cow.fi/mev-blocker', - external: true, - utmContent: 'footer-products-mev-blocker', - }, { label: 'CoW Explorer', href: 'https://explorer.cow.fi', diff --git a/libs/ui/src/pure/MenuBar/index.tsx b/libs/ui/src/pure/MenuBar/index.tsx index 95244ba4a1b..9e43355bacd 100644 --- a/libs/ui/src/pure/MenuBar/index.tsx +++ b/libs/ui/src/pure/MenuBar/index.tsx @@ -86,22 +86,6 @@ const DAO_NAV_ITEMS: MenuItem[] = [ external: true, utmContent: 'menubar-dao-nav-cowprotocol', }, - { - href: 'https://cow.fi/cow-amm', - productVariant: ProductVariant.CowAmm, - hoverColor: '#007CDB', - hoverBgColor: '#CCF8FF', - external: true, - utmContent: 'menubar-dao-nav-cowamm', - }, - { - href: 'https://cow.fi/mev-blocker', - productVariant: ProductVariant.MevBlocker, - hoverColor: '#F2CD16', - hoverBgColor: '#EC4612', - external: true, - utmContent: 'menubar-dao-nav-mevblocker', - }, ] const getLanguageName = (locale: string): string => { From e32ccf34bc710eae5bd1600b2da8c7e6c4e5c4f7 Mon Sep 17 00:00:00 2001 From: "cowswap-release-sync[bot]" <274575433+cowswap-release-sync[bot]@users.noreply.github.com> Date: Wed, 15 Jul 2026 14:57:44 +0000 Subject: [PATCH 4/4] chore(i18n): extract i18n strings [automatic] --- apps/cowswap-frontend/src/locales/en-US.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/cowswap-frontend/src/locales/en-US.po b/apps/cowswap-frontend/src/locales/en-US.po index 2271d57390d..d3d3236b41c 100644 --- a/apps/cowswap-frontend/src/locales/en-US.po +++ b/apps/cowswap-frontend/src/locales/en-US.po @@ -5995,8 +5995,8 @@ msgid "Safe Nonce: <0>{nonce}" msgstr "Safe Nonce: <0>{nonce}" #: apps/cowswap-frontend/src/modules/orderProgressBar/constants.ts -msgid "You can protect all your Ethereum transactions from MEV - not just trades on CoW Swap - by installing MEV Blocker." -msgstr "You can protect all your Ethereum transactions from MEV - not just trades on CoW Swap - by installing MEV Blocker." +#~ msgid "You can protect all your Ethereum transactions from MEV - not just trades on CoW Swap - by installing MEV Blocker." +#~ msgstr "You can protect all your Ethereum transactions from MEV - not just trades on CoW Swap - by installing MEV Blocker." #: apps/cowswap-frontend/src/modules/hooksStore/pure/AddCustomHookForm/constants.tsx msgid "HTTPS is required. Please use <0>https://"