diff --git a/web/src/assets/svgs/icons/eth-token-icon.png b/web/src/assets/svgs/icons/eth-token-icon.png deleted file mode 100644 index 5366d8a..0000000 Binary files a/web/src/assets/svgs/icons/eth-token-icon.png and /dev/null differ diff --git a/web/src/assets/svgs/icons/tokens/arb.svg b/web/src/assets/svgs/icons/tokens/arb.svg new file mode 100644 index 0000000..b437dee --- /dev/null +++ b/web/src/assets/svgs/icons/tokens/arb.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/src/assets/svgs/icons/tokens/dai.svg b/web/src/assets/svgs/icons/tokens/dai.svg new file mode 100644 index 0000000..33ca83e --- /dev/null +++ b/web/src/assets/svgs/icons/tokens/dai.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/web/src/assets/svgs/icons/tokens/eth.svg b/web/src/assets/svgs/icons/tokens/eth.svg new file mode 100644 index 0000000..8c1f27f --- /dev/null +++ b/web/src/assets/svgs/icons/tokens/eth.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/web/src/assets/svgs/icons/tokens/gno.svg b/web/src/assets/svgs/icons/tokens/gno.svg new file mode 100644 index 0000000..a40787b --- /dev/null +++ b/web/src/assets/svgs/icons/tokens/gno.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/web/src/assets/svgs/icons/tokens/matic.svg b/web/src/assets/svgs/icons/tokens/matic.svg new file mode 100644 index 0000000..17864b0 --- /dev/null +++ b/web/src/assets/svgs/icons/tokens/matic.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/web/src/assets/svgs/icons/tokens/op.svg b/web/src/assets/svgs/icons/tokens/op.svg new file mode 100644 index 0000000..acfe8fe --- /dev/null +++ b/web/src/assets/svgs/icons/tokens/op.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/web/src/assets/svgs/icons/tokens/pnk.svg b/web/src/assets/svgs/icons/tokens/pnk.svg new file mode 100644 index 0000000..0e425a0 --- /dev/null +++ b/web/src/assets/svgs/icons/tokens/pnk.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/web/src/assets/svgs/icons/tokens/unknown.svg b/web/src/assets/svgs/icons/tokens/unknown.svg new file mode 100644 index 0000000..5c9c9e3 --- /dev/null +++ b/web/src/assets/svgs/icons/tokens/unknown.svg @@ -0,0 +1,4 @@ + + + + diff --git a/web/src/assets/svgs/icons/tokens/usdc.svg b/web/src/assets/svgs/icons/tokens/usdc.svg new file mode 100644 index 0000000..ecb1394 --- /dev/null +++ b/web/src/assets/svgs/icons/tokens/usdc.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/web/src/assets/svgs/icons/tokens/usdt.svg b/web/src/assets/svgs/icons/tokens/usdt.svg new file mode 100644 index 0000000..919f760 --- /dev/null +++ b/web/src/assets/svgs/icons/tokens/usdt.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/web/src/assets/svgs/icons/tokens/weth.svg b/web/src/assets/svgs/icons/tokens/weth.svg new file mode 100644 index 0000000..0058639 --- /dev/null +++ b/web/src/assets/svgs/icons/tokens/weth.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/web/src/components/TransactionCard/index.tsx b/web/src/components/TransactionCard/index.tsx index e11d81b..38901a9 100644 --- a/web/src/components/TransactionCard/index.tsx +++ b/web/src/components/TransactionCard/index.tsx @@ -72,6 +72,7 @@ const TransactionCard: React.FC = ({ const nativeTokenSymbol = useNativeTokenSymbol(); const { tokenMetadata } = useTokenMetadata(token); const erc20TokenSymbol = tokenMetadata?.symbol; + const assetSymbol = token ? erc20TokenSymbol : nativeTokenSymbol; const title = transactionInfo?.title; const navigateAndScrollTop = useNavigateAndScrollTop(); @@ -86,11 +87,11 @@ const TransactionCard: React.FC = ({ {!isUndefined(title) ? {title} : } @@ -107,11 +108,11 @@ const TransactionCard: React.FC = ({ )} diff --git a/web/src/hooks/useFilteredTokens.ts b/web/src/hooks/useFilteredTokens.ts index a7cf974..bdad3f2 100644 --- a/web/src/hooks/useFilteredTokens.ts +++ b/web/src/hooks/useFilteredTokens.ts @@ -1,7 +1,6 @@ import { useEffect, useState } from "react"; import { useTokenMetadata } from "./useTokenMetadata"; import { IToken } from "context/NewTransactionContext"; -import EthTokenIcon from "svgs/icons/eth-token-icon.png"; export const useFilteredTokens = ( searchQuery: string, @@ -27,7 +26,7 @@ export const useFilteredTokens = ( const resultToken = { symbol: tokenMetadata.symbol, address: searchQuery.toLowerCase(), - logo: tokenMetadata.logo || EthTokenIcon, + logo: tokenMetadata.logo, }; const updatedTokens = [...tokens, resultToken]; diff --git a/web/src/pages/MyTransactions/Modal/PaymentReleased/Header.tsx b/web/src/pages/MyTransactions/Modal/PaymentReleased/Header.tsx index 1a20b54..3136cb4 100644 --- a/web/src/pages/MyTransactions/Modal/PaymentReleased/Header.tsx +++ b/web/src/pages/MyTransactions/Modal/PaymentReleased/Header.tsx @@ -2,7 +2,6 @@ import React from "react"; import styled from "styled-components"; import { formatEther } from "viem"; import { useTransactionDetailsContext } from "context/TransactionDetailsContext"; -import { useNativeTokenSymbol } from "hooks/useNativeTokenSymbol"; const StyledHeader = styled.h1` margin: 0; @@ -11,12 +10,11 @@ const StyledHeader = styled.h1` `; const Header: React.FC = () => { - const { amount, token } = useTransactionDetailsContext(); - const nativeTokenSymbol = useNativeTokenSymbol(); + const { amount, assetSymbol } = useTransactionDetailsContext(); return ( - Full payment released: {formatEther(amount)} {!token ? nativeTokenSymbol : token} + Full payment released: {formatEther(amount)} {assetSymbol} ); }; diff --git a/web/src/pages/MyTransactions/TransactionDetails/index.tsx b/web/src/pages/MyTransactions/TransactionDetails/index.tsx index f718fe5..537feba 100644 --- a/web/src/pages/MyTransactions/TransactionDetails/index.tsx +++ b/web/src/pages/MyTransactions/TransactionDetails/index.tsx @@ -54,16 +54,17 @@ const TransactionDetails: React.FC = () => { } = useTransactionDetailsContext(); const transactionInfo = useFetchIpfsJson(transactionUri); + const assetSymbol = token ? erc20TokenSymbol : nativeTokenSymbol; useEffect(() => { if (transactionDetails?.escrow) { const detailsWithSymbol = { ...transactionDetails.escrow, - erc20TokenSymbol: token ? erc20TokenSymbol : nativeTokenSymbol, + assetSymbol, }; setTransactionDetails(detailsWithSymbol); } - }, [transactionDetails, setTransactionDetails, erc20TokenSymbol, nativeTokenSymbol, token]); + }, [transactionDetails, setTransactionDetails, assetSymbol]); return ( @@ -80,7 +81,6 @@ const TransactionDetails: React.FC = () => { transactionCreationTimestamp={timestamp} sendingQuantity={!isUndefined(amount) ? formatEther(amount) : ""} deadline={deadline * 1000} - assetSymbol={!token ? nativeTokenSymbol : erc20TokenSymbol} overrideIsList={false} amount={!isUndefined(amount) ? formatEther(amount) : ""} isPreview={false} @@ -95,6 +95,7 @@ const TransactionDetails: React.FC = () => { disputeRequest, resolvedEvents, arbitrationCost, + assetSymbol, }} /> {status === "NoDispute" && payments?.length === 0 ? : null} diff --git a/web/src/pages/NewTransaction/Terms/Payment/GeneralTransaction/TokenAndAmount/TokenSelector/DropdownButton.tsx b/web/src/pages/NewTransaction/Terms/Payment/GeneralTransaction/TokenAndAmount/TokenSelector/DropdownButton.tsx index 1b4e654..78002d8 100644 --- a/web/src/pages/NewTransaction/Terms/Payment/GeneralTransaction/TokenAndAmount/TokenSelector/DropdownButton.tsx +++ b/web/src/pages/NewTransaction/Terms/Payment/GeneralTransaction/TokenAndAmount/TokenSelector/DropdownButton.tsx @@ -1,6 +1,7 @@ import React from "react"; import styled from "styled-components"; import Skeleton from "react-loading-skeleton"; +import TokenIcon from "./TokenItem/TokenIcon"; const Container = styled.div` border: 1px solid ${({ theme }) => theme.stroke}; @@ -26,11 +27,6 @@ const DropdownArrow = styled.span` margin-left: 8px; `; -const TokenLogo = styled.img` - width: 24px; - height: 24px; -`; - const DropdownContent = styled.div` display: flex; align-items: center; @@ -49,16 +45,14 @@ const SymbolSkeleton = styled(Skeleton)` height: 16px; `; -export const DropdownButton = ({ loading, sendingToken, onClick }) => ( - - - {loading ? ( - - ) : ( - sendingToken && - )} - {loading ? : sendingToken?.symbol} - - - -); +export const DropdownButton = ({ loading, sendingToken, onClick }) => { + return ( + + + {loading ? : } + {loading ? : sendingToken?.symbol} + + + + ); +}; diff --git a/web/src/pages/NewTransaction/Terms/Payment/GeneralTransaction/TokenAndAmount/TokenSelector/TokenItem/TokenIcon.tsx b/web/src/pages/NewTransaction/Terms/Payment/GeneralTransaction/TokenAndAmount/TokenSelector/TokenItem/TokenIcon.tsx new file mode 100644 index 0000000..c1f14ad --- /dev/null +++ b/web/src/pages/NewTransaction/Terms/Payment/GeneralTransaction/TokenAndAmount/TokenSelector/TokenItem/TokenIcon.tsx @@ -0,0 +1,57 @@ +import React from "react"; +import styled from "styled-components"; +import ArbIcon from "tsx:svgs/icons/tokens/arb.svg"; +import DaiIcon from "tsx:svgs/icons/tokens/dai.svg"; +import EthIcon from "tsx:svgs/icons/tokens/eth.svg"; +import GnoIcon from "tsx:svgs/icons/tokens/gno.svg"; +import MaticIcon from "tsx:svgs/icons/tokens/matic.svg"; +import OpIcon from "tsx:svgs/icons/tokens/op.svg"; +import PnkIcon from "tsx:svgs/icons/tokens/pnk.svg"; +import UsdcIcon from "tsx:svgs/icons/tokens/usdc.svg"; +import UsdtIcon from "tsx:svgs/icons/tokens/usdt.svg"; +import WethIcon from "tsx:svgs/icons/tokens/weth.svg"; +import UnknownTokenIcon from "tsx:svgs/icons/tokens/unknown.svg"; + +export const TokenLogoImg = styled.img` + width: 24px; + height: 24px; +`; + +export const StyledUnknownTokenIcon = styled(UnknownTokenIcon)` + width: 24px; + height: 24px; + circle { + fill: ${({ theme }) => theme.stroke}; + } +`; + +const tokenIcons = { + arb: ArbIcon, + dai: DaiIcon, + gno: GnoIcon, + matic: MaticIcon, + op: OpIcon, + pnk: PnkIcon, + usdc: UsdcIcon, + usdt: UsdtIcon, + weth: WethIcon, + eth: EthIcon, +}; + +const getTokenLogo = (tokenSymbol) => { + const symbol = tokenSymbol.toLowerCase(); + return tokenIcons[symbol] || null; +}; + +const TokenIcon = ({ symbol, logo }) => { + const TokenLogoComponent = getTokenLogo(symbol); + if (TokenLogoComponent) { + return ; + } else if (logo) { + return ; + } else { + return ; + } +}; + +export default TokenIcon; diff --git a/web/src/pages/NewTransaction/Terms/Payment/GeneralTransaction/TokenAndAmount/TokenSelector/TokenItem/index.tsx b/web/src/pages/NewTransaction/Terms/Payment/GeneralTransaction/TokenAndAmount/TokenSelector/TokenItem/index.tsx index 05124bf..c23d6a1 100644 --- a/web/src/pages/NewTransaction/Terms/Payment/GeneralTransaction/TokenAndAmount/TokenSelector/TokenItem/index.tsx +++ b/web/src/pages/NewTransaction/Terms/Payment/GeneralTransaction/TokenAndAmount/TokenSelector/TokenItem/index.tsx @@ -1,6 +1,7 @@ import React from "react"; import styled from "styled-components"; import Balance from "./Balance"; +import TokenIcon from "./TokenIcon"; const Container = styled.div<{ selected: boolean }>` display: flex; @@ -24,11 +25,6 @@ const LogoAndLabel = styled.div` gap: 8px; `; -const TokenLogo = styled.img` - width: 24px; - height: 24px; -`; - const TokenLabel = styled.span` color: ${({ theme }) => theme.primaryText}; `; @@ -37,7 +33,7 @@ const TokenItem = ({ token, selected, onSelect }) => { return ( onSelect(token)}> - + {token.symbol} diff --git a/web/src/pages/NewTransaction/Terms/Payment/GeneralTransaction/TokenAndAmount/TokenSelector/index.tsx b/web/src/pages/NewTransaction/Terms/Payment/GeneralTransaction/TokenAndAmount/TokenSelector/index.tsx index 89b4983..8c368c2 100644 --- a/web/src/pages/NewTransaction/Terms/Payment/GeneralTransaction/TokenAndAmount/TokenSelector/index.tsx +++ b/web/src/pages/NewTransaction/Terms/Payment/GeneralTransaction/TokenAndAmount/TokenSelector/index.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect, useRef } from "react"; +import React, { useState, useEffect, useRef, useMemo } from "react"; import styled from "styled-components"; import { useClickAway } from "react-use"; import { Alchemy } from "alchemy-sdk"; @@ -25,14 +25,17 @@ const TokenSelector: React.FC = () => { const [isOpen, setIsOpen] = useState(false); const containerRef = useRef(null); const [loading, setLoading] = useState(true); - const alchemyInstance = new Alchemy(alchemyConfig(chain?.id)); + + const alchemyInstance = useMemo(() => new Alchemy(alchemyConfig(chain?.id)), [chain?.id]); + useClickAway(containerRef, () => setIsOpen(false)); useEffect(() => { if (address && chain) { + localStorage.removeItem("tokens"); initializeTokens(address, setTokens, setLoading, chain, alchemyInstance); } - }, [address, chain]); + }, [address, chain, alchemyInstance]); useEffect(() => { if (tokens?.length > 0) { diff --git a/web/src/utils/fetchNativeToken.ts b/web/src/utils/fetchNativeToken.ts index fea5078..acb7ca0 100644 --- a/web/src/utils/fetchNativeToken.ts +++ b/web/src/utils/fetchNativeToken.ts @@ -1,9 +1,6 @@ -import EthTokenIcon from "svgs/icons/eth-token-icon.png"; - export const fetchNativeToken = (chain) => { return { symbol: chain?.nativeCurrency?.symbol, address: "native", - logo: EthTokenIcon, }; }; diff --git a/web/src/utils/fetchTokenInfo.ts b/web/src/utils/fetchTokenInfo.ts index 5278485..edb2e01 100644 --- a/web/src/utils/fetchTokenInfo.ts +++ b/web/src/utils/fetchTokenInfo.ts @@ -1,17 +1,15 @@ import { Alchemy } from "alchemy-sdk"; import { IToken } from "context/NewTransactionContext"; -import EthTokenIcon from "svgs/icons/eth-token-icon.png"; export const fetchTokenInfo = async (address: string, alchemyInstance: Alchemy) => { try { const metadata = await alchemyInstance.core.getTokenMetadata(address); return { - symbol: metadata.symbol?.toUpperCase() || "Unknown", - logo: metadata.logo || EthTokenIcon, + symbol: metadata.symbol?.toUpperCase(), + logo: metadata.logo, address, } as IToken; } catch (error) { - console.error("Error fetching token info:", error); - return { symbol: "Unknown", logo: EthTokenIcon }; + return console.error("Error fetching token info:", error); } };