From 0c11316b0e48cb8ab512ed8ead1ca7f4a08f019c Mon Sep 17 00:00:00 2001 From: Kahn <0xkahnchan@gmail.com> Date: Mon, 17 Aug 2026 15:29:28 +0800 Subject: [PATCH] fix: align perp dex source labels(OK-59905) --- .../PopularTrading/PopularTrading.tsx | 20 ++------ .../PopularTrading/metricColumns.tsx | 1 + .../Home/components/PopularTrading/types.ts | 1 + .../components/PopularTrading/utils.test.ts | 46 ++++++++++++++++++- .../Home/components/PopularTrading/utils.ts | 4 ++ .../TokenIdentityItem/TokenIdentityItem.tsx | 7 +++ .../TickerBar/PerpTickerBarMobile.tsx | 5 +- 7 files changed, 66 insertions(+), 18 deletions(-) diff --git a/packages/kit/src/views/Home/components/PopularTrading/PopularTrading.tsx b/packages/kit/src/views/Home/components/PopularTrading/PopularTrading.tsx index acfb340ebd88..fdf08b250e87 100644 --- a/packages/kit/src/views/Home/components/PopularTrading/PopularTrading.tsx +++ b/packages/kit/src/views/Home/components/PopularTrading/PopularTrading.tsx @@ -73,6 +73,7 @@ import { getMarketTokenDisplayPriceChange24h, getMarketTokenDisplayVolume24h, getTokenKey, + mapMarketPerpsTokenToDisplay, } from './utils'; import type { IFavoriteTokenDisplay } from './types'; @@ -560,21 +561,10 @@ function PopularTrading({ tableLayout }: { tableLayout?: boolean }) { // Perps item const perpsToken = perpsTokenMap.get(targetItem.perpsCoin); if (!perpsToken) return null; - return { - chainId: '', - contractAddress: '', - isNative: false, - symbol: perpsToken.displayName, - name: perpsToken.displayName, - logoUrl: perpsToken.tokenImageUrl ?? '', - price: parseFloat(perpsToken.markPrice ?? '0'), - priceChange24h: perpsToken.change24hPercent ?? 0, - marketCap: 0, - perpsCoin: targetItem.perpsCoin, - maxLeverage: perpsToken.maxLeverage, - perpsSubtitle: getTokenSubtitle(perpsToken.name, perpsAliases), - volume24h: parseFloat(perpsToken.volume24h ?? '0'), - }; + return mapMarketPerpsTokenToDisplay({ + token: perpsToken, + subtitle: getTokenSubtitle(perpsToken.name, perpsAliases), + }); } // Spot item diff --git a/packages/kit/src/views/Home/components/PopularTrading/metricColumns.tsx b/packages/kit/src/views/Home/components/PopularTrading/metricColumns.tsx index 3844dfbc041c..f221a0ab7df7 100644 --- a/packages/kit/src/views/Home/components/PopularTrading/metricColumns.tsx +++ b/packages/kit/src/views/Home/components/PopularTrading/metricColumns.tsx @@ -47,6 +47,7 @@ function renderPopularTradingTokenIdentity( stock={record.stock} maxLeverage={record.maxLeverage} perpsSubtitle={record.perpsSubtitle} + perpsDexLabel={record.perpsDexLabel} /> ); } diff --git a/packages/kit/src/views/Home/components/PopularTrading/types.ts b/packages/kit/src/views/Home/components/PopularTrading/types.ts index 6e39a55b3849..20301d4ed1de 100644 --- a/packages/kit/src/views/Home/components/PopularTrading/types.ts +++ b/packages/kit/src/views/Home/components/PopularTrading/types.ts @@ -15,6 +15,7 @@ interface IFavoriteTokenDisplay { perpsCoin?: string; maxLeverage?: number; perpsSubtitle?: string; + perpsDexLabel?: string; communityRecognized?: boolean; stock?: IMarketStockInfo; } diff --git a/packages/kit/src/views/Home/components/PopularTrading/utils.test.ts b/packages/kit/src/views/Home/components/PopularTrading/utils.test.ts index b9bec9465caa..58494a8a60c7 100644 --- a/packages/kit/src/views/Home/components/PopularTrading/utils.test.ts +++ b/packages/kit/src/views/Home/components/PopularTrading/utils.test.ts @@ -1,12 +1,31 @@ -import type { IMarketTokenListItem } from '@onekeyhq/shared/types/marketV2'; +import type { + IMarketPerpsTokenFromServer, + IMarketTokenListItem, +} from '@onekeyhq/shared/types/marketV2'; import { getMarketTokenDisplayPrice, getMarketTokenDisplayPriceChange24h, getMarketTokenDisplayVolume24h, + mapMarketPerpsTokenToDisplay, mapMarketTokenToDisplay, } from './utils'; +function buildServerPerpsToken(name: string): IMarketPerpsTokenFromServer { + return { + name, + displayName: 'UNITREE', + maxLeverage: 10, + tokenImageUrl: 'unitree.png', + markPrice: '90.38', + prevDayPrice: '72.58', + change24hPercent: 24.52, + volume24h: '10940000', + openInterest: '6660000', + fundingRate: '0.000008', + }; +} + describe('PopularTrading market token display utils', () => { test('normalizes placeholder market values instead of returning NaN', () => { const item: IMarketTokenListItem = { @@ -34,4 +53,29 @@ describe('PopularTrading market token display utils', () => { expect(displayToken?.logoUrls).toEqual(item.logoUrls); expect(displayToken?.communityRecognized).toBe(true); }); + + test.each([ + ['xyz:UNITREE', 'xyz'], + ['para:UNITREE', 'para'], + ])('preserves the %s perps DEX source label', (name, dexLabel) => { + expect( + mapMarketPerpsTokenToDisplay({ + token: buildServerPerpsToken(name), + subtitle: 'Unitree Robotics', + }), + ).toMatchObject({ + symbol: 'UNITREE', + perpsCoin: name, + perpsSubtitle: 'Unitree Robotics', + perpsDexLabel: dexLabel, + }); + }); + + test('does not add a DEX source label to main DEX perps', () => { + expect( + mapMarketPerpsTokenToDisplay({ + token: buildServerPerpsToken('BTC'), + }).perpsDexLabel, + ).toBeUndefined(); + }); }); diff --git a/packages/kit/src/views/Home/components/PopularTrading/utils.ts b/packages/kit/src/views/Home/components/PopularTrading/utils.ts index 3a58c6437948..701d34f8090f 100644 --- a/packages/kit/src/views/Home/components/PopularTrading/utils.ts +++ b/packages/kit/src/views/Home/components/PopularTrading/utils.ts @@ -1,3 +1,4 @@ +import { parseDexCoin } from '@onekeyhq/shared/src/utils/perpsUtils'; import type { IMarketPerpsTokenFromServer, IMarketTokenListItem, @@ -96,6 +97,8 @@ function mapMarketPerpsTokenToDisplay({ token: IMarketPerpsTokenFromServer; subtitle?: string; }): IFavoriteTokenDisplay { + const { dexLabel } = parseDexCoin(token.name); + return { chainId: '', contractAddress: '', @@ -109,6 +112,7 @@ function mapMarketPerpsTokenToDisplay({ volume24h: parseMarketValue(token.volume24h) ?? 0, perpsCoin: token.name, perpsSubtitle: subtitle, + perpsDexLabel: dexLabel, maxLeverage: token.maxLeverage, }; } diff --git a/packages/kit/src/views/Market/MarketHomeV2/components/MarketTokenList/components/TokenIdentityItem/TokenIdentityItem.tsx b/packages/kit/src/views/Market/MarketHomeV2/components/MarketTokenList/components/TokenIdentityItem/TokenIdentityItem.tsx index 174a1333f0bb..f502609fc49d 100644 --- a/packages/kit/src/views/Market/MarketHomeV2/components/MarketTokenList/components/TokenIdentityItem/TokenIdentityItem.tsx +++ b/packages/kit/src/views/Market/MarketHomeV2/components/MarketTokenList/components/TokenIdentityItem/TokenIdentityItem.tsx @@ -17,6 +17,7 @@ import { useNetworkLogoUri } from '@onekeyhq/kit/src/hooks/useNetworkLogoUri'; import { CommunityRecognizedBadge } from '@onekeyhq/kit/src/views/Market/components/CommunityRecognizedBadge'; import { LeverageBadge, + PerpDexBadge, StockSourceLogo, SubtitleText, } from '@onekeyhq/kit/src/views/Market/components/PerpsBadges'; @@ -94,6 +95,10 @@ interface ITokenIdentityItemProps { * Subtitle for perpetual tokens (e.g. Chinese name tag). */ perpsSubtitle?: string; + /** + * HIP-3 DEX source label for perpetual tokens (e.g. "xyz", "para"). + */ + perpsDexLabel?: string; /** * Whether to show the stock subtitle. Defaults to true. */ @@ -116,6 +121,7 @@ const BasicTokenIdentityItem: FC = ({ stock, maxLeverage, perpsSubtitle, + perpsDexLabel, showStockSubtitle = true, }) => { const { gtMd } = useMedia(); @@ -209,6 +215,7 @@ const BasicTokenIdentityItem: FC = ({ {symbolElement} {maxLeverage ? : null} + {gtMd ? ( <> diff --git a/packages/kit/src/views/Perp/components/TickerBar/PerpTickerBarMobile.tsx b/packages/kit/src/views/Perp/components/TickerBar/PerpTickerBarMobile.tsx index 111491d1ff1b..081d393f735c 100644 --- a/packages/kit/src/views/Perp/components/TickerBar/PerpTickerBarMobile.tsx +++ b/packages/kit/src/views/Perp/components/TickerBar/PerpTickerBarMobile.tsx @@ -204,7 +204,7 @@ function PerpBadgesRow() { return ( - + {isSpot ? intl.formatMessage({ id: ETranslations.dexmarket_spot, @@ -237,6 +237,7 @@ function PerpBadgesRow() { - + {intl.formatMessage({ id: ETranslations.perp_0_fee, })}