diff --git a/packages/extension/src/shared/token/storage.ts b/packages/extension/src/shared/token/storage.ts index 61b4a5c7..f43e9e0d 100644 --- a/packages/extension/src/shared/token/storage.ts +++ b/packages/extension/src/shared/token/storage.ts @@ -41,7 +41,7 @@ export const tokenSchema: yup.Schema = baseTokenSchema export async function addToken(token: Token, verified: boolean) { await assertSchema(tokenSchema, token) - return tokenStore.push({ verified, ...token }) + return tokenStore.push({ verified, hide: false, ...token }) } export async function hasToken(token: BaseToken) { @@ -66,6 +66,11 @@ export async function removeToken(token: BaseToken) { return tokenStore.remove((t) => equalToken(t, token)) } +export async function hideToken(token: Token) { + await assertSchema(tokenSchema, token) + return tokenStore.push({ ...token, hide: true }) +} + export async function updateTokenList() { const now = new Date() const tokenListTokens = await tokenListStore.get() @@ -96,7 +101,7 @@ export async function updateTokenListNow() { export async function getTokenList(): Promise { const tokenListTokens = await tokenListStore.get() - return tokenListTokens.tokens.map((t) => ({ ...t, verified: true })) + return tokenListTokens.tokens } async function fetchTokenListByUrl(url: string): Promise { diff --git a/packages/extension/src/shared/token/type.ts b/packages/extension/src/shared/token/type.ts index f8005070..76805675 100644 --- a/packages/extension/src/shared/token/type.ts +++ b/packages/extension/src/shared/token/type.ts @@ -24,6 +24,7 @@ export interface Token extends Required { verified?: boolean originChain?: string unchainedLogoURI?: string + hide?: boolean } export interface TokenListTokens { diff --git a/packages/extension/src/shared/token/utils.ts b/packages/extension/src/shared/token/utils.ts index 05cc2ab5..960218cc 100644 --- a/packages/extension/src/shared/token/utils.ts +++ b/packages/extension/src/shared/token/utils.ts @@ -31,7 +31,7 @@ export function convertTokenList(tokenList: TokenList): Token[] { const tokens = tokenList.tokens.flatMap((token) => { const networkId = defaultNetworkIds[tokenList.networkId] if (networkId) { - return [{ networkId, ...token }] + return [{ networkId, verified: true, showAlways: true, ...token }] } else { return [] } diff --git a/packages/extension/src/ui/features/accountTokens/AccountTokens.tsx b/packages/extension/src/ui/features/accountTokens/AccountTokens.tsx index 9529f274..e4303ee2 100644 --- a/packages/extension/src/ui/features/accountTokens/AccountTokens.tsx +++ b/packages/extension/src/ui/features/accountTokens/AccountTokens.tsx @@ -1,6 +1,6 @@ import { CellStack } from "@argent/ui" import { Flex, VStack } from "@chakra-ui/react" -import { FC } from "react" +import { FC, useEffect, useState } from "react" import { Account } from "../accounts/Account" import { getAccountName, @@ -12,7 +12,8 @@ import { StatusMessageBannerContainer } from "../statusMessage/StatusMessageBann import { AccountTokensButtons } from "./AccountTokensButtons" import { AccountTokensHeader } from "./AccountTokensHeader" import { TokenList } from "./TokenList" -import { useFungibleTokensWithBalance } from "./tokens.state" +import { networkIdSelector, useFungibleTokensWithBalance } from "./tokens.state" +import { tokenStore } from "../../../shared/token/storage" interface AccountTokensProps { account: Account @@ -23,23 +24,37 @@ export const AccountTokens: FC = ({ account }) => { const { isBackupRequired } = useBackupRequired() const { tokenDetails: tokensForAccount } = useFungibleTokensWithBalance(account) const accountName = getAccountName(account, accountNames) + const [hiddenTokenIds, setHiddenTokenIds] = useState([]) const showBackupBanner = isBackupRequired + const visibleTokensForAccount = tokensForAccount.filter((token) => !hiddenTokenIds.includes(token.id)) + + useEffect(() => { + tokenStore.get(networkIdSelector(account.networkId)).then((storedTokens) => { + const tokenIds: string[] = [] + for (const token of storedTokens) { + if (token.hide) { + tokenIds.push(token.id) + } + } + setHiddenTokenIds(tokenIds) + }) + }, [tokensForAccount, account.networkId]) return ( - + {showBackupBanner && } - + ) diff --git a/packages/extension/src/ui/features/accountTokens/HideTokenScreen.tsx b/packages/extension/src/ui/features/accountTokens/HideTokenScreen.tsx index a6f05cee..a38a04e7 100644 --- a/packages/extension/src/ui/features/accountTokens/HideTokenScreen.tsx +++ b/packages/extension/src/ui/features/accountTokens/HideTokenScreen.tsx @@ -2,7 +2,7 @@ import { FC, useState } from "react" import { Navigate, useNavigate, useParams } from "react-router-dom" import styled from "styled-components" -import { removeToken } from "../../../shared/token/storage" +import { hideToken } from "../../../shared/token/storage" import { useAppState } from "../../app.state" import { Alert } from "../../components/Alert" import { routes } from "../../routes" @@ -53,7 +53,7 @@ export const HideTokenScreen: FC = () => { const handleSubmit = () => { try { - removeToken(token) + hideToken(token) navigate(routes.accountTokens()) } catch { setError(t("Token not hidden")) diff --git a/packages/extension/src/ui/features/accountTokens/SendTokenScreen.tsx b/packages/extension/src/ui/features/accountTokens/SendTokenScreen.tsx index d2cdb4d7..710d8294 100644 --- a/packages/extension/src/ui/features/accountTokens/SendTokenScreen.tsx +++ b/packages/extension/src/ui/features/accountTokens/SendTokenScreen.tsx @@ -394,7 +394,7 @@ export const SendTokenScreen: FC = () => { if (!tokenWithBalance) { return } - const { id, name, symbol, balance, decimals, logoURI, verified, originChain, unchainedLogoURI } = toTokenView(tokenWithBalance) + const { id, name, symbol, balance, decimals, logoURI, verified, originChain, unchainedLogoURI, showAlways } = toTokenView(tokenWithBalance) const handleMaxClick = () => { setMaxClicked(true) @@ -438,7 +438,7 @@ export const SendTokenScreen: FC = () => { /> } - rightButton={} + rightButton={} scrollContent={t("Send {{ token }}", { token: symbol })} > <> diff --git a/packages/extension/src/ui/features/accountTokens/TokenScreen.tsx b/packages/extension/src/ui/features/accountTokens/TokenScreen.tsx index 4ed68b4c..0001d3a5 100644 --- a/packages/extension/src/ui/features/accountTokens/TokenScreen.tsx +++ b/packages/extension/src/ui/features/accountTokens/TokenScreen.tsx @@ -101,14 +101,14 @@ export const TokenScreen: FC = () => { return } - const { id, name, symbol, logoURI, verified, originChain, unchainedLogoURI } = toTokenView(token) + const { id, name, symbol, logoURI, verified, originChain, unchainedLogoURI, showAlways } = toTokenView(token) const displayBalance = prettifyTokenBalance(token, false) const isLoading = isValidating || tokenDetailsIsInitialising return ( } - rightButton={} + rightButton={} title={name === "Ether" ? "Ethereum" : name} > diff --git a/packages/extension/src/ui/features/accountTokens/tokens.state.ts b/packages/extension/src/ui/features/accountTokens/tokens.state.ts index 7b34a098..bcfcc139 100644 --- a/packages/extension/src/ui/features/accountTokens/tokens.state.ts +++ b/packages/extension/src/ui/features/accountTokens/tokens.state.ts @@ -30,7 +30,7 @@ interface UseTokensBase { error?: any } -const networkIdSelector = memoize( +export const networkIdSelector = memoize( (networkId: string) => (token: Token) => token.networkId === networkId, ) @@ -96,7 +96,7 @@ export const useToken = (baseToken: BaseToken): Token | undefined => { const tokenFromTokenList = tokenListTokens.tokens.find((t) => equalToken(t, baseToken)) if (tokenFromTokenList) { - return { ...tokenFromTokenList, verified: true } + return { ...tokenFromTokenList, verified: true, showAlways: true } } if (token === undefined && baseToken.networkId === 'devnet') { diff --git a/packages/extension/src/ui/features/actions/AddTokenScreen.tsx b/packages/extension/src/ui/features/actions/AddTokenScreen.tsx index 580d2940..d94df7f1 100644 --- a/packages/extension/src/ui/features/actions/AddTokenScreen.tsx +++ b/packages/extension/src/ui/features/actions/AddTokenScreen.tsx @@ -51,7 +51,7 @@ const ButtonSpacer = styled.div` ` function isValidUrl(url: string | undefined): boolean { - return !!url && yup.string().url().isValidSync(url) + return !url || !!url && yup.string().url().isValidSync(url) } const isDataComplete = (data: Partial): data is Token => {