diff --git a/RELEASE b/RELEASE index 32d3072536d..2028432287a 100644 --- a/RELEASE +++ b/RELEASE @@ -1,6 +1,6 @@ IPFS hash of the deployment: -- CIDv0: `Qma7JPknjeioxNgRPRcWs7UWvV6VJduMgmNMJ6GdxsvYJt` -- CIDv1: `bafybeifo4c4ij3unqr3bgji2gbqmnnb5vs52mopawwu7irbfppk7aoenwe` +- CIDv0: `QmWaBTFEnY4LqKBdeyyRBmwhCuphBhe3p3CKmxnnuNhY5z` +- CIDv1: `bafybeid2kthnxmhk5tcm2ogpsjzooeo3dj6bt2oh6tk3vbrsqf4sc2ogju` The latest release is always mirrored at [app.uniswap.org](https://app.uniswap.org). @@ -10,15 +10,15 @@ You can also access the Uniswap Interface from an IPFS gateway. Your Uniswap settings are never remembered across different URLs. IPFS gateways: -- https://bafybeifo4c4ij3unqr3bgji2gbqmnnb5vs52mopawwu7irbfppk7aoenwe.ipfs.dweb.link/ -- https://bafybeifo4c4ij3unqr3bgji2gbqmnnb5vs52mopawwu7irbfppk7aoenwe.ipfs.cf-ipfs.com/ -- [ipfs://Qma7JPknjeioxNgRPRcWs7UWvV6VJduMgmNMJ6GdxsvYJt/](ipfs://Qma7JPknjeioxNgRPRcWs7UWvV6VJduMgmNMJ6GdxsvYJt/) +- https://bafybeid2kthnxmhk5tcm2ogpsjzooeo3dj6bt2oh6tk3vbrsqf4sc2ogju.ipfs.dweb.link/ +- https://bafybeid2kthnxmhk5tcm2ogpsjzooeo3dj6bt2oh6tk3vbrsqf4sc2ogju.ipfs.cf-ipfs.com/ +- [ipfs://QmWaBTFEnY4LqKBdeyyRBmwhCuphBhe3p3CKmxnnuNhY5z/](ipfs://QmWaBTFEnY4LqKBdeyyRBmwhCuphBhe3p3CKmxnnuNhY5z/) -### 5.63.3 (2024-12-23) +### 5.63.4 (2025-01-02) ### Bug Fixes -* **web:** change default rpc url (#14764) 153ffd9 +* **web:** set duped events as executed to prevent retry - prod (#14781) 35193b4 diff --git a/VERSION b/VERSION index 3fab0614622..5f7c11993e8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -web/5.63.3 \ No newline at end of file +web/5.63.4 \ No newline at end of file diff --git a/packages/uniswap/src/data/rest/conversionTracking/tracking.ts b/packages/uniswap/src/data/rest/conversionTracking/tracking.ts index 8d06a3312a1..8318158f0d4 100644 --- a/packages/uniswap/src/data/rest/conversionTracking/tracking.ts +++ b/packages/uniswap/src/data/rest/conversionTracking/tracking.ts @@ -23,9 +23,13 @@ const buildTwitterProxyRequest = ({ method: RequestType.POST, headers: DEFAULT_HEADERS, body: JSON.stringify({ - conversion_time: addJitter(new Date()), - event_id: eventId, - identifiers: [{ [PlatformIdType.Twitter]: lead.id }], + conversions: [ + { + conversion_time: addJitter(new Date()), + event_id: eventId, + identifiers: [{ [PlatformIdType.Twitter]: lead.id }], + }, + ], }), }) diff --git a/packages/uniswap/src/data/rest/conversionTracking/useConversionTracking.ts b/packages/uniswap/src/data/rest/conversionTracking/useConversionTracking.ts index 05c055461f4..e47b0533355 100644 --- a/packages/uniswap/src/data/rest/conversionTracking/useConversionTracking.ts +++ b/packages/uniswap/src/data/rest/conversionTracking/useConversionTracking.ts @@ -1,3 +1,4 @@ +import { ConnectError } from '@connectrpc/connect' import { useAtom } from 'jotai' import { atomWithStorage } from 'jotai/utils' import { parse } from 'qs' @@ -46,6 +47,7 @@ export function useConversionTracking(): UseConversionTracking { const trackConversion = useCallback( async ({ platformIdType, eventId, eventName }: TrackConversionArgs) => { const lead = conversionLeads.find(({ type }) => type === platformIdType) + let setAsExecuted: boolean = false // Prevent triggering events under the following conditions: // - No corresponding lead @@ -74,13 +76,7 @@ export function useConversionTracking(): UseConversionTracking { throw new Error() } - setConversionLeads((leads: ConversionLead[]) => [ - ...leads.filter(({ id }) => lead.id !== id), - { - ...lead, - executedEvents: lead.executedEvents.concat([eventId]), - }, - ]) + setAsExecuted = true sendAnalyticsEvent(UniswapEventName.ConversionEventSubmitted, { id: lead.id, @@ -88,13 +84,36 @@ export function useConversionTracking(): UseConversionTracking { eventName, platformIdType, }) - } catch (e) { + } catch (error) { // Note: The request will be retried until it exists in executedEvents + // If the event has already been executed, but doesn't exist in executedEvents, this will ensure we don't retry errors + if (error instanceof ConnectError) { + if (error.message.includes('limit for this (user, event)')) { + setAsExecuted = true + } + } + } finally { + if (setAsExecuted) { + setConversionLeads((leads: ConversionLead[]) => [ + ...leads.filter(({ id }) => lead.id !== id), + { + ...lead, + executedEvents: lead.executedEvents.concat([eventId]), + }, + ]) + } } }, // TODO: Investigate why conversionProxy as a dependency causes a rendering loop // eslint-disable-next-line react-hooks/exhaustive-deps - [account.address, conversionLeads, setConversionLeads], + [ + account.address, + conversionLeads, + isConversionTrackingEnabled, + isGoogleConversionTrackingEnabled, + isTwitterConversionTrackingEnabled, + setConversionLeads, + ], ) const trackConversions = useCallback(