mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
exclude CELO native token balance from net worth
This commit is contained in:
@@ -14,6 +14,7 @@ on:
|
||||
- arbitrum_nova
|
||||
- arbitrum_sepolia
|
||||
- base
|
||||
- celo
|
||||
- celo_alfajores
|
||||
- garnet
|
||||
- gnosis
|
||||
|
||||
@@ -14,6 +14,7 @@ on:
|
||||
- arbitrum_nova
|
||||
- arbitrum_sepolia
|
||||
- base
|
||||
- celo
|
||||
- celo_alfajores
|
||||
- garnet
|
||||
- gnosis
|
||||
|
||||
Vendored
+1
@@ -364,6 +364,7 @@
|
||||
"arbitrum_sepolia",
|
||||
"base",
|
||||
"blackfort_testnet",
|
||||
"celo",
|
||||
"celo_alfajores",
|
||||
"garnet",
|
||||
"gnosis",
|
||||
|
||||
@@ -4,12 +4,13 @@ import { getEnvValue } from '../utils';
|
||||
|
||||
const title = 'Celo chain';
|
||||
|
||||
const config: Feature<{ }> = (() => {
|
||||
const config: Feature<{ nativeTokenAddress?: string }> = (() => {
|
||||
|
||||
if (getEnvValue('NEXT_PUBLIC_CELO_ENABLED') === 'true') {
|
||||
return Object.freeze({
|
||||
title,
|
||||
isEnabled: true,
|
||||
nativeTokenAddress: getEnvValue('NEXT_PUBLIC_CELO_NATIVE_TOKEN_ADDRESS'),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
# Set of ENVs for Celo Mainnet network explorer
|
||||
# https://celo.blockscout.com
|
||||
# This is an auto-generated file. To update all values, run "yarn dev:preset:sync --name=celo"
|
||||
|
||||
# Local ENVs
|
||||
NEXT_PUBLIC_APP_PROTOCOL=http
|
||||
NEXT_PUBLIC_APP_HOST=localhost
|
||||
NEXT_PUBLIC_APP_PORT=3000
|
||||
NEXT_PUBLIC_APP_ENV=development
|
||||
NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL=ws
|
||||
|
||||
NEXT_PUBLIC_CELO_NATIVE_TOKEN_ADDRESS=0x471EcE3750Da237f93B8E339c536989b8978a438
|
||||
|
||||
# Instance ENVs
|
||||
NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS=['talentprotocol', 'efp', 'webacy', 'deepdao', 'humanpassport', 'bankless', 'blockscoutbadges']
|
||||
NEXT_PUBLIC_ADDRESS_3RD_PARTY_WIDGETS_CONFIG_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/widgets/config.json
|
||||
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
|
||||
NEXT_PUBLIC_API_BASE_PATH=/
|
||||
NEXT_PUBLIC_API_HOST=celo.blockscout.com
|
||||
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
|
||||
NEXT_PUBLIC_CELO_ENABLED=true
|
||||
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
|
||||
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
|
||||
NEXT_PUBLIC_DEFI_DROPDOWN_ITEMS=[{'text':'Swapscout','icon':'swap','dappId':'swapscout'},{'text':'Revokescout','icon':'integration/partial','dappId':'revokescout'}]
|
||||
NEXT_PUBLIC_DEX_POOLS_ENABLED=true
|
||||
NEXT_PUBLIC_FEATURED_NETWORKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/featured-networks/celo.json
|
||||
NEXT_PUBLIC_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/sherblockHolmesBadge
|
||||
NEXT_PUBLIC_GAS_TRACKER_ENABLED=false
|
||||
NEXT_PUBLIC_GRAPHIQL_TRANSACTION=0xa214ff978b8535434d5806d8e9d0d5f8c946905fbba1def121014e7af36c1e8f
|
||||
NEXT_PUBLIC_HAS_USER_OPS=true
|
||||
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs']
|
||||
NEXT_PUBLIC_HOMEPAGE_HERO_BANNER_CONFIG={'background':['rgba(252, 255, 82, 1)'],'text_color':['rgba(0, 0, 0, 1)']}
|
||||
NEXT_PUBLIC_HOMEPAGE_STATS=['total_blocks','average_block_time','total_txs','wallet_addresses','current_epoch']
|
||||
NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED=true
|
||||
NEXT_PUBLIC_MARKETPLACE_BANNER_CONTENT_URL=https://gist.githubusercontent.com/0xdeval/b27a4aecaad513fa033e37430a4f9a47/raw/3a2fa70068ea27c3e6d58dc4cdbeb732968d62f3/revokescout-banner.html
|
||||
NEXT_PUBLIC_MARKETPLACE_BANNER_LINK_URL=https://revoke.blockscout.com?utm_source=blockscout&utm_medium=celo
|
||||
NEXT_PUBLIC_MARKETPLACE_CATEGORIES_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/marketplace-categories/default.json
|
||||
NEXT_PUBLIC_MARKETPLACE_ENABLED=true
|
||||
NEXT_PUBLIC_MARKETPLACE_RATING_AIRTABLE_API_KEY=patbqG4V2CI998jAq.9810c58c9de973ba2650621c94559088cbdfa1a914498e385621ed035d33c0d0
|
||||
NEXT_PUBLIC_MARKETPLACE_RATING_AIRTABLE_BASE_ID=appGkvtmKI7fXE4Vs
|
||||
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM=https://airtable.com/appiy5yijZpMMSKjT/shr6uMGPKjj1DK7NL
|
||||
NEXT_PUBLIC_MARKETPLACE_SUGGEST_IDEAS_FORM=https://airtable.com/appiy5yijZpMMSKjT/pag3t82DUCyhGRZZO/form
|
||||
NEXT_PUBLIC_METADATA_SERVICE_API_HOST=https://metadata.services.blockscout.com
|
||||
NEXT_PUBLIC_NAVIGATION_HIGHLIGHTED_ROUTES=['/apps']
|
||||
NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS=18
|
||||
NEXT_PUBLIC_NETWORK_CURRENCY_NAME=CELO
|
||||
NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL=CELO
|
||||
NEXT_PUBLIC_NETWORK_ICON=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/celo-icon-light.svg
|
||||
NEXT_PUBLIC_NETWORK_ICON_DARK=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/celo-icon-dark.svg
|
||||
NEXT_PUBLIC_NETWORK_ID=42220
|
||||
NEXT_PUBLIC_NETWORK_LOGO=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/celo-logo-light.svg
|
||||
NEXT_PUBLIC_NETWORK_LOGO_DARK=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/celo-logo-dark.svg
|
||||
NEXT_PUBLIC_NETWORK_MULTIPLE_GAS_CURRENCIES=true
|
||||
NEXT_PUBLIC_NETWORK_NAME=Celo Mainnet
|
||||
NEXT_PUBLIC_NETWORK_RPC_URL=https://forno.celo.org
|
||||
NEXT_PUBLIC_NETWORK_SHORT_NAME=Mainnet
|
||||
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
|
||||
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/celo.png
|
||||
NEXT_PUBLIC_PUZZLE_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/capyPuzzleBadge
|
||||
NEXT_PUBLIC_STATS_API_BASE_PATH=/stats-service
|
||||
NEXT_PUBLIC_STATS_API_HOST=https://celo.blockscout.com
|
||||
NEXT_PUBLIC_TRANSACTION_INTERPRETATION_PROVIDER=blockscout
|
||||
NEXT_PUBLIC_VIEWS_BLOCK_HIDDEN_FIELDS=['burnt_fees']
|
||||
NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED=true
|
||||
NEXT_PUBLIC_VIEWS_TOKEN_SCAM_TOGGLE_ENABLED=true
|
||||
NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com
|
||||
@@ -364,6 +364,16 @@ const celoSchema = yup
|
||||
.object()
|
||||
.shape({
|
||||
NEXT_PUBLIC_CELO_ENABLED: yup.boolean(),
|
||||
NEXT_PUBLIC_CELO_NATIVE_TOKEN_ADDRESS: yup
|
||||
.string()
|
||||
.min(42)
|
||||
.max(42)
|
||||
.matches(regexp.HEX_REGEXP_WITH_0X)
|
||||
.when('NEXT_PUBLIC_CELO_ENABLED', {
|
||||
is: (value: boolean) => value,
|
||||
then: (schema) => schema,
|
||||
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_CELO_NATIVE_TOKEN_ADDRESS can only be used if NEXT_PUBLIC_CELO_ENABLED is set to \'true\''),
|
||||
}),
|
||||
});
|
||||
|
||||
const apiDocsScheme = yup
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
NEXT_PUBLIC_CELO_ENABLED=true
|
||||
NEXT_PUBLIC_CELO_ENABLED=true
|
||||
NEXT_PUBLIC_CELO_NATIVE_TOKEN_ADDRESS=0x471EcE3750Da237f93B8E339c536989b8978a438
|
||||
@@ -792,6 +792,7 @@ For blockchains that use the Celo platform. _Note_, that once the Celo mainnet b
|
||||
| Variable | Type| Description | Compulsoriness | Default value | Example value | Version |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| NEXT_PUBLIC_CELO_ENABLED | `boolean` | Indicates that it is a Celo-based chain. | - | - | `true` | v1.37.0+ |
|
||||
| NEXT_PUBLIC_CELO_NATIVE_TOKEN_ADDRESS | `string` | The address of the CELO ERC-20 token. Used to exclude its balance from the net worth value of user tokens. | - | - | `0x471EcE3750Da237f93B8E339c536989b8978a438` | v2.3.0+ |
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -112,6 +112,7 @@ export const ENVS_MAP: Record<string, Array<[string, string]>> = {
|
||||
],
|
||||
celo: [
|
||||
[ 'NEXT_PUBLIC_CELO_ENABLED', 'true' ],
|
||||
[ 'NEXT_PUBLIC_CELO_NATIVE_TOKEN_ADDRESS', '0x471EcE3750Da237f93B8E339c536989b8978a438' ],
|
||||
],
|
||||
opSuperchain: [
|
||||
[ 'NEXT_PUBLIC_OP_SUPERCHAIN_ENABLED', 'true' ],
|
||||
|
||||
@@ -7,6 +7,7 @@ const PRESETS = {
|
||||
arbitrum_sepolia: 'https://arbitrum-sepolia.blockscout.com',
|
||||
base: 'https://base.blockscout.com',
|
||||
blackfort_testnet: 'https://blackfort-testnet.blockscout.com',
|
||||
celo: 'https://celo.blockscout.com',
|
||||
celo_alfajores: 'https://celo-alfajores.blockscout.com',
|
||||
eth: 'https://eth.blockscout.com',
|
||||
eth_goerli: 'https://eth-goerli.blockscout.com',
|
||||
|
||||
@@ -5,6 +5,7 @@ import type { AddressTokensResponse } from 'types/api/address';
|
||||
|
||||
import * as addressMock from 'mocks/address/address';
|
||||
import * as tokensMock from 'mocks/address/tokens';
|
||||
import * as tokenInfo from 'mocks/tokens/tokenInfo';
|
||||
import * as tokenInstance from 'mocks/tokens/tokenInstance';
|
||||
import * as socketServer from 'playwright/fixtures/socketServer';
|
||||
import { test, expect, devices } from 'playwright/lib';
|
||||
@@ -268,3 +269,25 @@ test.describe('update balances via socket', () => {
|
||||
await expect(component).toHaveScreenshot();
|
||||
});
|
||||
});
|
||||
|
||||
test('native token', async({ render, mockEnvs }) => {
|
||||
await mockEnvs([
|
||||
[ 'NEXT_PUBLIC_CELO_ENABLED', 'true' ],
|
||||
[ 'NEXT_PUBLIC_CELO_NATIVE_TOKEN_ADDRESS', tokenInfo.tokenInfoERC20c.address_hash ],
|
||||
]);
|
||||
const hooksConfig = {
|
||||
router: {
|
||||
query: { hash: ADDRESS_HASH, tab: 'tokens_erc20' },
|
||||
isReady: true,
|
||||
},
|
||||
};
|
||||
|
||||
const component = await render(
|
||||
<Box pt={{ base: '134px', lg: 6 }}>
|
||||
<AddressTokens/>
|
||||
</Box>,
|
||||
{ hooksConfig },
|
||||
);
|
||||
|
||||
await expect(component).toHaveScreenshot();
|
||||
});
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 45 KiB |
@@ -3,7 +3,7 @@ import React from 'react';
|
||||
|
||||
import * as addressMock from 'mocks/address/address';
|
||||
import * as tokensMock from 'mocks/address/tokens';
|
||||
import { tokenInfoERC20a } from 'mocks/tokens/tokenInfo';
|
||||
import { tokenInfoERC20c, tokenInfoERC20a } from 'mocks/tokens/tokenInfo';
|
||||
import { test, expect, devices } from 'playwright/lib';
|
||||
import MockAddressPage from 'ui/address/testUtils/MockAddressPage';
|
||||
|
||||
@@ -126,3 +126,22 @@ test('long values', async({ render, page, mockApiResponse }) => {
|
||||
|
||||
await expect(page).toHaveScreenshot({ clip: CLIPPING_AREA });
|
||||
});
|
||||
|
||||
test('native token', async({ render, mockEnvs, page }) => {
|
||||
await mockEnvs([
|
||||
[ 'NEXT_PUBLIC_CELO_ENABLED', 'true' ],
|
||||
[ 'NEXT_PUBLIC_CELO_NATIVE_TOKEN_ADDRESS', tokenInfoERC20c.address_hash ],
|
||||
]);
|
||||
|
||||
await render(
|
||||
<MockAddressPage>
|
||||
<Flex>
|
||||
<TokenSelect/>
|
||||
</Flex>
|
||||
</MockAddressPage>,
|
||||
{ hooksConfig },
|
||||
);
|
||||
await page.getByRole('button', { name: /select/i }).click();
|
||||
|
||||
await expect(page).toHaveScreenshot({ clip: CLIPPING_AREA });
|
||||
});
|
||||
|
||||
@@ -4,19 +4,25 @@ import React from 'react';
|
||||
|
||||
import { route } from 'nextjs-routes';
|
||||
|
||||
import config from 'configs/app';
|
||||
import getCurrencyValue from 'lib/getCurrencyValue';
|
||||
import { Link } from 'toolkit/chakra/link';
|
||||
import NativeTokenTag from 'ui/shared/celo/NativeTokenTag';
|
||||
import TokenEntity from 'ui/shared/entities/token/TokenEntity';
|
||||
import TruncatedValue from 'ui/shared/TruncatedValue';
|
||||
|
||||
import type { TokenEnhancedData } from '../utils/tokenUtils';
|
||||
|
||||
const celoFeature = config.features.celo;
|
||||
|
||||
interface Props {
|
||||
data: TokenEnhancedData;
|
||||
}
|
||||
|
||||
const TokenSelectItem = ({ data }: Props) => {
|
||||
|
||||
const isNativeToken = celoFeature.isEnabled && data.token.address_hash.toLowerCase() === celoFeature.nativeTokenAddress?.toLowerCase();
|
||||
|
||||
const secondRow = (() => {
|
||||
switch (data.token.type) {
|
||||
case 'ERC-20': {
|
||||
@@ -93,13 +99,22 @@ const TokenSelectItem = ({ data }: Props) => {
|
||||
noCopy
|
||||
noLink
|
||||
fontWeight={ 700 }
|
||||
width="auto"
|
||||
mr={ 2 }
|
||||
/>
|
||||
{ isNativeToken && <NativeTokenTag mr={ 2 }/> }
|
||||
{ data.usd && (
|
||||
<TruncatedValue value={ `$${ data.usd.toFormat(2) }` } fontWeight={ 700 } minW="120px" ml="auto" textAlign="right"/>
|
||||
<TruncatedValue
|
||||
value={ `$${ data.usd.toFormat(2) }` }
|
||||
fontWeight={ 700 }
|
||||
minW="120px"
|
||||
ml="auto"
|
||||
textAlign="right"
|
||||
color={ isNativeToken ? 'text.secondary' : undefined }
|
||||
/>
|
||||
) }
|
||||
</Flex>
|
||||
<Flex alignItems="center" justifyContent="space-between" w="100%" whiteSpace="nowrap">
|
||||
<Flex alignItems="center" justifyContent="space-between" w="100%" whiteSpace="nowrap" color={ isNativeToken ? 'text.secondary' : undefined }>
|
||||
{ secondRow }
|
||||
</Flex>
|
||||
</Link>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
@@ -3,13 +3,17 @@ import React from 'react';
|
||||
|
||||
import type { AddressTokenBalance } from 'types/api/address';
|
||||
|
||||
import config from 'configs/app';
|
||||
import getCurrencyValue from 'lib/getCurrencyValue';
|
||||
import { Skeleton } from 'toolkit/chakra/skeleton';
|
||||
import AddressAddToWallet from 'ui/shared/address/AddressAddToWallet';
|
||||
import NativeTokenTag from 'ui/shared/celo/NativeTokenTag';
|
||||
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
|
||||
import TokenEntity from 'ui/shared/entities/token/TokenEntity';
|
||||
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
|
||||
|
||||
const celoFeature = config.features.celo;
|
||||
|
||||
type Props = AddressTokenBalance & { isLoading: boolean };
|
||||
|
||||
const ERC20TokensListItem = ({ token, value, isLoading }: Props) => {
|
||||
@@ -19,16 +23,20 @@ const ERC20TokensListItem = ({ token, value, isLoading }: Props) => {
|
||||
usd: tokenValue,
|
||||
} = getCurrencyValue({ value: value, exchangeRate: token.exchange_rate, decimals: token.decimals, accuracy: 8, accuracyUsd: 2 });
|
||||
|
||||
const isNativeToken = celoFeature.isEnabled && token.address_hash.toLowerCase() === celoFeature.nativeTokenAddress?.toLowerCase();
|
||||
|
||||
return (
|
||||
<ListItemMobile rowGap={ 2 }>
|
||||
<Flex alignItems="center" width="100%">
|
||||
<Flex alignItems="center" width="100%" columnGap={ 2 }>
|
||||
<TokenEntity
|
||||
token={ token }
|
||||
isLoading={ isLoading }
|
||||
noCopy
|
||||
jointSymbol
|
||||
fontWeight="700"
|
||||
width="auto"
|
||||
/>
|
||||
{ isNativeToken && <NativeTokenTag/> }
|
||||
</Flex>
|
||||
<Flex alignItems="center" pl={ 8 }>
|
||||
<AddressEntity
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import { Flex, HStack } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
|
||||
import type { AddressTokenBalance } from 'types/api/address';
|
||||
|
||||
import config from 'configs/app';
|
||||
import getCurrencyValue from 'lib/getCurrencyValue';
|
||||
import { Skeleton } from 'toolkit/chakra/skeleton';
|
||||
import { TableCell, TableRow } from 'toolkit/chakra/table';
|
||||
import AddressAddToWallet from 'ui/shared/address/AddressAddToWallet';
|
||||
import NativeTokenTag from 'ui/shared/celo/NativeTokenTag';
|
||||
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
|
||||
import TokenEntity from 'ui/shared/entities/token/TokenEntity';
|
||||
|
||||
type Props = AddressTokenBalance & { isLoading: boolean };
|
||||
|
||||
const celoFeature = config.features.celo;
|
||||
|
||||
const ERC20TokensTableItem = ({
|
||||
token,
|
||||
value,
|
||||
@@ -23,16 +27,22 @@ const ERC20TokensTableItem = ({
|
||||
usd: tokenValue,
|
||||
} = getCurrencyValue({ value: value, exchangeRate: token.exchange_rate, decimals: token.decimals, accuracy: 8, accuracyUsd: 2 });
|
||||
|
||||
const isNativeToken = celoFeature.isEnabled && token.address_hash.toLowerCase() === celoFeature.nativeTokenAddress?.toLowerCase();
|
||||
|
||||
return (
|
||||
<TableRow role="group" >
|
||||
<TableCell verticalAlign="middle">
|
||||
<TokenEntity
|
||||
token={ token }
|
||||
isLoading={ isLoading }
|
||||
noCopy
|
||||
jointSymbol
|
||||
fontWeight="700"
|
||||
/>
|
||||
<HStack gap={ 2 }>
|
||||
<TokenEntity
|
||||
token={ token }
|
||||
isLoading={ isLoading }
|
||||
noCopy
|
||||
jointSymbol
|
||||
fontWeight="700"
|
||||
width="auto"
|
||||
/>
|
||||
{ isNativeToken && <NativeTokenTag/> }
|
||||
</HStack>
|
||||
</TableCell>
|
||||
<TableCell verticalAlign="middle">
|
||||
<Flex alignItems="center" width="150px" justifyContent="space-between">
|
||||
@@ -46,17 +56,17 @@ const ERC20TokensTableItem = ({
|
||||
</Flex>
|
||||
</TableCell>
|
||||
<TableCell isNumeric verticalAlign="middle">
|
||||
<Skeleton loading={ isLoading } display="inline-block">
|
||||
<Skeleton loading={ isLoading } display="inline-block" color={ isNativeToken ? 'text.secondary' : undefined }>
|
||||
{ token.exchange_rate && `$${ Number(token.exchange_rate).toLocaleString() }` }
|
||||
</Skeleton>
|
||||
</TableCell>
|
||||
<TableCell isNumeric verticalAlign="middle">
|
||||
<Skeleton loading={ isLoading } display="inline">
|
||||
<Skeleton loading={ isLoading } display="inline" color={ isNativeToken ? 'text.secondary' : undefined }>
|
||||
{ tokenQuantity }
|
||||
</Skeleton>
|
||||
</TableCell>
|
||||
<TableCell isNumeric verticalAlign="middle">
|
||||
<Skeleton loading={ isLoading } display="inline">
|
||||
<Skeleton loading={ isLoading } display="inline" color={ isNativeToken ? 'text.secondary' : undefined }>
|
||||
{ tokenValue && `$${ tokenValue }` }
|
||||
</Skeleton>
|
||||
</TableCell>
|
||||
|
||||
@@ -3,9 +3,15 @@ import BigNumber from 'bignumber.js';
|
||||
import type { AddressTokenBalance } from 'types/api/address';
|
||||
import type { TokenType } from 'types/api/token';
|
||||
|
||||
import config from 'configs/app';
|
||||
import sumBnReducer from 'lib/bigint/sumBnReducer';
|
||||
import { ZERO } from 'toolkit/utils/consts';
|
||||
|
||||
const celoFeature = config.features.celo;
|
||||
|
||||
const isNativeToken = (token: TokenEnhancedData) =>
|
||||
celoFeature.isEnabled && token.token.address_hash.toLowerCase() === celoFeature.nativeTokenAddress?.toLowerCase();
|
||||
|
||||
export type TokenEnhancedData = AddressTokenBalance & {
|
||||
usd?: BigNumber ;
|
||||
};
|
||||
@@ -94,7 +100,7 @@ export const calculateUsdValue = (data: AddressTokenBalance): TokenEnhancedData
|
||||
|
||||
export const getTokensTotalInfo = (data: TokenSelectData) => {
|
||||
const usd = Object.values(data)
|
||||
.map(({ items }) => items.reduce(usdValueReducer, ZERO))
|
||||
.map(({ items }) => items.filter((item) => !isNativeToken(item)).reduce(usdValueReducer, ZERO))
|
||||
.reduce(sumBnReducer, ZERO);
|
||||
|
||||
const num = Object.values(data)
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import React from 'react';
|
||||
|
||||
import config from 'configs/app';
|
||||
import { Link } from 'toolkit/chakra/link';
|
||||
import { Tag, type TagProps } from 'toolkit/chakra/tag';
|
||||
import { Tooltip } from 'toolkit/chakra/tooltip';
|
||||
|
||||
const feature = config.features.celo;
|
||||
|
||||
interface Props extends TagProps {}
|
||||
|
||||
const NativeTokenTag = (props: Props) => {
|
||||
if (!feature.isEnabled || !feature.nativeTokenAddress) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const tooltipContent = (
|
||||
<>
|
||||
<span>This ERC-20 token represents the native CELO balance for this address and isn’t counted twice. </span>
|
||||
<Link href="https://docs.celo.org/what-is-celo/using-celo/protocol/celo-token" external>
|
||||
Learn more
|
||||
</Link>
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<Tooltip content={ tooltipContent } interactive>
|
||||
<Tag { ...props }>Native token</Tag>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(NativeTokenTag);
|
||||
Reference in New Issue
Block a user