ci(release): publish latest release

parent 5df99a15
IPFS hash of the deployment:
- CIDv0: `QmainvWX1paa5SAQXowSshKypn1tC5d59gLN8w2coWzJwx`
- CIDv1: `bafybeifx7bho67bfj5b2bn7nw452bovpbv4iia5ndwi4kwvra5fcswhjr4`
- CIDv0: `QmYgGWW41t5rZ973ouoVCPSVJ7xSk1ouQS8hXJaVrwBydQ`
- CIDv1: `bafybeieztnrdyd2anpehiktteokw23mwgbjmnz42u4cpzosxjxignq2bf4`
The latest release is always mirrored at [app.uniswap.org](https://app.uniswap.org).
......@@ -10,95 +10,14 @@ You can also access the Uniswap Interface from an IPFS gateway.
Your Uniswap settings are never remembered across different URLs.
IPFS gateways:
- https://bafybeifx7bho67bfj5b2bn7nw452bovpbv4iia5ndwi4kwvra5fcswhjr4.ipfs.dweb.link/
- [ipfs://QmainvWX1paa5SAQXowSshKypn1tC5d59gLN8w2coWzJwx/](ipfs://QmainvWX1paa5SAQXowSshKypn1tC5d59gLN8w2coWzJwx/)
- https://bafybeieztnrdyd2anpehiktteokw23mwgbjmnz42u4cpzosxjxignq2bf4.ipfs.dweb.link/
- [ipfs://QmYgGWW41t5rZ973ouoVCPSVJ7xSk1ouQS8hXJaVrwBydQ/](ipfs://QmYgGWW41t5rZ973ouoVCPSVJ7xSk1ouQS8hXJaVrwBydQ/)
## 5.84.0 (2025-05-14)
## 5.85.0 (2025-05-15)
### Features
* **web:** add an e2e test for the sign up flow (#19146) c05749e
* **web:** add connector_id to lp txs (#19207) 50b933e
* **web:** add connector_id to send events (#19208) 7e4a30a
* **web:** add connector_id to swap analytics (#19206) 9d734f0
* **web:** add connector_id to wallet disconnect event (#19205) 6631d02
* **web:** add passkey mgmt analytics (#19172) 9d12f00
* **web:** detect delegations and log them (#19368) d22a9de
* **web:** display min/max/market for custom range position (#19485) cc4437b
* **web:** PUX add expandable swap details with tooltips (#18669) 21c0110
* **web:** PUX adding token rate to currency input (#18736) d7abe9f
* **web:** PUX adding user quote amount to trades (#18511) 10d6f6f
* **web:** PUX FOT (#18804) ae89a01
* **web:** PUX handle bridging (#19089) b7375af
* **web:** PUX max slippage shield animation (#18972) 4d635a4
* **web:** PUX max slippage tooltip (#18708) 23d955b
* **web:** PUX network cost tooltip (#18685) dff4cc1
* **web:** PUX price and route tooltips (#18681) f77ad8a
* **web:** PUX price diff (#18738) 859bca1
* **web:** PUX price impact warning (#18740) 9809ff3
* **web:** PUX you receive panel (#18664) 326c5b1
* **web:** retry with standard swap if batched fails (#19295) dbffc2b
* **web:** swap tracking (#19328) 4185c10
* **web:** track clicks of download app ctas (#19232) fbc651c
* **web:** track user prop delegate status (#19286) f2f3e52
* **web:** Update existing user cta text and remove experiment (#19349) f13e553
### Bug Fixes
* **web:** [lp] fix native buffer experiment (#18777) 7a03b16
* **web:** add create/increase params to analytic events (#19388) b2a4177
* **web:** add error handling for rewards calcs (#18988) 1923ffe
* **web:** add google fonts url to CSP style-src (#19248) f64259e
* **web:** add migration 24 for wallet capabilities (#19464) 3ffc371
* **web:** add providers to web storybook to fix AnimatedNumber story (#18632) 12b4874
* **web:** allow press on disabled web3-status-connected (#19535) b7c4ede
* **web:** avoid fetching calldata for invalid range (#19384) 552a144
* **web:** clicking swap setting icon should close settings modal if open (#19472) c248622
* **web:** correct delegation logging (#19415) ed73ce2
* **web:** correct some analytics (#19391) 26016ce
* **web:** dedupe and cache wallet capabilities calls (#19739) (#19750) ad67756
* **web:** delete DeprecatedWebButtons (#19213) 799b1c1
* **web:** downgrade two errors to warnings (#19344) 726ba31
* **web:** fix approval call for create + increase (#19223) f73b4dd
* **web:** fix key open search modal (#19332) eb41c21
* **web:** fix mweb chart panning (#19373) f3ab207
* **web:** handle isTokenOptionArray check for bridging section (#19363) de14b83
* **web:** icon bugs + lp incentive improvements (#19606) 4c7c09e
* **web:** limits mobile bug (#19271) 9d49bf8
* **web:** logging for mismatch and isDelegatedEOA (#19346) 53b3a5a
* **web:** migrate BreadcrumbNav to tamagui (#19212) 734de02
* **web:** migrate NFTTab to tamagui (#19216) d940820
* **web:** migrate OpenLimitOrdersButton to tamagui (#19217) a74ae36
* **web:** migrate TokensTab to tamagui (#19214) 622e711
* **web:** migrate UniExtensionPoolsMenu to tamagui (#19215) 6250c24
* **web:** missing permit tx (#19326) 915e983
* **web:** only support batch swaps on supported status (#19580) ce53969
* **web:** persist query client and remove extra provider (#19219) f2236dc
* **web:** preload WalletConnect provider to avoid waterfall requests (#19195) ea3bc3f
* **web:** price ux revert remove inline warning (#19439) a5574a3
* **web:** PUX auto slippage (#18805) 598d9d3
* **web:** pux design fixes (#19430) a1c6311
* **web:** remove disconnect logic in useConnect hook (#19190) 7e2b0bc
* **web:** tamagui LimitDetailActivityRow & PortfolioTabRow (#19220) 084eced
* **web:** tamagui LimitsMenu / LimitDisclaimer (#19218) 28fbc8e
* **web:** temp remove disabled prop from button (#19675) 17f177e
* **web:** update icon props to be compatible w react-feather (#19209) 2dd772b
* **web:** update url for EW sign in test (#19470) 2d1a87e
* **web:** usd amount hover state currency panel (#18841) 38a3d0c
* **web:** Use "Log In" in auth pop up (#19385) 9ea148b
* **web:** Use sign up for New User button (#19478) a0b6690
### Continuous Integration
* **web:** update sitemaps c080e0b
### Tests
* **web:** handle v2, v3, v4 pool not found graphql (#19348) 4898d1c
* **web:** use different test account (#19431) 014d910
* **web:** gracefully handle upgrade prompt rejection [prod] (#19757) b76e682
web/5.84.0
\ No newline at end of file
web/5.85.0
\ No newline at end of file
......@@ -5,9 +5,12 @@ import { PopupType } from 'components/Popups/types'
import { wagmiConfig } from 'components/Web3Provider/wagmiConfig'
import { HandleOnChainStepParams, getSigner, watchForInterruption } from 'state/sagas/transactions/utils'
import { addTransaction } from 'state/transactions/reducer'
import { handleGetCapabilities } from 'state/walletCapabilities/lib/handleGetCapabilities'
import { setCapabilitiesByChain } from 'state/walletCapabilities/reducer'
import { call, put } from 'typed-redux-saga'
import { OnChainTransactionStepBatched } from 'uniswap/src/features/transactions/steps/types'
import { ValidatedTransactionRequest } from 'uniswap/src/features/transactions/swap/utils/trade'
import { didUserReject } from 'utils/swapErrorToUserReadableMessage'
const CURRENT_SEND_CALLS_VERSION = '2.0.0'
async function sendCalls(params: {
......@@ -29,29 +32,51 @@ async function sendCalls(params: {
}
export function* handleAtomicSendCalls(
params: Omit<HandleOnChainStepParams, 'step'> & { step: OnChainTransactionStepBatched },
params: Omit<HandleOnChainStepParams, 'step'> & {
step: OnChainTransactionStepBatched
disableOneClickSwap: () => void
},
) {
const { step, info, account, ignoreInterrupt } = params
const { step, info, account, ignoreInterrupt, disableOneClickSwap } = params
const from = account.address
const { batchedTxRequests } = step
const chainId = batchedTxRequests[0].chainId
// Add a watcher to check if the transaction flow during user input
const { throwIfInterrupted } = yield* watchForInterruption(ignoreInterrupt)
try {
// Add a watcher to check if the transaction flow during user input
const { throwIfInterrupted } = yield* watchForInterruption(ignoreInterrupt)
const signer = yield* call(getSigner, account.address)
const batchId = yield* call(() => sendCalls({ signer, batchedTxRequests, from, chainId }))
const signer = yield* call(getSigner, account.address)
const batchId = yield* call(() => sendCalls({ signer, batchedTxRequests, from, chainId }))
const connectorId = getAccount(wagmiConfig).connector?.id
const batchInfo = { connectorId, batchId, chainId }
const connectorId = getAccount(wagmiConfig).connector?.id
const batchInfo = { connectorId, batchId, chainId }
// Add transaction to local state to start polling for status
yield* put(addTransaction({ from: account.address, info, hash: batchId, chainId, batchInfo }))
// Add transaction to local state to start polling for status
yield* put(addTransaction({ from: account.address, info, hash: batchId, chainId, batchInfo }))
popupRegistry.addPopup({ type: PopupType.Transaction, hash: batchId }, batchId)
popupRegistry.addPopup({ type: PopupType.Transaction, hash: batchId }, batchId)
// If the transaction flow was interrupted, throw an error after the step has completed
yield* call(throwIfInterrupted)
// If the transaction flow was interrupted, throw an error after the step has completed
yield* call(throwIfInterrupted)
return batchId
return batchId
} catch (error) {
// Specific handling for when the user rejects
if (error.code === 5750 || isMetaMaskNonTypicalRejection(error)) {
const updatedCapabilities = yield* call(handleGetCapabilities)
if (updatedCapabilities) {
// A wallet may update its capabilities after a transaction is sent, so we refresh state here so that subsequent transactions use the updated capabilities
yield* put(setCapabilitiesByChain(updatedCapabilities))
}
// If the user tries again,
disableOneClickSwap()
}
throw error
}
}
// TODO(WEB-7784): Remove once MetaMask fixes their error -32603 response code
function isMetaMaskNonTypicalRejection(error: any): boolean {
return didUserReject(error) && error.code === -32603
}
......@@ -6,6 +6,7 @@ import { useTotalBalancesUsdForAnalytics } from 'graphql/data/apollo/useTotalBal
import { useAccount } from 'hooks/useAccount'
import useSelectChain from 'hooks/useSelectChain'
import { formatSwapSignedAnalyticsEventProperties } from 'lib/utils/analytics'
import { useSetOverrideOneClickSwapFlag } from 'pages/Swap/settings/OneClickSwap'
import { useCallback } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { handleAtomicSendCalls } from 'state/sagas/transactions/5792'
......@@ -118,9 +119,10 @@ interface HandleSwapBatchedStepParams extends Omit<HandleOnChainStepParams, 'ste
step: SwapTransactionStepBatched
trade: ClassicTrade | BridgeTrade
analytics: SwapTradeBaseProperties
disableOneClickSwap: () => void
}
function* handleSwapTransactionBatchedStep(params: HandleSwapBatchedStepParams) {
const { trade, step } = params
const { trade, step, disableOneClickSwap } = params
const info = getSwapTransactionInfo(trade)
......@@ -130,6 +132,7 @@ function* handleSwapTransactionBatchedStep(params: HandleSwapBatchedStepParams)
step,
ignoreInterrupt: true, // We avoid interruption during the swap step, since it is too late to give user a new trade once the swap is submitted.
shouldWaitForConfirmation: false,
disableOneClickSwap,
})
handleSwapTransactionAnalytics({ ...params, batchId })
......@@ -190,6 +193,8 @@ type SwapParams = {
setCurrentStep: SetCurrentStepFn
setSteps: (steps: TransactionStep[]) => void
getOnPressRetry: (error: Error | undefined) => (() => void) | undefined
// TODO(WEB-7763): Upgrade jotai to v2 to avoid need for prop drilling `disableOneClickSwap`
disableOneClickSwap: () => void
onSuccess: () => void
onFailure: (error?: Error, onPressRetry?: () => void) => void
v4Enabled: boolean
......@@ -236,6 +241,7 @@ function* classicSwap(
) {
const {
account,
disableOneClickSwap,
setCurrentStep,
steps,
swapTxContext: { trade },
......@@ -268,7 +274,14 @@ function* classicSwap(
break
}
case TransactionStepType.SwapTransactionBatched: {
yield* call(handleSwapTransactionBatchedStep, { account, step, setCurrentStep, trade, analytics })
yield* call(handleSwapTransactionBatchedStep, {
account,
step,
setCurrentStep,
trade,
analytics,
disableOneClickSwap,
})
break
}
default: {
......@@ -374,6 +387,7 @@ export function useSwapCallback(): SwapCallback {
const portfolioBalanceUsd = useTotalBalancesUsdForAnalytics()
const disableOneClickSwap = useSetOverrideOneClickSwapFlag()
const getOnPressRetry = useGetOnPressRetry()
return useCallback(
......@@ -416,6 +430,7 @@ export function useSwapCallback(): SwapCallback {
account,
analytics,
getOnPressRetry,
disableOneClickSwap,
onSuccess,
onFailure,
setCurrentStep,
......@@ -452,6 +467,7 @@ export function useSwapCallback(): SwapCallback {
appDispatch,
swapStartTimestamp,
getOnPressRetry,
disableOneClickSwap,
],
)
}
......@@ -77,7 +77,7 @@ describe('walletCapabilities', () => {
expect(isAtomicBatchingSupportedByChainId(mockCapabilities, 1)).toBe(true)
const readyCapabilities: GetCapabilitiesResult = { '0x1': { atomic: { status: 'ready' } } }
expect(isAtomicBatchingSupportedByChainId(readyCapabilities, 1)).toBe(false)
expect(isAtomicBatchingSupportedByChainId(readyCapabilities, 1)).toBe(true)
const unsupportedCapabilities: GetCapabilitiesResult = { '0x1': { atomic: { status: 'unsupported' } } }
expect(isAtomicBatchingSupportedByChainId(unsupportedCapabilities, 1)).toBe(false)
......
......@@ -51,7 +51,10 @@ enum AtomicBatchingStatus {
}
export function isAtomicBatchingSupported(chainCapabilities: ChainCapabilities): boolean {
return chainCapabilities?.atomic?.status === AtomicBatchingStatus.Supported
return (
chainCapabilities?.atomic?.status === AtomicBatchingStatus.Supported ||
chainCapabilities?.atomic?.status === AtomicBatchingStatus.Ready
)
}
export function isAtomicBatchingSupportedByChainId(
......
......@@ -134,7 +134,7 @@ describe('walletCapabilities reducer', () => {
// Test various chain IDs
expect(selector(1)).toBe(true) // Chain 1 has status 'supported'
expect(selector(2)).toBe(false) // Chain 2 has status 'ready'
expect(selector(2)).toBe(true) // Chain 2 has status 'ready'
expect(selector(3)).toBe(false) // Chain 3 has status 'unsupported'
expect(selector(4)).toBe(false) // Chain 4 has no atomic capability
expect(selector(999)).toBe(false) // Chain 999 not in map
......@@ -148,7 +148,7 @@ describe('walletCapabilities reducer', () => {
// This tests that the internal helper correctly evaluates string values
const testCases = [
{ chainId: '0x1', atomicStatus: 'supported', expected: true },
{ chainId: '0x2', atomicStatus: 'ready', expected: false },
{ chainId: '0x2', atomicStatus: 'ready', expected: true },
{ chainId: '0x3', atomicStatus: 'unsupported', expected: false },
{ chainId: '0x4', atomicStatus: 'something-else', expected: false },
{ chainId: '0x5', atomicStatus: undefined, expected: false },
......
......@@ -15,6 +15,8 @@ export function didUserReject(error: any): boolean {
const reason = getReason(error)
if (
error?.code === 4001 ||
// eip-5792 upgrade rejected error https://eips.ethereum.org/EIPS/eip-5792#error-codes
error?.code === 5750 ||
// ethers v5.7.0 wrapped error
error?.code === 'ACTION_REJECTED' ||
// For Rainbow :
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment