diff --git a/components/brave_wallet_ui/common/async/lib.ts b/components/brave_wallet_ui/common/async/lib.ts index 1da6734c3e34..14955060fa88 100644 --- a/components/brave_wallet_ui/common/async/lib.ts +++ b/components/brave_wallet_ui/common/async/lib.ts @@ -676,7 +676,9 @@ export function refreshPrices () { fromAsset: network.symbol.toLowerCase(), toAsset: defaultFiatCurrency, price: nativeAssetPrice, - assetTimeframeChange: '' + assetTimeframeChange: '', + contractAddress: '', + chainId: network.chainId } })) @@ -687,7 +689,9 @@ export function refreshPrices () { fromAsset: token.token.symbol, toAsset: defaultFiatCurrency, price: '', - assetTimeframeChange: '' + assetTimeframeChange: '', + contractAddress: token.token.contractAddress, + chainId: token.token.chainId } // If a tokens balance is 0 we do not make an unnecessary api call for the price of that token @@ -705,7 +709,9 @@ export function refreshPrices () { const tokenPrice = { ...price.values[0], - fromAsset: token.token.symbol.toLowerCase() + fromAsset: token.token.symbol.toLowerCase(), + contractAddress: token.token.contractAddress, + chainId: token.token.chainId } return price.success ? tokenPrice : emptyPrice diff --git a/components/brave_wallet_ui/common/constants/mocks.ts b/components/brave_wallet_ui/common/constants/mocks.ts index d917374bb676..539233b6b21d 100644 --- a/components/brave_wallet_ui/common/constants/mocks.ts +++ b/components/brave_wallet_ui/common/constants/mocks.ts @@ -8,7 +8,8 @@ import { AppsListType, BraveWallet, SerializableTransactionInfo, - WalletAccountType + WalletAccountType, + AssetPriceWithContractAndChainId } from '../../constants/types' // mocks @@ -189,24 +190,30 @@ export const mockFilecoinAccount: WalletAccountType = { keyringId: BraveWallet.FILECOIN_TESTNET_KEYRING_ID } -export const mockAssetPrices: BraveWallet.AssetPrice[] = [ +export const mockAssetPrices: AssetPriceWithContractAndChainId[] = [ { fromAsset: 'ETH', price: '4000', toAsset: 'mockValue', - assetTimeframeChange: 'mockValue' + assetTimeframeChange: 'mockValue', + contractAddress: '0x1', + chainId: 'ETH' }, { fromAsset: 'DOG', price: '100', toAsset: 'mockValue', - assetTimeframeChange: 'mockValue' + assetTimeframeChange: 'mockValue', + contractAddress: '0xdog', + chainId: '0x1' }, { fromAsset: mockBasicAttentionToken.symbol, price: '0.88', toAsset: 'mockValue', - assetTimeframeChange: 'mockValue' + assetTimeframeChange: 'mockValue', + contractAddress: '0x0D8775F648430679A709E98d2b0Cb6250d2887EF', + chainId: '0x1' } ] diff --git a/components/brave_wallet_ui/common/hooks/assets.ts b/components/brave_wallet_ui/common/hooks/assets.ts index ae842569f45c..5412a2cf1807 100644 --- a/components/brave_wallet_ui/common/hooks/assets.ts +++ b/components/brave_wallet_ui/common/hooks/assets.ts @@ -55,8 +55,8 @@ export function useAssets () { const aBalance = getBalance(selectedAccount, a) const bBalance = getBalance(selectedAccount, b) - const bFiatBalance = computeFiatAmount(bBalance, b.symbol, b.decimals) - const aFiatBalance = computeFiatAmount(aBalance, a.symbol, a.decimals) + const bFiatBalance = computeFiatAmount(bBalance, b.symbol, b.decimals, b.contractAddress, b.chainId) + const aFiatBalance = computeFiatAmount(aBalance, a.symbol, a.decimals, a.contractAddress, a.chainId) return bFiatBalance.toNumber() - aFiatBalance.toNumber() }) diff --git a/components/brave_wallet_ui/common/hooks/pricing.test.ts b/components/brave_wallet_ui/common/hooks/pricing.test.ts index a585a4580c5d..7261bb039b46 100644 --- a/components/brave_wallet_ui/common/hooks/pricing.test.ts +++ b/components/brave_wallet_ui/common/hooks/pricing.test.ts @@ -12,26 +12,26 @@ import usePricing from './pricing' describe('usePricing hook', () => { it('should return asset price of DOG token', () => { const { result } = renderHook(() => usePricing(mockAssetPrices)) - expect(result.current.findAssetPrice('DOG')).toEqual('100') + expect(result.current.findAssetPrice('DOG', '0xdog', '0x1')).toEqual('100') }) it('should return empty asset price of unknown token', () => { const { result } = renderHook(() => usePricing(mockAssetPrices)) - expect(result.current.findAssetPrice('CAT')).toEqual('') + expect(result.current.findAssetPrice('CAT', '0xcat', '0x1')).toEqual('') }) it('should compute fiat amount for DOG token', () => { const { result } = renderHook(() => usePricing(mockAssetPrices)) - expect(result.current.computeFiatAmount('7', 'DOG', 1).formatAsFiat()).toEqual('70.00') + expect(result.current.computeFiatAmount('7', 'DOG', 1, '0xdog', '0x1').formatAsFiat()).toEqual('70.00') }) it('should return empty fiat value for unknown token', () => { const { result } = renderHook(() => usePricing(mockAssetPrices)) - expect(result.current.computeFiatAmount('7', 'CAT', 0).formatAsFiat()).toEqual('') + expect(result.current.computeFiatAmount('7', 'CAT', 0, '0xcat', '0x1').formatAsFiat()).toEqual('') }) it('should return empty fiat value for empty amount', () => { const { result } = renderHook(() => usePricing(mockAssetPrices)) - expect(result.current.computeFiatAmount('', 'DOG', 0).formatAsFiat()).toEqual('') + expect(result.current.computeFiatAmount('', 'DOG', 0, '0xdog', '0x1').formatAsFiat()).toEqual('') }) }) diff --git a/components/brave_wallet_ui/common/hooks/pricing.ts b/components/brave_wallet_ui/common/hooks/pricing.ts index 131f13679980..3611e31d0160 100644 --- a/components/brave_wallet_ui/common/hooks/pricing.ts +++ b/components/brave_wallet_ui/common/hooks/pricing.ts @@ -6,20 +6,32 @@ import * as React from 'react' // types -import { BraveWallet } from '../../constants/types' +import { AssetPriceWithContractAndChainId } from '../../constants/types' // utils import Amount from '../../utils/amount' import { findAssetPrice, computeFiatAmount } from '../../utils/pricing-utils' -export default function usePricing (spotPrices: BraveWallet.AssetPrice[]) { - const _findAssetPrice = React.useCallback((symbol: string) => { - return findAssetPrice(spotPrices, symbol) - }, [spotPrices]) +export default function usePricing (spotPrices: AssetPriceWithContractAndChainId[]) { + const _findAssetPrice = React.useCallback( + ( + symbol: string, + contractAddress: string, + chainId: string + ) => { + return findAssetPrice(spotPrices, symbol, contractAddress, chainId) + }, [spotPrices]) - const _computeFiatAmount = React.useCallback((value: string, symbol: string, decimals: number): Amount => { - return computeFiatAmount(spotPrices, { decimals, symbol, value }) - }, [spotPrices]) + const _computeFiatAmount = React.useCallback( + ( + value: string, + symbol: string, + decimals: number, + contractAddress: string, + chainId: string + ): Amount => { + return computeFiatAmount(spotPrices, { decimals, symbol, value, contractAddress, chainId }) + }, [spotPrices]) return { computeFiatAmount: _computeFiatAmount, diff --git a/components/brave_wallet_ui/components/desktop/popup-modals/sell-asset-modal/sell-asset-modal.tsx b/components/brave_wallet_ui/components/desktop/popup-modals/sell-asset-modal/sell-asset-modal.tsx index 8c2e9d4a2163..c953404430c9 100644 --- a/components/brave_wallet_ui/components/desktop/popup-modals/sell-asset-modal/sell-asset-modal.tsx +++ b/components/brave_wallet_ui/components/desktop/popup-modals/sell-asset-modal/sell-asset-modal.tsx @@ -82,17 +82,38 @@ export const SellAssetModal = (props: Props) => { { decimals: selectedAsset?.decimals ?? '', symbol: selectedAsset?.symbol ?? '', - value: sellAssetBalance + contractAddress: selectedAsset?.contractAddress ?? '', + value: sellAssetBalance, + chainId: selectedAsset?.chainId ?? '' }) - }, [spotPrices, sellAssetBalance, selectedAsset?.symbol, selectedAsset?.decimals]) + }, [ + spotPrices, + sellAssetBalance, + selectedAsset?.symbol, + selectedAsset?.decimals, + selectedAsset?.contractAddress, + selectedAsset.chainId + ]) const estimatedAssetAmount = React.useMemo(() => { if (sellAmount !== '') { - return `~${computeFiatAmountToAssetValue(sellAmount, spotPrices, selectedAsset?.symbol ?? '') + return `~${computeFiatAmountToAssetValue( + sellAmount, + spotPrices, + selectedAsset?.symbol ?? '', + selectedAsset?.contractAddress ?? '', + selectedAsset?.chainId ?? '' + ) .formatAsAsset(6, selectedAsset.symbol)}` } return `0.00 ${selectedAsset?.symbol}` - }, [sellAmount, spotPrices, selectedAsset.symbol]) + }, [ + sellAmount, + spotPrices, + selectedAsset?.symbol, + selectedAsset?.contractAddress, + selectedAsset?.chainId + ]) const formattedFiatBalance = React.useMemo(() => { return fiatBalance ? new Amount(fiatBalance.format(2)).formatAsFiat(defaultCurrencies.fiat) : undefined diff --git a/components/brave_wallet_ui/components/desktop/portfolio-account-item/index.tsx b/components/brave_wallet_ui/components/desktop/portfolio-account-item/index.tsx index e3931d46ed75..35dcee833b31 100644 --- a/components/brave_wallet_ui/components/desktop/portfolio-account-item/index.tsx +++ b/components/brave_wallet_ui/components/desktop/portfolio-account-item/index.tsx @@ -7,7 +7,7 @@ import { create } from 'ethereum-blockies' import { useHistory } from 'react-router' // Types -import { BraveWallet, DefaultCurrencies, WalletRoutes } from '../../../constants/types' +import { BraveWallet, DefaultCurrencies, WalletRoutes, AssetPriceWithContractAndChainId } from '../../../constants/types' // Hooks import { useExplorer, usePricing } from '../../../common/hooks' @@ -42,9 +42,11 @@ import { import { SellButtonRow, SellButton } from '../../shared/style' interface Props { - spotPrices: BraveWallet.AssetPrice[] + spotPrices: AssetPriceWithContractAndChainId[] address: string defaultCurrencies: DefaultCurrencies + assetContractAddress: string + assetChainId: string assetBalance: string assetTicker: string assetDecimals: number @@ -58,6 +60,8 @@ interface Props { export const PortfolioAccountItem = (props: Props) => { const { + assetContractAddress, + assetChainId, assetBalance, address, assetTicker, @@ -94,8 +98,8 @@ export const PortfolioAccountItem = (props: Props) => { }, [assetBalance, assetDecimals]) const fiatBalance: Amount = React.useMemo(() => { - return computeFiatAmount(assetBalance, assetTicker, assetDecimals) - }, [computeFiatAmount, assetDecimals, assetBalance, assetTicker]) + return computeFiatAmount(assetBalance, assetTicker, assetDecimals, assetContractAddress, assetChainId) + }, [computeFiatAmount, assetDecimals, assetBalance, assetTicker, assetContractAddress, assetChainId]) const isAssetsBalanceZero = React.useMemo(() => { return new Amount(assetBalance).isZero() diff --git a/components/brave_wallet_ui/components/desktop/portfolio-asset-item/index.tsx b/components/brave_wallet_ui/components/desktop/portfolio-asset-item/index.tsx index df78e7677cd2..d231cb13aa7c 100644 --- a/components/brave_wallet_ui/components/desktop/portfolio-asset-item/index.tsx +++ b/components/brave_wallet_ui/components/desktop/portfolio-asset-item/index.tsx @@ -84,8 +84,14 @@ export const PortfolioAssetItem = ({ .formatAsAsset(6, token.symbol) const fiatBalance = React.useMemo(() => { - return computeFiatAmount(spotPrices, { decimals: token.decimals, symbol: token.symbol, value: assetBalance }) - }, [spotPrices, assetBalance, token.symbol, token.decimals]) + return computeFiatAmount(spotPrices, { + decimals: token.decimals, + symbol: token.symbol, + value: assetBalance, + contractAddress: token.contractAddress, + chainId: token.chainId + }) + }, [spotPrices, assetBalance, token.symbol, token.decimals, token.chainId]) const formattedFiatBalance = React.useMemo(() => { return fiatBalance.formatAsFiat(defaultCurrencies.fiat) diff --git a/components/brave_wallet_ui/components/desktop/views/portfolio/components/accounts-and-transctions-list/index.tsx b/components/brave_wallet_ui/components/desktop/views/portfolio/components/accounts-and-transctions-list/index.tsx index cad7eed7023a..19964175b930 100644 --- a/components/brave_wallet_ui/components/desktop/views/portfolio/components/accounts-and-transctions-list/index.tsx +++ b/components/brave_wallet_ui/components/desktop/views/portfolio/components/accounts-and-transctions-list/index.tsx @@ -166,6 +166,8 @@ export const AccountsAndTransactionsList = ({ spotPrices={transactionSpotPrices} defaultCurrencies={defaultCurrencies} key={account.address} + assetContractAddress={selectedAsset.contractAddress} + assetChainId={selectedAsset.chainId} assetTicker={selectedAsset.symbol} assetDecimals={selectedAsset.decimals} name={account.name} diff --git a/components/brave_wallet_ui/components/desktop/views/portfolio/components/token-lists/token-list.tsx b/components/brave_wallet_ui/components/desktop/views/portfolio/components/token-lists/token-list.tsx index 9a0bdad20b6e..b6c5bdcb830f 100644 --- a/components/brave_wallet_ui/components/desktop/views/portfolio/components/token-lists/token-list.tsx +++ b/components/brave_wallet_ui/components/desktop/views/portfolio/components/token-lists/token-list.tsx @@ -146,8 +146,8 @@ export const TokenLists = ({ return [...fungibleTokens].sort(function (a, b) { const aBalance = a.assetBalance const bBalance = b.assetBalance - const bFiatBalance = computeFiatAmount(bBalance, b.asset.symbol, b.asset.decimals) - const aFiatBalance = computeFiatAmount(aBalance, a.asset.symbol, a.asset.decimals) + const bFiatBalance = computeFiatAmount(bBalance, b.asset.symbol, b.asset.decimals, b.asset.contractAddress, b.asset.chainId) + const aFiatBalance = computeFiatAmount(aBalance, a.asset.symbol, a.asset.decimals, a.asset.contractAddress, a.asset.chainId) return assetFilterItemInfo.id === 'highToLow' ? bFiatBalance.toNumber() - aFiatBalance.toNumber() : aFiatBalance.toNumber() - bFiatBalance.toNumber() diff --git a/components/brave_wallet_ui/components/desktop/views/portfolio/portfolio-asset.tsx b/components/brave_wallet_ui/components/desktop/views/portfolio/portfolio-asset.tsx index 37e810458d9e..6db3406de39a 100644 --- a/components/brave_wallet_ui/components/desktop/views/portfolio/portfolio-asset.tsx +++ b/components/brave_wallet_ui/components/desktop/views/portfolio/portfolio-asset.tsx @@ -276,7 +276,13 @@ export const PortfolioAsset = (props: Props) => { const visibleAssetFiatBalances = visibleAssetOptions .map((item) => { - return computeFiatAmount(item.assetBalance, item.asset.symbol, item.asset.decimals) + return computeFiatAmount( + item.assetBalance, + item.asset.symbol, + item.asset.decimals, + item.asset.contractAddress, + item.asset.chainId + ) }) const grandTotal = visibleAssetFiatBalances.reduce(function (a, b) { @@ -347,7 +353,9 @@ export const PortfolioAsset = (props: Props) => { ? computeFiatAmount( fullAssetBalances.assetBalance, fullAssetBalances.asset.symbol, - fullAssetBalances.asset.decimals + fullAssetBalances.asset.decimals, + fullAssetBalances.asset.contractAddress, + fullAssetBalances.asset.chainId ) : Amount.empty(), [fullAssetBalances] diff --git a/components/brave_wallet_ui/components/desktop/views/portfolio/portfolio-overview.tsx b/components/brave_wallet_ui/components/desktop/views/portfolio/portfolio-overview.tsx index e1bed5f440e8..d3dca9c4333d 100644 --- a/components/brave_wallet_ui/components/desktop/views/portfolio/portfolio-overview.tsx +++ b/components/brave_wallet_ui/components/desktop/views/portfolio/portfolio-overview.tsx @@ -156,7 +156,9 @@ export const PortfolioOverview = () => { { value: item.assetBalance, decimals: item.asset.decimals, - symbol: item.asset.symbol + symbol: item.asset.symbol, + contractAddress: item.asset.contractAddress, + chainId: item.asset.chainId } ) }) diff --git a/components/brave_wallet_ui/components/extension/confirm-transaction-panel/common/gas.tsx b/components/brave_wallet_ui/components/extension/confirm-transaction-panel/common/gas.tsx index 763de4e722bd..95d3f6e205f9 100644 --- a/components/brave_wallet_ui/components/extension/confirm-transaction-panel/common/gas.tsx +++ b/components/brave_wallet_ui/components/extension/confirm-transaction-panel/common/gas.tsx @@ -48,7 +48,7 @@ export function EditPendingTransactionGas (props: Props) { { } return computeFiatAmount( - selectedAccount.nativeBalanceRegistry[selectedNetwork.chainId], selectedNetwork.symbol, selectedNetwork.decimals + selectedAccount.nativeBalanceRegistry[selectedNetwork.chainId], + selectedNetwork.symbol, + selectedNetwork.decimals, + '', + selectedNetwork.chainId ) }, [computeFiatAmount, selectedNetwork, selectedAccount]) diff --git a/components/brave_wallet_ui/constants/types.ts b/components/brave_wallet_ui/constants/types.ts index 19ebb7808b8f..788702252c22 100644 --- a/components/brave_wallet_ui/constants/types.ts +++ b/components/brave_wallet_ui/constants/types.ts @@ -221,6 +221,11 @@ export interface TokenRegistry { [chainID: string]: BraveWallet.BlockchainToken[] } +export interface AssetPriceWithContractAndChainId extends BraveWallet.AssetPrice { + contractAddress: string + chainId: string +} + export interface WalletState { hasInitialized: boolean isFilecoinEnabled: boolean @@ -244,7 +249,7 @@ export interface WalletState { selectedPortfolioTimeline: BraveWallet.AssetPriceTimeframe networkList: BraveWallet.NetworkInfo[] hiddenNetworkList: BraveWallet.NetworkInfo[] - transactionSpotPrices: BraveWallet.AssetPrice[] + transactionSpotPrices: AssetPriceWithContractAndChainId[] addUserAssetError: boolean defaultEthereumWallet: BraveWallet.DefaultWallet defaultSolanaWallet: BraveWallet.DefaultWallet @@ -302,8 +307,8 @@ export interface PageState { enablingAutoPin: boolean isAutoPinEnabled: boolean pinStatusOverview: BraveWallet.TokenPinOverview | undefined - selectedAssetFiatPrice: BraveWallet.AssetPrice | undefined - selectedAssetCryptoPrice: BraveWallet.AssetPrice | undefined + selectedAssetFiatPrice: AssetPriceWithContractAndChainId | undefined + selectedAssetCryptoPrice: AssetPriceWithContractAndChainId | undefined selectedAssetPriceHistory: GetPriceHistoryReturnInfo[] portfolioPriceHistory: PriceDataObjectType[] mnemonic?: string @@ -364,7 +369,7 @@ export type SwapValidationErrorType = export interface GetPriceReturnInfo { success: boolean - values: BraveWallet.AssetPrice[] + values: AssetPriceWithContractAndChainId[] } export interface GetPriceHistoryReturnInfo { diff --git a/components/brave_wallet_ui/page/async/wallet_page_async_handler.ts b/components/brave_wallet_ui/page/async/wallet_page_async_handler.ts index a4837b6282eb..143829d265f8 100644 --- a/components/brave_wallet_ui/page/async/wallet_page_async_handler.ts +++ b/components/brave_wallet_ui/page/async/wallet_page_async_handler.ts @@ -141,7 +141,22 @@ handler.on(WalletPageActions.selectAsset.type, async (store: Store, payload: Upd const selectedAsset = payload.asset const defaultPrices = await assetRatioService.getPrice([getTokenParam(selectedAsset)], [defaultFiat, defaultCrypto], payload.timeFrame) const priceHistory = await assetRatioService.getPriceHistory(getTokenParam(selectedAsset), defaultFiat, payload.timeFrame) - store.dispatch(WalletPageActions.updatePriceInfo({ priceHistory: priceHistory, defaultFiatPrice: defaultPrices.values[0], defaultCryptoPrice: defaultPrices.values[1], timeFrame: payload.timeFrame })) + store.dispatch(WalletPageActions.updatePriceInfo( + { + priceHistory: priceHistory, + defaultFiatPrice: { + ...defaultPrices.values[0], + contractAddress: payload.asset.contractAddress, + chainId: payload.asset.chainId + }, + defaultCryptoPrice: { + ...defaultPrices.values[1], + contractAddress: payload.asset.contractAddress, + chainId: payload.asset.chainId + }, + timeFrame: payload.timeFrame + } + )) if (payload.asset.isErc721 || payload.asset.isNft) { store.dispatch(WalletPageActions.getNFTMetadata(payload.asset)) diff --git a/components/brave_wallet_ui/page/constants/action_types.ts b/components/brave_wallet_ui/page/constants/action_types.ts index 9f17d91d07bd..ad4d606ea718 100644 --- a/components/brave_wallet_ui/page/constants/action_types.ts +++ b/components/brave_wallet_ui/page/constants/action_types.ts @@ -6,7 +6,8 @@ import { FilecoinNetwork } from '../../common/hardware/types' import { BraveWallet, - GetPriceHistoryReturnObjectInfo + GetPriceHistoryReturnObjectInfo, + AssetPriceWithContractAndChainId } from '../../constants/types' export type CreateWalletPayloadType = { @@ -82,8 +83,8 @@ export type UpdateSelectedAssetType = { export type SelectAssetPayloadType = { priceHistory: GetPriceHistoryReturnObjectInfo | undefined - defaultFiatPrice?: BraveWallet.AssetPrice - defaultCryptoPrice?: BraveWallet.AssetPrice + defaultFiatPrice?: AssetPriceWithContractAndChainId + defaultCryptoPrice?: AssetPriceWithContractAndChainId timeFrame: BraveWallet.AssetPriceTimeframe } diff --git a/components/brave_wallet_ui/page/screens/send/components/select-token-modal/select-token-modal.tsx b/components/brave_wallet_ui/page/screens/send/components/select-token-modal/select-token-modal.tsx index 3938b53e84aa..9d9094b43e33 100644 --- a/components/brave_wallet_ui/page/screens/send/components/select-token-modal/select-token-modal.tsx +++ b/components/brave_wallet_ui/page/screens/send/components/select-token-modal/select-token-modal.tsx @@ -121,7 +121,13 @@ export const SelectTokenModal = React.forwardRef( const getAccountFiatValue = React.useCallback((account: WalletAccountType) => { const amounts = getTokensBySearchValue(account).map((token) => { const balance = getBalance(account, token) - return computeFiatAmount(spotPrices, { decimals: token.decimals, symbol: token.symbol, value: balance }).format() + return computeFiatAmount(spotPrices, { + decimals: token.decimals, + symbol: token.symbol, + value: balance, + contractAddress: token.contractAddress, + chainId: token.chainId + }).format() }) const reducedAmounts = amounts.reduce(function (a, b) { return a !== '' && b !== '' diff --git a/components/brave_wallet_ui/page/screens/send/components/token-list-item/token-list-item.tsx b/components/brave_wallet_ui/page/screens/send/components/token-list-item/token-list-item.tsx index 4d37563f1bcc..207a9f6b1330 100644 --- a/components/brave_wallet_ui/page/screens/send/components/token-list-item/token-list-item.tsx +++ b/components/brave_wallet_ui/page/screens/send/components/token-list-item/token-list-item.tsx @@ -69,8 +69,21 @@ export const TokenListItem = (props: Props) => { }, [token, networks]) const fiatBalance = React.useMemo(() => { - return computeFiatAmount(spotPrices, { decimals: token.decimals, symbol: token.symbol, value: balance }) - }, [spotPrices, balance, token.symbol, token.decimals]) + return computeFiatAmount(spotPrices, { + decimals: token.decimals, + symbol: token.symbol, + value: balance, + contractAddress: token.contractAddress, + chainId: token.chainId + }) + }, [ + spotPrices, + balance, + token.symbol, + token.decimals, + token.contractAddress, + token.chainId + ]) const formattedFiatBalance = React.useMemo(() => { return fiatBalance.formatAsFiat(defaultCurrencies.fiat) diff --git a/components/brave_wallet_ui/page/screens/send/send/send.tsx b/components/brave_wallet_ui/page/screens/send/send/send.tsx index f78bad787043..bf33ad4a0614 100644 --- a/components/brave_wallet_ui/page/screens/send/send/send.tsx +++ b/components/brave_wallet_ui/page/screens/send/send/send.tsx @@ -219,7 +219,9 @@ export const Send = (props: Props) => { symbol: selectedSendAsset.symbol, value: new Amount(sendAmount !== '' ? sendAmount : '0') .multiplyByDecimals(selectedSendAsset.decimals) // ETH → Wei conversion - .toHex() + .toHex(), + contractAddress: selectedSendAsset.contractAddress, + chainId: selectedSendAsset.chainId }).formatAsFiat(defaultCurrencies.fiat) }, [spotPrices, selectedSendAsset, sendAmount, defaultCurrencies.fiat, sendAssetBalance, selectedSendOption]) diff --git a/components/brave_wallet_ui/stories/mock-data/current-price-data.ts b/components/brave_wallet_ui/stories/mock-data/current-price-data.ts index 3e8c41383ca1..14511b499d24 100644 --- a/components/brave_wallet_ui/stories/mock-data/current-price-data.ts +++ b/components/brave_wallet_ui/stories/mock-data/current-price-data.ts @@ -2,7 +2,7 @@ // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this file, // you can obtain one at https://mozilla.org/MPL/2.0/. -import { BraveWallet } from '../../constants/types' +import { AssetPriceWithContractAndChainId } from '../../constants/types' export const mockedCurrentPriceData = [ { @@ -40,17 +40,21 @@ export const mockedCurrentPriceData = [ } ] -export const mockTransactionSpotPrices: BraveWallet.AssetPrice[] = [ +export const mockTransactionSpotPrices: AssetPriceWithContractAndChainId[] = [ { fromAsset: 'ETH', toAsset: 'USD', price: '3300', - assetTimeframeChange: '' + assetTimeframeChange: '', + contractAddress: '', + chainId: '0x1' }, { fromAsset: 'BAT', toAsset: 'USD', price: '0.85', - assetTimeframeChange: '' + assetTimeframeChange: '', + contractAddress: '0x0D8775F648430679A709E98d2b0Cb6250d2887EF', + chainId: '0x1' } ] diff --git a/components/brave_wallet_ui/stories/mock-data/mock-wallet-state.ts b/components/brave_wallet_ui/stories/mock-data/mock-wallet-state.ts index 67ef7ba9ef87..758d5223938c 100644 --- a/components/brave_wallet_ui/stories/mock-data/mock-wallet-state.ts +++ b/components/brave_wallet_ui/stories/mock-data/mock-wallet-state.ts @@ -231,19 +231,25 @@ export const mockWalletState: WalletState = { assetTimeframeChange: '', fromAsset: 'eth', price: '2581.2', - toAsset: 'usd' + toAsset: 'usd', + contractAddress: '', + chainId: '0x1' }, { assetTimeframeChange: '', fromAsset: 'eth', price: '0', - toAsset: 'usd' + toAsset: 'usd', + contractAddress: '', + chainId: '0x1' }, { assetTimeframeChange: '-0.18757681821254726', fromAsset: 'usdc', price: '0.999414', - toAsset: 'usd' + toAsset: 'usd', + contractAddress: '0xusdc', + chainId: '0x1' } ], userVisibleTokensInfo: [ diff --git a/components/brave_wallet_ui/utils/pricing-utils.test.ts b/components/brave_wallet_ui/utils/pricing-utils.test.ts index 3ea999d85ef5..d524b28646c7 100644 --- a/components/brave_wallet_ui/utils/pricing-utils.test.ts +++ b/components/brave_wallet_ui/utils/pricing-utils.test.ts @@ -16,11 +16,13 @@ import { describe('findAssetPrice', () => { it('should find the price of a coin from within a list of asset prices', () => { - const { symbol } = mockBasicAttentionToken + const { symbol, chainId, contractAddress } = mockBasicAttentionToken expect( findAssetPrice( mockAssetPrices, - symbol + symbol, + contractAddress, + chainId ) ).toBe('0.88') }) @@ -28,12 +30,12 @@ describe('findAssetPrice', () => { describe('computeFiatAmount', () => { it('should find and convert the fiat value of a token', () => { - const { symbol, decimals } = mockBasicAttentionToken + const { symbol, decimals, contractAddress, chainId } = mockBasicAttentionToken expect( computeFiatAmount( mockAssetPrices, - { symbol, decimals, value: '20' } + { symbol, decimals, value: '20', contractAddress, chainId } ).format() ).toBe('0.0000000000000000176') }) @@ -41,13 +43,15 @@ describe('computeFiatAmount', () => { describe('computeFiatAmountToAssetValue', () => { it('should find and convert the fiat amoount to token value', () => { - const { symbol } = mockBasicAttentionToken + const { symbol, contractAddress, chainId } = mockBasicAttentionToken expect( computeFiatAmountToAssetValue( '200', mockAssetPrices, - symbol + symbol, + contractAddress, + chainId ).format(6) ).toBe('227.273') }) diff --git a/components/brave_wallet_ui/utils/pricing-utils.ts b/components/brave_wallet_ui/utils/pricing-utils.ts index 4151c3b9c664..2f7b940c68de 100644 --- a/components/brave_wallet_ui/utils/pricing-utils.ts +++ b/components/brave_wallet_ui/utils/pricing-utils.ts @@ -3,24 +3,33 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this file, // you can obtain one at https://mozilla.org/MPL/2.0/. -import { BraveWallet } from '../constants/types' +import { AssetPriceWithContractAndChainId } from '../constants/types' import Amount from './amount' -export const findAssetPrice = (spotPrices: BraveWallet.AssetPrice[], symbol: string) => { +export const findAssetPrice = ( + spotPrices: AssetPriceWithContractAndChainId[], + symbol: string, + contractAddress: string, + chainId: string +) => { return spotPrices.find( - (token) => token.fromAsset.toLowerCase() === symbol.toLowerCase() + (token) => token.fromAsset.toLowerCase() === symbol.toLowerCase() && + token.contractAddress === contractAddress && + token.chainId === chainId )?.price ?? '' } export const computeFiatAmount = ( - spotPrices: BraveWallet.AssetPrice[], + spotPrices: AssetPriceWithContractAndChainId[], asset: { value: string symbol: string decimals: number + contractAddress: string + chainId: string } ): Amount => { - const price = findAssetPrice(spotPrices, asset.symbol) + const price = findAssetPrice(spotPrices, asset.symbol, asset.contractAddress, asset.chainId) if (!price || !asset.value) { return Amount.empty() @@ -33,10 +42,12 @@ export const computeFiatAmount = ( export const computeFiatAmountToAssetValue = ( fiatAmount: string, - spotPrices: BraveWallet.AssetPrice[], - assetSymbol: string + spotPrices: AssetPriceWithContractAndChainId[], + assetSymbol: string, + contractAddress: string, + chainId: string ): Amount => { - const price = findAssetPrice(spotPrices, assetSymbol) + const price = findAssetPrice(spotPrices, assetSymbol, contractAddress, chainId) if (!price || !fiatAmount) { return Amount.empty() diff --git a/components/brave_wallet_ui/utils/tx-utils.ts b/components/brave_wallet_ui/utils/tx-utils.ts index 10d1f2ab1ce1..036d4f85779d 100644 --- a/components/brave_wallet_ui/utils/tx-utils.ts +++ b/components/brave_wallet_ui/utils/tx-utils.ts @@ -16,7 +16,8 @@ import { TimeDelta, SerializableTimeDelta, SerializableOriginInfo, - SortingOrder + SortingOrder, + AssetPriceWithContractAndChainId } from '../constants/types' import { SolanaTransactionTypes } from '../common/constants/solana' import { MAX_UINT256, NATIVE_ASSET_CONTRACT_ADDRESS_0X } from '../common/constants/magics' @@ -1317,7 +1318,7 @@ export const getTransactionFiatValues = ({ normalizedTransferredValue: string sellAmountWei?: string sellToken?: BraveWallet.BlockchainToken - spotPrices: BraveWallet.AssetPrice[] + spotPrices: AssetPriceWithContractAndChainId[] token?: BraveWallet.BlockchainToken transferredValueWei?: string tx: TransactionInfo @@ -1339,7 +1340,9 @@ export const getTransactionFiatValues = ({ ? computeFiatAmount(spotPrices, { decimals: txNetwork.decimals, symbol: txNetwork.symbol, - value: transferredValueWei || '' + value: transferredValueWei || '', + contractAddress: '', + chainId: txNetwork.chainId }) : Amount.empty() @@ -1356,7 +1359,7 @@ export const getTransactionFiatValues = ({ if (tx.txType === BraveWallet.TransactionType.ERC20Transfer) { const [, amount] = tx.txArgs // (address recipient, uint256 amount) → bool - const price = findAssetPrice(spotPrices, token?.symbol ?? '') + const price = findAssetPrice(spotPrices, token?.symbol ?? '', token?.contractAddress ?? '', token?.chainId ?? '') const sendAmountFiat = new Amount(amount) .divideByDecimals(token?.decimals ?? 18) @@ -1399,7 +1402,7 @@ export const getTransactionFiatValues = ({ // SPL if (isSolanaSplTransaction(tx)) { - const price = findAssetPrice(spotPrices, token?.symbol ?? '') + const price = findAssetPrice(spotPrices, token?.symbol ?? '', token?.contractAddress ?? '', token?.chainId ?? '') const sendAmountFiat = new Amount(normalizedTransferredValue).times(price) return { @@ -1419,7 +1422,9 @@ export const getTransactionFiatValues = ({ ? computeFiatAmount(spotPrices, { decimals: sellToken.decimals, symbol: sellToken.symbol, - value: sellAmountWei + value: sellAmountWei, + contractAddress: sellToken.contractAddress, + chainId: sellToken.chainId }) : Amount.empty() @@ -1437,7 +1442,9 @@ export const getTransactionFiatValues = ({ ? computeFiatAmount(spotPrices, { decimals: txNetwork.decimals, symbol: txNetwork.symbol, - value: getTransactionBaseValue(tx) || '' + value: getTransactionBaseValue(tx) || '', + contractAddress: '', + chainId: txNetwork.chainId }) : Amount.empty() @@ -1678,12 +1685,14 @@ export const parseTransactionWithPrices = ({ tx: TransactionInfo transactionNetwork?: BraveWallet.NetworkInfo userVisibleTokensList: BraveWallet.BlockchainToken[] - spotPrices: BraveWallet.AssetPrice[] + spotPrices: AssetPriceWithContractAndChainId[] }): ParsedTransaction => { const networkSpotPrice = transactionNetwork ? findAssetPrice( spotPrices, - transactionNetwork.symbol + transactionNetwork.symbol, + '', + transactionNetwork.chainId ) : ''