Skip to content

Commit d5a20aa

Browse files
committed
fix: sbtc balance on testnet
1 parent 03ed476 commit d5a20aa

16 files changed

Lines changed: 223 additions & 87 deletions

File tree

src/app/_components/NewNavBar/MobileNavPage.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { usePrimaryPages } from '@/common/utils/navbar-utils';
12
import { Text } from '@/ui/Text';
23
import { Box, Flex, Icon, Stack, useDisclosure } from '@chakra-ui/react';
34
import { CaretLeft, CaretRight, X } from '@phosphor-icons/react';
@@ -8,7 +9,7 @@ import { SharedMobileNavBar } from './NavBar';
89
import { PrimaryPageLink, SecondaryPageLink } from './PagesLinks';
910
import { Prices } from './Prices';
1011
import { SettingsPopoverContent } from './SettingsPopover';
11-
import { primaryPages, secondaryPages } from './consts';
12+
import { secondaryPages } from './consts';
1213

1314
const topOpacityDuration = 0.3;
1415

@@ -19,6 +20,7 @@ const MobileContentTop = ({
1920
isSettingsMenuOpen: boolean;
2021
onClose: () => void;
2122
}) => {
23+
const primaryPages = usePrimaryPages();
2224
return (
2325
<Box position="relative">
2426
<AnimatePresence>

src/app/_components/NewNavBar/PagesSlidingMenu.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
import {
2+
SBTC_TOKEN_CONTRACT_ID_MAINNET,
3+
SBTC_TOKEN_CONTRACT_ID_TESTNET,
4+
} from '@/app/token/[tokenId]/consts';
5+
import { usePrimaryPages } from '@/common/utils/navbar-utils';
16
import { Text } from '@/ui/Text';
27
import { Flex, Icon, Separator, Stack } from '@chakra-ui/react';
38
import { CaretUpDown, List } from '@phosphor-icons/react';
@@ -6,12 +11,13 @@ import { useMemo, useState } from 'react';
611

712
import { SlidingMenu } from '../../../common/components/SlidingMenu';
813
import { PrimaryPageLink, SecondaryPageLink } from './PagesLinks';
9-
import { PrimaryPageLabel, primaryPages, secondaryPages } from './consts';
14+
import { PrimaryPageLabel, secondaryPages } from './consts';
1015

1116
const getPageLabelFromPath = (path: string): PrimaryPageLabel => {
1217
if (path === '/transactions') return 'Transactions';
1318
if (path === '/tokens') return 'Tokens';
14-
if (path === '/token/SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token') return 'sBTC';
19+
if (path === `/token/${SBTC_TOKEN_CONTRACT_ID_MAINNET}`) return 'sBTC';
20+
if (path === `/token/${SBTC_TOKEN_CONTRACT_ID_TESTNET}`) return 'sBTC';
1521
if (path === '/signers') return 'Signers';
1622
if (path === '/blocks') return 'Blocks';
1723
if (path === '/mempool') return 'Mempool';
@@ -29,6 +35,7 @@ export const PagesSlidingMenu = () => {
2935
const [isOpen, setIsOpen] = useState(false);
3036
const path = usePathname();
3137
const pageLabel = getPageLabelFromPath(path);
38+
const primaryPages = usePrimaryPages();
3239

3340
const menuContent = useMemo(() => {
3441
return (
@@ -48,7 +55,7 @@ export const PagesSlidingMenu = () => {
4855
</Stack>
4956
</Stack>
5057
);
51-
}, [pageLabel]);
58+
}, [pageLabel, primaryPages]);
5259

5360
return (
5461
<SlidingMenu

src/app/_components/NewNavBar/consts.ts

Lines changed: 70 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
import {
2+
SBTC_TOKEN_CONTRACT_ID_MAINNET,
3+
SBTC_TOKEN_CONTRACT_ID_TESTNET,
4+
} from '@/app/token/[tokenId]/consts';
5+
16
export type PrimaryPage = {
27
id: PrimaryPageId;
38
label: PrimaryPageLabel;
@@ -30,58 +35,71 @@ export type PrimaryPageId =
3035
| 'nfts'
3136
| 'analytics';
3237

33-
export const primaryPages: PrimaryPage[] = [
34-
{
35-
id: 'home',
36-
label: 'Home',
37-
href: '/',
38-
},
39-
{
40-
id: 'blocks',
41-
label: 'Blocks',
42-
href: '/blocks',
43-
},
44-
{
45-
id: 'transactions',
46-
label: 'Transactions',
47-
href: '/transactions',
48-
},
49-
{
50-
id: 'mempool',
51-
label: 'Mempool',
52-
href: '/mempool',
53-
},
54-
{
55-
id: 'sbtc',
56-
label: 'sBTC',
57-
href: '/token/SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token',
58-
},
59-
// {
60-
// id: 'stacking',
61-
// label: 'Stacking',
62-
// href: '/stacking',
63-
// },
64-
{
65-
id: 'signers',
66-
label: 'Signers',
67-
href: '/signers',
68-
},
69-
{
70-
id: 'tokens',
71-
label: 'Tokens',
72-
href: '/tokens',
73-
},
74-
// {
75-
// id: 'nfts',
76-
// label: 'NFTs',
77-
// href: '/nfts',
78-
// },
79-
// {
80-
// id: 'analytics',
81-
// label: 'Analytics',
82-
// href: '/analytics',
83-
// },
84-
];
38+
export const homePage: PrimaryPage = {
39+
id: 'home',
40+
label: 'Home',
41+
href: '/',
42+
};
43+
44+
export const blocksPage: PrimaryPage = {
45+
id: 'blocks',
46+
label: 'Blocks',
47+
href: '/blocks',
48+
};
49+
50+
export const transactionsPage: PrimaryPage = {
51+
id: 'transactions',
52+
label: 'Transactions',
53+
href: '/transactions',
54+
};
55+
56+
export const mempoolPage: PrimaryPage = {
57+
id: 'mempool',
58+
label: 'Mempool',
59+
href: '/mempool',
60+
};
61+
62+
export const sbtcMainnetPage: PrimaryPage = {
63+
id: 'sbtc',
64+
label: 'sBTC',
65+
href: `/token/${SBTC_TOKEN_CONTRACT_ID_MAINNET}`,
66+
};
67+
68+
export const sbtcTestnetPage: PrimaryPage = {
69+
id: 'sbtc',
70+
label: 'sBTC',
71+
href: `/token/${SBTC_TOKEN_CONTRACT_ID_TESTNET}`,
72+
};
73+
74+
export const stackingPage: PrimaryPage = {
75+
id: 'stacking',
76+
label: 'Stacking',
77+
href: '/stacking',
78+
};
79+
80+
export const signersPage: PrimaryPage = {
81+
id: 'signers',
82+
label: 'Signers',
83+
href: '/signers',
84+
};
85+
86+
export const tokensPage: PrimaryPage = {
87+
id: 'tokens',
88+
label: 'Tokens',
89+
href: '/tokens',
90+
};
91+
92+
export const nftsPage: PrimaryPage = {
93+
id: 'nfts',
94+
label: 'NFTs',
95+
href: '/nfts',
96+
};
97+
98+
export const analyticsPage: PrimaryPage = {
99+
id: 'analytics',
100+
label: 'Analytics',
101+
href: '/analytics',
102+
};
85103

86104
export type SecondaryPageLabel = 'Sandbox' | 'Status Center' | 'Support';
87105
export type SecondaryPageId = 'sandbox' | 'status-center' | 'support';

src/app/address/[principal]/redesign/AddressOverview.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { SBTC_ASSET_ID, SBTC_DECIMALS } from '@/app/token/[tokenId]/consts';
1+
import { SBTC_DECIMALS } from '@/app/token/[tokenId]/consts';
22
import {
33
PriceSummaryItemValue,
44
RowCopyButton,
@@ -10,6 +10,7 @@ import { SectionTabsContentContainer } from '@/common/components/SectionTabs';
1010
import { StackingCardItem } from '@/common/components/id-pages/Overview';
1111
import { AddressTxsTable } from '@/common/components/table/table-examples/AddressTxsTable';
1212
import { ADDRESS_ID_PAGE_RECENT_ADDRESS_TXS_LIMIT } from '@/common/components/table/table-examples/consts';
13+
import { useSbtcTokenAssetId } from '@/common/utils/fungible-token-utils';
1314
import { getFtDecimalAdjustedBalance, microToStacks } from '@/common/utils/utils';
1415
import { SimpleTag } from '@/ui/Badge';
1516
import { Button } from '@/ui/Button';
@@ -124,14 +125,15 @@ export function BalanceCard({
124125
showAvailableSection?: boolean;
125126
principal?: string;
126127
}) {
128+
const sbtcTokenAssetId = useSbtcTokenAssetId();
127129
const totalBalanceMicroStx = balancesData?.stx?.balance;
128130
const isStxBalanceDefined =
129131
totalBalanceMicroStx !== undefined && !isNaN(parseFloat(totalBalanceMicroStx));
130132
const totalBalanceStx = isStxBalanceDefined ? microToStacks(totalBalanceMicroStx) : 0;
131133
const totalBalanceUsdValue = isStxBalanceDefined ? totalBalanceStx * stxPrice : 0;
132134

133135
const fungibleTokenBalances = balancesData?.fungible_tokens;
134-
const sbtcBalance = fungibleTokenBalances?.[SBTC_ASSET_ID]?.balance;
136+
const sbtcBalance = fungibleTokenBalances?.[sbtcTokenAssetId]?.balance;
135137
const isSbtcBalanceDefined = sbtcBalance !== undefined && !isNaN(parseFloat(sbtcBalance));
136138
const sbtcBalanceNumber = isSbtcBalanceDefined
137139
? getFtDecimalAdjustedBalance(sbtcBalance, SBTC_DECIMALS)

src/app/token/[tokenId]/consts.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,26 @@
1-
export const sbtcDepositAddress = 'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4';
2-
export const sbtcContractAddress = 'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token';
3-
export const sbtcWidthdrawlContractAddress =
1+
export const SBTC_TOKEN_CONTRACT_ID_MAINNET =
2+
'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token';
3+
export const SBTC_TOKEN_CONTRACT_ID_TESTNET =
4+
'ST1F7QA2MDF17S807EPA36TSS8AMEFY4KA9TVGWXT.sbtc-token';
5+
6+
export const SBTC_TOKEN_ASSET_ID_MAINNET =
7+
'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token::sbtc-token';
8+
export const SBTC_TOKEN_ASSET_ID_TESTNET =
9+
'ST1F7QA2MDF17S807EPA36TSS8AMEFY4KA9TVGWXT.sbtc-token::sbtc-token';
10+
11+
export const SBTC_DEPOSIT_CONTRACT_ID_MAINNET =
12+
'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-deposit';
13+
export const SBTC_DEPOSIT_CONTRACT_ADDRESS_TESTNET = 'ST1F7QA2MDF17S807EPA36TSS8AMEFY4KA9TVGWXT';
14+
export const SBTC_DEPOSIT_CONTRACT_ID_TESTNET =
15+
'ST1F7QA2MDF17S807EPA36TSS8AMEFY4KA9TVGWXT.sbtc-deposit';
16+
17+
export const SBTC_WITHDRAWAL_CONTRACT_ID_MAINNET =
418
'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-withdrawal';
5-
export const SBTC_ASSET_ID = 'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token::sbtc-token';
19+
export const SBTC_WITHDRAWAL_CONTRACT_ID_TESTNET =
20+
'ST1F7QA2MDF17S807EPA36TSS8AMEFY4KA9TVGWXT.sbtc-withdrawal';
21+
622
export const SBTC_DECIMALS = 8;
23+
724
export const DROID_CONTRACT_ADDRESS = 'SP2EEV5QBZA454MSMW9W3WJNRXVJF36VPV17FFKYH.DROID';
825
const zsbtcContractAddress = 'SP2VCQJGH7PHP2DJK7Z0V48AGBHQAW3R3ZW1QF4N.zsbtc-token';
926
export const usdcxContractAddress = 'SP120SBRBQJ00MCWS7TM5R8WJNTTKD5K0HFRC2CNE.usdcx';
@@ -26,6 +43,6 @@ export const LEGIT_SBTC_DERIVATIVES = [zsbtcContractAddress];
2643
export const VERIFIED_TOKENS = [
2744
DROID_CONTRACT_ADDRESS,
2845
zsbtcContractAddress,
29-
sbtcContractAddress,
46+
SBTC_TOKEN_CONTRACT_ID_MAINNET,
3047
usdcxContractAddress,
3148
];

src/app/token/[tokenId]/page-data.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { fetchTokenDataFromLunarCrush, fetchTokenMetadata } from '@/api/data-fetchers';
2-
import { isSBTC } from '@/app/tokens/utils';
2+
import { NetworkModes } from '@/common/types/network';
33
import { logError } from '@/common/utils/error-utils';
4+
import { getIsSBTC } from '@/common/utils/fungible-token-utils';
45

56
import { FungibleTokenHolderList } from '@stacks/stacks-blockchain-api-types';
67

@@ -119,7 +120,8 @@ export function mergeTokenData(
119120
tokenDataFromStacksApi: TokenDataFromStacksApi | undefined,
120121
tokenDataFromLunarCrush: TokenDataFromLunarCrush | undefined,
121122
holders: FungibleTokenHolderList | undefined,
122-
tokenId: string
123+
tokenId: string,
124+
chain: NetworkModes
123125
): MergedTokenData {
124126
// Basic token information
125127
const name = safeGet(tokenDataFromLunarCrush?.name, tokenDataFromStacksApi?.name);
@@ -132,7 +134,7 @@ export function mergeTokenData(
132134
: undefined;
133135

134136
// Special handling for circulating supply for SBTC. If it's SBTC, use the holders total supply (aka circulating supply), otherwise use the circulating supply from LunarCrush first, then fallback to the circulating supply from Stacks API
135-
const isSbtc = isSBTC(tokenId);
137+
const isSbtc = getIsSBTC(tokenId, chain);
136138
const circulatingSupplyFromStacksApi = parseFloat(holders?.total_supply || '0');
137139
const circulatingSupply = isSbtc
138140
? safeGet(circulatingSupplyFromStacksApi, tokenDataFromLunarCrush?.circulatingSupply)

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,13 @@ export default async function (props: {
115115
const tx = handleSettledResult(txResult, 'Failed to fetch transaction');
116116
holders = handleSettledResult(holdersResult, 'Failed to fetch holders');
117117

118-
tokenData = mergeTokenData(tokenDataFromStacksApi, tokenDataFromLunarCrush, holders, tokenId);
118+
tokenData = mergeTokenData(
119+
tokenDataFromStacksApi,
120+
tokenDataFromLunarCrush,
121+
holders,
122+
tokenId,
123+
(chain as NetworkModes) || NetworkModes.Mainnet
124+
);
119125

120126
txBlockTime =
121127
tx && isConfirmedTx<Transaction, MempoolTransaction>(tx) ? tx.block_time : undefined;

src/app/tokens/TokenRow/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { RISKY_TOKENS, VERIFIED_TOKENS } from '@/app/token/[tokenId]/consts';
2+
import { getHasSBTCInNameOrSymbol, useIsSBTC } from '@/common/utils/fungible-token-utils';
23
import { Flex, Icon, Table } from '@chakra-ui/react';
34
import { FtBasicMetadataResponse } from '@hirosystems/token-metadata-api-client';
45
import { SealCheck, Warning } from '@phosphor-icons/react';
@@ -8,7 +9,6 @@ import { TokenLink, TxLink } from '../../../common/components/ExplorerLinks';
89
import { abbreviateNumber, getFtDecimalAdjustedBalance } from '../../../common/utils/utils';
910
import { Text } from '../../../ui/Text';
1011
import { TokenAvatar } from '../../address/[principal]/TokenBalanceCard/TokenAvatar';
11-
import { isSBTC, referencesSBTC } from '../utils';
1212

1313
export const TokenRow: FC<{
1414
ftToken: FtBasicMetadataResponse;
@@ -17,8 +17,8 @@ export const TokenRow: FC<{
1717
const symbol = ftToken.symbol || '';
1818
const contractId = ftToken.contract_principal;
1919

20-
const includesSbtc = referencesSBTC(name, symbol);
21-
const isSbtc = isSBTC(contractId);
20+
const includesSbtc = getHasSBTCInNameOrSymbol(name, ftToken.symbol ?? '');
21+
const isSbtc = useIsSBTC(ftToken.contract_principal);
2222

2323
const tokenBadge = useMemo(() => {
2424
if (isSbtc || VERIFIED_TOKENS.includes(contractId)) {

src/app/tokens/useTokens.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use client';
22

3+
import { useSbtcTokenContractId } from '@/common/utils/fungible-token-utils';
34
import { FtBasicMetadataResponse } from '@hirosystems/token-metadata-api-client';
45
import { useCallback, useMemo } from 'react';
56

@@ -8,7 +9,7 @@ import {
89
useSuspenseInfiniteQueryResult,
910
} from '../../common/hooks/useInfiniteQueryResult';
1011
import { useFtTokens, useSuspenseFtTokens } from '../../common/queries/useFtTokens';
11-
import { sbtcContractAddress, usdcxContractAddress } from '../token/[tokenId]/consts';
12+
import { usdcxContractAddress } from '../token/[tokenId]/consts';
1213

1314
export const useSuspenseTokens = (
1415
debouncedSearchTerm: string
@@ -19,6 +20,7 @@ export const useSuspenseTokens = (
1920
loadMore: () => void;
2021
} => {
2122
const searchByNameResponse = useSuspenseFtTokens({ name: debouncedSearchTerm || undefined });
23+
const sbtcContractId = useSbtcTokenContractId();
2224

2325
const searchBySymbol = !!debouncedSearchTerm;
2426
const searchByAddress = new RegExp('^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{28,41}').test(
@@ -35,10 +37,7 @@ export const useSuspenseTokens = (
3537
);
3638

3739
const shouldAddPinnedTokens = useMemo(() => !debouncedSearchTerm, [debouncedSearchTerm]); // Only add pinned tokens if no search term is provided. If they are searched, they will be added by default. If a search term that is not a pinned token is provided, they should not be added.
38-
const sbtcResponse = useFtTokens(
39-
{ address: sbtcContractAddress },
40-
{ enabled: shouldAddPinnedTokens }
41-
);
40+
const sbtcResponse = useFtTokens({ address: sbtcContractId }, { enabled: shouldAddPinnedTokens });
4241
const usdcxResponse = useFtTokens(
4342
{ address: usdcxContractAddress },
4443
{ enabled: shouldAddPinnedTokens }

src/app/tokens/utils.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import { FtBasicMetadataResponse } from '@hirosystems/token-metadata-api-client'
33
import {
44
LEGIT_SBTC_DERIVATIVES,
55
RISKY_TOKENS,
6-
sbtcContractAddress,
6+
SBTC_TOKEN_CONTRACT_ID_MAINNET,
7+
SBTC_TOKEN_CONTRACT_ID_TESTNET,
78
} from '../token/[tokenId]/consts';
89

910
export const referencesSBTC = (
@@ -20,7 +21,9 @@ export const isSBTC = (contractId: string) => {
2021
if (!contractId) {
2122
return false;
2223
}
23-
return contractId === sbtcContractAddress;
24+
return (
25+
contractId === SBTC_TOKEN_CONTRACT_ID_MAINNET || contractId === SBTC_TOKEN_CONTRACT_ID_TESTNET
26+
);
2427
};
2528

2629
export function showSBTCTokenAlert(tokenName: string, tokenSymbol: string, contractId: string) {

0 commit comments

Comments
 (0)