diff --git a/.release-please-manifest.json b/.release-please-manifest.json index d633f0449f..14b0d8a36c 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,5 +1,5 @@ { - "apps/cowswap-frontend": "1.97.0", + "apps/cowswap-frontend": "1.97.1", "apps/explorer": "2.42.0", "libs/permit-utils": "0.6.0", "libs/widget-lib": "0.18.0", @@ -9,7 +9,7 @@ "libs/assets": "1.12.0", "libs/common-const": "1.13.0", "libs/common-hooks": "1.6.1", - "libs/common-utils": "1.9.0", + "libs/common-utils": "1.9.1", "libs/core": "1.6.0", "libs/ens": "1.3.0", "libs/events": "1.5.0", @@ -17,7 +17,7 @@ "libs/tokens": "1.14.0", "libs/types": "1.5.0", "libs/ui": "1.18.0", - "libs/wallet": "1.9.1", + "libs/wallet": "1.9.2", "apps/cow-fi": "1.19.3", "libs/wallet-provider": "1.0.0", "libs/ui-utils": "1.1.0", diff --git a/apps/cowswap-frontend/CHANGELOG.md b/apps/cowswap-frontend/CHANGELOG.md index a1a1555b47..296f1c0055 100644 --- a/apps/cowswap-frontend/CHANGELOG.md +++ b/apps/cowswap-frontend/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.97.1](https://github.com/cowprotocol/cowswap/compare/cowswap-v1.97.0...cowswap-v1.97.1) (2025-01-30) + + +### Bug Fixes + +* type guard to make sure provider is a JsonRpcProvider ([#5357](https://github.com/cowprotocol/cowswap/issues/5357)) ([6a2e030](https://github.com/cowprotocol/cowswap/commit/6a2e030aa7f88ef207fad8910750b18dcf719503)) + ## [1.97.0](https://github.com/cowprotocol/cowswap/compare/cowswap-v1.96.2...cowswap-v1.97.0) (2025-01-29) diff --git a/apps/cowswap-frontend/package.json b/apps/cowswap-frontend/package.json index 206e74d13f..1171269385 100644 --- a/apps/cowswap-frontend/package.json +++ b/apps/cowswap-frontend/package.json @@ -1,6 +1,6 @@ { "name": "@cowprotocol/cowswap", - "version": "1.97.0", + "version": "1.97.1", "description": "CoW Swap", "main": "index.js", "author": "", diff --git a/apps/cowswap-frontend/src/common/utils/assertProviderNetwork.ts b/apps/cowswap-frontend/src/common/utils/assertProviderNetwork.ts new file mode 100644 index 0000000000..1c67ff2416 --- /dev/null +++ b/apps/cowswap-frontend/src/common/utils/assertProviderNetwork.ts @@ -0,0 +1,23 @@ +import { getChainIdImmediately } from '@cowprotocol/common-utils' +import { SupportedChainId } from '@cowprotocol/cow-sdk' +import { JsonRpcProvider, Provider } from '@ethersproject/providers' + +export async function assertProviderNetwork( + chainId: SupportedChainId, + provider: JsonRpcProvider | Provider, + description: string, +): Promise { + const ethereumProvider = (provider as unknown as { provider: typeof window.ethereum }).provider + + // Do assert only for Metamask + if (!ethereumProvider || !ethereumProvider.isMetaMask || ethereumProvider.isRabby) return chainId + + const network = await getChainIdImmediately(provider) + if (network !== chainId) { + throw new Error( + `Wallet chainId differs from app chainId. Wallet: ${network}, App: ${chainId}. Action: ${description}`, + ) + } + + return network +} diff --git a/apps/cowswap-frontend/src/legacy/hooks/useWrapCallback.ts b/apps/cowswap-frontend/src/legacy/hooks/useWrapCallback.ts index 31e1cea3eb..647efe70d5 100644 --- a/apps/cowswap-frontend/src/legacy/hooks/useWrapCallback.ts +++ b/apps/cowswap-frontend/src/legacy/hooks/useWrapCallback.ts @@ -2,7 +2,6 @@ import { getChainCurrencySymbols, RADIX_HEX } from '@cowprotocol/common-const' import { calculateGasMargin, formatTokenAmount, - getChainIdImmediately, getIsNativeToken, isRejectRequestProviderError, } from '@cowprotocol/common-utils' @@ -10,13 +9,15 @@ import { SupportedChainId } from '@cowprotocol/cow-sdk' import { Command } from '@cowprotocol/types' import { BigNumber } from '@ethersproject/bignumber' import { Contract } from '@ethersproject/contracts' -import { JsonRpcProvider, TransactionResponse } from '@ethersproject/providers' +import { TransactionResponse } from '@ethersproject/providers' import { Currency, CurrencyAmount } from '@uniswap/sdk-core' import { useTransactionAdder } from 'legacy/state/enhancedTransactions/hooks' import { wrapAnalytics } from 'modules/analytics' +import { assertProviderNetwork } from 'common/utils/assertProviderNetwork' + // Use a 180K gas as a fallback if there's issue calculating the gas estimation (fixes some issues with some nodes failing to calculate gas costs for SC wallets) const WRAP_UNWRAP_GAS_LIMIT_DEFAULT = BigNumber.from('180000') @@ -114,10 +115,7 @@ async function wrapContractCall( const estimatedGas = await wethContract.estimateGas.deposit({ value: amountHex }).catch(_handleGasEstimateError) const gasLimit = calculateGasMargin(estimatedGas) - const network = await getChainIdImmediately(wethContract.provider as JsonRpcProvider) - if (network !== chainId) { - throw new Error(`Wallet chainId differs from app chainId. Wallet: ${network}, App: ${chainId}`) - } + const network = await assertProviderNetwork(chainId, wethContract.provider, 'wrap') const tx = await wethContract.populateTransaction.deposit({ value: amountHex, gasLimit }) @@ -134,10 +132,7 @@ async function unwrapContractCall( const tx = await wethContract.populateTransaction.withdraw(amountHex, { gasLimit }) - const network = await getChainIdImmediately(wethContract.provider as JsonRpcProvider) - if (network !== chainId) { - throw new Error(`Wallet chainId differs from app chainId. Wallet: ${network}, App: ${chainId}`) - } + const network = await assertProviderNetwork(chainId, wethContract.provider, 'unwrap') return wethContract.signer.sendTransaction({ ...tx, chainId: network }) } diff --git a/apps/cowswap-frontend/src/modules/swap/services/ethFlow/steps/signEthFlowOrderStep.ts b/apps/cowswap-frontend/src/modules/swap/services/ethFlow/steps/signEthFlowOrderStep.ts index 43ba87aefc..c3f2b41342 100644 --- a/apps/cowswap-frontend/src/modules/swap/services/ethFlow/steps/signEthFlowOrderStep.ts +++ b/apps/cowswap-frontend/src/modules/swap/services/ethFlow/steps/signEthFlowOrderStep.ts @@ -1,8 +1,7 @@ import { CoWSwapEthFlow } from '@cowprotocol/abis' -import { calculateGasMargin, getChainIdImmediately } from '@cowprotocol/common-utils' +import { calculateGasMargin } from '@cowprotocol/common-utils' import { OrderClass, SigningScheme, UnsignedOrder } from '@cowprotocol/cow-sdk' import { ContractTransaction } from '@ethersproject/contracts' -import { JsonRpcProvider } from '@ethersproject/providers' import { NativeCurrency } from '@uniswap/sdk-core' import { Order } from 'legacy/state/orders/actions' @@ -11,6 +10,7 @@ import { getSignOrderParams, mapUnsignedOrderToOrder, PostOrderParams } from 'le import { logTradeFlow, logTradeFlowError } from 'modules/trade/utils/logger' import { GAS_LIMIT_DEFAULT } from 'common/constants/common' +import { assertProviderNetwork } from 'common/utils/assertProviderNetwork' type EthFlowOrderParams = Omit & { sellToken: NativeCurrency @@ -45,12 +45,7 @@ export async function signEthFlowOrderStep( throw new Error('[EthFlow::SignEthFlowOrderStep] No quoteId passed') } - const network = await getChainIdImmediately(ethFlowContract.provider as JsonRpcProvider) - if (network !== orderParams.chainId) { - throw new Error( - `Wallet chainId differs from order params chainId. Wallet: ${network}, Order: ${orderParams.chainId}`, - ) - } + const network = await assertProviderNetwork(orderParams.chainId, ethFlowContract.provider, 'eth-flow') const ethOrderParams: EthFlowCreateOrderParams = { ...order, diff --git a/apps/cowswap-frontend/src/react-app-env.d.ts b/apps/cowswap-frontend/src/react-app-env.d.ts index 8aedbafa22..8da6f43fb6 100644 --- a/apps/cowswap-frontend/src/react-app-env.d.ts +++ b/apps/cowswap-frontend/src/react-app-env.d.ts @@ -14,6 +14,7 @@ interface Window { // value that is populated and returns true by the Coinbase Wallet mobile dapp browser isCoinbaseWallet?: true isMetaMask?: true + isRabby?: true autoRefreshOnNetworkChange?: boolean autoConnect?: boolean setSelectedProvider: (any) => void diff --git a/libs/common-utils/CHANGELOG.md b/libs/common-utils/CHANGELOG.md index b90dc66f40..451762712e 100644 --- a/libs/common-utils/CHANGELOG.md +++ b/libs/common-utils/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.9.1](https://github.com/cowprotocol/cowswap/compare/common-utils-v1.9.0...common-utils-v1.9.1) (2025-01-30) + + +### Bug Fixes + +* type guard to make sure provider is a JsonRpcProvider ([#5357](https://github.com/cowprotocol/cowswap/issues/5357)) ([6a2e030](https://github.com/cowprotocol/cowswap/commit/6a2e030aa7f88ef207fad8910750b18dcf719503)) + ## [1.9.0](https://github.com/cowprotocol/cowswap/compare/common-utils-v1.8.0...common-utils-v1.9.0) (2025-01-29) diff --git a/libs/common-utils/package.json b/libs/common-utils/package.json index c918683a6e..0a9da1b4c9 100644 --- a/libs/common-utils/package.json +++ b/libs/common-utils/package.json @@ -1,6 +1,6 @@ { "name": "@cowprotocol/common-utils", - "version": "1.9.0", + "version": "1.9.1", "main": "./index.js", "types": "./index.d.ts", "exports": { diff --git a/libs/common-utils/src/getChainIdImmediately.ts b/libs/common-utils/src/getChainIdImmediately.ts index d5eebfc62f..b018f5027e 100644 --- a/libs/common-utils/src/getChainIdImmediately.ts +++ b/libs/common-utils/src/getChainIdImmediately.ts @@ -1,6 +1,11 @@ -import { JsonRpcProvider } from '@ethersproject/providers' +import { JsonRpcProvider, Provider } from '@ethersproject/providers' + +export async function getChainIdImmediately(provider: JsonRpcProvider | Provider): Promise { + if (!isJsonRpcProvider(provider)) { + console.error('Provider is not a JsonRpcProvider') + return undefined + } -export async function getChainIdImmediately(provider: JsonRpcProvider): Promise { try { const chainId = await provider.send('eth_chainId', []) @@ -10,3 +15,7 @@ export async function getChainIdImmediately(provider: JsonRpcProvider): Promise< return undefined } } + +function isJsonRpcProvider(provider: JsonRpcProvider | Provider): provider is JsonRpcProvider { + return (provider as JsonRpcProvider).send !== undefined +} diff --git a/libs/wallet/CHANGELOG.md b/libs/wallet/CHANGELOG.md index 495df7df23..86a9011df4 100644 --- a/libs/wallet/CHANGELOG.md +++ b/libs/wallet/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.9.2](https://github.com/cowprotocol/cowswap/compare/wallet-v1.9.1...wallet-v1.9.2) (2025-01-30) + + +### Bug Fixes + +* type guard to make sure provider is a JsonRpcProvider ([#5357](https://github.com/cowprotocol/cowswap/issues/5357)) ([6a2e030](https://github.com/cowprotocol/cowswap/commit/6a2e030aa7f88ef207fad8910750b18dcf719503)) + ## [1.9.1](https://github.com/cowprotocol/cowswap/compare/wallet-v1.9.0...wallet-v1.9.1) (2025-01-29) diff --git a/libs/wallet/package.json b/libs/wallet/package.json index 84564ef932..f1549fa632 100644 --- a/libs/wallet/package.json +++ b/libs/wallet/package.json @@ -1,6 +1,6 @@ { "name": "@cowprotocol/wallet", - "version": "1.9.1", + "version": "1.9.2", "main": "./index.js", "types": "./index.d.ts", "exports": { diff --git a/libs/wallet/src/web3-react/connectors/TrezorConnector/index.ts b/libs/wallet/src/web3-react/connectors/TrezorConnector/index.ts index bff3abf862..303aa1279d 100644 --- a/libs/wallet/src/web3-react/connectors/TrezorConnector/index.ts +++ b/libs/wallet/src/web3-react/connectors/TrezorConnector/index.ts @@ -143,7 +143,7 @@ export class TrezorConnector extends Connector { this.customProvider = customProvider - const chainId = await customProvider.send('eth_chainId', []) + const chainId = +(await customProvider.send('eth_chainId', [])) trezorConnect.on('DEVICE_EVENT', (event) => { if (event.type === 'device-disconnect') { diff --git a/libs/wallet/src/web3-react/connectors/TrezorConnector/sendTransactionHandler.ts b/libs/wallet/src/web3-react/connectors/TrezorConnector/sendTransactionHandler.ts index 064d3acdbe..104a9633f4 100644 --- a/libs/wallet/src/web3-react/connectors/TrezorConnector/sendTransactionHandler.ts +++ b/libs/wallet/src/web3-react/connectors/TrezorConnector/sendTransactionHandler.ts @@ -14,7 +14,7 @@ export async function sendTransactionHandler( provider: JsonRpcProvider, trezorConnect: TrezorConnect, ) { - const chainId = await provider.send('eth_chainId', []) + const chainId = +(await provider.send('eth_chainId', [])) const nonce = await provider.send('eth_getTransactionCount', [account, 'latest']) const originalTx = params[0]