Skip to content

Commit

Permalink
Merge branch 'main' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
anxolin committed Nov 9, 2023
2 parents f841990 + c202eb0 commit 50a54c0
Show file tree
Hide file tree
Showing 47 changed files with 607 additions and 326 deletions.
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,39 @@
# Changelog

## [1.49.0](https://github.com/cowprotocol/cowswap/compare/v1.48.17...v1.49.0) (2023-11-09)


### Features

* add comment to config ([#3345](https://github.com/cowprotocol/cowswap/issues/3345)) ([1534611](https://github.com/cowprotocol/cowswap/commit/153461103342fbbaa84d340b4eb48ae94cc5b2d3))
* change appKey into appCode ([#3361](https://github.com/cowprotocol/cowswap/issues/3361)) ([b9127d9](https://github.com/cowprotocol/cowswap/commit/b9127d93c05eaf942913065c008d839f694b2ae1))
* change from node v16 to v18 ([#3350](https://github.com/cowprotocol/cowswap/issues/3350)) ([edc7de3](https://github.com/cowprotocol/cowswap/commit/edc7de3d5bb0e17088a58c266641022e79f0e346))
* hide nose picker loader ([#3338](https://github.com/cowprotocol/cowswap/issues/3338)) ([4cc2f1a](https://github.com/cowprotocol/cowswap/commit/4cc2f1abdc8a2429f2772c2992d76036c8d9ac9e))
* improve appCode, config and readme ([#3362](https://github.com/cowprotocol/cowswap/issues/3362)) ([c18bb2e](https://github.com/cowprotocol/cowswap/commit/c18bb2edc8f4f433a4ca0ef1be78e4222747fe8a))
* iterate on configurator ([#3364](https://github.com/cowprotocol/cowswap/issues/3364)) ([c4ba4bb](https://github.com/cowprotocol/cowswap/commit/c4ba4bb2014291454bcae7d0f2a3f4d99b74a3a5))
* **permit:** don't show gas-free flags when permit is not supported ([#3346](https://github.com/cowprotocol/cowswap/issues/3346)) ([1a56029](https://github.com/cowprotocol/cowswap/commit/1a560290b9fc82f3ba17ac1fd9ca9950da796661))
* **permit:** load pre generated permit info ([#3316](https://github.com/cowprotocol/cowswap/issues/3316)) ([46943ad](https://github.com/cowprotocol/cowswap/commit/46943ad45eb58ec5819dc0d8932017144928c144))
* **permit:** remove permit related feature flags ([#3320](https://github.com/cowprotocol/cowswap/issues/3320)) ([372b1a6](https://github.com/cowprotocol/cowswap/commit/372b1a67de71941f1deca46c0459cef2a32c536b))
* **permit:** update gas-free flag tooltip ([#3332](https://github.com/cowprotocol/cowswap/issues/3332)) ([4caf929](https://github.com/cowprotocol/cowswap/commit/4caf9299c697ab838970cd23e4445397b091cf21))
* simplify theme config ([#3363](https://github.com/cowprotocol/cowswap/issues/3363)) ([6b262ab](https://github.com/cowprotocol/cowswap/commit/6b262ab129cbfa62342b0a17ee2e67f26149f045))
* **wallets:** connect wallet rounded modal ([#3368](https://github.com/cowprotocol/cowswap/issues/3368)) ([d5ef0a8](https://github.com/cowprotocol/cowswap/commit/d5ef0a8898e58f8f85d2f0709a24eae513fe00b7))
* **widget-configurator:** button to show drawer ([#3324](https://github.com/cowprotocol/cowswap/issues/3324)) ([cbc1521](https://github.com/cowprotocol/cowswap/commit/cbc152108910f3d954aca10b5815dcf519aa78fd))
* **widget-configurator:** google analytics events ([#3335](https://github.com/cowprotocol/cowswap/issues/3335)) ([9b1074e](https://github.com/cowprotocol/cowswap/commit/9b1074e021399d25e7f105c3228a26113dc2edf1))
* **widget:** links to landing and docs ([#3359](https://github.com/cowprotocol/cowswap/issues/3359)) ([aeb4e11](https://github.com/cowprotocol/cowswap/commit/aeb4e111c7d047bd9607f1c5af3c4c21305f5096))


### Bug Fixes

* fix issue with RPC env ([#3353](https://github.com/cowprotocol/cowswap/issues/3353)) ([ede338d](https://github.com/cowprotocol/cowswap/commit/ede338d29279654873f0f8677d6e09ca2e41686f))
* fix race condition with widget ([#3367](https://github.com/cowprotocol/cowswap/issues/3367)) ([43e2204](https://github.com/cowprotocol/cowswap/commit/43e22046de4ace3c85b9bb7d1a7409c2851fb395))
* **tokens:** fix token lists styles ([#3360](https://github.com/cowprotocol/cowswap/issues/3360)) ([f9a4d0b](https://github.com/cowprotocol/cowswap/commit/f9a4d0b667c621f6f6692db926a727636b774511))
* **tokens:** use default value for user-added tokens migration ([#3347](https://github.com/cowprotocol/cowswap/issues/3347)) ([c9e235c](https://github.com/cowprotocol/cowswap/commit/c9e235cdf466b80d9241099fcfd4cb7c6230ee89))
* **twap:** fix infinite loop in orders hook ([#3348](https://github.com/cowprotocol/cowswap/issues/3348)) ([097728c](https://github.com/cowprotocol/cowswap/commit/097728c92b25f71c2a0ee0de4b56953c888afc0e))
* update chainId in trade state ([#3340](https://github.com/cowprotocol/cowswap/issues/3340)) ([60a16ec](https://github.com/cowprotocol/cowswap/commit/60a16ec96987ed3e9c6115664dbe0eb164c4ddb7))
* update connect wallet modal styles ([#3341](https://github.com/cowprotocol/cowswap/issues/3341)) ([e577b76](https://github.com/cowprotocol/cowswap/commit/e577b766a3e876e8caf167f3a19206a034b7be06))
* **widget-configurator:** switch network only when user changed in the configurator ([#3369](https://github.com/cowprotocol/cowswap/issues/3369)) ([51eb483](https://github.com/cowprotocol/cowswap/commit/51eb483643d80b1b0a39775b68b055a3ff8a8b92))
* **widget-lib:** adjust code for server-side rendering ([#3339](https://github.com/cowprotocol/cowswap/issues/3339)) ([db8743d](https://github.com/cowprotocol/cowswap/commit/db8743d586a58dc8f38ea7b0167e1369c5bb8f06))

## [1.48.17](https://github.com/cowprotocol/cowswap/compare/v1.48.16...v1.48.17) (2023-11-03)


Expand Down
14 changes: 7 additions & 7 deletions apps/cowswap-frontend/.env
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@
# To set your own `AppData`, change `REACT_APP_FULL_APP_DATA_<environment>`

# AppData, build yours at https://explorer.cow.fi/appdata
REACT_APP_FULL_APP_DATA_PRODUCTION='{"version":"0.10.0","appCode":"CoW Swap","environment":"production","metadata":{}}'
REACT_APP_FULL_APP_DATA_ENS='{"version":"0.10.0","appCode":"CoW Swap","environment":"ens","metadata":{}}'
REACT_APP_FULL_APP_DATA_BARN='{"version":"0.10.0","appCode":"CoW Swap","environment":"barn","metadata":{}}'
REACT_APP_FULL_APP_DATA_STAGING='{"version":"0.10.0","appCode":"CoW Swap","environment":"staging","metadata":{}}'
REACT_APP_FULL_APP_DATA_PR='{"version":"0.10.0","appCode":"CoW Swap","environment":"pr","metadata":{}}'
REACT_APP_FULL_APP_DATA_DEVELOPMENT='{"version":"0.10.0","appCode":"CoW Swap","environment":"development","metadata":{}}'
REACT_APP_FULL_APP_DATA_LOCAL='{"version":"0.10.0","appCode":"CoW Swap","environment":"local","metadata":{}}'
REACT_APP_FULL_APP_DATA_PRODUCTION='{"version":"0.11.0","appCode":"CoW Swap","environment":"production","metadata":{}}'
REACT_APP_FULL_APP_DATA_ENS='{"version":"0.11.0","appCode":"CoW Swap","environment":"ens","metadata":{}}'
REACT_APP_FULL_APP_DATA_BARN='{"version":"0.11.0","appCode":"CoW Swap","environment":"barn","metadata":{}}'
REACT_APP_FULL_APP_DATA_STAGING='{"version":"0.11.0","appCode":"CoW Swap","environment":"staging","metadata":{}}'
REACT_APP_FULL_APP_DATA_PR='{"version":"0.11.0","appCode":"CoW Swap","environment":"pr","metadata":{}}'
REACT_APP_FULL_APP_DATA_DEVELOPMENT='{"version":"0.11.0","appCode":"CoW Swap","environment":"development","metadata":{}}'
REACT_APP_FULL_APP_DATA_LOCAL='{"version":"0.11.0","appCode":"CoW Swap","environment":"local","metadata":{}}'



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export function useAnalyticsReporter() {

const walletName = _walletName || getConnectionName(connection.type, isMetaMask)

const injectedWidgetAppId = injectedWidgetMetaData.appKey
const injectedWidgetAppId = injectedWidgetMetaData?.appCode

useEffect(() => {
// Custom dimension 2 - walletname
Expand Down
4 changes: 2 additions & 2 deletions apps/cowswap-frontend/src/common/pure/IconSpinner/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ const Wrapper = styled.div<{ size: number; spinnerWidth: number; bgColor: UI }>`
z-index: 1;
}
> img,
> svg,
img,
svg,
> span {
object-fit: contain;
z-index: 2;
Expand Down
4 changes: 3 additions & 1 deletion apps/cowswap-frontend/src/common/pure/Modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ export const CowModal = styled(Modal)<{
border?: string
padding?: string
}>`
border-radius: var(${UI.BORDER_RADIUS_NORMAL});
> [data-reach-dialog-content] {
color: var(${UI.COLOR_TEXT1});
width: 100%;
Expand Down Expand Up @@ -151,4 +153,4 @@ export const CowModal = styled(Modal)<{
export const NewCowModal = styled(Modal)`
width: 100vw;
height: 100vh;
`
`
10 changes: 1 addition & 9 deletions apps/cowswap-frontend/src/modules/appData/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@ import { useAtomValue, useSetAtom } from 'jotai'
import { useMemo } from 'react'

import { DEFAULT_APP_CODE, SAFE_APP_CODE } from '@cowprotocol/common-const'
import { isInjectedWidget } from '@cowprotocol/common-utils'
import { useIsSafeApp } from '@cowprotocol/wallet'

import { useInjectedWidgetMetaData } from 'modules/injectedWidget'

import { addAppDataToUploadQueueAtom, appDataHooksAtom, appDataInfoAtom } from './state/atoms'
import { AppDataInfo } from './types'

Expand All @@ -17,21 +14,16 @@ export function useAppData(): AppDataInfo | null {
}

export function useAppCode(): string | null {
const injectedWidgetMetaData = useInjectedWidgetMetaData()
const isSafeApp = useIsSafeApp()

return useMemo(() => {
if (isInjectedWidget()) {
return injectedWidgetMetaData.appKey
}

if (APP_CODE) {
// appCode coming from env var has priority
return APP_CODE
}

return isSafeApp ? SAFE_APP_CODE : DEFAULT_APP_CODE
}, [isSafeApp, injectedWidgetMetaData])
}, [isSafeApp])
}

export function useUploadAppData() {
Expand Down
2 changes: 2 additions & 0 deletions apps/cowswap-frontend/src/modules/appData/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,5 @@ export type PreHooks = latest.PreHooks
export type PostHooks = latest.PostHooks

export type AppDataRootSchema = latest.AppDataRootSchema

export type AppDataWidget = latest.Widget
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { useSetAtom } from 'jotai'
import { useEffect } from 'react'
import { useEffect, useRef } from 'react'

import { CowEnv, SupportedChainId } from '@cowprotocol/cow-sdk'

import { AppCodeWithWidgetMetadata } from 'modules/injectedWidget/hooks/useAppCodeWidgetAware'
import { UtmParams } from 'modules/utm'

import { useAppCode } from '../hooks'
import { appDataInfoAtom } from '../state/atoms'
import { AppDataHooks, AppDataOrderClass } from '../types'
import { buildAppData, BuildAppDataParams } from '../utils/buildAppData'
import { getAppData } from '../utils/fullAppData'

export type UseAppDataParams = {
appCodeWithWidgetMetadata: AppCodeWithWidgetMetadata | null
chainId: SupportedChainId
slippageBips: string
orderClass: AppDataOrderClass
Expand All @@ -23,21 +24,28 @@ export type UseAppDataParams = {
* Fetches and updates appDataInfo whenever a dependency changes
* The hook can be called only from an updater
*/
export function AppDataInfoUpdater({ chainId, slippageBips, orderClass, utm, hooks }: UseAppDataParams): void {
export function AppDataInfoUpdater({
appCodeWithWidgetMetadata,
chainId,
slippageBips,
orderClass,
utm,
hooks,
}: UseAppDataParams): void {
// AppDataInfo, from Jotai
const setAppDataInfo = useSetAtom(appDataInfoAtom)

// AppCode is dynamic and based on how it's loaded (if used as a Gnosis Safe app)
const appCode = useAppCode()
const updateAppDataPromiseRef = useRef(Promise.resolve())

useEffect(() => {
if (!appCode) {
if (!appCodeWithWidgetMetadata) {
// reset values when there is no price estimation or network changes
setAppDataInfo(null)
return
}

const params: BuildAppDataParams = { chainId, slippageBips, appCode, orderClass, utm, hooks }
const { appCode, environment, widget } = appCodeWithWidgetMetadata
const params: BuildAppDataParams = { chainId, slippageBips, appCode, environment, orderClass, utm, hooks, widget }

const updateAppData = async (): Promise<void> => {
try {
Expand All @@ -51,9 +59,11 @@ export function AppDataInfoUpdater({ chainId, slippageBips, orderClass, utm, hoo
}
}

updateAppData()
}, [appCode, chainId, setAppDataInfo, slippageBips, orderClass, utm, hooks])
// Chain the next update to avoid race conditions
updateAppDataPromiseRef.current = updateAppDataPromiseRef.current.finally(updateAppData)
}, [appCodeWithWidgetMetadata, chainId, setAppDataInfo, slippageBips, orderClass, utm, hooks])
}

function getEnvByClass(orderClass: string): CowEnv | undefined {
if (orderClass === 'twap') {
return 'prod' // Upload the appData to production always, since WatchTower will create the orders there
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import { percentToBips } from '@cowprotocol/common-utils'
import { useWalletInfo } from '@cowprotocol/wallet'
import { Percent } from '@uniswap/sdk-core'

import { useAppCodeWidgetAware } from 'modules/injectedWidget/hooks/useAppCodeWidgetAware'
import { useUtm } from 'modules/utm'

import { AppDataHooksUpdater } from './AppDataHooksUpdater'
import { AppDataInfoUpdater, UseAppDataParams } from './AppDataInfoUpdater'

import { useAppDataHooks } from '../hooks'
import { useAppCode, useAppDataHooks } from '../hooks'
import { AppDataOrderClass } from '../types'

interface AppDataUpdaterProps {
Expand All @@ -20,14 +21,23 @@ interface AppDataUpdaterProps {
export const AppDataUpdater = React.memo(({ slippage, orderClass }: AppDataUpdaterProps) => {
const { chainId } = useWalletInfo()

const appCode = useAppCode()
const slippageBips = percentToBips(slippage)
const utm = useUtm()
const hooks = useAppDataHooks()
const appCodeWithWidgetMetadata = useAppCodeWidgetAware(appCode)

if (!chainId) return null

return (
<AppDataUpdaterMemo chainId={chainId} slippageBips={slippageBips} orderClass={orderClass} utm={utm} hooks={hooks} />
<AppDataUpdaterMemo
appCodeWithWidgetMetadata={appCodeWithWidgetMetadata}
chainId={chainId}
slippageBips={slippageBips}
orderClass={orderClass}
utm={utm}
hooks={hooks}
/>
)
})

Expand Down
16 changes: 11 additions & 5 deletions apps/cowswap-frontend/src/modules/appData/utils/buildAppData.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
import { stringifyDeterministic } from '@cowprotocol/app-data'
import { environmentName } from '@cowprotocol/common-utils'
import { SupportedChainId } from '@cowprotocol/cow-sdk'

import { metadataApiSDK } from 'cowSdk'
import { keccak256, toUtf8Bytes } from 'ethers/lib/utils'

import { UtmParams } from 'modules/utm'

import { AppDataHooks, AppDataInfo, AppDataOrderClass, AppDataRootSchema } from '../types'
import { AppDataHooks, AppDataInfo, AppDataOrderClass, AppDataRootSchema, AppDataWidget } from '../types'

export type BuildAppDataParams = {
appCode: string
environment?: string
chainId: SupportedChainId
slippageBips: string
orderClass: AppDataOrderClass
referrerAccount?: string
utm: UtmParams | undefined
hooks?: AppDataHooks
widget?: AppDataWidget
}

async function generateAppDataFromDoc(
Expand All @@ -32,9 +33,11 @@ export async function buildAppData({
slippageBips,
referrerAccount,
appCode,
environment,
orderClass: orderClassName,
utm,
hooks,
widget,
}: BuildAppDataParams): Promise<AppDataInfo> {
const referrerParams =
referrerAccount && chainId === SupportedChainId.MAINNET ? { address: referrerAccount } : undefined
Expand All @@ -44,8 +47,8 @@ export async function buildAppData({

const doc = await metadataApiSDK.generateAppDataDoc({
appCode,
environment: environmentName,
metadata: { referrer: referrerParams, quote: quoteParams, orderClass, utm, hooks },
environment,
metadata: { referrer: referrerParams, quote: quoteParams, orderClass, utm, hooks, widget },
})

const { fullAppData, appDataKeccak256 } = await generateAppDataFromDoc(doc)
Expand All @@ -57,7 +60,10 @@ export function toKeccak256(fullAppData: string) {
return keccak256(toUtf8Bytes(fullAppData))
}

export async function updateHooksOnAppData(appData: AppDataInfo, hooks: AppDataHooks | undefined): Promise<AppDataInfo> {
export async function updateHooksOnAppData(
appData: AppDataInfo,
hooks: AppDataHooks | undefined
): Promise<AppDataInfo> {
const { doc } = appData

const newDoc = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { EnvironmentName, environmentName } from '@cowprotocol/common-utils'
import { AppDataInfo } from '../types'
import { toKeccak256 } from '../utils/buildAppData'

const DEFAULT_FULL_APP_DATA = '{"version":"0.10.0","appCode":"CoW Swap","metadata":{}}'
const DEFAULT_FULL_APP_DATA = '{"version":"0.11.0","appCode":"CoW Swap","metadata":{}}'

let appData: AppDataInfo = (() => {
const fullAppData = getFullAppDataByEnv(environmentName)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { useMemo } from 'react'

import { environmentName } from '@cowprotocol/common-utils'

import { AppDataWidget } from 'modules/appData/types'

import { useInjectedWidgetMetaData } from './useInjectedWidgetMetaData'

export interface AppCodeWithWidgetMetadata {
appCode: string
environment?: string
widget?: AppDataWidget
}

/**
* The final "appCode" used in the appData is different depending on whether the app is being used in the widget mode or not.
*
* In order to make the official `appCode` of the app not widget aware (to depend only on the appCode of the app), we use this
* widget that will use the official `appCode` and the injected metadata from the widget to derive the 3 depending filds:
* - appCode: the official `appCode` of the app when not used in the widget mode, or the `appCode` of the host app using the widget
* - environment: the environment of the app when not used in the widget mode, or not specified in widget mode
* - widget: The widget metadata if in widget mode
*
* @param appCodeOfficial the official `appCode` of the app
*
*/
export function useAppCodeWidgetAware(appCodeOfficial: string | null): AppCodeWithWidgetMetadata | null {
const injectedWidgetMetadata = useInjectedWidgetMetaData()

const appCodeInjectedHostApp = injectedWidgetMetadata?.appCode

return useMemo(() => {
// appCodeOfficial is required for generating the appData, if not provided, return null
if (!appCodeOfficial) {
return null
}

// If running in widget mode, and the host app injects us an appCode
if (appCodeInjectedHostApp) {
return {
// The main appCode will be the one of the host app that uses the widget
appCode: appCodeInjectedHostApp,
widget: {
// In the widget appCode we include the official appCode and environment (this way we report which app is backing the widget iframe)
appCode: appCodeOfficial,
environment: environmentName,
},
}
}

// Return the official appCode and environment as the main appCode/environment in the appData
return {
appCode: appCodeOfficial,
environment: environmentName,
}
}, [appCodeOfficial, appCodeInjectedHostApp])
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import { useAtomValue } from 'jotai'

import { isInjectedWidget } from '@cowprotocol/common-utils'

import { CowSwapWidgetMetaData, injectedWidgetMetaDataAtom } from '../state/injectedWidgetMetaDataAtom'

export function useInjectedWidgetMetaData(): CowSwapWidgetMetaData {
return useAtomValue(injectedWidgetMetaDataAtom)
export function useInjectedWidgetMetaData(): CowSwapWidgetMetaData | undefined {
const injectedWidgetMetaData = useAtomValue(injectedWidgetMetaDataAtom)

if (!isInjectedWidget()) {
return undefined
}

return injectedWidgetMetaData
}
Loading

0 comments on commit 50a54c0

Please sign in to comment.