diff --git a/src/apps/popup/pages/home/index.tsx b/src/apps/popup/pages/home/index.tsx index 2359cf928..41f41f56b 100644 --- a/src/apps/popup/pages/home/index.tsx +++ b/src/apps/popup/pages/home/index.tsx @@ -1,4 +1,4 @@ -import React, { useCallback } from 'react'; +import React, { useCallback, useEffect } from 'react'; import { Trans, useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; import styled from 'styled-components'; @@ -96,6 +96,14 @@ export function HomePageContent() { } }, [activeAccount?.publicKey, network]); + useEffect(() => { + if (!state?.activeTabId) { + const container = document.querySelector('#ms-container'); + + container?.scrollTo(0, 0); + } + }, [state?.activeTabId]); + return ( {activeAccount && ( diff --git a/src/apps/popup/pages/nft-details/index.tsx b/src/apps/popup/pages/nft-details/index.tsx index 54bd7ad73..83aab8dcc 100644 --- a/src/apps/popup/pages/nft-details/index.tsx +++ b/src/apps/popup/pages/nft-details/index.tsx @@ -1,4 +1,4 @@ -import React, { useMemo } from 'react'; +import React, { useEffect, useMemo } from 'react'; import { useParams } from 'react-router-dom'; import { useSelector } from 'react-redux'; @@ -30,6 +30,12 @@ export const NftDetailsPage = () => { [contractPackageHash, nftTokes, tokenId] ); + useEffect(() => { + if (!nftToken) { + navigate(RouterPath.Home); + } + }, [navigate, nftToken]); + return ( ( diff --git a/src/apps/popup/pages/token-details/index.tsx b/src/apps/popup/pages/token-details/index.tsx index ac51084e0..8f6b77fb7 100644 --- a/src/apps/popup/pages/token-details/index.tsx +++ b/src/apps/popup/pages/token-details/index.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { useParams } from 'react-router-dom'; +import { useSelector } from 'react-redux'; import { HeaderSubmenuBarNavLink, @@ -7,12 +8,12 @@ import { PopupHeader, PopupLayout } from '@libs/layout'; -import { useFetchErc20Tokens } from '@src/hooks'; +import { selectErc20Tokens } from '@background/redux/account-info/selectors'; import { TokenPageContent } from './content'; export const TokenDetailPage = () => { - const erc20Tokens = useFetchErc20Tokens(); + const erc20Tokens = useSelector(selectErc20Tokens); const { tokenName } = useParams(); return ( @@ -25,7 +26,10 @@ export const TokenDetailPage = () => { renderSubmenuBarItems={() => ( <> - + )} /> diff --git a/src/apps/popup/pages/transfer-nft/index.tsx b/src/apps/popup/pages/transfer-nft/index.tsx index 3cd70ec3c..2ebc6e7e4 100644 --- a/src/apps/popup/pages/transfer-nft/index.tsx +++ b/src/apps/popup/pages/transfer-nft/index.tsx @@ -39,25 +39,31 @@ export const TransferNftPage = () => { const [haveReverseOwnerLookUp, setHaveReverseOwnerLookUp] = useState(false); const { contractPackageHash, tokenId } = useParams(); - const nftTokes = useSelector(selectAccountNftTokens); + const nftTokens = useSelector(selectAccountNftTokens); const csprBalance = useSelector(selectAccountBalance); const activeAccount = useSelector(selectVaultActiveAccount); const { networkName, nodeUrl } = useSelector( selectApiConfigBasedOnActiveNetwork ); + const { t } = useTranslation(); + const navigate = useTypedNavigate(); + const nftToken = useMemo( () => - nftTokes?.find( + nftTokens?.find( token => token.token_id === tokenId && token.contract_package_hash === contractPackageHash ), - [contractPackageHash, nftTokes, tokenId] + [contractPackageHash, nftTokens, tokenId] ); - const { t } = useTranslation(); - const navigate = useTypedNavigate(); + useEffect(() => { + if (!nftToken) { + navigate(RouterPath.Home); + } + }, [navigate, nftToken]); useEffect(() => { if (nftToken?.contract_package?.metadata?.owner_reverse_lookup_mode) { diff --git a/src/apps/popup/pages/transfer-nft/utils.ts b/src/apps/popup/pages/transfer-nft/utils.ts index fdc830d4b..4af251554 100644 --- a/src/apps/popup/pages/transfer-nft/utils.ts +++ b/src/apps/popup/pages/transfer-nft/utils.ts @@ -39,7 +39,7 @@ export const getDefaultPaymentAmountBasedOnNftTokenStandard = ( case NFTTokenStandard.CEP78: return motesToCSPR(NFT_CEP78_PAYMENT_AMOUNT_AVERAGE_MOTES); default: - throw new Error('Unknown token standard.'); + return '0'; } }; diff --git a/src/libs/layout/containers.ts b/src/libs/layout/containers.ts index 8536bc3a9..084a178be 100644 --- a/src/libs/layout/containers.ts +++ b/src/libs/layout/containers.ts @@ -248,8 +248,8 @@ export const BreakWordContainer = styled.div` `; export const IllustrationContainer = styled.div` - margin-top: 24px; - margin-left: 16px; + padding-top: 24px; + padding-left: 16px; `; export const OnboardingIllustrationContainer = styled(IllustrationContainer)` diff --git a/src/libs/layout/header/header-view-in-explorer.tsx b/src/libs/layout/header/header-view-in-explorer.tsx index 49d090a47..1d86a6095 100644 --- a/src/libs/layout/header/header-view-in-explorer.tsx +++ b/src/libs/layout/header/header-view-in-explorer.tsx @@ -9,23 +9,25 @@ import { getBlockExplorerDeployUrl, getContractNftUrl } from '@src/constants'; -import { formatErc20TokenBalance } from '@popup/pages/home/components/tokens-list/utils'; -import { useCasperToken, useFetchErc20Tokens } from '@src/hooks'; +import { useCasperToken } from '@src/hooks'; import { selectApiConfigBasedOnActiveNetwork } from '@background/redux/settings/selectors'; import { selectVaultActiveAccount } from '@background/redux/vault/selectors'; +import { ContractPackageWithBalance } from '@libs/services/erc20-service'; interface HeaderViewInExplorerProps { tokenName?: string; deployHash?: string; nftTokenId?: string; contractHash?: string; + erc20Tokens?: ContractPackageWithBalance[]; } export function HeaderViewInExplorer({ tokenName, deployHash, nftTokenId, - contractHash + contractHash, + erc20Tokens }: HeaderViewInExplorerProps) { const [hrefToTokenOnCasperLive, setHrefToTokenOnCasperLive] = useState< string | undefined @@ -41,7 +43,6 @@ export function HeaderViewInExplorer({ const activeAccount = useSelector(selectVaultActiveAccount); const casperToken = useCasperToken(); - const erc20Tokens = useFetchErc20Tokens(); useEffect(() => { if (!tokenName && deployHash) { @@ -59,12 +60,16 @@ export function HeaderViewInExplorer({ } } else { // ERC-20 token case - const erc20TokensList = formatErc20TokenBalance(erc20Tokens); - const token = erc20TokensList?.find(token => token.id === tokenName); + const token = erc20Tokens?.find( + token => token.contract_package_hash === tokenName + ); if (token) { setHrefToTokenOnCasperLive( - getBlockExplorerContractUrl(casperLiveUrl, token.id) + getBlockExplorerContractUrl( + casperLiveUrl, + token.contract_package_hash + ) ); } } diff --git a/src/libs/services/account-activity-service/account-activity-service.ts b/src/libs/services/account-activity-service/account-activity-service.ts index 6bea6bb70..5e37b1f59 100644 --- a/src/libs/services/account-activity-service/account-activity-service.ts +++ b/src/libs/services/account-activity-service/account-activity-service.ts @@ -11,9 +11,10 @@ import { getAccountTransferLink } from './constants'; export const accountCasperActivityRequest = ( casperApiUrl: string, accountHash: string, - page: number + page: number, + signal?: AbortSignal ): Promise> => - fetch(getAccountTransferLink(casperApiUrl, accountHash, page)) + fetch(getAccountTransferLink(casperApiUrl, accountHash, page), { signal }) .then(toJson) .catch(handleError); @@ -28,7 +29,8 @@ export const fetchAccountCasperActivity = ({ }) => queryClient.fetchQuery( ['accountCasperActivityRequest', casperApiUrl, accountHash, page], - () => accountCasperActivityRequest(casperApiUrl, accountHash, page), + ({ signal }) => + accountCasperActivityRequest(casperApiUrl, accountHash, page, signal), { staleTime: ACCOUNT_CASPER_ACTIVITY_REFRESH_RATE } ); diff --git a/src/libs/services/account-activity-service/extended-deploys-service.ts b/src/libs/services/account-activity-service/extended-deploys-service.ts index 0c93febe4..e3d44b585 100644 --- a/src/libs/services/account-activity-service/extended-deploys-service.ts +++ b/src/libs/services/account-activity-service/extended-deploys-service.ts @@ -17,9 +17,10 @@ import { export const extendedDeploysRequest = ( casperApiUrl: string, - deployHash: string + deployHash: string, + signal?: AbortSignal ): Promise => - fetch(getExtendedDeploysHashLink(casperApiUrl, deployHash)) + fetch(getExtendedDeploysHashLink(casperApiUrl, deployHash), { signal }) .then(toJson) .catch(handleError); @@ -32,7 +33,7 @@ export const fetchExtendedDeploysInfo = ({ }) => queryClient.fetchQuery( ['accountTransactionsRequest', casperApiUrl, deployHash], - () => extendedDeploysRequest(casperApiUrl, deployHash) + ({ signal }) => extendedDeploysRequest(casperApiUrl, deployHash, signal) ); export const dispatchFetchExtendedDeploysInfo = ( @@ -45,9 +46,12 @@ export const dispatchFetchExtendedDeploysInfo = ( export const accountExtendedDeploysRequest = ( casperApiUrl: string, publicKey: string, - page: number + page: number, + signal?: AbortSignal ): Promise> => - fetch(getAccountExtendedDeploysLink(casperApiUrl, publicKey, page)) + fetch(getAccountExtendedDeploysLink(casperApiUrl, publicKey, page), { + signal + }) .then(toJson) .catch(handleError); @@ -62,7 +66,8 @@ export const fetchAccountExtendedDeploys = ({ }): Promise | ErrorResponse> => queryClient.fetchQuery( ['accountDeploysRequest', casperApiUrl, publicKey, page], - () => accountExtendedDeploysRequest(casperApiUrl, publicKey, page), + ({ signal }) => + accountExtendedDeploysRequest(casperApiUrl, publicKey, page, signal), { staleTime: ACCOUNT_DEPLOY_REFRESH_RATE } ); diff --git a/src/libs/services/account-info/account-info.ts b/src/libs/services/account-info/account-info.ts index 3d57e0c2a..20e9f8de3 100644 --- a/src/libs/services/account-info/account-info.ts +++ b/src/libs/services/account-info/account-info.ts @@ -10,9 +10,10 @@ import { FETCH_QUERY_OPTIONS } from '@src/constants'; const accountInfoRequest = ( accountHash: string, - casperApiUrl: string + casperApiUrl: string, + signal?: AbortSignal ): Promise> => - fetch(getAccountInfoUrl({ accountHash, casperApiUrl })) + fetch(getAccountInfoUrl({ accountHash, casperApiUrl }), { signal }) .then(toJson) .catch(handleError); @@ -25,7 +26,7 @@ export const fetchAccountInfo = ({ }) => queryClient.fetchQuery( ['accountInfoRequest', accountHash, casperApiUrl], - () => accountInfoRequest(accountHash, casperApiUrl), + ({ signal }) => accountInfoRequest(accountHash, casperApiUrl, signal), { staleTime: FETCH_QUERY_OPTIONS.apiCacheTime } diff --git a/src/libs/services/balance-service/balance-service.ts b/src/libs/services/balance-service/balance-service.ts index 055c36677..868d7aabf 100644 --- a/src/libs/services/balance-service/balance-service.ts +++ b/src/libs/services/balance-service/balance-service.ts @@ -16,19 +16,23 @@ import { import { getCurrencyRateUrl, getAccountBalanceUrl } from './constants'; export const currencyRateRequest = ( - casperApiUrl: string + casperApiUrl: string, + signal?: AbortSignal ): Promise => - fetch(getCurrencyRateUrl(casperApiUrl)).then(toJson).catch(handleError); + fetch(getCurrencyRateUrl(casperApiUrl), { signal }) + .then(toJson) + .catch(handleError); export const accountBalanceRequest = ( publicKey: string, - casperApiUrl: string + casperApiUrl: string, + signal?: AbortSignal ): Promise => { if (!publicKey) { throw Error('Missing public key'); } - return fetch(getAccountBalanceUrl({ publicKey, casperApiUrl })) + return fetch(getAccountBalanceUrl({ publicKey, casperApiUrl }), { signal }) .then(res => { if (res.status === 404) { return { @@ -55,7 +59,7 @@ export const fetchAccountBalance = ({ }) => queryClient.fetchQuery( ['getAccountBalanceRequest', publicKey, casperApiUrl], - () => accountBalanceRequest(publicKey, casperApiUrl), + ({ signal }) => accountBalanceRequest(publicKey, casperApiUrl, signal), { staleTime: BALANCE_REFRESH_RATE } @@ -64,7 +68,7 @@ export const fetchAccountBalance = ({ export const fetchCurrencyRate = ({ casperApiUrl }: { casperApiUrl: string }) => queryClient.fetchQuery( 'getCurrencyRateRequest', - () => currencyRateRequest(casperApiUrl), + ({ signal }) => currencyRateRequest(casperApiUrl, signal), { staleTime: CURRENCY_REFRESH_RATE } diff --git a/src/libs/services/erc20-service/erc20-service.ts b/src/libs/services/erc20-service/erc20-service.ts index a6524194a..8bafb6674 100644 --- a/src/libs/services/erc20-service/erc20-service.ts +++ b/src/libs/services/erc20-service/erc20-service.ts @@ -14,9 +14,10 @@ import { getContractPackageUrl, getErc20TokensUrl } from './constants'; export const erc20TokensRequest = ( casperApiUrl: string, - accountHash: string + accountHash: string, + signal?: AbortSignal ): Promise> => - fetch(getErc20TokensUrl(casperApiUrl, accountHash)) + fetch(getErc20TokensUrl(casperApiUrl, accountHash), { signal }) .then(toJson) .catch(handleError); @@ -29,15 +30,16 @@ export const fetchErc20Tokens = ({ }) => queryClient.fetchQuery( ['getErc20Tokens', accountHash, casperApiUrl], - () => erc20TokensRequest(casperApiUrl, accountHash), + ({ signal }) => erc20TokensRequest(casperApiUrl, accountHash, signal), { staleTime: TOKENS_REFRESH_RATE } ); export const contractPackageRequest = ( casperApiUrl: string, - contractPackageHash: string + contractPackageHash: string, + signal?: AbortSignal ): Promise => - fetch(getContractPackageUrl(casperApiUrl, contractPackageHash)) + fetch(getContractPackageUrl(casperApiUrl, contractPackageHash), { signal }) .then(toJson) .catch(handleError); @@ -50,7 +52,8 @@ export const fetchContractPackage = ({ }) => queryClient.fetchQuery( ['contractPackageRequest', casperApiUrl, contractPackageHash], - () => contractPackageRequest(casperApiUrl, contractPackageHash), + ({ signal }) => + contractPackageRequest(casperApiUrl, contractPackageHash, signal), { staleTime: TOKENS_REFRESH_RATE } ); diff --git a/src/libs/services/nft-service/nft-service.ts b/src/libs/services/nft-service/nft-service.ts index 3e673a3f6..588a78ccf 100644 --- a/src/libs/services/nft-service/nft-service.ts +++ b/src/libs/services/nft-service/nft-service.ts @@ -14,9 +14,10 @@ import { serviceMessage } from '@background/service-message'; export const nftTokensRequest = ( casperApiUrl: string, accountHash: string, - page: number + page: number, + signal?: AbortSignal ): Promise> => - fetch(getNftTokensUrl(casperApiUrl, accountHash, page)) + fetch(getNftTokensUrl(casperApiUrl, accountHash, page), { signal }) .then(toJson) .catch(handleError); @@ -31,7 +32,7 @@ export const fetchNftTokens = ({ }): Promise | ErrorResponse> => queryClient.fetchQuery( ['getNftTokens', accountHash, casperApiUrl, page], - () => nftTokensRequest(casperApiUrl, accountHash, page), + ({ signal }) => nftTokensRequest(casperApiUrl, accountHash, page, signal), { staleTime: NFT_TOKENS_REFRESH_RATE } ); diff --git a/src/libs/ui/components/tabs/tabs.tsx b/src/libs/ui/components/tabs/tabs.tsx index ca6c673e8..df83d76a6 100644 --- a/src/libs/ui/components/tabs/tabs.tsx +++ b/src/libs/ui/components/tabs/tabs.tsx @@ -14,7 +14,7 @@ const TabsContainer = styled(AlignedSpaceBetweenFlexRow)` const StickyTabsContainer = styled.div` position: sticky; - top: 0; + top: -2px; z-index: 5; padding: 16px 0;