Skip to content

Commit

Permalink
feat: merge develop
Browse files Browse the repository at this point in the history
  • Loading branch information
fairlighteth committed Oct 20, 2023
2 parents aa56228 + 6a36d1a commit 146b508
Show file tree
Hide file tree
Showing 38 changed files with 517 additions and 606 deletions.
97 changes: 97 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,102 @@
# Changelog

## [1.48.7](https://github.com/cowprotocol/cowswap/compare/v1.48.6...v1.48.7) (2023-10-19)


### Bug Fixes

* **swap:** periodically refresh unsupported tokens state ([#3252](https://github.com/cowprotocol/cowswap/issues/3252)) ([f5986a3](https://github.com/cowprotocol/cowswap/commit/f5986a30f850eead4eb633069967ac34947ab68e))

## [1.48.6](https://github.com/cowprotocol/cowswap/compare/v1.48.5...v1.48.6) (2023-10-18)


### Bug Fixes

* **permit:** usdc limit orders warning ([#3247](https://github.com/cowprotocol/cowswap/issues/3247)) ([d958d0f](https://github.com/cowprotocol/cowswap/commit/d958d0fefb6f18418fb596b75b872e5b381d915d))

## [1.48.5](https://github.com/cowprotocol/cowswap/compare/v1.48.4...v1.48.5) (2023-10-18)


### Features

* deploy to IPFS ([#3237](https://github.com/cowprotocol/cowswap/issues/3237)) ([e69af4d](https://github.com/cowprotocol/cowswap/commit/e69af4d7140e384180c98b4c5175b341a2e9a542))


### Bug Fixes

* display token logos from CoW Protocol correctly ([#3244](https://github.com/cowprotocol/cowswap/issues/3244)) ([caaf980](https://github.com/cowprotocol/cowswap/commit/caaf9800da89e1df21cdffe2afc4eaa98260d0c3))

## [1.48.4](https://github.com/cowprotocol/cowswap/compare/v1.48.3...v1.48.4) (2023-10-18)


### Bug Fixes

* **permit:** add support for usdc mainnet ([#3231](https://github.com/cowprotocol/cowswap/issues/3231)) ([8de7cfc](https://github.com/cowprotocol/cowswap/commit/8de7cfc51e2324f75b968aee015a2488d4dd2ba9))

## [1.48.3](https://github.com/cowprotocol/cowswap/compare/v1.48.2...v1.48.3) (2023-10-18)


### Bug Fixes

* display trade menu item badge ([#3236](https://github.com/cowprotocol/cowswap/issues/3236)) ([9d54b0a](https://github.com/cowprotocol/cowswap/commit/9d54b0acc8fd1af409776d005a2858647db817c6))

## [1.48.2](https://github.com/cowprotocol/cowswap/compare/v1.48.1...v1.48.2) (2023-10-17)


### Bug Fixes

* **swap:** don't reset swap form on recipient ens input ([#3234](https://github.com/cowprotocol/cowswap/issues/3234)) ([9c1f2f1](https://github.com/cowprotocol/cowswap/commit/9c1f2f1b13597a4af5600c1c915bd59ecf14f578))

## [1.48.1](https://github.com/cowprotocol/cowswap/compare/v1.48.0...v1.48.1) (2023-10-17)


### Bug Fixes

* **swap:** don't crash app when token decimals eq 0 ([#3228](https://github.com/cowprotocol/cowswap/issues/3228)) ([aad09c6](https://github.com/cowprotocol/cowswap/commit/aad09c6b71c1c0a8dabb1f3ea85292bed332dbc7))
* **wc:** add back patch which fixes WC path issue ([#3230](https://github.com/cowprotocol/cowswap/issues/3230)) ([4f4b7d5](https://github.com/cowprotocol/cowswap/commit/4f4b7d56e1cf806d52f09875f95c0afa15a06985))

## [1.48.0](https://github.com/cowprotocol/cowswap/compare/v1.47.1...v1.48.0) (2023-10-16)


### Features

* **permit:** allowance warning ([#3184](https://github.com/cowprotocol/cowswap/issues/3184)) ([f4700d9](https://github.com/cowprotocol/cowswap/commit/f4700d9ac34bf281f6efb9bcbc60bebacb8ac68f))
* **permit:** disable permit for SC wallets ([#3213](https://github.com/cowprotocol/cowswap/issues/3213)) ([29e5178](https://github.com/cowprotocol/cowswap/commit/29e5178a4c15eb56568f5da0d0a30990a47bc76f))
* **permit:** modals LIMIT ([#3164](https://github.com/cowprotocol/cowswap/issues/3164)) ([70e5653](https://github.com/cowprotocol/cowswap/commit/70e56534eaa17456e42e2ba30541537e44d76c78))
* **permit:** modals SWAP ([#3158](https://github.com/cowprotocol/cowswap/issues/3158)) ([ed53662](https://github.com/cowprotocol/cowswap/commit/ed53662eedec3fb4ce3d880c9303df701f5059c1))
* **permit:** refactor permit caching ([#3183](https://github.com/cowprotocol/cowswap/issues/3183)) ([e902e36](https://github.com/cowprotocol/cowswap/commit/e902e36d6d6320dfa1649a448a834df49f115ce4))
* remove walletConnect v1 and use v2 by default ([#3156](https://github.com/cowprotocol/cowswap/issues/3156)) ([4b3fbc0](https://github.com/cowprotocol/cowswap/commit/4b3fbc0f6de2f89235cc69fdc6e7eaefb9bd12b6))
* **tokens:** new UI component for token select modal ([#3166](https://github.com/cowprotocol/cowswap/issues/3166)) ([d5b69cd](https://github.com/cowprotocol/cowswap/commit/d5b69cd4716d1a77e94a4ecba808186e96ef4794))
* **tokens:** new UI for tokens management ([#3174](https://github.com/cowprotocol/cowswap/issues/3174)) ([6c2c253](https://github.com/cowprotocol/cowswap/commit/6c2c2535a11707ad1cc30aa17bd003863d832faa))


### Bug Fixes

* **eth-flow:** update refund info for expired orders ([#3222](https://github.com/cowprotocol/cowswap/issues/3222)) ([dede0d0](https://github.com/cowprotocol/cowswap/commit/dede0d0431511ad1b1ed0548f6d42f881b0f95e0))
* **permit:** improve permittable detection ([#3226](https://github.com/cowprotocol/cowswap/issues/3226)) ([79cb48a](https://github.com/cowprotocol/cowswap/commit/79cb48aa9cd21689d64e13fe57044c4f345c4118))
* **swap:** handle errors from order posting API ([#3224](https://github.com/cowprotocol/cowswap/issues/3224)) ([99df6d2](https://github.com/cowprotocol/cowswap/commit/99df6d2ca9fd5040624977f385e03b2442587c15))

## [1.47.1](https://github.com/cowprotocol/cowswap/compare/v1.47.0...v1.47.1) (2023-09-29)


### Features

* allow to change rpc nodes ([#3160](https://github.com/cowprotocol/cowswap/issues/3160)) ([b9b4be2](https://github.com/cowprotocol/cowswap/commit/b9b4be24ece99ddef83f351d47cc86a9ac3ff5da))
* **orders-table:** approve order token from allowance warn tooltip ([#3144](https://github.com/cowprotocol/cowswap/issues/3144)) ([aa943bf](https://github.com/cowprotocol/cowswap/commit/aa943bf06ab2ba3bb3040bae96106b4463f1283a))
* update approve button color ([#3169](https://github.com/cowprotocol/cowswap/issues/3169)) ([802f288](https://github.com/cowprotocol/cowswap/commit/802f288379329d6a526933be988e6669020bb872))


### Bug Fixes

* don't fetch tokens list ens hashes ([#3152](https://github.com/cowprotocol/cowswap/issues/3152)) ([49989f9](https://github.com/cowprotocol/cowswap/commit/49989f987e729749c17c64984ca3338f774198f9))
* fix bad import ([8546bbc](https://github.com/cowprotocol/cowswap/commit/8546bbc6e792cd913511c87ecfa3ab7453648ce6))
* **twap:** approve infinite amount ([#3141](https://github.com/cowprotocol/cowswap/issues/3141)) ([c5ab768](https://github.com/cowprotocol/cowswap/commit/c5ab768f85a0a463accaf436114fdcab7b538d80))


### Miscellaneous Chores

* **release:** hotfix 1.47.1 Merge pull request [#3171](https://github.com/cowprotocol/cowswap/issues/3171) from cowprotocol/hotfix/1.47.1 ([ce8671f](https://github.com/cowprotocol/cowswap/commit/ce8671fe3705f79a0bb73729855dfd59bbd48b52))

## [1.47.0](https://github.com/cowprotocol/cowswap/compare/v1.47.0-RC.0...v1.47.0) (2023-09-11)


Expand Down
14 changes: 4 additions & 10 deletions apps/cowswap-frontend/src/api/gnosisProtocol/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
CowEnv,
EnrichedOrder,
NativePriceResponse,
OrderBookApiError,
OrderKind,
OrderQuoteRequest,
OrderQuoteResponse,
Expand All @@ -25,9 +24,11 @@ import { LegacyFeeQuoteParams as FeeQuoteParams } from 'legacy/state/price/types

import { getAppData } from 'modules/appData'

import { ApiErrorCodes, ApiErrorObject } from 'api/gnosisProtocol/errors/OperatorError'
import { ApiErrorCodes } from 'api/gnosisProtocol/errors/OperatorError'
import GpQuoteError, { GpQuoteErrorDetails, mapOperatorErrorToQuoteError } from 'api/gnosisProtocol/errors/QuoteError'

import { getIsOrderBookTypedError } from './getIsOrderBookTypedError'

function getProfileUrl(): Partial<Record<ChainId, string>> {
if (isLocal || isDev || isPr || isBarn) {
return {
Expand Down Expand Up @@ -165,7 +166,7 @@ export async function getQuote(params: FeeQuoteParams): Promise<OrderQuoteRespon
}

return orderBookApi.getQuote(quoteParams, { chainId }).catch((error) => {
if (isOrderbookTypedError(error)) {
if (getIsOrderBookTypedError(error)) {
const errorObject = mapOperatorErrorToQuoteError(error.body)

return Promise.reject(errorObject ? new GpQuoteError(errorObject) : error)
Expand All @@ -175,13 +176,6 @@ export async function getQuote(params: FeeQuoteParams): Promise<OrderQuoteRespon
})
}

export type OrderbookTypedError = OrderBookApiError<ApiErrorObject>

function isOrderbookTypedError(e: any): e is OrderbookTypedError {
const error = e as OrderbookTypedError
return error.body.errorType !== undefined && error.body.description !== undefined
}

export async function getOrder(chainId: ChainId, orderId: string, env?: CowEnv): Promise<EnrichedOrder | null> {
const contextOverride = {
chainId,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { OrderBookApiError } from '@cowprotocol/cow-sdk'

import { ApiErrorObject } from './errors/OperatorError'

export type OrderBookTypedError = OrderBookApiError<ApiErrorObject>

export function getIsOrderBookTypedError(e: any): e is OrderBookTypedError {
const error = e as OrderBookTypedError
return error.body.errorType !== undefined && error.body.description !== undefined
}
1 change: 1 addition & 0 deletions apps/cowswap-frontend/src/api/gnosisProtocol/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as realApi from './api'
import * as mockApi from './mock'

export type { UnsupportedToken, OrderID } from './api'
export { getIsOrderBookTypedError } from './getIsOrderBookTypedError'

const useMock = process.env.REACT_APP_MOCK === 'true'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,29 @@ function getTokenLogoURI(address: string, chainId: SupportedChainId = SupportedC

const currencyLogoCache = new Map<string, Array<string>>()

const COW_PROTOCOL_REPO = 'cowprotocol/token-lists'
function getLogoURI(currency: Currency | null): string | null {
if (!currency) return null

const logoURI = (currency as Currency & { logoURI: string }).logoURI

if (!logoURI) return null

// Always lowercase logo URI if it's from CoW Protocol repo
// Because CoW Protocol repo has all logos in lowercase
if (logoURI.includes(COW_PROTOCOL_REPO)) return logoURI.toLowerCase()

return logoURI
}

// TODO: must be refactored
export default function useCurrencyLogoURIs(currency?: Currency | null): string[] {
const currencyAddress = currency ? (currency.isNative ? NATIVE_CURRENCY_BUY_ADDRESS : currency.address) : null
// There is a modification of Token in useDetectNativeToken()
const externalLogo = useProxyTokenLogo(currency?.chainId, currencyAddress)
const cacheKey = `${currencyAddress}|${currency?.chainId}`
const cached = currencyLogoCache.get(cacheKey)
const logoURI = currency ? (currency as Currency & { logoURI: string }).logoURI : null
const logoURI = getLogoURI(currency || null)
const imageOverride = currency?.isToken ? ADDRESS_IMAGE_OVERRIDE[currency.address] : null

if (cached) {
Expand Down
14 changes: 13 additions & 1 deletion apps/cowswap-frontend/src/common/updaters/FeesUpdater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { OrderKind } from '@cowprotocol/cow-sdk'
import { useENSAddress } from '@cowprotocol/ens'
import { useWalletInfo } from '@cowprotocol/wallet'

import ms from 'ms.macro'

import { useRefetchQuoteCallback } from 'legacy/hooks/useRefetchPriceCallback'
import { useIsUnsupportedTokenGp } from 'legacy/state/lists/hooks'
import { useAllQuotes, useIsBestQuoteLoading, useSetQuoteError } from 'legacy/state/price/hooks'
Expand All @@ -29,6 +31,14 @@ export const TYPED_VALUE_DEBOUNCE_TIME = 350
const REFETCH_CHECK_INTERVAL = 10000 // Every 10s
const RENEW_FEE_QUOTES_BEFORE_EXPIRATION_TIME = 30000 // Will renew the quote if there's less than 30 seconds left for the quote to expire
const WAITING_TIME_BETWEEN_EQUAL_REQUESTS = 5000 // Prevents from sending the same request to often (max, every 5s)
const UNSUPPORTED_TOKEN_TTL = ms`1h`

/**
* Since a token might become supported, we should periodically (once in 1h) refresh its state
*/
const isUnsupportedTokenExpired = ({ dateAdded }: { dateAdded: number }) => {
return dateAdded + UNSUPPORTED_TOKEN_TTL < Date.now()
}

type FeeQuoteParams = Omit<LegacyFeeQuoteParams, 'validTo'>

Expand Down Expand Up @@ -233,7 +243,9 @@ export function FeesUpdater(): null {
// Callback to re-fetch both the fee and the price
const refetchQuoteIfRequired = () => {
// if no token is unsupported and needs refetching
const hasToRefetch = !unsupportedToken && isRefetchQuoteRequired(isLoading, quoteParams, quoteInfo)
const hasToRefetch =
(!unsupportedToken || isUnsupportedTokenExpired(unsupportedToken)) &&
isRefetchQuoteRequired(isLoading, quoteParams, quoteInfo)

if (hasToRefetch) {
// Decide if this is a new quote, or just a refresh
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect, useCallback, useRef } from 'react'

import { EXPIRED_ORDERS_PENDING_TIME } from '@cowprotocol/common-const'
import { NATIVE_CURRENCY_BUY_ADDRESS } from '@cowprotocol/common-const'
import { SupportedChainId as ChainId } from '@cowprotocol/cow-sdk'
import { useWalletInfo } from '@cowprotocol/wallet'

Expand All @@ -24,7 +24,6 @@ export function ExpiredOrdersUpdater(): null {
const updateOrders = useCallback(
async (chainId: ChainId, account: string) => {
const lowerCaseAccount = account.toLowerCase()
const now = Date.now()

if (isUpdating.current) {
return
Expand All @@ -33,26 +32,24 @@ export function ExpiredOrdersUpdater(): null {
try {
isUpdating.current = true

// Filter orders:
// Filter expired orders:
// - Only eth-flow orders
// - Owned by the current connected account
// - Created in the last 5 min, no further
// - Not yet refunded
const pending = expiredRef.current.filter(({ owner, creationTime: creationTimeString, refundHash }) => {
const creationTime = new Date(creationTimeString).getTime()
const orderWithoutRefund = expiredRef.current.filter(({ owner, refundHash, sellToken }) => {
const isEthFlowOrder = sellToken === NATIVE_CURRENCY_BUY_ADDRESS

return (
owner.toLowerCase() === lowerCaseAccount && now - creationTime < EXPIRED_ORDERS_PENDING_TIME && !refundHash
)
return isEthFlowOrder && owner.toLowerCase() === lowerCaseAccount && !refundHash
})

if (pending.length === 0) {
if (orderWithoutRefund.length === 0) {
// console.debug(`[CancelledOrdersUpdater] No orders are being expired`)
return
} else {
console.debug(`[ExpiredOrdersUpdater] Checking ${pending.length} recently expired orders...`)
console.debug(`[ExpiredOrdersUpdater] Checking ${orderWithoutRefund.length} recently expired orders...`)
}

const ordersPromises = pending.map(({ id }) => getOrder(chainId, id))
const ordersPromises = orderWithoutRefund.map(({ id }) => getOrder(chainId, id))

const resolvedPromises = await Promise.allSettled(ordersPromises)

Expand Down
2 changes: 2 additions & 0 deletions apps/cowswap-frontend/src/cow-react/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ import { WithLDProvider } from 'modules/application/containers/WithLDProvider'
import { FortuneWidget } from 'modules/fortune/containers/FortuneWidget'

import { FeatureGuard } from 'common/containers/FeatureGuard'
import { IframeResizer } from 'utils/iframeResizer'

import { WalletUnsupportedNetworkBanner } from '../common/containers/WalletUnsupportedNetworkBanner'


// Node removeChild hackaround
// based on: https://github.com/facebook/react/issues/11538#issuecomment-417504600
nodeRemoveChildFix()
Expand Down
4 changes: 1 addition & 3 deletions apps/cowswap-frontend/src/legacy/theme/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,7 @@ export default function ThemeProvider({ children }: { children?: React.ReactNode
const darkMode = useIsDarkMode()
const isInjectedWidgetMode = isInjectedWidget()

const themeObject = useMemo(() => {
return theme(darkMode, isInjectedWidgetMode);
}, [darkMode, isInjectedWidgetMode]);
const themeObject = useMemo(() => theme(darkMode, isInjectedWidgetMode), [darkMode, isInjectedWidgetMode])

return <StyledComponentsThemeProvider theme={themeObject}>{children}</StyledComponentsThemeProvider>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ export const BodyWrapper = styled.div`
justify-content: center;
flex: 1 1 auto;
z-index: 2;
padding: ${({ theme }) => theme.isInjectedWidgetMode ? '16px 16px 0' : '5vh 16px 0'};
padding: ${({ theme }) => (theme.isInjectedWidgetMode ? '16px 16px 0' : '5vh 16px 0')};
${({ theme }) => theme.mediaWidth.upToMedium`
padding: ${({ theme }) => theme.isInjectedWidgetMode ? '0 0 16px' : '0 10px 16px'};
padding: ${({ theme }) => (theme.isInjectedWidgetMode ? '0 0 16px' : '0 10px 16px')};
flex: none;
`}
`
Original file line number Diff line number Diff line change
Expand Up @@ -82,28 +82,32 @@ export function TradeWidgetLinks({
)
})

const singleMenuItem = menuItems.length === 1;
const singleMenuItem = menuItems.length === 1

return isDropdown ? (
<>
<styledEl.MenuItem onClick={() => !singleMenuItem && setDropdownVisible(!isDropdownVisible)} isDropdownVisible={isDropdownVisible}>
<styledEl.MenuItem
onClick={() => !singleMenuItem && setDropdownVisible(!isDropdownVisible)}
isDropdownVisible={isDropdownVisible}
>
<styledEl.Link to={menuItems.find((item) => item.props.isActive)?.props.routePath || '#'}>
<Trans>
{menuItems.find((item) => item.props.isActive)?.props.item.label}
{!singleMenuItem ? <SVG src={IMAGE_CARRET} title="select" /> : null}
</Trans>
</styledEl.Link>
</styledEl.MenuItem>

{isDropdownVisible && <styledEl.SelectMenu>
{isDropdownVisible && <ModalHeader onBack={handleMenuItemClick}>Trading mode</ModalHeader>}
{menuItems}

{isDropdownVisible && (
<styledEl.SelectMenu>
<ModalHeader onBack={handleMenuItemClick}>Trading mode</ModalHeader>
{menuItems}
</styledEl.SelectMenu>
}
)}
</>
) : (
<styledEl.Wrapper>{menuItems}</styledEl.Wrapper>
);
)
}

const MenuItem = ({
Expand All @@ -126,7 +130,7 @@ const MenuItem = ({
<styledEl.MenuItem isActive={isActive} onClick={onClick} isDropdownVisible={isDropdownVisible}>
<styledEl.Link to={routePath}>
<Trans>{item.label}</Trans>
{item.featureGuard && badgeText && (
{badgeText && (
<styledEl.Badge type={badgeType}>
<Trans>{badgeText}</Trans>
</styledEl.Badge>
Expand Down
8 changes: 8 additions & 0 deletions apps/cowswap-frontend/src/modules/permit/const.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { DAI } from '@cowprotocol/common-const'
import { SupportedChainId } from '@cowprotocol/cow-sdk'
import { MaxUint256 } from '@ethersproject/constants'
import { Wallet } from '@ethersproject/wallet'
Expand Down Expand Up @@ -31,3 +32,10 @@ export const ORDER_TYPE_SUPPORTS_PERMIT: Record<TradeType, boolean> = {
}

export const PENDING_ORDER_PERMIT_CHECK_INTERVAL = ms`1min`

// DAI's mainnet contract (https://etherscan.io/address/0x6b175474e89094c44da98b954eedeac495271d0f#readContract) returns
// `1` for the version, while when calling the contract method returns `2`.
// Also, if we use the version returned by the contract, it simply doesn't work
// Thus, do not call it for DAI.
// TODO: figure out whether more tokens behave the same way
export const TOKENS_TO_SKIP_VERSION = new Set([DAI.address.toLowerCase()])
Loading

0 comments on commit 146b508

Please sign in to comment.