Skip to content
Open
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
4 changes: 3 additions & 1 deletion src/app/_components/NewNavBar/MobileNavPage.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { usePrimaryPages } from '@/common/utils/navbar-utils';
import { Text } from '@/ui/Text';
import { Box, Flex, Icon, Stack, useDisclosure } from '@chakra-ui/react';
import { CaretLeft, CaretRight, X } from '@phosphor-icons/react';
Expand All @@ -8,7 +9,7 @@ import { SharedMobileNavBar } from './NavBar';
import { PrimaryPageLink, SecondaryPageLink } from './PagesLinks';
import { Prices } from './Prices';
import { SettingsPopoverContent } from './SettingsPopover';
import { primaryPages, secondaryPages } from './consts';
import { secondaryPages } from './consts';

const topOpacityDuration = 0.3;

Expand All @@ -19,6 +20,7 @@ const MobileContentTop = ({
isSettingsMenuOpen: boolean;
onClose: () => void;
}) => {
const primaryPages = usePrimaryPages();
return (
<Box position="relative">
<AnimatePresence>
Expand Down
13 changes: 10 additions & 3 deletions src/app/_components/NewNavBar/PagesSlidingMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import {
SBTC_TOKEN_CONTRACT_ID_MAINNET,
SBTC_TOKEN_CONTRACT_ID_TESTNET,
} from '@/app/token/[tokenId]/consts';
import { usePrimaryPages } from '@/common/utils/navbar-utils';
import { Text } from '@/ui/Text';
import { Flex, Icon, Separator, Stack } from '@chakra-ui/react';
import { CaretUpDown, List } from '@phosphor-icons/react';
Expand All @@ -6,12 +11,13 @@ import { useMemo, useState } from 'react';

import { SlidingMenu } from '../../../common/components/SlidingMenu';
import { PrimaryPageLink, SecondaryPageLink } from './PagesLinks';
import { PrimaryPageLabel, primaryPages, secondaryPages } from './consts';
import { PrimaryPageLabel, secondaryPages } from './consts';

const getPageLabelFromPath = (path: string): PrimaryPageLabel => {
if (path === '/transactions') return 'Transactions';
if (path === '/tokens') return 'Tokens';
if (path === '/token/SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token') return 'sBTC';
if (path === `/token/${SBTC_TOKEN_CONTRACT_ID_MAINNET}`) return 'sBTC';
if (path === `/token/${SBTC_TOKEN_CONTRACT_ID_TESTNET}`) return 'sBTC';
if (path === '/signers') return 'Signers';
if (path === '/blocks') return 'Blocks';
if (path === '/mempool') return 'Mempool';
Expand All @@ -29,6 +35,7 @@ export const PagesSlidingMenu = () => {
const [isOpen, setIsOpen] = useState(false);
const path = usePathname();
const pageLabel = getPageLabelFromPath(path);
const primaryPages = usePrimaryPages();

const menuContent = useMemo(() => {
return (
Expand All @@ -48,7 +55,7 @@ export const PagesSlidingMenu = () => {
</Stack>
</Stack>
);
}, [pageLabel]);
}, [pageLabel, primaryPages]);

return (
<SlidingMenu
Expand Down
122 changes: 70 additions & 52 deletions src/app/_components/NewNavBar/consts.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import {
SBTC_TOKEN_CONTRACT_ID_MAINNET,
SBTC_TOKEN_CONTRACT_ID_TESTNET,
} from '@/app/token/[tokenId]/consts';

export type PrimaryPage = {
id: PrimaryPageId;
label: PrimaryPageLabel;
Expand Down Expand Up @@ -30,58 +35,71 @@ export type PrimaryPageId =
| 'nfts'
| 'analytics';

export const primaryPages: PrimaryPage[] = [
{
id: 'home',
label: 'Home',
href: '/',
},
{
id: 'blocks',
label: 'Blocks',
href: '/blocks',
},
{
id: 'transactions',
label: 'Transactions',
href: '/transactions',
},
{
id: 'mempool',
label: 'Mempool',
href: '/mempool',
},
{
id: 'sbtc',
label: 'sBTC',
href: '/token/SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token',
},
// {
// id: 'stacking',
// label: 'Stacking',
// href: '/stacking',
// },
{
id: 'signers',
label: 'Signers',
href: '/signers',
},
{
id: 'tokens',
label: 'Tokens',
href: '/tokens',
},
// {
// id: 'nfts',
// label: 'NFTs',
// href: '/nfts',
// },
// {
// id: 'analytics',
// label: 'Analytics',
// href: '/analytics',
// },
];
export const homePage: PrimaryPage = {
id: 'home',
label: 'Home',
href: '/',
};

export const blocksPage: PrimaryPage = {
id: 'blocks',
label: 'Blocks',
href: '/blocks',
};

export const transactionsPage: PrimaryPage = {
id: 'transactions',
label: 'Transactions',
href: '/transactions',
};

export const mempoolPage: PrimaryPage = {
id: 'mempool',
label: 'Mempool',
href: '/mempool',
};

export const sbtcMainnetPage: PrimaryPage = {
id: 'sbtc',
label: 'sBTC',
href: `/token/${SBTC_TOKEN_CONTRACT_ID_MAINNET}`,
};

export const sbtcTestnetPage: PrimaryPage = {
id: 'sbtc',
label: 'sBTC',
href: `/token/${SBTC_TOKEN_CONTRACT_ID_TESTNET}`,
};

export const stackingPage: PrimaryPage = {
id: 'stacking',
label: 'Stacking',
href: '/stacking',
};

export const signersPage: PrimaryPage = {
id: 'signers',
label: 'Signers',
href: '/signers',
};

export const tokensPage: PrimaryPage = {
id: 'tokens',
label: 'Tokens',
href: '/tokens',
};

export const nftsPage: PrimaryPage = {
id: 'nfts',
label: 'NFTs',
href: '/nfts',
};

export const analyticsPage: PrimaryPage = {
id: 'analytics',
label: 'Analytics',
href: '/analytics',
};

export type SecondaryPageLabel = 'Sandbox' | 'Status Center' | 'Support';
export type SecondaryPageId = 'sandbox' | 'status-center' | 'support';
Expand Down
6 changes: 4 additions & 2 deletions src/app/address/[principal]/redesign/AddressOverview.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SBTC_ASSET_ID, SBTC_DECIMALS } from '@/app/token/[tokenId]/consts';
import { SBTC_DECIMALS } from '@/app/token/[tokenId]/consts';
import {
PriceSummaryItemValue,
RowCopyButton,
Expand All @@ -10,6 +10,7 @@ import { SectionTabsContentContainer } from '@/common/components/SectionTabs';
import { StackingCardItem } from '@/common/components/id-pages/Overview';
import { AddressTxsTable } from '@/common/components/table/table-examples/AddressTxsTable';
import { ADDRESS_ID_PAGE_RECENT_ADDRESS_TXS_LIMIT } from '@/common/components/table/table-examples/consts';
import { useSbtcTokenAssetId } from '@/common/utils/fungible-token-utils';
import { getFtDecimalAdjustedBalance, microToStacks } from '@/common/utils/utils';
import { SimpleTag } from '@/ui/Badge';
import { Button } from '@/ui/Button';
Expand Down Expand Up @@ -124,14 +125,15 @@ export function BalanceCard({
showAvailableSection?: boolean;
principal?: string;
}) {
const sbtcTokenAssetId = useSbtcTokenAssetId();
const totalBalanceMicroStx = balancesData?.stx?.balance;
const isStxBalanceDefined =
totalBalanceMicroStx !== undefined && !isNaN(parseFloat(totalBalanceMicroStx));
const totalBalanceStx = isStxBalanceDefined ? microToStacks(totalBalanceMicroStx) : 0;
const totalBalanceUsdValue = isStxBalanceDefined ? totalBalanceStx * stxPrice : 0;

const fungibleTokenBalances = balancesData?.fungible_tokens;
const sbtcBalance = fungibleTokenBalances?.[SBTC_ASSET_ID]?.balance;
const sbtcBalance = fungibleTokenBalances?.[sbtcTokenAssetId]?.balance;
const isSbtcBalanceDefined = sbtcBalance !== undefined && !isNaN(parseFloat(sbtcBalance));
const sbtcBalanceNumber = isSbtcBalanceDefined
? getFtDecimalAdjustedBalance(sbtcBalance, SBTC_DECIMALS)
Expand Down
27 changes: 22 additions & 5 deletions src/app/token/[tokenId]/consts.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
export const sbtcDepositAddress = 'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4';
export const sbtcContractAddress = 'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token';
export const sbtcWidthdrawlContractAddress =
export const SBTC_TOKEN_CONTRACT_ID_MAINNET =
'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token';
export const SBTC_TOKEN_CONTRACT_ID_TESTNET =
'ST1F7QA2MDF17S807EPA36TSS8AMEFY4KA9TVGWXT.sbtc-token';
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this one is "correct".


export const SBTC_TOKEN_ASSET_ID_MAINNET =
'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token::sbtc-token';
export const SBTC_TOKEN_ASSET_ID_TESTNET =
'ST1F7QA2MDF17S807EPA36TSS8AMEFY4KA9TVGWXT.sbtc-token::sbtc-token';

export const SBTC_DEPOSIT_CONTRACT_ID_MAINNET =
'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-deposit';
export const SBTC_DEPOSIT_CONTRACT_ADDRESS_TESTNET = 'ST1F7QA2MDF17S807EPA36TSS8AMEFY4KA9TVGWXT';
export const SBTC_DEPOSIT_CONTRACT_ID_TESTNET =
'ST1F7QA2MDF17S807EPA36TSS8AMEFY4KA9TVGWXT.sbtc-deposit';

export const SBTC_WITHDRAWAL_CONTRACT_ID_MAINNET =
'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-withdrawal';
export const SBTC_ASSET_ID = 'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token::sbtc-token';
export const SBTC_WITHDRAWAL_CONTRACT_ID_TESTNET =
'ST1F7QA2MDF17S807EPA36TSS8AMEFY4KA9TVGWXT.sbtc-withdrawal';

export const SBTC_DECIMALS = 8;

export const DROID_CONTRACT_ADDRESS = 'SP2EEV5QBZA454MSMW9W3WJNRXVJF36VPV17FFKYH.DROID';
const zsbtcContractAddress = 'SP2VCQJGH7PHP2DJK7Z0V48AGBHQAW3R3ZW1QF4N.zsbtc-token';
export const usdcxContractAddress = 'SP120SBRBQJ00MCWS7TM5R8WJNTTKD5K0HFRC2CNE.usdcx';
Expand All @@ -26,6 +43,6 @@ export const LEGIT_SBTC_DERIVATIVES = [zsbtcContractAddress];
export const VERIFIED_TOKENS = [
DROID_CONTRACT_ADDRESS,
zsbtcContractAddress,
sbtcContractAddress,
SBTC_TOKEN_CONTRACT_ID_MAINNET,
usdcxContractAddress,
];
8 changes: 5 additions & 3 deletions src/app/token/[tokenId]/page-data.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { fetchTokenDataFromLunarCrush, fetchTokenMetadata } from '@/api/data-fetchers';
import { isSBTC } from '@/app/tokens/utils';
import { NetworkModes } from '@/common/types/network';
import { logError } from '@/common/utils/error-utils';
import { getIsSBTC } from '@/common/utils/fungible-token-utils';

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

Expand Down Expand Up @@ -119,7 +120,8 @@ export function mergeTokenData(
tokenDataFromStacksApi: TokenDataFromStacksApi | undefined,
tokenDataFromLunarCrush: TokenDataFromLunarCrush | undefined,
holders: FungibleTokenHolderList | undefined,
tokenId: string
tokenId: string,
chain: NetworkModes
): MergedTokenData {
// Basic token information
const name = safeGet(tokenDataFromLunarCrush?.name, tokenDataFromStacksApi?.name);
Expand All @@ -132,7 +134,7 @@ export function mergeTokenData(
: undefined;

// 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
const isSbtc = isSBTC(tokenId);
const isSbtc = getIsSBTC(tokenId, chain);
const circulatingSupplyFromStacksApi = parseFloat(holders?.total_supply || '0');
const circulatingSupply = isSbtc
? safeGet(circulatingSupplyFromStacksApi, tokenDataFromLunarCrush?.circulatingSupply)
Expand Down
8 changes: 7 additions & 1 deletion src/app/token/[tokenId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,13 @@ export default async function (props: {
const tx = handleSettledResult(txResult, 'Failed to fetch transaction');
holders = handleSettledResult(holdersResult, 'Failed to fetch holders');

tokenData = mergeTokenData(tokenDataFromStacksApi, tokenDataFromLunarCrush, holders, tokenId);
tokenData = mergeTokenData(
tokenDataFromStacksApi,
tokenDataFromLunarCrush,
holders,
tokenId,
(chain as NetworkModes) || NetworkModes.Mainnet
);

txBlockTime =
tx && isConfirmedTx<Transaction, MempoolTransaction>(tx) ? tx.block_time : undefined;
Expand Down
6 changes: 3 additions & 3 deletions src/app/tokens/TokenRow/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { RISKY_TOKENS, VERIFIED_TOKENS } from '@/app/token/[tokenId]/consts';
import { getHasSBTCInNameOrSymbol, useIsSBTC } from '@/common/utils/fungible-token-utils';
import { Flex, Icon, Table } from '@chakra-ui/react';
import { FtBasicMetadataResponse } from '@hirosystems/token-metadata-api-client';
import { SealCheck, Warning } from '@phosphor-icons/react';
Expand All @@ -8,7 +9,6 @@ import { TokenLink, TxLink } from '../../../common/components/ExplorerLinks';
import { abbreviateNumber, getFtDecimalAdjustedBalance } from '../../../common/utils/utils';
import { Text } from '../../../ui/Text';
import { TokenAvatar } from '../../address/[principal]/TokenBalanceCard/TokenAvatar';
import { isSBTC, referencesSBTC } from '../utils';

export const TokenRow: FC<{
ftToken: FtBasicMetadataResponse;
Expand All @@ -17,8 +17,8 @@ export const TokenRow: FC<{
const symbol = ftToken.symbol || '';
const contractId = ftToken.contract_principal;

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

const tokenBadge = useMemo(() => {
if (isSbtc || VERIFIED_TOKENS.includes(contractId)) {
Expand Down
9 changes: 4 additions & 5 deletions src/app/tokens/useTokens.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client';

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

Expand All @@ -8,7 +9,7 @@ import {
useSuspenseInfiniteQueryResult,
} from '../../common/hooks/useInfiniteQueryResult';
import { useFtTokens, useSuspenseFtTokens } from '../../common/queries/useFtTokens';
import { sbtcContractAddress, usdcxContractAddress } from '../token/[tokenId]/consts';
import { usdcxContractAddress } from '../token/[tokenId]/consts';

export const useSuspenseTokens = (
debouncedSearchTerm: string
Expand All @@ -19,6 +20,7 @@ export const useSuspenseTokens = (
loadMore: () => void;
} => {
const searchByNameResponse = useSuspenseFtTokens({ name: debouncedSearchTerm || undefined });
const sbtcContractId = useSbtcTokenContractId();

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

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.
const sbtcResponse = useFtTokens(
{ address: sbtcContractAddress },
{ enabled: shouldAddPinnedTokens }
);
const sbtcResponse = useFtTokens({ address: sbtcContractId }, { enabled: shouldAddPinnedTokens });
const usdcxResponse = useFtTokens(
{ address: usdcxContractAddress },
{ enabled: shouldAddPinnedTokens }
Expand Down
7 changes: 5 additions & 2 deletions src/app/tokens/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { FtBasicMetadataResponse } from '@hirosystems/token-metadata-api-client'
import {
LEGIT_SBTC_DERIVATIVES,
RISKY_TOKENS,
sbtcContractAddress,
SBTC_TOKEN_CONTRACT_ID_MAINNET,
SBTC_TOKEN_CONTRACT_ID_TESTNET,
} from '../token/[tokenId]/consts';

export const referencesSBTC = (
Expand All @@ -20,7 +21,9 @@ export const isSBTC = (contractId: string) => {
if (!contractId) {
return false;
}
return contractId === sbtcContractAddress;
return (
contractId === SBTC_TOKEN_CONTRACT_ID_MAINNET || contractId === SBTC_TOKEN_CONTRACT_ID_TESTNET
);
};

export function showSBTCTokenAlert(tokenName: string, tokenSymbol: string, contractId: string) {
Expand Down
Loading
Loading