Skip to content

Commit

Permalink
fixup! feat(suite): nft section
Browse files Browse the repository at this point in the history
  • Loading branch information
enjojoy committed Dec 2, 2024
1 parent d6a21f1 commit 1478947
Show file tree
Hide file tree
Showing 16 changed files with 173 additions and 171 deletions.
5 changes: 5 additions & 0 deletions packages/blockchain-link-types/src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type {
AddressAlias,
TokenTransfer as BlockbookTokenTransfer,
ContractInfo,
MultiTokenValue,
StakingPool,
} from './blockbook-api';

Expand Down Expand Up @@ -188,6 +189,10 @@ export interface TokenInfo {
accounts?: TokenAccount[]; // token accounts for solana
policyId?: string; // Cardano policy id
fingerprint?: string; // Cardano starting with "asset"
multiTokenValues?: MultiTokenValue[];
ids?: string[];
totalReceived?: string;
totalSent?: string;
// transfers: number, // total transactions?
}

Expand Down
7 changes: 5 additions & 2 deletions packages/suite/src/components/wallet/TokenIconSetWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@ export const TokenIconSetWrapper = ({ accounts, network }: TokenIconSetWrapperPr

if (!allTokensWithRates.length) return null;

const tokens = getTokens(allTokensWithRates, network, coinDefinitions)
.shownWithBalance as TokensWithRates[];
const tokens = getTokens({
tokens: allTokensWithRates,
symbol: network,
tokenDefinitions: coinDefinitions,
})?.shownWithBalance as TokensWithRates[];

const aggregatedTokens = Object.values(
tokens.reduce((acc: Record<string, TokensWithRates>, token) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,22 @@ export const AccountSection = ({

const showGroup = ['ethereum', 'solana', 'cardano'].includes(networkType);

const tokens = getTokens(accountTokens, account.symbol, coinDefinitions);
const tokens = getTokens({
tokens: accountTokens,
symbol: account.symbol,
tokenDefinitions: coinDefinitions,
});

const dataTestKey = `@account-menu/${symbol}/${accountType}/${index}`;

return showGroup && (isStakeShown || tokens.shownWithBalance.length) ? (
return showGroup && (isStakeShown || tokens?.shownWithBalance?.length) ? (
<AccountItemsGroup
key={`${descriptor}-${symbol}`}
account={account}
accountLabel={accountLabel}
selected={selected}
showStaking={isStakeShown}
tokens={tokens.shownWithBalance}
tokens={tokens?.shownWithBalance}
dataTestKey={dataTestKey}
/>
) : (
Expand All @@ -62,7 +66,7 @@ export const AccountSection = ({
onClick={onItemClick}
accountLabel={accountLabel}
formattedBalance={formattedBalance}
tokens={tokens.shownWithBalance}
tokens={tokens?.shownWithBalance}
dataTestKey={dataTestKey}
/>
);
Expand Down
59 changes: 0 additions & 59 deletions packages/suite/src/utils/wallet/nftUtils.ts
Original file line number Diff line number Diff line change
@@ -1,60 +1 @@
import { isTokenDefinitionKnown, TokenDefinition } from '@suite-common/token-definitions';
import { isNftMatchesSearch, filterNftTokens } from '@suite-common/wallet-utils';
import { NetworkSymbol, getNetworkFeatures } from '@suite-common/wallet-config';
import { Token } from '@trezor/blockchain-link-types/src/blockbook-api';

type GetNfts = {
tokens: Token[];
symbol: NetworkSymbol;
nftDefinitions?: TokenDefinition;
searchQuery?: string;
};

export type NftType = 'ERC721' | 'ERC1155';

export const getNfts = ({ tokens, symbol, nftDefinitions, searchQuery }: GetNfts) => {
// filter out NFT tokens until we implement them
const nfts = filterNftTokens(tokens);

const hasNftDefinitions = getNetworkFeatures(symbol).includes('nft-definitions');

const shownVerified: Token[] = [];
const shownUnverified: Token[] = [];
const hiddenVerified: Token[] = [];
const hiddenUnverified: Token[] = [];

nfts.forEach(token => {
const isKnown = isTokenDefinitionKnown(nftDefinitions?.data, symbol, token.contract || '');
const isHidden = nftDefinitions?.hide.includes(token.contract || '');
const isShown = nftDefinitions?.show.includes(token.contract || '');

const query = searchQuery ? searchQuery.trim().toLowerCase() : '';

if (searchQuery && !isNftMatchesSearch(token, query)) return;

const pushToArray = (arrayVerified: Token[], arrayUnverified: Token[]) => {
if (isKnown) {
arrayVerified.push(token);
} else {
arrayUnverified.push(token);
}
};

if (isShown) {
pushToArray(shownVerified, shownUnverified);
} else if (hasNftDefinitions && !isKnown) {
pushToArray(hiddenVerified, hiddenUnverified);
} else if (isHidden) {
pushToArray(hiddenVerified, hiddenUnverified);
} else {
pushToArray(shownVerified, shownUnverified);
}
});

return {
shownVerified,
shownUnverified,
hiddenVerified,
hiddenUnverified,
};
};
75 changes: 59 additions & 16 deletions packages/suite/src/utils/wallet/tokenUtils.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import { BigNumber } from '@trezor/utils/src/bigNumber';
import { Account, Rate, TokenAddress, RatesByKey } from '@suite-common/wallet-types';
import { TokenInfo } from '@trezor/connect';
import { getFiatRateKey, isNftToken, isTokenMatchesSearch } from '@suite-common/wallet-utils';
import {
getFiatRateKey,
isNftMatchesSearch,
isNftToken,
isTokenMatchesSearch,
} from '@suite-common/wallet-utils';
import { NetworkSymbol, getNetworkFeatures } from '@suite-common/wallet-config';
import { FiatCurrencyCode } from '@suite-common/suite-config';
import {
EnhancedTokenInfo,
TokenDefinition,
isTokenDefinitionKnown,
} from '@suite-common/token-definitions';
import { Token } from '@trezor/blockchain-link-types/src/blockbook-api';

export interface TokensWithRates extends TokenInfo {
fiatValue: BigNumber;
Expand Down Expand Up @@ -65,16 +71,46 @@ export const formatTokenSymbol = (symbol: string) => {
return isTokenSymbolLong ? `${upperCasedSymbol.slice(0, 7)}...` : upperCasedSymbol;
};

export const getTokens = (
tokens: EnhancedTokenInfo[] | TokenInfo[],
symbol: NetworkSymbol,
coinDefinitions?: TokenDefinition,
searchQuery?: string,
) => {
type GetTokens = {
tokens: EnhancedTokenInfo[] | TokenInfo[];
symbol: NetworkSymbol;
tokenDefinitions?: TokenDefinition;
searchQuery?: string;
isNft?: boolean;
};

export type TokensResult = {
shownWithBalance: EnhancedTokenInfo[];
shownWithoutBalance: EnhancedTokenInfo[];
hiddenWithBalance: EnhancedTokenInfo[];
hiddenWithoutBalance: EnhancedTokenInfo[];
unverifiedWithBalance: EnhancedTokenInfo[];
unverifiedWithoutBalance: EnhancedTokenInfo[];
};

// export type NftTokensResult = {
// shownVerified: EnhancedTokenInfo[];
// shownUnverified: EnhancedTokenInfo[];
// hiddenVerified: EnhancedTokenInfo[];
// hiddenUnverified: EnhancedTokenInfo[];
// };

export const getTokens = ({
tokens = [],
symbol,
tokenDefinitions,
searchQuery,
isNft = false,
}: GetTokens): TokensResult => {
// filter out NFT tokens until we implement them
const tokensWithoutNFTs = tokens.filter(token => !isNftToken(token));

const hasCoinDefinitions = getNetworkFeatures(symbol).includes('coin-definitions');
const filteredTokens = isNft
? tokens.filter(token => isNftToken(token))
: tokens.filter(token => !isNftToken(token));

const hasDefinitions = getNetworkFeatures(symbol).includes(
isNft ? 'nft-definitions' : 'coin-definitions',
);

const shownWithBalance: EnhancedTokenInfo[] = [];
const shownWithoutBalance: EnhancedTokenInfo[] = [];
Expand All @@ -83,16 +119,23 @@ export const getTokens = (
const unverifiedWithBalance: EnhancedTokenInfo[] = [];
const unverifiedWithoutBalance: EnhancedTokenInfo[] = [];

tokensWithoutNFTs.forEach(token => {
const isKnown = isTokenDefinitionKnown(coinDefinitions?.data, symbol, token.contract);
const isHidden = coinDefinitions?.hide.includes(token.contract);
const isShown = coinDefinitions?.show.includes(token.contract);
filteredTokens.forEach(token => {
const isKnown = isTokenDefinitionKnown(tokenDefinitions?.data, symbol, token.contract);
const isHidden = tokenDefinitions?.hide.includes(token.contract);
const isShown = tokenDefinitions?.show.includes(token.contract);

const query = searchQuery ? searchQuery.trim().toLowerCase() : '';

if (searchQuery && !isTokenMatchesSearch(token, query)) return;
if (
searchQuery &&
(!isTokenMatchesSearch(token, query) ||
(isNft && isNftMatchesSearch(token as Token, query)))
)
return;

const hasBalance = new BigNumber(token?.balance || '0').gt(0);
const hasBalance =
new BigNumber(token?.balance || '0').gt(0) ||
(isNft && (token?.multiTokenValues?.length || 0) > 0);

const pushToArray = (
arrayWithBalance: EnhancedTokenInfo[],
Expand All @@ -107,7 +150,7 @@ export const getTokens = (

if (isShown) {
pushToArray(shownWithBalance, shownWithoutBalance);
} else if (hasCoinDefinitions && !isKnown) {
} else if (hasDefinitions && !isKnown) {
pushToArray(unverifiedWithBalance, unverifiedWithoutBalance);
} else if (isHidden) {
pushToArray(hiddenWithBalance, hiddenWithoutBalance);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,13 @@ export const handleTokensAndStakingData = (
const assetStakingBalance = accountsThatStaked.reduce((total, account) => {
return total.plus(getAccountTotalStakingBalance(account));
}, new BigNumber(0));
const tokens = getTokens(assetTokens ?? [], symbol, coinDefinitions);
const tokens = getTokens({
tokens: assetTokens ?? [],
symbol,
tokenDefinitions: coinDefinitions,
});
const tokensWithRates = enhanceTokensWithRates(
tokens.shownWithBalance ?? [],
tokens?.shownWithBalance ?? [],
localCurrency,
symbol,
currentFiatRates,
Expand Down
32 changes: 17 additions & 15 deletions packages/suite/src/views/wallet/nfts/HiddenNfts.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Banner, Column, H3 } from '@trezor/components';
import { SelectedAccountLoaded } from '@suite-common/wallet-types';
import NftsTable from './NftsTable/NftsTable';
import { selectNftDefinitions } from '@suite-common/token-definitions';

import { Translation } from 'src/components/suite';
import { Token } from '@trezor/blockchain-link-types/src/blockbook-api';
import { useSelector } from 'src/hooks/suite';
import { getNfts } from 'src/utils/wallet/nftUtils';
import { selectNftDefinitions } from '@suite-common/token-definitions';
import { filterNftTokens } from '@suite-common/wallet-utils';
import { getTokens } from 'src/utils/wallet/tokenUtils';

import NftsTable from './NftsTable/NftsTable';
import { NoTokens } from '../tokens/common/NoTokens';

type NftsTableProps = {
Expand All @@ -15,29 +15,33 @@ type NftsTableProps = {
};

const HiddenNfts = ({ selectedAccount, searchQuery }: NftsTableProps) => {
const filteredTokens = filterNftTokens(selectedAccount.account.tokens || []);
// const filteredTokens = filterNftTokens(selectedAccount.account.tokens || []);
const nftDefinitions = useSelector(state =>
selectNftDefinitions(state, selectedAccount.account.symbol),
);
const nfts = getNfts({
tokens: filteredTokens as Token[],
const nfts = getTokens({
tokens: selectedAccount.account.tokens ?? [],
symbol: selectedAccount.account.symbol,
nftDefinitions,
tokenDefinitions: nftDefinitions,
isNft: true,
searchQuery,
});

return nfts.hiddenVerified.length > 0 || nfts.hiddenUnverified.length > 0 ? (
return nfts &&
(nfts.hiddenWithBalance.length > 0 ||
nfts.hiddenWithoutBalance.length > 0 ||
nfts.unverifiedWithBalance.length > 0 ||
nfts.unverifiedWithoutBalance.length > 0) ? (
<Column gap={24} alignItems="stretch">
<NftsTable
selectedAccount={selectedAccount}
searchQuery={searchQuery}
type="ERC721"
shown={false}
verified={true}
nfts={nfts}
/>
<NftsTable
selectedAccount={selectedAccount}
searchQuery={searchQuery}
type="ERC1155"
shown={false}
verified={true}
Expand All @@ -51,23 +55,21 @@ const HiddenNfts = ({ selectedAccount, searchQuery }: NftsTableProps) => {
</Banner>
<NftsTable
selectedAccount={selectedAccount}
searchQuery={searchQuery}
type="ERC721"
shown={false}
verified={false}
nfts={nfts}
/>
<NftsTable
selectedAccount={selectedAccount}
searchQuery={searchQuery}
type="ERC1155"
shown={false}
verified={false}
nfts={nfts}
/>
</Column>
) : (
<NoTokens title={<Translation id={'TR_TOKENS_EMPTY'} />} />
<NoTokens title={<Translation id="TR_TOKENS_EMPTY" />} />
);
};

Expand Down
16 changes: 9 additions & 7 deletions packages/suite/src/views/wallet/nfts/NftsNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ import { Row } from '@trezor/components';

import { useSelector } from 'src/hooks/suite';
import { NavigationItem } from 'src/components/suite/layouts/SuiteLayout/Sidebar/NavigationItem';
import { getNfts } from 'src/utils/wallet/nftUtils';
import { selectRouteName } from 'src/reducers/suite/routerReducer';
import { SearchAction } from 'src/components/wallet/SearchAction';
import { filterNftTokens } from '@suite-common/wallet-utils';
import { getTokens } from 'src/utils/wallet/tokenUtils';

interface NftsNavigationProps {
selectedAccount: SelectedAccountLoaded;
Expand All @@ -33,9 +32,14 @@ export const NftsNavigation = ({
selectNftDefinitions(state, selectedAccount.account.symbol),
);

const filteredTokens = filterNftTokens(account.tokens || []);
// const filteredTokens = filterNftTokens(account.tokens || []);

const nfts = getNfts({ tokens: filteredTokens, symbol: account.symbol, nftDefinitions });
const nfts = getTokens({
tokens: account.tokens || [],
symbol: account.symbol,
tokenDefinitions: nftDefinitions,
isNft: true,
});

useEffect(() => {
setSearchQuery('');
Expand All @@ -52,9 +56,7 @@ export const NftsNavigation = ({
goToRoute="wallet-nfts"
preserveParams
iconSize="mediumLarge"
itemsCount={
nfts.shownVerified.length + nfts.shownUnverified.length || undefined
}
itemsCount={nfts?.shownWithBalance.length || undefined}
isRounded
typographyStyle="hint"
/>
Expand Down
Loading

0 comments on commit 1478947

Please sign in to comment.