diff --git a/README.md b/README.md index bafdfeb66..ebfc391d8 100644 --- a/README.md +++ b/README.md @@ -252,7 +252,6 @@ The file `common.ts` with type [`AppConfig`](src/config/types.ts) contains impor - `selectedConnectors`: List of connectors to make available by default in the wallet selection modal that will be shown even if the connector is not injected. - `blockedConnectors`: List of EIP-6963 injected connectors names to block in the wallet selection modal. - `isSimulatorEnabled`: Flag to enable the simulation page. -- `showStrategyRoi`: Optional flag to show the Strategy ROI in the Strategy Block. ROI is hidden by default. - `network` - `name`: Network name. - `logoUrl`: Network logo URL. diff --git a/e2e/screenshots/simulator/recurring/Recurring_limit_limit/form.png b/e2e/screenshots/simulator/recurring/Recurring_limit_limit/form.png index c95fddb9f..b4ebc7da2 100644 Binary files a/e2e/screenshots/simulator/recurring/Recurring_limit_limit/form.png and b/e2e/screenshots/simulator/recurring/Recurring_limit_limit/form.png differ diff --git a/e2e/screenshots/simulator/recurring/Recurring_range_limit/form.png b/e2e/screenshots/simulator/recurring/Recurring_range_limit/form.png index 14612c4c1..30d19c4c8 100644 Binary files a/e2e/screenshots/simulator/recurring/Recurring_range_limit/form.png and b/e2e/screenshots/simulator/recurring/Recurring_range_limit/form.png differ diff --git a/e2e/screenshots/strategy/disposable/Disposable_buy_limit/create/form.png b/e2e/screenshots/strategy/disposable/Disposable_buy_limit/create/form.png index 911f53cb9..7430fcfe5 100644 Binary files a/e2e/screenshots/strategy/disposable/Disposable_buy_limit/create/form.png and b/e2e/screenshots/strategy/disposable/Disposable_buy_limit/create/form.png differ diff --git a/e2e/screenshots/strategy/disposable/Disposable_buy_limit/create/my-strategy.png b/e2e/screenshots/strategy/disposable/Disposable_buy_limit/create/my-strategy.png index eb4bef5d1..90d4fd163 100644 Binary files a/e2e/screenshots/strategy/disposable/Disposable_buy_limit/create/my-strategy.png and b/e2e/screenshots/strategy/disposable/Disposable_buy_limit/create/my-strategy.png differ diff --git a/e2e/screenshots/strategy/disposable/Disposable_buy_limit/deposit/form.png b/e2e/screenshots/strategy/disposable/Disposable_buy_limit/deposit/form.png index 732010254..3cb6ee5b3 100644 Binary files a/e2e/screenshots/strategy/disposable/Disposable_buy_limit/deposit/form.png and b/e2e/screenshots/strategy/disposable/Disposable_buy_limit/deposit/form.png differ diff --git a/e2e/screenshots/strategy/disposable/Disposable_buy_range/create/form.png b/e2e/screenshots/strategy/disposable/Disposable_buy_range/create/form.png index 456eecf22..7660060e6 100644 Binary files a/e2e/screenshots/strategy/disposable/Disposable_buy_range/create/form.png and b/e2e/screenshots/strategy/disposable/Disposable_buy_range/create/form.png differ diff --git a/e2e/screenshots/strategy/disposable/Disposable_buy_range/create/my-strategy.png b/e2e/screenshots/strategy/disposable/Disposable_buy_range/create/my-strategy.png index 0e271cb0b..dc6d8a227 100644 Binary files a/e2e/screenshots/strategy/disposable/Disposable_buy_range/create/my-strategy.png and b/e2e/screenshots/strategy/disposable/Disposable_buy_range/create/my-strategy.png differ diff --git a/e2e/screenshots/strategy/disposable/Disposable_buy_range/deposit/form.png b/e2e/screenshots/strategy/disposable/Disposable_buy_range/deposit/form.png index 8caafcbec..56021e602 100644 Binary files a/e2e/screenshots/strategy/disposable/Disposable_buy_range/deposit/form.png and b/e2e/screenshots/strategy/disposable/Disposable_buy_range/deposit/form.png differ diff --git a/e2e/screenshots/strategy/disposable/Disposable_buy_range/duplicate/form.png b/e2e/screenshots/strategy/disposable/Disposable_buy_range/duplicate/form.png index 02a3f579a..23d10b5df 100644 Binary files a/e2e/screenshots/strategy/disposable/Disposable_buy_range/duplicate/form.png and b/e2e/screenshots/strategy/disposable/Disposable_buy_range/duplicate/form.png differ diff --git a/e2e/screenshots/strategy/disposable/Disposable_sell_limit/create/form.png b/e2e/screenshots/strategy/disposable/Disposable_sell_limit/create/form.png index 75ca0ea36..a19b66148 100644 Binary files a/e2e/screenshots/strategy/disposable/Disposable_sell_limit/create/form.png and b/e2e/screenshots/strategy/disposable/Disposable_sell_limit/create/form.png differ diff --git a/e2e/screenshots/strategy/disposable/Disposable_sell_limit/create/my-strategy.png b/e2e/screenshots/strategy/disposable/Disposable_sell_limit/create/my-strategy.png index 6614251c2..7c0f1f649 100644 Binary files a/e2e/screenshots/strategy/disposable/Disposable_sell_limit/create/my-strategy.png and b/e2e/screenshots/strategy/disposable/Disposable_sell_limit/create/my-strategy.png differ diff --git a/e2e/screenshots/strategy/disposable/Disposable_sell_range/create/my-strategy.png b/e2e/screenshots/strategy/disposable/Disposable_sell_range/create/my-strategy.png index b6bce4b41..404cb8681 100644 Binary files a/e2e/screenshots/strategy/disposable/Disposable_sell_range/create/my-strategy.png and b/e2e/screenshots/strategy/disposable/Disposable_sell_range/create/my-strategy.png differ diff --git a/e2e/screenshots/strategy/overlapping/Overlapping/create/my-strategy.png b/e2e/screenshots/strategy/overlapping/Overlapping/create/my-strategy.png index 1a9b1204a..062f93a24 100644 Binary files a/e2e/screenshots/strategy/overlapping/Overlapping/create/my-strategy.png and b/e2e/screenshots/strategy/overlapping/Overlapping/create/my-strategy.png differ diff --git a/e2e/screenshots/strategy/recurring/Recurring_limit_limit/create/form.png b/e2e/screenshots/strategy/recurring/Recurring_limit_limit/create/form.png index 4666380ca..3e3246390 100644 Binary files a/e2e/screenshots/strategy/recurring/Recurring_limit_limit/create/form.png and b/e2e/screenshots/strategy/recurring/Recurring_limit_limit/create/form.png differ diff --git a/e2e/screenshots/strategy/recurring/Recurring_limit_limit/create/my-strategy.png b/e2e/screenshots/strategy/recurring/Recurring_limit_limit/create/my-strategy.png index ecd640490..9e04c4fed 100644 Binary files a/e2e/screenshots/strategy/recurring/Recurring_limit_limit/create/my-strategy.png and b/e2e/screenshots/strategy/recurring/Recurring_limit_limit/create/my-strategy.png differ diff --git a/e2e/screenshots/strategy/recurring/Recurring_limit_limit/deposit/form.png b/e2e/screenshots/strategy/recurring/Recurring_limit_limit/deposit/form.png index 1bedce888..42f5544f5 100644 Binary files a/e2e/screenshots/strategy/recurring/Recurring_limit_limit/deposit/form.png and b/e2e/screenshots/strategy/recurring/Recurring_limit_limit/deposit/form.png differ diff --git a/e2e/screenshots/strategy/recurring/Recurring_limit_range/create/my-strategy.png b/e2e/screenshots/strategy/recurring/Recurring_limit_range/create/my-strategy.png index e07a6b732..320a719fb 100644 Binary files a/e2e/screenshots/strategy/recurring/Recurring_limit_range/create/my-strategy.png and b/e2e/screenshots/strategy/recurring/Recurring_limit_range/create/my-strategy.png differ diff --git a/e2e/screenshots/strategy/recurring/Recurring_limit_range/deposit/form.png b/e2e/screenshots/strategy/recurring/Recurring_limit_range/deposit/form.png index 574861194..517e7151e 100644 Binary files a/e2e/screenshots/strategy/recurring/Recurring_limit_range/deposit/form.png and b/e2e/screenshots/strategy/recurring/Recurring_limit_range/deposit/form.png differ diff --git a/e2e/screenshots/strategy/recurring/Recurring_range_limit/create/my-strategy.png b/e2e/screenshots/strategy/recurring/Recurring_range_limit/create/my-strategy.png index a57eec91d..4a8e344f2 100644 Binary files a/e2e/screenshots/strategy/recurring/Recurring_range_limit/create/my-strategy.png and b/e2e/screenshots/strategy/recurring/Recurring_range_limit/create/my-strategy.png differ diff --git a/e2e/screenshots/strategy/recurring/Recurring_range_limit/deposit/form.png b/e2e/screenshots/strategy/recurring/Recurring_range_limit/deposit/form.png index c5d01bcd5..c874795e6 100644 Binary files a/e2e/screenshots/strategy/recurring/Recurring_range_limit/deposit/form.png and b/e2e/screenshots/strategy/recurring/Recurring_range_limit/deposit/form.png differ diff --git a/e2e/screenshots/strategy/recurring/Recurring_range_range/create/form.png b/e2e/screenshots/strategy/recurring/Recurring_range_range/create/form.png index 54c8deb54..8b82ce91e 100644 Binary files a/e2e/screenshots/strategy/recurring/Recurring_range_range/create/form.png and b/e2e/screenshots/strategy/recurring/Recurring_range_range/create/form.png differ diff --git a/e2e/screenshots/strategy/recurring/Recurring_range_range/create/my-strategy.png b/e2e/screenshots/strategy/recurring/Recurring_range_range/create/my-strategy.png index b2fdbd1fb..8dbf6b33f 100644 Binary files a/e2e/screenshots/strategy/recurring/Recurring_range_range/create/my-strategy.png and b/e2e/screenshots/strategy/recurring/Recurring_range_range/create/my-strategy.png differ diff --git a/e2e/screenshots/strategy/recurring/Recurring_range_range/deposit/form.png b/e2e/screenshots/strategy/recurring/Recurring_range_range/deposit/form.png index 1cbddaeb1..ad302bab1 100644 Binary files a/e2e/screenshots/strategy/recurring/Recurring_range_range/deposit/form.png and b/e2e/screenshots/strategy/recurring/Recurring_range_range/deposit/form.png differ diff --git a/e2e/screenshots/strategy/recurring/Recurring_range_range/undercut/form.png b/e2e/screenshots/strategy/recurring/Recurring_range_range/undercut/form.png index 7b2c2f5e3..f119f9be7 100644 Binary files a/e2e/screenshots/strategy/recurring/Recurring_range_range/undercut/form.png and b/e2e/screenshots/strategy/recurring/Recurring_range_range/undercut/form.png differ diff --git a/e2e/utils/DebugDriver.ts b/e2e/utils/DebugDriver.ts index 1cb23479a..464fcf1d0 100644 --- a/e2e/utils/DebugDriver.ts +++ b/e2e/utils/DebugDriver.ts @@ -38,7 +38,7 @@ export const setupLocalStorage = async (page: Page, testInfo: TestInfo) => { // each value is stringified to match lsservice for (const [key, value] of Object.entries(storage)) { localStorage.setItem( - `carbon-ethereum-v1.1-${key}`, + `carbon-ethereum-v1.2-${key}`, JSON.stringify(value) ); } diff --git a/src/components/strategies/overview/StrategyContent.tsx b/src/components/strategies/overview/StrategyContent.tsx index 28b943ea6..c986974f7 100644 --- a/src/components/strategies/overview/StrategyContent.tsx +++ b/src/components/strategies/overview/StrategyContent.tsx @@ -6,7 +6,6 @@ import { StrategyBlockCreate } from 'components/strategies/overview/strategyBloc import { CarbonLogoLoading } from 'components/common/CarbonLogoLoading'; import { cn } from 'utils/helpers'; import styles from './StrategyContent.module.css'; -import config from 'config'; type Props = { strategies: StrategyWithFiat[]; @@ -45,12 +44,7 @@ export const _StrategyContent: FC = ({ className={cn('xl:gap-25 grid gap-20 lg:gap-10', styles.strategyList)} > {strategies.map((s) => ( - + ))} {!isExplorer && } diff --git a/src/components/strategies/overview/StrategyFilterSort.tsx b/src/components/strategies/overview/StrategyFilterSort.tsx index 3ca7b2816..ad1a885e5 100644 --- a/src/components/strategies/overview/StrategyFilterSort.tsx +++ b/src/components/strategies/overview/StrategyFilterSort.tsx @@ -7,60 +7,14 @@ import { ReactComponent as IconFilter } from 'assets/icons/filter.svg'; import { lsService } from 'services/localeStorage'; import { useStrategyCtx } from 'hooks/useStrategies'; import { cn } from 'utils/helpers'; -import config from 'config'; - -// [START] Used for localStorage migration: Remove it after Nov 2023 -export enum EnumStrategySort { - Recent, - Old, - PairAscending, - PairDescending, - RoiAscending, - RoiDescending, -} -export const strategySortMapping: Record = { - [EnumStrategySort.Recent]: 'recent', - [EnumStrategySort.Old]: 'old', - [EnumStrategySort.PairAscending]: 'pairAsc', - [EnumStrategySort.PairDescending]: 'pairDesc', - [EnumStrategySort.RoiAscending]: 'roiAsc', - [EnumStrategySort.RoiDescending]: 'roiDesc', -}; -const isEnumSort = ( - sort: StrategySort | EnumStrategySort -): sort is EnumStrategySort => sort in strategySortMapping; export const getSortFromLS = (): StrategySort => { - const sort = lsService.getItem('strategyOverviewSort'); - const isRoiSort = sort === 'roiDesc' || sort === 'roiAsc'; - if (!config.showStrategyRoi && (sort === undefined || isRoiSort)) - return 'recent'; - if (sort === undefined) return 'roiDesc'; - return isEnumSort(sort) ? strategySortMapping[sort] : sort; + return lsService.getItem('strategyOverviewSort') || 'trades'; }; -export enum EnumStrategyFilter { - All, - Active, - Inactive, -} -export const strategyFilterMapping: Record = - { - [EnumStrategyFilter.All]: 'all', - [EnumStrategyFilter.Active]: 'active', - [EnumStrategyFilter.Inactive]: 'inactive', - }; - -const isEnumFilter = ( - filter: StrategyFilter | EnumStrategyFilter -): filter is EnumStrategyFilter => filter in strategyFilterMapping; - export const getFilterFromLS = (): StrategyFilter => { - const filter = lsService.getItem('strategyOverviewFilter'); - if (filter === undefined) return 'all'; - return isEnumFilter(filter) ? strategyFilterMapping[filter] : filter; + return lsService.getItem('strategyOverviewFilter') || 'all'; }; -// [END] export const strategyFilter = { all: 'All', @@ -74,16 +28,10 @@ export const strategySort = { old: 'Oldest Created', pairAsc: 'Pair (A->Z)', pairDesc: 'Pair (Z->A)', - roiAsc: 'ROI (Ascending)', - roiDesc: 'ROI (Descending)', totalBudgetDesc: 'Total Budget', + trades: 'Trades', }; -if (config.showStrategyRoi) { - strategySort['roiAsc'] = ''; - strategySort['roiDesc'] = ''; -} - export type StrategySort = keyof typeof strategySort; interface Props { diff --git a/src/components/strategies/overview/strategyBlock/StrategyBlock.tsx b/src/components/strategies/overview/strategyBlock/StrategyBlock.tsx index 9eab6637f..30d1a6cb3 100644 --- a/src/components/strategies/overview/strategyBlock/StrategyBlock.tsx +++ b/src/components/strategies/overview/strategyBlock/StrategyBlock.tsx @@ -12,32 +12,27 @@ interface Props { strategy: StrategyWithFiat; className?: string; isExplorer?: boolean; - showStrategyRoi?: boolean; } export const StrategyBlock: FC = ({ strategy, className, isExplorer, - showStrategyRoi, }) => { return ( - +
diff --git a/src/components/strategies/overview/strategyBlock/StrategyBlockBudget.tsx b/src/components/strategies/overview/strategyBlock/StrategyBlockBudget.tsx index aad62ac73..3358125b5 100644 --- a/src/components/strategies/overview/strategyBlock/StrategyBlockBudget.tsx +++ b/src/components/strategies/overview/strategyBlock/StrategyBlockBudget.tsx @@ -1,16 +1,13 @@ import { FC } from 'react'; -import { Tooltip } from 'components/common/tooltip/Tooltip'; -import { ReactComponent as IconTooltip } from 'assets/icons/tooltip.svg'; import { cn, prettifyNumber } from 'utils/helpers'; import { useFiatCurrency } from 'hooks/useFiatCurrency'; import { StrategyWithFiat } from 'libs/queries'; interface Props { - fullWidth?: boolean; strategy: StrategyWithFiat; } -export const StrategyBlockBudget: FC = ({ strategy, fullWidth }) => { +export const StrategyBlockBudget: FC = ({ strategy }) => { const baseFiat = useFiatCurrency(strategy.base); const quoteFiat = useFiatCurrency(strategy.quote); const noFiatValue = !baseFiat.hasFiatValue() && !quoteFiat.hasFiatValue(); @@ -22,17 +19,13 @@ export const StrategyBlockBudget: FC = ({ strategy, fullWidth }) => { return (
- }> -

- Total Budget - -

-
+

+ Total Budget +

= ({ strategy, fullWidth }) => {

); }; - -const TooltipContent: FC = () => { - const currency = useFiatCurrency(); - const fiatSymbol = currency.selectedFiatCurrency; - return

Sum of the {fiatSymbol} value of the token budgets.

; -}; diff --git a/src/components/strategies/overview/strategyBlock/StrategyBlockBuySell.tsx b/src/components/strategies/overview/strategyBlock/StrategyBlockBuySell.tsx index 0bcaf2b91..c8c5cd505 100644 --- a/src/components/strategies/overview/strategyBlock/StrategyBlockBuySell.tsx +++ b/src/components/strategies/overview/strategyBlock/StrategyBlockBuySell.tsx @@ -23,8 +23,8 @@ export const StrategyBlockBuySell: FC<{ const fiatBudget = buy ? strategy.fiatBudget.quote : strategy.fiatBudget.base; const fiatBudgetValue = getFiatDisplayValue(fiatBudget, currency); - const buyTooltip = `This is the available amount of ${otherToken.symbol} tokens that you are willing to use in order to buy ${token.symbol}.`; - const sellTooltip = `This is the available amount of ${otherToken.symbol} tokens that you are willing to sell.`; + const buyTooltip = `${otherToken.symbol} tokens available to buy ${token.symbol}.`; + const sellTooltip = `${otherToken.symbol} tokens available for sale.`; const noCurrencyTooltip = `There is no ${currency} value for this token.`; return ( diff --git a/src/components/strategies/overview/strategyBlock/StrategyBlockHeader.tsx b/src/components/strategies/overview/strategyBlock/StrategyBlockHeader.tsx index 531a7dc25..93104ba33 100644 --- a/src/components/strategies/overview/strategyBlock/StrategyBlockHeader.tsx +++ b/src/components/strategies/overview/strategyBlock/StrategyBlockHeader.tsx @@ -21,7 +21,7 @@ interface Props { export const StrategyBlockHeader: FC = ({ strategy, isExplorer }) => { const { base, quote } = strategy; return ( -
+
= ({ strategy, showStrategyRoi }) => { +export const StrategyBlockInfo: FC = ({ strategy }) => { return ( - <> - {!!showStrategyRoi && } - - +
+ + +
); }; diff --git a/src/components/strategies/overview/strategyBlock/StrategyBlockRoi.tsx b/src/components/strategies/overview/strategyBlock/StrategyBlockRoi.tsx deleted file mode 100644 index 0525072ed..000000000 --- a/src/components/strategies/overview/strategyBlock/StrategyBlockRoi.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { FC } from 'react'; -import { Tooltip } from 'components/common/tooltip/Tooltip'; -import { NewTabLink, externalLinks } from 'libs/routing'; -import { ReactComponent as IconLink } from 'assets/icons/link.svg'; -import { ReactComponent as IconTooltip } from 'assets/icons/tooltip.svg'; -import { cn, formatNumberWithApproximation } from 'utils/helpers'; -import { Strategy } from 'libs/queries'; - -interface Props { - strategy: Strategy; -} - -export const StrategyBlockRoi: FC = ({ strategy }) => { - const roi = strategy.roi; - const roiFormatted = formatNumberWithApproximation(roi, { - isPercentage: true, - approximateBelow: 0.01, - }); - const color = roi.gte(0) ? 'text-success' : 'text-error'; - - return ( -
- }> -

- ROI - -

-
-

{roiFormatted.value}

-
- ); -}; - -const TooltipContent: FC<{}> = () => ( - <> - - Total percentage returns of the strategy from its creation as compared to - HODL.  - - - Learn how ROI is calculated. - - - -); diff --git a/src/components/strategies/overview/strategyBlock/StrategyBlockTradeCount.tsx b/src/components/strategies/overview/strategyBlock/StrategyBlockTradeCount.tsx new file mode 100644 index 000000000..0eb61ebfd --- /dev/null +++ b/src/components/strategies/overview/strategyBlock/StrategyBlockTradeCount.tsx @@ -0,0 +1,27 @@ +import { FC } from 'react'; +import { cn, prettifyNumber } from 'utils/helpers'; +import { StrategyWithFiat } from 'libs/queries'; + +interface Props { + strategy: StrategyWithFiat; +} + +export const StrategyBlockTradeCount: FC = ({ strategy }) => { + const count = prettifyNumber(strategy.tradeCount, { + abbreviate: true, + decimals: 0, + }); + return ( +
+

+ Trade Count +

+

{count}

+
+ ); +}; diff --git a/src/components/strategies/overview/utils.ts b/src/components/strategies/overview/utils.ts index 87e7b1b66..07602014d 100644 --- a/src/components/strategies/overview/utils.ts +++ b/src/components/strategies/overview/utils.ts @@ -38,22 +38,18 @@ const sortFn: Record = { b.quote.symbol.localeCompare(a.quote.symbol) ); }, - roiAsc: (a, b) => { - if (differentStatus(a, b)) return a.status === 'active' ? -1 : 1; - return a.roi.minus(b.roi).toNumber(); - }, - roiDesc: (a, b) => { - if (differentStatus(a, b)) return a.status === 'active' ? -1 : 1; - return a.roi.minus(b.roi).times(-1).toNumber(); - }, totalBudgetDesc: (a, b) => { if (differentStatus(a, b)) return a.status === 'active' ? -1 : 1; return a.fiatBudget.total.minus(b.fiatBudget.total).times(-1).toNumber(); }, + trades: (a, b) => { + if (differentStatus(a, b)) return a.status === 'active' ? -1 : 1; + return b.tradeCount - a.tradeCount; + }, }; export const getCompareFunctionBySortType = (sortType: StrategySort) => { - return sortFn[sortType] ?? sortFn['roiDesc']; + return sortFn[sortType] ?? sortFn['trades']; }; export const getSortAndFilterItems = () => { const sortItems = Object.entries(strategySort) diff --git a/src/config/celo/common.ts b/src/config/celo/common.ts index 67ded2bbc..32b9f8c1d 100644 --- a/src/config/celo/common.ts +++ b/src/config/celo/common.ts @@ -23,7 +23,6 @@ export const commonConfig: AppConfig = { blockedConnectors: ['Tailwind', 'Compass Wallet', 'Seif'], walletConnectProjectId: 'f9d8863ab6c03f2293d7d56d7c0c0853', isSimulatorEnabled: true, - showStrategyRoi: true, policiesLastUpdated: '31 Jul, 2024', network: { name: 'Celo Network', diff --git a/src/config/configSchema.ts b/src/config/configSchema.ts index 21762b3b6..529778896 100644 --- a/src/config/configSchema.ts +++ b/src/config/configSchema.ts @@ -18,7 +18,6 @@ export const AppConfigSchema = v.object({ blockedConnectors: v.optional(ConnectorSchema), walletConnectProjectId: v.string(), isSimulatorEnabled: v.boolean(), - showStrategyRoi: v.optional(v.boolean()), sentryDSN: v.optional(v.string()), policiesLastUpdated: v.optional(v.string()), network: v.object({ diff --git a/src/config/ethereum/common.ts b/src/config/ethereum/common.ts index bea2d1f7a..4a09950f4 100644 --- a/src/config/ethereum/common.ts +++ b/src/config/ethereum/common.ts @@ -36,7 +36,6 @@ export const commonConfig: AppConfig = { blockedConnectors: ['Tailwind', 'Compass Wallet', 'Seif'], walletConnectProjectId: 'f9d8863ab6c03f2293d7d56d7c0c0853', isSimulatorEnabled: true, - showStrategyRoi: true, policiesLastUpdated: '18 April, 2023', network: { name: 'Ethereum Network', diff --git a/src/hooks/useStrategies.tsx b/src/hooks/useStrategies.tsx index 1fe5ba1db..a3ee61a9c 100644 --- a/src/hooks/useStrategies.tsx +++ b/src/hooks/useStrategies.tsx @@ -22,6 +22,7 @@ import { useGetMultipleTokenPrices } from 'libs/queries/extApi/tokenPrice'; import { useStore } from 'store'; import { SafeDecimal } from 'libs/safedecimal'; import { useNavigate, useSearch } from 'libs/routing'; +import { useTradeCount } from 'libs/queries/extApi/tradeCount'; export type StrategyFilterOutput = ReturnType; @@ -110,13 +111,22 @@ export const useStrategiesWithFiat = ( const price = priceQueries[i].data?.[selectedFiatCurrency]; prices[address] = price; } + const tradeCountQuery = useTradeCount(); + const tradeCount: Record = {}; + for (const item of tradeCountQuery.data ?? []) { + tradeCount[item.strategyId] = item.tradeCount; + } return strategies.map((strategy) => { const basePrice = new SafeDecimal(prices[strategy.base.address] ?? 0); const quotePrice = new SafeDecimal(prices[strategy.quote.address] ?? 0); const base = basePrice.times(strategy.order1.balance); const quote = quotePrice.times(strategy.order0.balance); const total = base.plus(quote); - return { ...strategy, fiatBudget: { base, quote, total } }; + return { + ...strategy, + fiatBudget: { base, quote, total }, + tradeCount: tradeCount[strategy.id] ?? 0, + }; }); }; @@ -127,7 +137,7 @@ export const StrategyContext = createContext({ isPending: true, search: '', setSearch: () => undefined, - sort: 'roiDesc', + sort: 'trades', setSort: () => undefined, filter: 'all', setFilter: () => undefined, diff --git a/src/libs/queries/extApi/roi.ts b/src/libs/queries/extApi/roi.ts deleted file mode 100644 index e53326907..000000000 --- a/src/libs/queries/extApi/roi.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { useQuery } from '@tanstack/react-query'; -import { QueryKey } from 'libs/queries/queryKey'; -import { FIVE_MIN_IN_MS } from 'utils/time'; -import { carbonApi } from 'utils/carbonApi'; -import config from 'config'; - -export const useGetRoi = () => { - return useQuery({ - queryKey: QueryKey.roi(), - // Note: config.showStrategyRoi is not used in the 'enabled' option because - // useGetRoi.isFetched is used as an 'enabled' signal for other queries. - // If this flag is set to false, the query will finish fetching but not fetch from the API. - queryFn: async () => !!config.showStrategyRoi && carbonApi.getRoi(), - refetchInterval: FIVE_MIN_IN_MS, - staleTime: FIVE_MIN_IN_MS, - }); -}; diff --git a/src/libs/queries/extApi/tradeCount.ts b/src/libs/queries/extApi/tradeCount.ts new file mode 100644 index 000000000..2c44ee63e --- /dev/null +++ b/src/libs/queries/extApi/tradeCount.ts @@ -0,0 +1,17 @@ +import { useQuery } from '@tanstack/react-query'; +import { QueryKey } from 'libs/queries/queryKey'; +import { ONE_HOUR_IN_MS } from 'utils/time'; +import { carbonApi } from 'utils/carbonApi'; + +export interface TradeCount { + strategyId: string; + tradeCount: number; +} + +export const useTradeCount = () => { + return useQuery({ + queryKey: QueryKey.tradeCount(), + queryFn: carbonApi.getTradeCount, + staleTime: ONE_HOUR_IN_MS, + }); +}; diff --git a/src/libs/queries/index.ts b/src/libs/queries/index.ts index 61d15d1d7..46938e3e3 100644 --- a/src/libs/queries/index.ts +++ b/src/libs/queries/index.ts @@ -17,5 +17,4 @@ export { useGetOrderBook } from 'libs/queries/sdk/orderBook'; export type { OrderRow } from 'libs/queries/sdk/orderBook'; export { useGetMaxSourceAmountByPair } from 'libs/queries/sdk/maxSourceAmount'; export { useGetTokenPrice } from 'libs/queries/extApi/tokenPrice'; -export { useGetRoi } from 'libs/queries/extApi/roi'; export * from 'libs/queries/extApi/simulator'; diff --git a/src/libs/queries/queryKey.ts b/src/libs/queries/queryKey.ts index 437b9edc5..f6502e975 100644 --- a/src/libs/queries/queryKey.ts +++ b/src/libs/queries/queryKey.ts @@ -39,6 +39,7 @@ export namespace QueryKey { 'token-price-history', params, ]; + export const tradeCount = () => [...extAPI, 'trade-count']; export const strategy = (id: string) => [...sdk, 'strategy', id]; export const strategies = (user?: string) => [ diff --git a/src/libs/queries/sdk/strategy.ts b/src/libs/queries/sdk/strategy.ts index 1c28a533d..4d9b46191 100644 --- a/src/libs/queries/sdk/strategy.ts +++ b/src/libs/queries/sdk/strategy.ts @@ -19,8 +19,6 @@ import { import { MarginalPriceOptions } from '@bancor/carbon-sdk/strategy-management'; import { carbonSDK } from 'libs/sdk'; import { getLowestBits } from 'utils/helpers'; -import { RoiRow } from 'utils/carbonApi'; -import { useGetRoi } from 'libs/queries/extApi/roi'; import { useGetAddressFromEns } from 'libs/queries/chain/ens'; export type StrategyStatus = 'active' | 'noBudget' | 'paused' | 'inactive'; @@ -41,7 +39,6 @@ export interface Strategy { order1: Order; status: StrategyStatus; encoded: EncodedStrategyBNStr; - roi: SafeDecimal; } export interface StrategyWithFiat extends Strategy { @@ -50,6 +47,7 @@ export interface StrategyWithFiat extends Strategy { quote: SafeDecimal; base: SafeDecimal; }; + tradeCount: number; } interface StrategiesHelperProps { @@ -57,7 +55,6 @@ interface StrategiesHelperProps { getTokenById: (id: string) => Token | undefined; importToken: (token: Token) => void; Token: (address: string) => { read: TokenContract }; - roiData: RoiRow[]; } const buildStrategiesHelper = async ({ @@ -65,7 +62,6 @@ const buildStrategiesHelper = async ({ getTokenById, importToken, Token, - roiData, }: StrategiesHelperProps) => { const _getTknData = async (address: string) => { const data = await fetchTokenData(Token, address); @@ -123,8 +119,6 @@ const buildStrategiesHelper = async ({ marginalRate: s.sellPriceMarginal, }; - const roi = new SafeDecimal(roiData.find((r) => r.id === s.id)?.ROI || 0); - const strategy: Strategy = { id: s.id, idDisplay: getLowestBits(s.id), @@ -134,7 +128,6 @@ const buildStrategiesHelper = async ({ order1, status, encoded: s.encoded, - roi, }; return strategy; @@ -158,8 +151,6 @@ export const useGetUserStrategies = ({ user }: Props) => { const isValidAddress = utils.isAddress(address); const isZeroAddress = address === config.addresses.tokens.ZERO; - const roiQuery = useGetRoi(); - return useQuery({ queryKey: QueryKey.strategies(address), queryFn: async () => { @@ -171,14 +162,9 @@ export const useGetUserStrategies = ({ user }: Props) => { getTokenById, importToken, Token, - roiData: roiQuery.data || [], }); }, - enabled: - tokens.length > 0 && - isInitialized && - roiQuery.isFetched && - ensAddress.isFetched, + enabled: tokens.length > 0 && isInitialized && ensAddress.isFetched, staleTime: ONE_DAY_IN_MS, retry: false, }); @@ -188,7 +174,6 @@ export const useGetStrategy = (id: string) => { const { isInitialized } = useCarbonInit(); const { tokens, getTokenById, importToken } = useTokens(); const { Token } = useContract(); - const roiQuery = useGetRoi(); return useQuery({ queryKey: QueryKey.strategy(id), @@ -199,11 +184,10 @@ export const useGetStrategy = (id: string) => { getTokenById, importToken, Token, - roiData: roiQuery.data || [], }); return strategies[0]; }, - enabled: tokens.length > 0 && isInitialized && roiQuery.isFetched, + enabled: tokens.length > 0 && isInitialized, staleTime: ONE_DAY_IN_MS, retry: false, }); @@ -219,8 +203,6 @@ export const useGetPairStrategies = ({ token0, token1 }: PropsPair) => { const { tokens, getTokenById, importToken } = useTokens(); const { Token } = useContract(); - const roiQuery = useGetRoi(); - return useQuery({ queryKey: QueryKey.strategiesByPair(token0, token1), queryFn: async () => { @@ -231,10 +213,9 @@ export const useGetPairStrategies = ({ token0, token1 }: PropsPair) => { getTokenById, importToken, Token, - roiData: roiQuery.data || [], }); }, - enabled: tokens.length > 0 && isInitialized && roiQuery.isFetched, + enabled: tokens.length > 0 && isInitialized, staleTime: ONE_DAY_IN_MS, retry: false, }); diff --git a/src/libs/testing-library/utils/mock.ts b/src/libs/testing-library/utils/mock.ts index 3d6d5ebc9..898dc0324 100644 --- a/src/libs/testing-library/utils/mock.ts +++ b/src/libs/testing-library/utils/mock.ts @@ -3,7 +3,6 @@ import { HttpResponse, http, RequestHandler } from 'msw'; import { debugTokens } from '../../../../e2e/utils/types'; import tokenListsMock from '../../../../e2e/mocks/tokenLists.json'; import { Order, Strategy } from 'libs/queries'; -import { SafeDecimal } from 'libs/safedecimal'; import { TokenPriceHistoryResult } from 'libs/queries/extApi/tokenPrice'; /** @@ -153,7 +152,6 @@ export const mockStrategy = (params: MockStrategyParams): Strategy => ({ quote: tokenList[params.quote], status: 'active', encoded: {} as any, - roi: new SafeDecimal('1'), order0: params.order0, order1: params.order1, }); diff --git a/src/pages/strategy/index.tsx b/src/pages/strategy/index.tsx index d14b352f3..1c7bdf952 100644 --- a/src/pages/strategy/index.tsx +++ b/src/pages/strategy/index.tsx @@ -100,7 +100,6 @@ export const StrategyPage = () => { } const base = strategy.base; const quote = strategy.quote; - const showStrategyRoi = config.showStrategyRoi; const isNativeChart = config.ui.priceChart === 'native'; return ( @@ -122,15 +121,12 @@ export const StrategyPage = () => { />
-
-

Strategy Info

- +
+

Strategy Info

+
diff --git a/src/services/localeStorage/index.ts b/src/services/localeStorage/index.ts index 6582aea53..a71b662fa 100644 --- a/src/services/localeStorage/index.ts +++ b/src/services/localeStorage/index.ts @@ -5,8 +5,6 @@ import { TradePair } from 'libs/modals/modals/ModalTradeTokenList'; import { TradePairCategory } from 'libs/modals/modals/ModalTradeTokenList/ModalTradeTokenListContent'; import { ChooseTokenCategory } from 'libs/modals/modals/ModalTokenList/ModalTokenListContent'; import { - EnumStrategyFilter, - EnumStrategySort, StrategyFilter, StrategySort, } from 'components/strategies/overview/StrategyFilterSort'; @@ -40,8 +38,8 @@ interface LocalStorageSchema { tradeMaxOrders: string; chooseTokenCategory: ChooseTokenCategory; carbonControllerAddress: string; - strategyOverviewFilter: StrategyFilter | EnumStrategyFilter; - strategyOverviewSort: StrategySort | EnumStrategySort; + strategyOverviewFilter: StrategyFilter; + strategyOverviewSort: StrategySort; voucherContractAddress: string; tokenListCache: { tokens: Token[]; timestamp: number }; sdkCompressedCacheData: string; @@ -55,6 +53,20 @@ interface LocalStorageSchema { configOverride: Partial; } +enum EnumStrategySort { + Recent, + Old, + PairAscending, + PairDescending, + RoiAscending, + RoiDescending, +} +enum EnumStrategyFilter { + All, + Active, + Inactive, +} + // ************************** / // LOCAL STORAGE MIGRATION AND CLEAN_UP // Order matters! The migrations are performed in top to bottom order. In most cases, new migrations should be added to the bottom of the list @@ -85,6 +97,27 @@ const migrations: Migration[] = [ migrateAndRemoveItem({ prevFormattedKey, nextFormattedKey }); }, }, + { + migrate: (prevFormattedKey) => { + const prefix = `carbon-${NETWORK}-v1.1-`; + if (prevFormattedKey === `${prefix}strategyOverviewSort`) { + const current = lsService.getItem('strategyOverviewSort') as any; + if (current in EnumStrategySort) removeItem({ prevFormattedKey }); + if (['roiAsc', 'roiDesc'].includes(current)) + removeItem({ prevFormattedKey }); + } + if (prevFormattedKey === `${prefix}strategyOverviewFilter`) { + const current = lsService.getItem('strategyOverviewFilter') as any; + if (current in EnumStrategyFilter) removeItem({ prevFormattedKey }); + } + const isMatch = prevFormattedKey.startsWith(prefix); + if (!isMatch) return; + const key = prevFormattedKey.slice(prefix.length); + if (!key) return; + const nextFormattedKey = ['carbon', NETWORK, 'v1.2', key].join('-'); + migrateAndRemoveItem({ prevFormattedKey, nextFormattedKey }); + }, + }, ]; export const lsService = new ManagedLocalStorage( diff --git a/src/utils/carbonApi.ts b/src/utils/carbonApi.ts index 2e25bfa23..e5ca2cbf9 100644 --- a/src/utils/carbonApi.ts +++ b/src/utils/carbonApi.ts @@ -13,6 +13,7 @@ import { ServerActivityMeta, } from 'libs/queries/extApi/activity'; import { lsService } from 'services/localeStorage'; +import { TradeCount } from 'libs/queries/extApi/tradeCount'; // Only ETH is supported as network currency by the API const NETWORK_CURRENCY = @@ -36,11 +37,6 @@ export type FiatPriceDict = { [k in FiatSymbol]: number; }; -export type RoiRow = { - ROI: string; - id: string; -}; - const get = async ( endpoint: string, params: Object = {}, @@ -83,9 +79,6 @@ const carbonApi = { ): Promise => { return get('history/prices', params); }, - getRoi: async (): Promise => { - return get('roi'); - }, getSimulator: async ( params: SimulatorAPIParams ): Promise => { @@ -100,6 +93,7 @@ const carbonApi = { getActivityMeta: async (params: QueryActivityParams) => { return get('activity/meta', params); }, + getTradeCount: () => get('analytics/trades_count'), }; export { carbonApi }; diff --git a/src/utils/constants.ts b/src/utils/constants.ts index c9c7e6a75..0c98fcb4f 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -1,3 +1,3 @@ export const APP_ID = 'carbon'; -export const APP_VERSION = 'v1.1'; +export const APP_VERSION = 'v1.2'; export const NETWORK = import.meta.env.VITE_NETWORK || 'ethereum'; diff --git a/src/utils/helpers/number.ts b/src/utils/helpers/number.ts index 0660c2a7b..56a7265ed 100644 --- a/src/utils/helpers/number.ts +++ b/src/utils/helpers/number.ts @@ -147,18 +147,16 @@ export function prettifyNumber( // Force value to be positive if (num.lte(0)) { - return Intl.NumberFormat(locale, { - ...intlOptions, - minimumFractionDigits: 2, - maximumFractionDigits: 2, - }).format(0); + intlOptions.minimumFractionDigits = Math.min(options.decimals ?? 2, 2); + intlOptions.maximumFractionDigits = Math.min(options.decimals ?? 2, 2); + return Intl.NumberFormat(locale, intlOptions).format(0); } if (num.gte(1)) { - intlOptions.minimumFractionDigits = 2; + intlOptions.minimumFractionDigits = Math.min(options.decimals ?? 2, 2); intlOptions.maximumFractionDigits = Math.max(options.decimals ?? 2, 2); } else if (num.gte(0.001)) { - intlOptions.minimumFractionDigits = 2; + intlOptions.minimumFractionDigits = Math.min(options.decimals ?? 2, 2); intlOptions.maximumFractionDigits = Math.max(options.decimals ?? 6, 2); } else { intlOptions.maximumSignificantDigits = 5;