diff --git a/components/brave_wallet_ui/common/async/base-query-cache.ts b/components/brave_wallet_ui/common/async/base-query-cache.ts index 4fccda676139..0344716c07b7 100644 --- a/components/brave_wallet_ui/common/async/base-query-cache.ts +++ b/components/brave_wallet_ui/common/async/base-query-cache.ts @@ -45,15 +45,15 @@ import getAPIProxy from './bridge' import { addChainIdToToken, getAssetIdKey, - GetBlockchainTokenIdArg + GetBlockchainTokenIdArg, + getDeletedTokenIds, + getHiddenTokenIds } from '../../utils/asset-utils' import { addLogoToToken } from './lib' import { makeNetworkAsset } from '../../options/asset-options' import { isIpfs } from '../../utils/string-utils' import { getEnabledCoinTypes } from '../../utils/api-utils' -import { - getBraveRewardsProxy -} from './brave_rewards_api_proxy' +import { getBraveRewardsProxy } from './brave_rewards_api_proxy' import { getRewardsBATToken, getNormalizedExternalRewardsWallet, @@ -73,11 +73,12 @@ export class BaseQueryCache { private _networksRegistry?: NetworksRegistry private _allAccountsInfo?: BraveWallet.AllAccountsInfo private _accountsRegistry?: AccountInfoEntityState + private _knownTokensRegistry?: BlockchainTokenEntityAdaptorState private _userTokensRegistry?: BlockchainTokenEntityAdaptorState private _nftImageIpfsGateWayUrlRegistry: Record = {} private _extractedIPFSUrlRegistry: Record = {} private _enabledCoinTypes: number[] - private _erc721MetadataRegistry: Record + private _erc721MetadataRegistry: Record = {} public rewardsInfo: BraveRewardsInfo | undefined = undefined getWalletInfo = async () => { @@ -252,20 +253,32 @@ export class BaseQueryCache { this._networksRegistry = undefined } + getKnownTokensRegistry = async () => { + if (!this._knownTokensRegistry) { + const networksRegistry = await this.getNetworksRegistry() + this._knownTokensRegistry = await makeTokensRegistry( + networksRegistry, + 'known' + ) + } + return this._knownTokensRegistry + } + getUserTokensRegistry = async () => { if (!this._userTokensRegistry) { const networksRegistry = await this.getNetworksRegistry() - - const userTokensByChainIdRegistry = await makeTokensRegistry( + this._userTokensRegistry = await makeTokensRegistry( networksRegistry, 'user' ) - - this._userTokensRegistry = userTokensByChainIdRegistry } return this._userTokensRegistry } + clearKnownTokensRegistry = () => { + this._knownTokensRegistry = undefined + } + clearUserTokensRegistry = () => { this._userTokensRegistry = undefined } @@ -431,18 +444,30 @@ export async function makeTokensRegistry( networksRegistry: NetworksRegistry, listType: AssetsListType ) { + const locallyDeletedTokenIds: string[] = + listType === 'user' ? getDeletedTokenIds() : [] + const locallyHiddenTokenIds: string[] = + listType === 'user' ? getHiddenTokenIds() : [] + const locallyRemovedTokenIds = locallyDeletedTokenIds.concat( + locallyHiddenTokenIds + ) + const nonFungibleTokenIds: string[] = [] const fungibleTokenIds: string[] = [] const idsByChainId: Record = {} const idsByCoinType: Record = {} const visibleTokenIds: string[] = [] - const hiddenTokenIds: string[] = [] const visibleTokenIdsByChainId: Record = {} const hiddenTokenIdsByChainId: Record = {} const visibleTokenIdsByCoinType: Record = {} const hiddenTokenIdsByCoinType: Record = {} + const deletedTokenIds: string[] = locallyDeletedTokenIds + const hiddenTokenIds: string[] = [] + const spamTokenIds: string[] = [] + const nonSpamTokenIds: string[] = [] + const fungibleIdsByChainId: Record = {} const fungibleIdsByCoinType: Record = {} const fungibleVisibleTokenIds: string[] = [] @@ -493,34 +518,41 @@ export async function makeTokensRegistry( nonFungibleIdsByChainId[networkId] = [] nonFungibleVisibleTokenIdsByChainId[networkId] = [] nonFungibleHiddenTokenIdsByChainId[networkId] = [] + for (const token of fullTokensListForNetwork) { const tokenId = getAssetIdKey(token) const { visible } = token const isNft = token.isNft || token.isErc1155 || token.isErc721 + const isHidden = !visible || locallyRemovedTokenIds.includes(tokenId) idsByChainId[networkId].push(tokenId) + + if (token.isSpam) { + spamTokenIds.push(tokenId) + } else { + nonSpamTokenIds.push(tokenId) + } + if (isNft) { nonFungibleTokenIds.push(tokenId) nonFungibleIdsByChainId[networkId].push(tokenId) + if (isHidden) { + hiddenTokenIdsByChainId[networkId].push(tokenId) + nonFungibleHiddenTokenIdsByChainId[networkId].push(tokenId) + } else { + visibleTokenIdsByChainId[networkId].push(tokenId) + nonFungibleVisibleTokenIdsByChainId[networkId].push(tokenId) + } } else { fungibleTokenIds.push(tokenId) fungibleIdsByChainId[networkId].push(tokenId) - } - - if (visible) { - visibleTokenIdsByChainId[networkId].push(tokenId) - if (isNft) { - nonFungibleVisibleTokenIdsByChainId[networkId].push(tokenId) + if (isHidden) { + hiddenTokenIdsByChainId[networkId].push(tokenId) + fungibleHiddenTokenIdsByChainId[networkId].push(tokenId) } else { + visibleTokenIdsByChainId[networkId].push(tokenId) fungibleVisibleTokenIdsByChainId[networkId].push(tokenId) } - } else { - hiddenTokenIdsByChainId[networkId].push(tokenId) - if (isNft) { - nonFungibleHiddenTokenIdsByChainId[networkId].push(tokenId) - } else { - fungibleHiddenTokenIdsByChainId[networkId].push(tokenId) - } } } @@ -572,11 +604,12 @@ export async function makeTokensRegistry( ...fungibleVisibleTokenIdsByChainId[networkId] ) - // All hidden ids hiddenTokenIds.push(...hiddenTokenIdsByChainId[networkId]) + nonFungibleHiddenTokenIds.push( ...nonFungibleHiddenTokenIdsByChainId[networkId] ) + fungibleHiddenTokenIds.push(...fungibleHiddenTokenIdsByChainId[networkId]) return fullTokensListForNetwork @@ -589,6 +622,7 @@ export async function makeTokensRegistry( idsByChainId, visibleTokenIds, hiddenTokenIds, + deletedTokenIds, visibleTokenIdsByChainId, visibleTokenIdsByCoinType, idsByCoinType, @@ -607,7 +641,10 @@ export async function makeTokensRegistry( nonFungibleIdsByCoinType, nonFungibleVisibleTokenIds, nonFungibleVisibleTokenIdsByChainId, - nonFungibleVisibleTokenIdsByCoinType + nonFungibleVisibleTokenIdsByCoinType, + + spamTokenIds, + nonSpamTokenIds }, userTokenListsForNetworks.flat(1) ) diff --git a/components/brave_wallet_ui/common/constants/local-storage-keys.ts b/components/brave_wallet_ui/common/constants/local-storage-keys.ts index d71af48233cc..962d0ec4be32 100644 --- a/components/brave_wallet_ui/common/constants/local-storage-keys.ts +++ b/components/brave_wallet_ui/common/constants/local-storage-keys.ts @@ -34,7 +34,9 @@ export const LOCAL_STORAGE_KEYS = { CURRENT_PANEL: 'BRAVE_WALLET_CURRENT_PANEL', LAST_VISITED_PANEL: 'BRAVE_WALLET_LAST_VISITED_PANEL', TOKEN_BALANCES: 'BRAVE_WALLET_TOKEN_BALANCES', - SAVED_SESSION_ROUTE: 'BRAVE_WALLET_SAVED_SESSION_ROUTE' + SAVED_SESSION_ROUTE: 'BRAVE_WALLET_SAVED_SESSION_ROUTE', + USER_HIDDEN_TOKEN_IDS: 'BRAVE_WALLET_USER_HIDDEN_TOKEN_IDS', + USER_DELETED_TOKEN_IDS: 'BRAVE_WALLET_USER_DELETED_TOKEN_IDS' } as const const LOCAL_STORAGE_KEYS_DEPRECATED = { diff --git a/components/brave_wallet_ui/common/slices/entities/blockchain-token.entity.ts b/components/brave_wallet_ui/common/slices/entities/blockchain-token.entity.ts index 4c7ca88596fe..4ff5c91db2fb 100644 --- a/components/brave_wallet_ui/common/slices/entities/blockchain-token.entity.ts +++ b/components/brave_wallet_ui/common/slices/entities/blockchain-token.entity.ts @@ -38,6 +38,7 @@ export type BlockchainTokenEntityAdaptorState = ReturnType< idsByCoinType: Record visibleTokenIds: string[] hiddenTokenIds: string[] + deletedTokenIds: string[] visibleTokenIdsByChainId: Record visibleTokenIdsByCoinType: Record hiddenTokenIdsByChainId: Record @@ -64,6 +65,10 @@ export type BlockchainTokenEntityAdaptorState = ReturnType< nonFungibleVisibleTokenIdsByCoinType: Record nonFungibleHiddenTokenIdsByChainId: Record nonFungibleHiddenTokenIdsByCoinType: Record + + // spam + spamTokenIds: string[] + nonSpamTokenIds: string[] } export const blockchainTokenEntityAdaptorInitialState: // @@ -73,6 +78,7 @@ BlockchainTokenEntityAdaptorState = { idsByCoinType: {}, visibleTokenIds: [], hiddenTokenIds: [], + deletedTokenIds: [], visibleTokenIdsByChainId: {}, visibleTokenIdsByCoinType: {}, hiddenTokenIdsByChainId: {}, @@ -96,14 +102,16 @@ BlockchainTokenEntityAdaptorState = { nonFungibleVisibleTokenIdsByChainId: {}, nonFungibleVisibleTokenIdsByCoinType: {}, nonFungibleHiddenTokenIdsByChainId: {}, - nonFungibleHiddenTokenIdsByCoinType: {} + nonFungibleHiddenTokenIdsByCoinType: {}, + + spamTokenIds: [], + nonSpamTokenIds: [] } export const combineTokenRegistries = ( tokensRegistry: BlockchainTokenEntityAdaptorState, userTokensRegistry: BlockchainTokenEntityAdaptorState ): BlockchainTokenEntityAdaptorState => { - // TODO: hidden ids const chainIds = new Set( Object.keys(tokensRegistry.idsByChainId).concat( Object.keys(userTokensRegistry.idsByChainId) @@ -346,6 +354,11 @@ export const combineTokenRegistries = ( // use the tokens registry state to reduce amount of additions ...tokensRegistry, + // unmodified user registry ids + deletedTokenIds: userTokensRegistry.deletedTokenIds, + spamTokenIds: userTokensRegistry.spamTokenIds, + nonSpamTokenIds: userTokensRegistry.nonSpamTokenIds, + // new combined grouping Ids visibleTokenIds, hiddenTokenIds, diff --git a/components/brave_wallet_ui/utils/asset-utils.ts b/components/brave_wallet_ui/utils/asset-utils.ts index 4fc4f70791b3..2c69487d89e3 100644 --- a/components/brave_wallet_ui/utils/asset-utils.ts +++ b/components/brave_wallet_ui/utils/asset-utils.ts @@ -9,8 +9,8 @@ import { BraveWallet } from '../constants/types' // utils import Amount from './amount' import { getRampNetworkPrefix } from './string-utils' - import { getNetworkLogo, makeNativeAssetLogo } from '../options/asset-options' +import { LOCAL_STORAGE_KEYS } from '../common/constants/local-storage-keys' export const getUniqueAssets = (assets: BraveWallet.BlockchainToken[]) => { return assets.filter((asset, index) => { @@ -273,3 +273,23 @@ export function tokenNameToNftCollectionName( return token.name } + +export const getHiddenTokenIds = (): string[] => { + return JSON.parse( + localStorage.getItem(LOCAL_STORAGE_KEYS.USER_HIDDEN_TOKEN_IDS) || '[]' + ) +} + +export const getDeletedTokenIds = (): string[] => { + return JSON.parse( + localStorage.getItem(LOCAL_STORAGE_KEYS.USER_DELETED_TOKEN_IDS) || '[]' + ) +} + +export const getHiddenOrDeletedTokenIdsList = () => { + return getDeletedTokenIds().concat(getHiddenTokenIds()) +} + +export const isTokenIdRemoved = (tokenId: string, removedIds: string[]) => { + return removedIds.includes(tokenId) +}