Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ import {
getMarketTokenDisplayPriceChange24h,
getMarketTokenDisplayVolume24h,
getTokenKey,
mapMarketPerpsTokenToDisplay,
} from './utils';

import type { IFavoriteTokenDisplay } from './types';
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ function renderPopularTradingTokenIdentity(
stock={record.stock}
maxLeverage={record.maxLeverage}
perpsSubtitle={record.perpsSubtitle}
perpsDexLabel={record.perpsDexLabel}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ interface IFavoriteTokenDisplay {
perpsCoin?: string;
maxLeverage?: number;
perpsSubtitle?: string;
perpsDexLabel?: string;
communityRecognized?: boolean;
stock?: IMarketStockInfo;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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 = {
Expand Down Expand Up @@ -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();
});
});
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { parseDexCoin } from '@onekeyhq/shared/src/utils/perpsUtils';
import type {
IMarketPerpsTokenFromServer,
IMarketTokenListItem,
Expand Down Expand Up @@ -96,6 +97,8 @@ function mapMarketPerpsTokenToDisplay({
token: IMarketPerpsTokenFromServer;
subtitle?: string;
}): IFavoriteTokenDisplay {
const { dexLabel } = parseDexCoin(token.name);

return {
chainId: '',
contractAddress: '',
Expand All @@ -109,6 +112,7 @@ function mapMarketPerpsTokenToDisplay({
volume24h: parseMarketValue(token.volume24h) ?? 0,
perpsCoin: token.name,
perpsSubtitle: subtitle,
perpsDexLabel: dexLabel,
maxLeverage: token.maxLeverage,
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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.
*/
Expand All @@ -116,6 +121,7 @@ const BasicTokenIdentityItem: FC<ITokenIdentityItemProps> = ({
stock,
maxLeverage,
perpsSubtitle,
perpsDexLabel,
showStockSubtitle = true,
}) => {
const { gtMd } = useMedia();
Expand Down Expand Up @@ -209,6 +215,7 @@ const BasicTokenIdentityItem: FC<ITokenIdentityItemProps> = ({
<XStack alignItems="center" gap="$1">
{symbolElement}
{maxLeverage ? <LeverageBadge leverage={maxLeverage} /> : null}
<PerpDexBadge dexLabel={perpsDexLabel} />
{gtMd ? (
<>
<StockSourceLogo stock={stock} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ function PerpBadgesRow() {
return (
<XStack alignItems="center" gap="$1.5" onLayout={handleLayout}>
<Badge radius="$1" bg="$bgSubdued" px="$1" py={0}>
<SizableText color="$textSubdued" fontSize={10}>
<SizableText color="$textSubdued" fontSize={10} lineHeight={16}>
{isSpot
? intl.formatMessage({
id: ETranslations.dexmarket_spot,
Expand Down Expand Up @@ -237,6 +237,7 @@ function PerpBadgesRow() {
<SizableText
color="$textInfo"
fontSize={10}
lineHeight={16}
numberOfLines={1}
ellipsizeMode="tail"
flexShrink={1}
Expand All @@ -256,7 +257,7 @@ function PerpBadgesRow() {
) : null}
{!isSpot && builderFeeRate === 0 ? (
<Badge radius="$1" bg="$bgSuccess" px="$0.5" py={0}>
<SizableText color="$textSuccess" fontSize={10}>
<SizableText color="$textSuccess" fontSize={10} lineHeight={16}>
{intl.formatMessage({
id: ETranslations.perp_0_fee,
})}
Expand Down
Loading