Skip to content

Commit e4a68bb

Browse files
committed
fix: fixed sbtc page
1 parent 67e9a23 commit e4a68bb

File tree

25 files changed

+367
-86
lines changed

25 files changed

+367
-86
lines changed

src/__tests__/pages/token/[tokenId].test.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ describe('getTokenInfo', () => {
6868
name: 'NAME',
6969
symbol: 'SYMBOL',
7070
totalSupply: null,
71+
circulatingSupply: null,
7172
},
7273
extended: {
7374
categories: [],

src/app/_components/PageTitle.tsx

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,7 @@ import { Heading, HeadingProps } from '../../ui/Heading';
66

77
export function PageTitle({ children, ...props }: { children: ReactNode } & HeadingProps) {
88
return (
9-
<Heading
10-
as="h1"
11-
fontWeight={'medium'}
12-
fontSize="4xl"
13-
mt={20}
14-
mb="0"
15-
color={'slate.50'}
16-
{...props}
17-
>
9+
<Heading as="h1" fontWeight={'medium'} fontSize="4xl" mb={0} color={'slate.50'} {...props}>
1810
{children}
1911
</Heading>
2012
);

src/app/_components/PageWrapper.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export function PageWrapper({
8888
minHeight={'100vh'}
8989
>
9090
<NavBar tokenPrice={tokenPrice} />
91-
<Flex direction={'column'} mt={10} mb={8} gap={7}>
91+
<Flex direction={'column'} mt={30} mb={8} gap={7}>
9292
{children}
9393
</Flex>
9494
<Footer />

src/app/_components/Stats/StackingCycle.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { FC, ReactNode } from 'react';
2-
import * as React from 'react';
32

4-
import { numberToString } from '../../../common/utils/utils';
3+
import { abbreviateNumber } from '../../../common/utils/utils';
54
import { Box } from '../../../ui/Box';
65
import { GridProps } from '../../../ui/Grid';
76
import { StatSection } from './StatSection';
@@ -16,7 +15,7 @@ export const StackingCycle: FC<
1615
return (
1716
<StatSection
1817
title={title}
19-
bodyMainText={stackedSTX ? numberToString(stackedSTX) : '0'}
18+
bodyMainText={stackedSTX ? abbreviateNumber(stackedSTX) : '0'}
2019
bodySecondaryText={<Box ml={1}>STX stacked</Box>}
2120
caption={caption}
2221
{...rest}

src/app/_components/Stats/StxSupply/index.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Info } from '@phosphor-icons/react';
44

55
import { useGlobalContext } from '../../../../common/context/useGlobalContext';
66
import { useSuspenseStxSupply } from '../../../../common/queries/useStxSupply';
7-
import { numberToString } from '../../../../common/utils/utils';
7+
import { abbreviateNumber } from '../../../../common/utils/utils';
88
import { Box } from '../../../../ui/Box';
99
import { Flex } from '../../../../ui/Flex';
1010
import { GridProps } from '../../../../ui/Grid';
@@ -18,11 +18,11 @@ function StxSupplyBase(props: GridProps) {
1818
data: { total_stx, unlocked_stx, total_stx_year_2050 },
1919
} = useSuspenseStxSupply();
2020
const circulatingSupplyNumber = unlocked_stx ? Number(unlocked_stx) : 0;
21-
const circulatingSupplyFormatted = numberToString(circulatingSupplyNumber);
21+
const circulatingSupplyFormatted = abbreviateNumber(circulatingSupplyNumber);
2222
const totalSupplyNumber = total_stx ? Number(total_stx) : 0;
23-
const totalSupplyFormatted = numberToString(totalSupplyNumber);
23+
const totalSupplyFormatted = abbreviateNumber(totalSupplyNumber);
2424
const maxSupplyBy2050Number = total_stx_year_2050 ? Number(total_stx_year_2050) : 0;
25-
const maxSupplyBy2050Formatted = numberToString(maxSupplyBy2050Number);
25+
const maxSupplyBy2050Formatted = abbreviateNumber(maxSupplyBy2050Number);
2626
const percentageUnlocked = ((circulatingSupplyNumber / totalSupplyNumber) * 100).toFixed(1);
2727
const isMainnet = useGlobalContext().activeNetwork.mode === 'mainnet';
2828

src/app/signer/[signerKey]/PageClient.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
'use client';
22

3-
import { useBreakpointValue } from '@/ui/hooks/useBreakpointValue';
43
import { useParams } from 'next/navigation';
54
import { ReactNode } from 'react';
65

76
import { Grid } from '../../../ui/Grid';
87
import { Stack } from '../../../ui/Stack';
8+
import { useBreakpointValue } from '../../../ui/hooks/useBreakpointValue';
99
import { PageTitle } from '../../_components/PageTitle';
1010
import { AssociatedAddressesTable } from './AssociatedAddressesTable';
1111
import { SignerStats } from './SignerStats';

src/app/signer/[signerKey]/StackingHistoryTable.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
'use client';
22

3-
import { formatSignerLatency } from '@/app/signers/SignersTable';
43
import { useColorModeValue } from '@chakra-ui/react';
54
import styled from '@emotion/styled';
65
import { ReactNode, Suspense, useCallback, useMemo, useState } from 'react';
76

7+
import { formatSignerLatency } from '../../../app/signers/SignersTable';
88
import { StackingHistoryInfo, useSignerStackingHistory } from '../../../app/signers/data/UseSigner';
99
import { ListFooter } from '../../../common/components/ListFooter';
1010
import { Section } from '../../../common/components/Section';

src/app/signers/StxStackedCard.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Suspense } from 'react';
22

33
import { Card } from '../../common/components/Card';
44
import { TokenPrice } from '../../common/types/tokenPrice';
5-
import { numberToString } from '../../common/utils/utils';
5+
import { abbreviateNumber } from '../../common/utils/utils';
66
import { Text } from '../../ui/Text';
77
import { ExplorerErrorBoundary } from '../_components/ErrorBoundary';
88
import { StatCardBase } from './StatsCardBase';
@@ -31,7 +31,7 @@ export function StxStackedCardBase({ tokenPrice }: { tokenPrice: TokenPrice }) {
3131
return (
3232
<StatCardBase
3333
statTitle="STX stacked"
34-
statValue={numberToString(stackedSupply)}
34+
statValue={abbreviateNumber(stackedSupply)}
3535
moreInfo={
3636
moreInfo ? (
3737
<Text

src/app/signers/TotalStackedCard.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Suspense } from 'react';
22

33
import { Card } from '../../common/components/Card';
4-
import { numberToString } from '../../common/utils/utils';
4+
import { abbreviateNumber } from '../../common/utils/utils';
55
import { ExplorerErrorBoundary } from '../_components/ErrorBoundary';
66
import { StatCardBase } from './StatsCardBase';
77
import { useStxSupply } from './data/useStxSupply';
@@ -18,7 +18,7 @@ export function TotalStackedCardBase() {
1818
<StatCardBase
1919
statTitle="Total stacked"
2020
statValue={stxStackedPercentageFormatted}
21-
moreInfo={`of ${numberToString(circulatingSupply)} circulating supply`}
21+
moreInfo={`of ${abbreviateNumber(circulatingSupply)} circulating supply`}
2222
/>
2323
);
2424
}

src/app/token/[tokenId]/PageClient.tsx

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
'use client';
22

3+
import { getHasSBTCInName, getIsSBTC } from '@/app/tokens/utils';
4+
import { Box, Icon, Image, Link, Stack, Text } from '@chakra-ui/react';
5+
import { SealCheck, Warning } from '@phosphor-icons/react';
6+
37
import { Sip10Disclaimer } from '../../../common/components/Sip10Disclaimer';
48
import { Flex } from '../../../ui/Flex';
59
import { Tag } from '../../../ui/Tag';
610
import { TagLabel } from '../../../ui/TagLabel';
7-
import { PageTitle, PageTitleWithTags } from '../../_components/PageTitle';
11+
import { PageTitle } from '../../_components/PageTitle';
812
import { Tabs } from './Tabs';
913
import { TokenInfo } from './TokenInfo';
1014
import { TokenInfoProps } from './types';
@@ -17,29 +21,77 @@ export default function PageClient({
1721
tokenInfo: TokenInfoProps;
1822
}) {
1923
if (!tokenInfo.basic) throw new Error('Could not find token info');
20-
const { name, symbol } = tokenInfo.basic;
24+
const { name, symbol, imageUri } = tokenInfo.basic;
2125
const categories = tokenInfo.extended?.categories || [];
22-
26+
const hasSBTCInName = getHasSBTCInName(name ?? '', symbol ?? '');
27+
const isSBTC = getIsSBTC(tokenId);
2328
return (
2429
<>
25-
<Flex justifyContent={'space-between'} alignItems={'flex-end'}>
26-
{!!categories.length ? (
27-
<PageTitleWithTags
28-
tags={categories.map(category => (
30+
<Stack gap={2}>
31+
{!!categories.length && (
32+
<Flex gap={2}>
33+
{categories.map(category => (
2934
<Tag key={category}>
3035
<TagLabel>{category}</TagLabel>
3136
</Tag>
3237
))}
33-
>
34-
{name} ({symbol})
35-
</PageTitleWithTags>
36-
) : (
38+
</Flex>
39+
)}
40+
<Flex alignItems={'center'} gap={2} flexWrap="wrap">
41+
<Image src={imageUri} alt={name ?? ''} h={10} w={10} />
3742
<PageTitle>
3843
{name} ({symbol})
3944
</PageTitle>
40-
)}
41-
{/*{!!tokenInfo.extended?.links && <LinksMenu links={tokenInfo.extended.links} />}*/}
42-
</Flex>
45+
{isSBTC && (
46+
<Tag
47+
color="green.600"
48+
bg="green.300"
49+
border="1px solid var(--stacks-colors-green-500)"
50+
pt={1}
51+
py={2.5}
52+
>
53+
<Flex alignItems={'center'} gap={1}>
54+
<Icon as={SealCheck} h={4} w={4} color="green.600" />
55+
<Text fontSize={'md'}>Verified</Text>
56+
</Flex>
57+
</Tag>
58+
)}
59+
{hasSBTCInName && !isSBTC && (
60+
<Tag
61+
color="red.600"
62+
bg="red.200"
63+
border="1px solid var(--stacks-colors-red-500)"
64+
pt={1}
65+
py={2.5}
66+
>
67+
<Flex alignItems={'center'} gap={1}>
68+
<Icon as={Warning} h={4} w={4} color="red.600" />
69+
<Text fontSize={'md'}>Unverified</Text>
70+
</Flex>
71+
</Tag>
72+
)}
73+
</Flex>
74+
</Stack>
75+
{hasSBTCInName && !isSBTC && (
76+
<Box borderRadius="xl" bg="red.200" p={4}>
77+
<Flex gap={2}>
78+
<Icon as={Warning} h={4} w={4} color="red.600" />
79+
<Text fontSize="sm" display="inline">
80+
<Text as="span" fontWeight="bold">
81+
Warning:&nbsp;
82+
</Text>
83+
This is not{' '}
84+
<Link
85+
href="https://explorer.hiro.so/token/SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token?chain=mainnet"
86+
isExternal
87+
>
88+
the official sBTC token
89+
</Link>{' '}
90+
and may be a scam. Engaging with unverified tokens could result in loss of funds.
91+
</Text>
92+
</Flex>
93+
</Box>
94+
)}
4395
<TokenInfo tokenInfo={tokenInfo} txId={tokenId} />
4496
<Tabs
4597
tokenId={tokenId}

src/app/token/[tokenId]/Tabs/holders/Holders.tsx

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { useColorModeValue } from '@chakra-ui/react';
22
import styled from '@emotion/styled';
3-
import { ReactNode, Suspense } from 'react';
3+
import { ReactNode, Suspense, useMemo } from 'react';
44

55
import { AddressLink } from '../../../../../common/components/ExplorerLinks';
66
import { ListFooter } from '../../../../../common/components/ListFooter';
77
import { Section } from '../../../../../common/components/Section';
88
import { useSuspenseInfiniteQueryResult } from '../../../../../common/hooks/useInfiniteQueryResult';
99
import { useContractById } from '../../../../../common/queries/useContractById';
10-
import { truncateMiddle } from '../../../../../common/utils/utils';
10+
import { useFtMetadata } from '../../../../../common/queries/useFtMetadata';
11+
import { ftDecimals, truncateMiddle } from '../../../../../common/utils/utils';
1112
import { Flex } from '../../../../../ui/Flex';
1213
import { Table } from '../../../../../ui/Table';
1314
import { Tbody } from '../../../../../ui/Tbody';
@@ -98,11 +99,12 @@ function generateHolderRowInfo(
9899
address: string,
99100
balance: number,
100101
totalSupply: number,
101-
tokenPrice: number | null | undefined
102+
tokenPrice: number | null | undefined,
103+
decimals: number | undefined
102104
): HolderRowInfo {
103105
return {
104106
address,
105-
balance: balance.toLocaleString(),
107+
balance: ftDecimals(balance, decimals || 0).toLocaleString(),
106108
percentage: `${((balance / totalSupply) * 100).toFixed(2).toLocaleString()}%`,
107109
value:
108110
typeof tokenPrice === 'number' ? (balance * tokenPrice).toFixed(2).toLocaleString() : 'N/A',
@@ -199,6 +201,9 @@ const HoldersTableBase = ({
199201
const { isFetchingNextPage, fetchNextPage, hasNextPage } = response;
200202
const { total: totalNumHolders, total_supply: totalSupply } = response.data.pages[0];
201203
const holderBalances = useSuspenseInfiniteQueryResult<HolderInfo, HolderResponseType>(response);
204+
const filteredHolderBalances = holderBalances.filter(holder => holder.balance !== '0');
205+
const { data: tokenMetadata } = useFtMetadata(contract?.contract_id);
206+
const decimals = useMemo(() => tokenMetadata?.decimals, [tokenMetadata]);
202207

203208
if (!holderBalances || !totalNumHolders || !totalSupply) {
204209
throw new Error('Holders data is not available');
@@ -209,7 +214,7 @@ const HoldersTableBase = ({
209214
<HoldersTableLayout
210215
numHolders={<Text fontWeight="medium">{totalNumHolders.toLocaleString()} Holders</Text>}
211216
holdersTableHeaders={<HoldersTableHeaders hasPrice={!!tokenPrice} />}
212-
holdersTableRows={holderBalances.map((holder, i) => {
217+
holdersTableRows={filteredHolderBalances.map((holder, i) => {
213218
const { address, balance } = holder;
214219
return (
215220
<HolderTableRow
@@ -219,7 +224,8 @@ const HoldersTableBase = ({
219224
address,
220225
parseInt(balance),
221226
parseInt(totalSupply),
222-
tokenPrice
227+
tokenPrice,
228+
decimals
223229
)}
224230
isFirst={i === 0}
225231
isLast={i === holderBalances.length - 1}

src/app/token/[tokenId]/TokenInfo/MarketCap.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { FC } from 'react';
22

3-
import { numberToString } from '../../../../common/utils/utils';
3+
import { abbreviateNumber } from '../../../../common/utils/utils';
44
import { Flex } from '../../../../ui/Flex';
55
import { GridProps } from '../../../../ui/Grid';
66
import { StatSection } from '../../../_components/Stats/StatSection';
@@ -16,11 +16,11 @@ export const MarketCap: FC<
1616
return (
1717
<StatSection
1818
title="Market Cap"
19-
bodyMainText={marketCap ? `$${numberToString(marketCap)}` : 'N/A'}
19+
bodyMainText={marketCap ? `$${abbreviateNumber(marketCap)}` : 'N/A'}
2020
bodySecondaryText={null}
2121
caption={
2222
<Flex fontSize={'12px'} fontWeight="500" alignItems={'center'} gap={'6px'}>
23-
Trading Volume: ${tradingVolume24h ? numberToString(tradingVolume24h) : 'N/A'}
23+
Trading Volume: ${tradingVolume24h ? abbreviateNumber(tradingVolume24h) : 'N/A'}
2424
{tradingVolumeChangePercentage24h ? (
2525
<TrendArrow change={tradingVolumeChangePercentage24h} size={'11px'} />
2626
) : null}

src/app/token/[tokenId]/TokenInfo/Supply.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { FC } from 'react';
22

3-
import { numberToString } from '../../../../common/utils/utils';
3+
import { abbreviateNumber } from '../../../../common/utils/utils';
44
import { Flex } from '../../../../ui/Flex';
55
import { GridProps } from '../../../../ui/Grid';
66
import { StatSection } from '../../../_components/Stats/StatSection';
@@ -14,11 +14,11 @@ export const Supply: FC<
1414
return (
1515
<StatSection
1616
title="Circulating Supply"
17-
bodyMainText={circulatingSupply ? numberToString(circulatingSupply) : <>N/A</>}
17+
bodyMainText={circulatingSupply ? abbreviateNumber(circulatingSupply) : <>N/A</>}
1818
bodySecondaryText={null}
1919
caption={
2020
<Flex fontSize={'12px'} color={'textTitle'} fontWeight="500" alignItems={'center'}>
21-
Total Supply: {totalSupply ? numberToString(totalSupply) : 'N/A'}
21+
Total Supply: {totalSupply ? abbreviateNumber(totalSupply) : 'N/A'}
2222
</Flex>
2323
}
2424
{...gridProps}

src/app/token/[tokenId]/TokenInfo/Transaction.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { useColorMode } from '@chakra-ui/react';
22
import { FC } from 'react';
33

44
import { TxLink } from '../../../../common/components/ExplorerLinks';
5-
import { numberToString } from '../../../../common/utils/utils';
65
import { Box } from '../../../../ui/Box';
76
import { Flex } from '../../../../ui/Flex';
87
import { GridProps } from '../../../../ui/Grid';

src/app/token/[tokenId]/TokenInfo/index.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ export const TokenInfo: FC<{ tokenInfo: TokenInfoProps; txId: string }> = ({ tok
1414
<Wrapper>
1515
<Supply
1616
borderRightWidth={['0px', '0px', '1px', '1px']}
17-
circulatingSupply={tokenInfo.extended?.circulatingSupply}
17+
circulatingSupply={
18+
tokenInfo.basic?.circulatingSupply || tokenInfo.extended?.circulatingSupply
19+
// tokenInfo.extended?.circulatingSupply
20+
}
1821
totalSupply={tokenInfo.basic?.totalSupply}
1922
/>
2023
<Price

0 commit comments

Comments
 (0)