diff --git a/components/brave_wallet_ui/common/async/handlers.ts b/components/brave_wallet_ui/common/async/handlers.ts index c736134db2bf..8e284559462f 100644 --- a/components/brave_wallet_ui/common/async/handlers.ts +++ b/components/brave_wallet_ui/common/async/handlers.ts @@ -288,16 +288,7 @@ handler.on(WalletActions.getAllTokensList.getType(), async (store) => { }) handler.on(WalletActions.addUserAsset.getType(), async (store: Store, payload: BraveWallet.BlockchainToken) => { - const { braveWalletService, jsonRpcService } = getAPIProxy() - if (payload.isErc721) { - // Get NFTMetadata - const result = await jsonRpcService.getERC721Metadata(payload.contractAddress, payload.tokenId, payload.chainId) - if (!result.error) { - const response = JSON.parse(result.response) - payload.logo = response.image || payload.logo - } - } - + const { braveWalletService } = getAPIProxy() const result = await braveWalletService.addUserAsset(payload) store.dispatch(WalletActions.addUserAssetError(!result.success)) }) diff --git a/components/brave_wallet_ui/common/hooks/assets.ts b/components/brave_wallet_ui/common/hooks/assets.ts index ab10fcfd1676..911f7e3ef834 100644 --- a/components/brave_wallet_ui/common/hooks/assets.ts +++ b/components/brave_wallet_ui/common/hooks/assets.ts @@ -20,25 +20,6 @@ import usePricing from './pricing' import useBalance from './balance' import { useIsMounted } from './useIsMounted' import { useLib } from './useLib' -import { httpifyIpfsUrl } from '../../utils/string-utils' - -const assetsLogo = (assets: BraveWallet.BlockchainToken[]) => { - return assets.map(token => { - let logo = token.logo - if (token.logo?.startsWith('ipfs://')) { - logo = httpifyIpfsUrl(token.logo) - } else if (token.logo?.startsWith('data:image/')) { - logo = token.logo - } else { - logo = `chrome://erc-token-images/${token.logo}` - } - - return { - ...token, - logo - } as BraveWallet.BlockchainToken - }) -} export function useAssets () { // redux @@ -73,7 +54,10 @@ export function useAssets () { React.useEffect(() => { isMounted && getBuyAssets().then(tokens => { if (isMounted) { - setBuyAssetOptions(assetsLogo(tokens)) + setBuyAssetOptions(tokens.map(token => ({ + ...token, + logo: `chrome://erc-token-images/${token.logo}` + }) as BraveWallet.BlockchainToken)) } }).catch(e => console.error(e)) }, []) diff --git a/components/brave_wallet_ui/components/desktop/popup-modals/edit-visible-assets-modal/index.tsx b/components/brave_wallet_ui/components/desktop/popup-modals/edit-visible-assets-modal/index.tsx index 1299b90ddc45..0b3705ade95d 100644 --- a/components/brave_wallet_ui/components/desktop/popup-modals/edit-visible-assets-modal/index.tsx +++ b/components/brave_wallet_ui/components/desktop/popup-modals/edit-visible-assets-modal/index.tsx @@ -559,7 +559,7 @@ const EditVisibleAssetsModal = (props: Props) => { <> {filteredTokenList.slice(0, tokenDisplayAmount).map((token) => { }, [fiatBalance]) const isLoading = React.useMemo(() => { - return formattedAssetBalance === '' && !token.isErc721 - }, [formattedAssetBalance, token]) + return formattedAssetBalance === '' + }, [formattedAssetBalance]) const tokensNetwork = React.useMemo(() => { return getTokensNetwork(networks, token) @@ -111,7 +111,7 @@ const PortfolioAssetItem = (props: Props) => { {token.visible && // Selecting an erc721 token is temp disabled until UI is ready for viewing NFTs // or when showing loading skeleton - + {isLoading diff --git a/components/brave_wallet_ui/components/desktop/views/portfolio/components/nft-details/index.tsx b/components/brave_wallet_ui/components/desktop/views/portfolio/components/nft-details/index.tsx index a3f542397940..46e10339424e 100644 --- a/components/brave_wallet_ui/components/desktop/views/portfolio/components/nft-details/index.tsx +++ b/components/brave_wallet_ui/components/desktop/views/portfolio/components/nft-details/index.tsx @@ -12,16 +12,17 @@ import { useExplorer } from '../../../../../../common/hooks' // Utils import Amount from '../../../../../../utils/amount' -import { getLocale } from '$web-common/locale' +import { CurrencySymbols } from '../../../../../../utils/currency-symbols' +import { getLocale } from '../../../../../../../common/locale' // Styled Components import { StyledWrapper, - LoadIcon, - LoadingOverlay, NFTImage, DetailColumn, TokenName, + TokenFiatValue, + TokenCryptoValue, DetailSectionRow, DetailSectionColumn, DetailSectionTitle, @@ -29,6 +30,7 @@ import { ProjectDetailRow, ProjectDetailName, ProjectDetailDescription, + ProjectDetailImage, ProjectDetailButtonRow, ProjectDetailButton, ProjectDetailButtonSeperator, @@ -37,32 +39,28 @@ import { ProjectFacebookIcon, ProjectDetailIDRow, ExplorerIcon, - ExplorerButton, - NFTImageSkeletonWrapper + ExplorerButton } from './style' -import { LoadingSkeleton } from '../../../../../shared' export interface Props { - isLoading: boolean selectedAsset: BraveWallet.BlockchainToken - nftMetadata: NFTMetadataReturnType | undefined + nftMetadata: NFTMetadataReturnType defaultCurrencies: DefaultCurrencies - selectedNetwork: BraveWallet.NetworkInfo + selectedNetwork: BraveWallet.EthereumChain } const NFTDetails = (props: Props) => { - const [isImageLoaded, setIsImageLoaded] = React.useState(false) const { - isLoading, selectedAsset, nftMetadata, + defaultCurrencies, selectedNetwork } = props const onClickViewOnBlockExplorer = useExplorer(selectedNetwork) const onClickWebsite = () => { - chrome.tabs.create({ url: nftMetadata?.contractInformation?.website }, () => { + chrome.tabs.create({ url: nftMetadata.contractInformation.website }, () => { if (chrome.runtime.lastError) { console.error('tabs.create failed: ' + chrome.runtime.lastError.message) } @@ -70,7 +68,7 @@ const NFTDetails = (props: Props) => { } const onClickTwitter = () => { - chrome.tabs.create({ url: nftMetadata?.contractInformation?.twitter }, () => { + chrome.tabs.create({ url: nftMetadata.contractInformation.twitter }, () => { if (chrome.runtime.lastError) { console.error('tabs.create failed: ' + chrome.runtime.lastError.message) } @@ -78,7 +76,7 @@ const NFTDetails = (props: Props) => { } const onClickFacebook = () => { - chrome.tabs.create({ url: nftMetadata?.contractInformation?.facebook }, () => { + chrome.tabs.create({ url: nftMetadata.contractInformation.facebook }, () => { if (chrome.runtime.lastError) { console.error('tabs.create failed: ' + chrome.runtime.lastError.message) } @@ -87,81 +85,61 @@ const NFTDetails = (props: Props) => { return ( - {isLoading && - - - - } - {nftMetadata && - <> - setIsImageLoaded(true)} - /> - {!isImageLoaded && - + + + + {selectedAsset.name} { + selectedAsset.tokenId + ? '#' + new Amount(selectedAsset.tokenId).toNumber() + : '' } - - - {selectedAsset.name} { - selectedAsset.tokenId - ? '#' + new Amount(selectedAsset.tokenId).toNumber() - : '' - } - - {/* TODO: Add floorFiatPrice & floorCryptoPrice when data is available from backend: https://github.com/brave/brave-browser/issues/22627 */} - {/* {CurrencySymbols[defaultCurrencies.fiat]}{nftMetadata.floorFiatPrice} */} - {/* {nftMetadata.floorCryptoPrice} {selectedNetwork.symbol} */} - - - {getLocale('braveWalletNFTDetailBlockchain')} - {nftMetadata.chainName} - - - {getLocale('braveWalletNFTDetailTokenStandard')} - {nftMetadata.tokenType} - - - {getLocale('braveWalletNFTDetailTokenID')} - - - { - selectedAsset.tokenId - ? '#' + new Amount(selectedAsset.tokenId).toNumber() - : '' - } - - - - - - - - - {/* TODO: Add nft logo when data is available from backend: https://github.com/brave/brave-browser/issues/22627 */} - {/* */} - {nftMetadata.contractInformation.name} - {nftMetadata.contractInformation.website && nftMetadata.contractInformation.twitter && nftMetadata.contractInformation.facebook && - - - - - - - - - - - - - - } - - {nftMetadata.contractInformation.description} - - - } + + {CurrencySymbols[defaultCurrencies.fiat]}{nftMetadata.floorFiatPrice} + {nftMetadata.floorCryptoPrice} {selectedNetwork.symbol} + + + {getLocale('braveWalletNFTDetailBlockchain')} + {nftMetadata.chainName} + + + {getLocale('braveWalletNFTDetailTokenStandard')} + {nftMetadata.tokenType} + + + {getLocale('braveWalletNFTDetailTokenID')} + + + { + selectedAsset.tokenId + ? '#' + new Amount(selectedAsset.tokenId).toNumber() + : '' + } + + + + + + + + + + {nftMetadata.contractInformation.name} + + + + + + + + + + + + + + + {nftMetadata.contractInformation.description} + ) diff --git a/components/brave_wallet_ui/components/desktop/views/portfolio/components/nft-details/style.ts b/components/brave_wallet_ui/components/desktop/views/portfolio/components/nft-details/style.ts index dcc59009b81d..78b7e922c778 100644 --- a/components/brave_wallet_ui/components/desktop/views/portfolio/components/nft-details/style.ts +++ b/components/brave_wallet_ui/components/desktop/views/portfolio/components/nft-details/style.ts @@ -3,13 +3,7 @@ import { WalletButton } from '../../../../../shared/style' import WebsiteIcon from '../../../../../../assets/svg-icons/website-icon.svg' import TwitterIcon from '../../../../../../assets/svg-icons/twitter-icon.svg' import FacebookIcon from '../../../../../../assets/svg-icons/facebook-icon.svg' -import { LoaderIcon, OpenNewIcon } from 'brave-ui/components/icons' - -export interface StyleProps { - isLoading: boolean -} - -const nftImageDimension = '440px' +import { OpenNewIcon } from 'brave-ui/components/icons' export const StyledWrapper = styled.div` display: flex; @@ -17,23 +11,12 @@ export const StyledWrapper = styled.div` align-items: flex-start; justify-content: flex-start; width: 100%; - min-height: ${nftImageDimension}; - margin: 16px 0 50px 0; -` - -export const NFTImage = styled.img>` - display: ${p => p.isLoading ? 'none' : 'block'}; - width: ${nftImageDimension}; - height: ${nftImageDimension}; - margin-right: 28px; - border-radius: 12px; ` -export const NFTImageSkeletonWrapper = styled.div` - min-width: ${nftImageDimension}; - height: ${nftImageDimension}; - margin-right: 28px; - border-radius: 12px; +export const NFTImage = styled.img` + width: 440px; + height: 440px; + margin-right: 10px; ` export const DetailColumn = styled.div` @@ -222,22 +205,3 @@ export const ExplorerIcon = styled(OpenNewIcon)` height: 14px; color: ${(p) => p.theme.color.interactive05}; ` - -export const LoadingOverlay = styled.div>` - display: ${(p) => p.isLoading ? 'flex' : 'none'}; - flex-direction: column; - align-items: center; - justify-content: center; - width: 100%; - height: 440px; - position: absolute; - z-index: 10; - backdrop-filter: blur(5px); -` - -export const LoadIcon = styled(LoaderIcon)` - color: ${p => p.theme.color.interactive08}; - height: 70px; - width: 70px; - opacity: .4; -` diff --git a/components/brave_wallet_ui/components/desktop/views/portfolio/index.tsx b/components/brave_wallet_ui/components/desktop/views/portfolio/index.tsx index 0bdc18de4e33..75d15da58f47 100644 --- a/components/brave_wallet_ui/components/desktop/views/portfolio/index.tsx +++ b/components/brave_wallet_ui/components/desktop/views/portfolio/index.tsx @@ -32,7 +32,7 @@ import { WithHideBalancePlaceholder } from '../../' -import NFTDetails from './components/nft-details' +// import NFTDetails from './components/nft-details' import TokenLists from './components/token-lists' import AccountsAndTransactionsList from './components/accounts-and-transctions-list' @@ -87,6 +87,7 @@ const Portfolio = (props: Props) => { const history = useHistory() // redux + const dispatch = useDispatch() const { defaultCurrencies, addUserAssetError, @@ -203,8 +204,6 @@ const Portfolio = (props: Props) => { // more custom hooks const parseTransaction = useTransactionParser(selectedAssetsNetwork, accounts, transactionSpotPrices, userVisibleTokensInfo) - const { isFetchingNFTMetadata, nftMetadata } = useSelector((state: { page: PageState }) => state.page) - const dispatch = useDispatch() // memos / computed @@ -305,9 +304,6 @@ const Portfolio = (props: Props) => { const goBack = () => { selectAsset(undefined) - if (nftMetadata) { - dispatch(WalletPageActions.updateNFTMetadata(undefined)) - } setfilteredAssetList(userAssetList) toggleNav() } @@ -426,15 +422,15 @@ const Portfolio = (props: Props) => { /> } - {selectedAsset?.isErc721 && + {/* Temp Commented out until we have an API to get NFT MetaData */} + {/* {selectedAsset?.isErc721 && - } + } */} , config const isValidIcon = React.useMemo(() => { if (isRemoteURL || isDataURL) { - return tokenImageURL?.includes('data:image/') ? true : isValidIconExtension(new URL(asset.logo).pathname) + const url = new URL(asset.logo) + return isValidIconExtension(url.pathname) } if (isStorybook) { return true @@ -75,7 +76,7 @@ function withPlaceholderIcon (WrappedComponent: React.ComponentType, config const remoteImage = React.useMemo(() => { if (isRemoteURL) { - return httpifyIpfsUrl(tokenImageURL) + return `chrome://image?${tokenImageURL}` } return '' }, [tokenImageURL]) diff --git a/components/brave_wallet_ui/constants/types.ts b/components/brave_wallet_ui/constants/types.ts index ade32b8fbec6..204b59830afd 100644 --- a/components/brave_wallet_ui/constants/types.ts +++ b/components/brave_wallet_ui/constants/types.ts @@ -251,8 +251,6 @@ export interface PageState { invalidMnemonic: boolean selectedTimeline: BraveWallet.AssetPriceTimeframe selectedAsset: BraveWallet.BlockchainToken | undefined - isFetchingNFTMetadata: boolean - nftMetadata: NFTMetadataReturnType | undefined selectedAssetFiatPrice: BraveWallet.AssetPrice | undefined selectedAssetCryptoPrice: BraveWallet.AssetPrice | undefined selectedAssetPriceHistory: GetPriceHistoryReturnInfo[] @@ -590,7 +588,11 @@ export interface CreateAccountOptionsType { icon: string } +// This is mostly speculative +// will likely change once we have an api for getting +// nft metadata export interface NFTMetadataReturnType { + chain: string chainName: string tokenType: string tokenID: string diff --git a/components/brave_wallet_ui/page/actions/wallet_page_actions.ts b/components/brave_wallet_ui/page/actions/wallet_page_actions.ts index 175eabef4e03..4b7a30058be1 100644 --- a/components/brave_wallet_ui/page/actions/wallet_page_actions.ts +++ b/components/brave_wallet_ui/page/actions/wallet_page_actions.ts @@ -24,7 +24,6 @@ import { } from '../constants/action_types' import { BraveWallet, - NFTMetadataReturnType, UpdateAccountNamePayloadType } from '../../constants/types' @@ -61,6 +60,3 @@ export const setMetaMaskInitialized = createAction('setMetaMaskInitiali export const importFromCryptoWallets = createAction('importFromCryptoWallets') export const importFromMetaMask = createAction('importFromMetaMask') export const openWalletSettings = createAction('openWalletSettings') -export const getNFTMetadata = createAction('getNFTMetadata') -export const setIsFetchingNFTMetadata = createAction('setIsFetchingNFTMetadata') -export const updateNFTMetadata = createAction('updateNFTMetadata') 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 d57531b1c052..47acaed2f321 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 @@ -8,7 +8,6 @@ import * as WalletPageActions from '../actions/wallet_page_actions' import * as WalletActions from '../../common/actions/wallet_actions' import { BraveWallet, - NFTMetadataReturnType, UpdateAccountNamePayloadType, WalletState } from '../../constants/types' @@ -32,9 +31,6 @@ import { import { NewUnapprovedTxAdded } from '../../common/constants/action_types' import { Store } from '../../common/async/types' import { getTokenParam } from '../../utils/api-utils' -import getAPIProxy from '../../common/async/bridge' -import { getTokensNetwork } from '../../utils/network-utils' -import { httpifyIpfsUrl } from '../../utils/string-utils' const handler = new AsyncActionHandler() @@ -95,10 +91,6 @@ handler.on(WalletPageActions.selectAsset.getType(), async (store: Store, payload 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 })) - - if (payload.asset.isErc721) { - store.dispatch(WalletPageActions.getNFTMetadata(payload.asset)) - } } else { store.dispatch(WalletPageActions.updatePriceInfo({ priceHistory: undefined, defaultFiatPrice: undefined, defaultCryptoPrice: undefined, timeFrame: payload.timeFrame })) } @@ -233,36 +225,4 @@ handler.on(WalletPageActions.openWalletSettings.getType(), async (store) => { }) }) -handler.on(WalletPageActions.getNFTMetadata.getType(), async (store, payload: BraveWallet.BlockchainToken) => { - store.dispatch(WalletPageActions.setIsFetchingNFTMetadata(true)) - const { jsonRpcService } = getAPIProxy() - const result = await jsonRpcService.getERC721Metadata(payload.contractAddress, payload.tokenId, payload.chainId) - - if (!result.error) { - const response = JSON.parse(result.response) - const tokenNetwork = getTokensNetwork(getWalletState(store).networkList, payload) - const nftMetadata: NFTMetadataReturnType = { - chainName: tokenNetwork.chainName, - tokenType: 'ERC721', // getNFTMetadata currently supports only ERC721 standard. When other standards are supported, this value should be dynamic - tokenID: payload.tokenId, - imageURL: response.image.startsWith('data:image/') ? response.image : httpifyIpfsUrl(response.image), - floorFiatPrice: '', - floorCryptoPrice: '', - contractInformation: { - address: payload.contractAddress, - name: response.name, - description: response.description, - website: '', - twitter: '', - facebook: '', - logo: '' - } - } - store.dispatch(WalletPageActions.updateNFTMetadata(nftMetadata)) - } else { - console.error(result.errorMessage) - } - store.dispatch(WalletPageActions.setIsFetchingNFTMetadata(false)) -}) - export default handler.middleware diff --git a/components/brave_wallet_ui/page/reducers/page_reducer.ts b/components/brave_wallet_ui/page/reducers/page_reducer.ts index 2d93cd4a8807..78862d2538d6 100644 --- a/components/brave_wallet_ui/page/reducers/page_reducer.ts +++ b/components/brave_wallet_ui/page/reducers/page_reducer.ts @@ -8,8 +8,7 @@ import * as Actions from '../actions/wallet_page_actions' import { BraveWallet, PageState, - ImportWalletError, - NFTMetadataReturnType + ImportWalletError } from '../../constants/types' import { WalletCreatedPayloadType, @@ -27,8 +26,6 @@ const defaultState: PageState = { importWalletError: { hasError: false }, selectedTimeline: BraveWallet.AssetPriceTimeframe.OneDay, selectedAsset: undefined, - isFetchingNFTMetadata: true, - nftMetadata: undefined, selectedAssetFiatPrice: undefined, selectedAssetCryptoPrice: undefined, selectedAssetPriceHistory: [], @@ -169,21 +166,6 @@ export const createPageReducer = (initialState: PageState) => { isMetaMaskInitialized: payload } }) - - reducer.on(Actions.updateNFTMetadata, (state: PageState, payload: NFTMetadataReturnType) => { - return { - ...state, - nftMetadata: payload - } - }) - - reducer.on(Actions.setIsFetchingNFTMetadata, (state: PageState, payload: boolean) => { - return { - ...state, - isFetchingNFTMetadata: payload - } - }) - return reducer } diff --git a/components/brave_wallet_ui/stories/mock-data/mock-nft-metadata.ts b/components/brave_wallet_ui/stories/mock-data/mock-nft-metadata.ts index 9c2f318e6043..3849c20f592e 100644 --- a/components/brave_wallet_ui/stories/mock-data/mock-nft-metadata.ts +++ b/components/brave_wallet_ui/stories/mock-data/mock-nft-metadata.ts @@ -4,6 +4,7 @@ import MooncatProjectIcon from '../../assets/png-icons/mooncat-project-icon.png' export const mockNFTMetadata: NFTMetadataReturnType[] = [ { + chain: '0x1', chainName: 'Ethereum', tokenType: 'ERC721', tokenID: '0x42a5', diff --git a/components/brave_wallet_ui/stories/mock-data/mock-page-state.ts b/components/brave_wallet_ui/stories/mock-data/mock-page-state.ts index 099b59065c89..9140f9dd262e 100644 --- a/components/brave_wallet_ui/stories/mock-data/mock-page-state.ts +++ b/components/brave_wallet_ui/stories/mock-data/mock-page-state.ts @@ -1,9 +1,6 @@ import { BraveWallet, PageState } from '../../constants/types' -import { mockNFTMetadata } from './mock-nft-metadata' export const mockPageState: PageState = { - isFetchingNFTMetadata: false, - nftMetadata: mockNFTMetadata[0], hasInitialized: false, importAccountError: false, importWalletError: { diff --git a/components/brave_wallet_ui/utils/string-utils.ts b/components/brave_wallet_ui/utils/string-utils.ts index a5b8b47f656e..a742243d2034 100644 --- a/components/brave_wallet_ui/utils/string-utils.ts +++ b/components/brave_wallet_ui/utils/string-utils.ts @@ -6,19 +6,7 @@ export const toProperCase = (value: string) => (txt) => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()) export const isRemoteImageURL = (url?: string) => - url?.startsWith('http://') || url?.startsWith('https://') || url?.startsWith('data:image/') || url?.startsWith('ipfs://') + url?.startsWith('http://') || url?.startsWith('https://') || url?.startsWith('data:image/') export const isValidIconExtension = (url?: string) => - url?.endsWith('.jpg') || url?.endsWith('.jpeg') || url?.endsWith('.png') || url?.endsWith('.svg') || url?.endsWith('.gif') - -export const httpifyIpfsUrl = (url: string | undefined) => { - if (!url) { - return '' - } - - if (url.startsWith('data:image/')) { - return url - } - - return `chrome://image/?${url.includes('ipfs://') ? url.replace('ipfs://', 'https://ipfs.io/ipfs/') : url}` -} + url?.endsWith('.jpg') || url?.endsWith('.jpeg') || url?.endsWith('.png') || url?.endsWith('.svg')