diff --git a/apps/main/package.json b/apps/main/package.json index 3b3bf08ae..34a7b02a7 100644 --- a/apps/main/package.json +++ b/apps/main/package.json @@ -26,7 +26,7 @@ "typescript": "*" }, "dependencies": { - "@curvefi/api": "^2.65.29", + "@curvefi/api": "^2.66.1", "@curvefi/lending-api": "^2.4.1", "@curvefi/stablecoin-api": "^1.5.8", "@hookform/error-message": "^2.0.1", diff --git a/apps/main/src/dex/components/PagePoolList/index.tsx b/apps/main/src/dex/components/PagePoolList/index.tsx index 46fc48abb..c67ee9cb7 100644 --- a/apps/main/src/dex/components/PagePoolList/index.tsx +++ b/apps/main/src/dex/components/PagePoolList/index.tsx @@ -1,5 +1,4 @@ import type { ColumnKeys, PagePoolList, SearchParams } from '@main/components/PagePoolList/types' -import { t } from '@lingui/macro' import React, { useCallback, useEffect, useMemo, useState } from 'react' import styled from 'styled-components' import { COLUMN_KEYS } from '@main/components/PagePoolList/utils' @@ -16,8 +15,6 @@ import TableHeadMobile from '@main/components/PagePoolList/components/TableHeadM import TableSettings from '@main/components/PagePoolList/components/TableSettings/TableSettings' import TableRowNoResult from '@main/components/PagePoolList/components/TableRowNoResult' import { PoolRow } from '@main/components/PagePoolList/components/PoolRow' -import { ConnectWalletPrompt, useWalletStore } from '@ui-kit/features/connect-wallet' -import { isLoading } from '@ui/utils' const PoolList = ({ rChainId, @@ -49,10 +46,7 @@ const PoolList = ({ const fetchPoolsRewardsApy = useStore((state) => state.pools.fetchPoolsRewardsApy) const setFormValues = useStore((state) => state.poolList.setFormValues) const { initCampaignRewards, initiated } = useStore((state) => state.campaigns) - const provider = useWalletStore((s) => s.provider) const network = useStore((state) => state.networks.networks[rChainId]) - const connectWallet = useStore((s) => s.updateConnectState) - const connectState = useStore((s) => s.connectState) const [showDetail, setShowDetail] = useState('') @@ -183,73 +177,61 @@ const PoolList = ({ updatePath={updatePath} /> - {!provider ? ( - - connectWallet()} - isLoading={isLoading(connectState)} + + {isXSmDown ? ( + + ) : ( + - - ) : ( -
- {isXSmDown ? ( - - ) : ( - + {isReadyWithApiData && formStatus.noResult ? ( + + ) : isReady && Array.isArray(result) ? ( + <> + {result.map((poolId: string, index: number) => ( + + ))} + + ) : ( + + + )} - - {isReadyWithApiData && formStatus.noResult ? ( - - ) : isReady && Array.isArray(result) ? ( - <> - {result.map((poolId: string, index: number) => ( - - ))} - - ) : ( - - - - )} - -
+ + + +
- - - -
- )} + + ) } diff --git a/apps/main/src/dex/hooks/usePageOnMount.ts b/apps/main/src/dex/hooks/usePageOnMount.ts index 25102a3ae..e4f0352c4 100644 --- a/apps/main/src/dex/hooks/usePageOnMount.ts +++ b/apps/main/src/dex/hooks/usePageOnMount.ts @@ -1,17 +1,17 @@ import type { Location, NavigateFunction, Params } from 'react-router' import type { ConnectState } from '@ui/utils' +import { isFailure, isLoading, isSuccess } from '@ui/utils' import type { INetworkName } from '@curvefi/api/lib/interfaces' import { ethers } from 'ethers' import { useCallback, useEffect } from 'react' -import { useConnectWallet, useSetChain, useSetLocale, getWalletSignerAddress } from '@ui-kit/features/connect-wallet' +import { getWalletSignerAddress, useConnectWallet, useSetChain, useSetLocale } from '@ui-kit/features/connect-wallet' import { CONNECT_STAGE, REFRESH_INTERVAL, ROUTE } from '@main/constants' import { dynamicActivate, updateAppLocale } from '@ui-kit/lib/i18n' import { useNetworkFromUrl, useParsedParams } from '@main/utils/utilsRouter' import { getWalletChainId } from '@ui-kit/features/connect-wallet' import { initCurveJs } from '@main/utils/utilsCurvejs' -import { isFailure, isLoading, isSuccess } from '@ui/utils' import useStore from '@main/store/useStore' import { useUserProfileStore } from '@ui-kit/features/user-profile' import { ChainId, PageProps, Wallet } from '@main/types/main.types' @@ -48,8 +48,8 @@ function usePageOnMount(params: Params, location: Location, navigate: NavigateFu updateGlobalStoreByKey('isLoadingApi', true) updateGlobalStoreByKey('isLoadingCurve', true) // remove -> use connectState - if (useWallet && wallet && chainId) { - const api = await initCurveJs(chainId, wallet) + if (chainId) { + const api = await initCurveJs(chainId, (useWallet && wallet) || undefined) setNetworkConfigs(api) updateCurveJs(api, prevCurveApi, wallet) updateConnectState('success', '') diff --git a/apps/main/src/dex/store/createPoolsSlice.ts b/apps/main/src/dex/store/createPoolsSlice.ts index c40005322..b5e546124 100644 --- a/apps/main/src/dex/store/createPoolsSlice.ts +++ b/apps/main/src/dex/store/createPoolsSlice.ts @@ -329,6 +329,7 @@ const createPoolsSlice = (set: SetState, get: GetState): PoolsSlic }, fetchBasePools: async (curve: CurveApi) => { const chainId = curve.chainId + if (curve.isNoRPC) return set( produce((state: State) => { state.pools.basePoolsLoading = true diff --git a/apps/main/src/dex/utils/utilsCurvejs.ts b/apps/main/src/dex/utils/utilsCurvejs.ts index 311a1e9eb..e305d80e8 100644 --- a/apps/main/src/dex/utils/utilsCurvejs.ts +++ b/apps/main/src/dex/utils/utilsCurvejs.ts @@ -2,9 +2,13 @@ import cloneDeep from 'lodash/cloneDeep' import { FORMAT_OPTIONS, formatNumber } from '@ui/utils' import { CurveApi, ChainId, Pool, RewardsApy, Wallet } from '@main/types/main.types' -export async function initCurveJs(chainId: ChainId, wallet: Wallet) { +export async function initCurveJs(chainId: ChainId, wallet?: Wallet) { const curveApi = cloneDeep((await import('@curvefi/api')).default) as CurveApi - await curveApi.init('Web3', { network: { chainId }, externalProvider: getWalletProvider(wallet) }, { chainId }) + if (wallet) { + await curveApi.init('Web3', { network: { chainId }, externalProvider: getWalletProvider(wallet) }, { chainId }) + } else { + await curveApi.init('NoRPC', 'NoRPC', { chainId }) + } return curveApi } diff --git a/packages/curve-ui-kit/src/shared/ui/Metric.tsx b/packages/curve-ui-kit/src/shared/ui/Metric.tsx index f206c33dd..a0a099488 100644 --- a/packages/curve-ui-kit/src/shared/ui/Metric.tsx +++ b/packages/curve-ui-kit/src/shared/ui/Metric.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react' +import { useMemo, useState } from 'react' import Alert from '@mui/material/Alert' import Stack from '@mui/material/Stack' @@ -13,6 +13,7 @@ import { TypographyVariantKey } from '@ui-kit/themes/typography' import { abbreviateNumber, scaleSuffix } from '@ui-kit/utils' import { Duration } from '../../themes/design/0_primitives' import AlertTitle from '@mui/material/AlertTitle' +import { MAX_USD_VALUE } from 'ui' const { Spacing, IconSize } = SizesAndSpaces @@ -94,6 +95,14 @@ type MetricValueProps = Required void } +function runFormatter(value: number, formatter: (value: number) => string, abbreviate: boolean, symbol?: string) { + if (symbol === '$' && value > MAX_USD_VALUE) { + console.warn(`USD value is too large: ${value}`) + return `?` + } + return formatter(abbreviate ? abbreviateNumber(value) : value) +} + const MetricValue = ({ value, formatter, @@ -114,7 +123,10 @@ const MetricValue = ({ )} - {formatter(abbreviate ? abbreviateNumber(value) : value)} + {useMemo( + () => runFormatter(value, formatter, abbreviate, unit?.symbol), + [formatter, abbreviate, value, unit?.symbol], + )} {abbreviate && ( diff --git a/packages/curve-ui-kit/src/themes/design/2_theme.ts b/packages/curve-ui-kit/src/themes/design/2_theme.ts index 35a5ccb6f..4dbbe253c 100644 --- a/packages/curve-ui-kit/src/themes/design/2_theme.ts +++ b/packages/curve-ui-kit/src/themes/design/2_theme.ts @@ -1,4 +1,4 @@ -import { Blues, Grays, Greens, Reds, Violet, TransitionFunction } from './0_primitives' +import { Blues, Grays, Greens, Reds, TransitionFunction, Violet } from './0_primitives' import { SurfacesAndText } from './1_surfaces_text' const { plain, inverted } = SurfacesAndText @@ -148,13 +148,6 @@ export const createLightDesign = (Light: typeof plain.Light | typeof inverted.Li }, } as const - const Feedback = { - Success: Greens[300], - Info: Layer[3].Fill, - Warning: Reds[400], - Error: Reds[500], - } as const - const Tabs = { Transition, UnderLined: { @@ -246,7 +239,7 @@ export const createLightDesign = (Light: typeof plain.Light | typeof inverted.Li Default: Grays[400], Active: Light.Text.highlight, Filled: Grays[850], - Error: Feedback.Error, + Error: Reds[500], }, }, Nested: { @@ -256,7 +249,7 @@ export const createLightDesign = (Light: typeof plain.Light | typeof inverted.Li Default: Grays[400], Active: Light.Text.highlight, Filled: Grays[850], - Error: Feedback.Error, + Error: Reds[500], }, }, }, @@ -285,7 +278,6 @@ export const createLightDesign = (Light: typeof plain.Light | typeof inverted.Li Color, Text, Button, - Feedback, Layer, Tabs, Chips, @@ -493,13 +485,6 @@ export const createDarkDesign = (Dark: typeof plain.Dark | typeof inverted.Dark) }, } as const - const Feedback = { - Success: Greens[400], - Info: Layer[3].Fill, - Warning: Reds[300], - Error: Reds[500], - } as const - const Tabs = { Transition, UnderLined: { @@ -589,7 +574,7 @@ export const createDarkDesign = (Dark: typeof plain.Dark | typeof inverted.Dark) Default: color[600], Active: Dark.Text.highlight, Filled: color[75], - Error: Feedback.Error, + Error: Reds[500], }, }, Nested: { @@ -599,7 +584,7 @@ export const createDarkDesign = (Dark: typeof plain.Dark | typeof inverted.Dark) Default: color[600], Active: Dark.Text.highlight, Filled: color[75], - Error: Feedback.Error, + Error: Reds[500], }, }, }, @@ -628,7 +613,6 @@ export const createDarkDesign = (Dark: typeof plain.Dark | typeof inverted.Dark) Color, Text, Button, - Feedback, Layer, Tabs, Chips, @@ -779,13 +763,6 @@ export const createChadDesign = (Chad: typeof plain.Chad | typeof inverted.Chad) }, } as const - const Feedback = { - Success: Greens[400], - Info: Layer[3].Fill, - Warning: Reds[400], - Error: Reds[500], - } as const - const Tabs = { Transition, UnderLined: { @@ -877,7 +854,7 @@ export const createChadDesign = (Chad: typeof plain.Chad | typeof inverted.Chad) Default: Violet[200], Active: Chad.Text.highlight, Filled: Violet[400], - Error: Feedback.Error, + Error: Reds[500], }, }, Nested: { @@ -887,7 +864,7 @@ export const createChadDesign = (Chad: typeof plain.Chad | typeof inverted.Chad) Default: Violet[200], Active: Chad.Text.highlight, Filled: Violet[400], - Error: Feedback.Error, + Error: Reds[500], }, }, }, @@ -916,7 +893,6 @@ export const createChadDesign = (Chad: typeof plain.Chad | typeof inverted.Chad) Color, Text, Button, - Feedback, Layer, Tabs, Chips, diff --git a/packages/curve-ui-kit/src/themes/palette/palette.ts b/packages/curve-ui-kit/src/themes/palette/palette.ts index ccab6d075..0b8d53538 100644 --- a/packages/curve-ui-kit/src/themes/palette/palette.ts +++ b/packages/curve-ui-kit/src/themes/palette/palette.ts @@ -3,7 +3,7 @@ import { PaletteOptions } from '@mui/material' export const createPalette = ( mode: 'light' | 'dark', - { Layer, Color, Feedback, Text: { TextColors } }: DesignSystem, + { Layer, Color, Text: { TextColors } }: DesignSystem, ): PaletteOptions => ({ mode, primary: { main: Color.Primary[500] }, diff --git a/packages/ui/src/utils/utilsConstants.ts b/packages/ui/src/utils/utilsConstants.ts index a0bca3a10..b1c3dfc3f 100644 --- a/packages/ui/src/utils/utilsConstants.ts +++ b/packages/ui/src/utils/utilsConstants.ts @@ -6,6 +6,9 @@ export const CURVE_ASSETS_URL = `${CURVE_CDN_URL}/curve-assets` export const CURVE_LOGO_URL = `${CURVE_ASSETS_URL}/branding/logo.png` export const NOT_FOUND_IMAGE_URL = `${CURVE_ASSETS_URL}/branding/four-oh-llama.jpg` +// Sometimes API returns overflowed USD values. Don't show them! +export const MAX_USD_VALUE = 100_000_000_000_000 // $ 100T 🤑 + export const getImageBaseUrl = (blockchainId: string) => `${CURVE_ASSETS_URL}/images/assets${blockchainId == 'ethereum' ? '' : `-${blockchainId}`}/` diff --git a/packages/ui/src/utils/utilsFormat.ts b/packages/ui/src/utils/utilsFormat.ts index da8ee92bf..d15d39a52 100644 --- a/packages/ui/src/utils/utilsFormat.ts +++ b/packages/ui/src/utils/utilsFormat.ts @@ -2,6 +2,7 @@ import { detect, fromUrl, fromNavigator } from '@lingui/detect-locale' import BigNumber from 'bignumber.js' import isUndefined from 'lodash/isUndefined' import isNaN from 'lodash/isNaN' +import { MAX_USD_VALUE } from './utilsConstants' BigNumber.config({ EXPONENTIAL_AT: 20, ROUNDING_MODE: BigNumber.ROUND_HALF_UP }) export const BN = BigNumber @@ -140,6 +141,10 @@ export function formatNumber(val: number | string | undefined | null, options?: } function _formatNumber(val: string | number, options: NumberFormatOptions) { + if (options.currency === 'USD' && Number(val) > MAX_USD_VALUE) { + console.warn(`USD value is too large: ${val}`) + return `?` + } return new Intl.NumberFormat(localeDetected, options).format( options.style === 'percent' ? Number(val) / 100 : Number(val), ) diff --git a/yarn.lock b/yarn.lock index a8fbadf04..7ed54a5d3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3341,15 +3341,15 @@ __metadata: languageName: node linkType: hard -"@curvefi/api@npm:^2.65.29": - version: 2.65.29 - resolution: "@curvefi/api@npm:2.65.29" +"@curvefi/api@npm:^2.66.1": + version: 2.66.1 + resolution: "@curvefi/api@npm:2.66.1" dependencies: "@curvefi/ethcall": "npm:6.0.7" bignumber.js: "npm:^9.1.2" ethers: "npm:^6.13.4" memoizee: "npm:^0.4.17" - checksum: 10c0/90a04fc6a7842e63b977580b449bce4f1f6776abacae5ac7a0c9dca1a51f6a561827574092d62c7bfddd67fc48c1d270acbbc584e18ff2c89613e9c98c3a87ce + checksum: 10c0/70e1510f7fbc5b88edbc67e049dba38ce9e7f6c150237a04fda7b63aa3f317ffd0d5f49df414cc4360a98452c017652bec4532245a12a02ea7bcaecdb110565e languageName: node linkType: hard @@ -21426,7 +21426,7 @@ __metadata: version: 0.0.0-use.local resolution: "main@workspace:apps/main" dependencies: - "@curvefi/api": "npm:^2.65.29" + "@curvefi/api": "npm:^2.66.1" "@curvefi/lending-api": "npm:^2.4.1" "@curvefi/stablecoin-api": "npm:^1.5.8" "@hookform/error-message": "npm:^2.0.1"