diff --git a/.changeset/khaki-monkeys-thank.md b/.changeset/khaki-monkeys-thank.md new file mode 100644 index 0000000000000..7895814f8f522 --- /dev/null +++ b/.changeset/khaki-monkeys-thank.md @@ -0,0 +1,6 @@ +--- +'@mysten/create-dapp': minor +'@mysten/dapp-kit': minor +--- + +Upgrade dapp-kit and the scaffold applications to react-query v5 diff --git a/apps/core/package.json b/apps/core/package.json index 6e4172eddd9cd..2839888675e11 100644 --- a/apps/core/package.json +++ b/apps/core/package.json @@ -30,7 +30,7 @@ "@mysten/kiosk": "workspace:*", "@mysten/sui.js": "workspace:*", "@sentry/react": "^7.59.2", - "@tanstack/react-query": "^4.29.25", + "@tanstack/react-query": "^5.0.0", "bignumber.js": "^9.1.1", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/apps/core/src/hooks/useFormatCoin.ts b/apps/core/src/hooks/useFormatCoin.ts index 6a94e457c7ed4..fac9c65b332b3 100644 --- a/apps/core/src/hooks/useFormatCoin.ts +++ b/apps/core/src/hooks/useFormatCoin.ts @@ -87,7 +87,7 @@ export function useCoinMetadata(coinType?: string | null) { retry: false, enabled: !!coinType, staleTime: Infinity, - cacheTime: 24 * 60 * 60 * 1000, + gcTime: 24 * 60 * 60 * 1000, }); } diff --git a/apps/core/src/hooks/useGetCoins.ts b/apps/core/src/hooks/useGetCoins.ts index 41a5d9c8637b4..f0e09553fb177 100644 --- a/apps/core/src/hooks/useGetCoins.ts +++ b/apps/core/src/hooks/useGetCoins.ts @@ -3,7 +3,7 @@ import { useSuiClient } from '@mysten/dapp-kit'; import { PaginatedCoins } from '@mysten/sui.js/client'; -import { useInfiniteQuery, UseInfiniteQueryResult } from '@tanstack/react-query'; +import { useInfiniteQuery } from '@tanstack/react-query'; const MAX_COINS_PER_REQUEST = 10; @@ -11,25 +11,19 @@ export function useGetCoins( coinType: string, address?: string | null, maxCoinsPerRequest = MAX_COINS_PER_REQUEST, -): UseInfiniteQueryResult { +) { const client = useSuiClient(); - return useInfiniteQuery( - ['get-coins', address, coinType, maxCoinsPerRequest], - ({ pageParam }) => + return useInfiniteQuery({ + queryKey: ['get-coins', address, coinType, maxCoinsPerRequest], + initialPageParam: null, + getNextPageParam: ({ hasNextPage, nextCursor }) => (hasNextPage ? nextCursor : null), + queryFn: ({ pageParam }) => client.getCoins({ owner: address!, coinType, - cursor: pageParam ? pageParam.cursor : null, + cursor: pageParam as string | null, limit: maxCoinsPerRequest, }), - { - getNextPageParam: ({ hasNextPage, nextCursor }) => - hasNextPage - ? { - cursor: nextCursor, - } - : false, - enabled: !!address, - }, - ); + enabled: !!address, + }); } diff --git a/apps/core/src/hooks/useGetDelegatedStake.tsx b/apps/core/src/hooks/useGetDelegatedStake.tsx index 87f5006df7ad1..72cb32d48f066 100644 --- a/apps/core/src/hooks/useGetDelegatedStake.tsx +++ b/apps/core/src/hooks/useGetDelegatedStake.tsx @@ -7,7 +7,7 @@ import { useQuery, type UseQueryOptions } from '@tanstack/react-query'; type UseGetDelegatedStakesOptions = { address: string; -} & UseQueryOptions; +} & Omit, 'queryKey' | 'queryFn'>; export function useGetDelegatedStake(options: UseGetDelegatedStakesOptions) { const client = useSuiClient(); diff --git a/apps/core/src/hooks/useGetDynamicFields.ts b/apps/core/src/hooks/useGetDynamicFields.ts index b5a2c78afd5bc..bc867f09c33ce 100644 --- a/apps/core/src/hooks/useGetDynamicFields.ts +++ b/apps/core/src/hooks/useGetDynamicFields.ts @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { useSuiClient } from '@mysten/dapp-kit'; +import { DynamicFieldPage } from '@mysten/sui.js/src/client'; import { normalizeSuiAddress } from '@mysten/sui.js/utils'; import { useInfiniteQuery } from '@tanstack/react-query'; @@ -9,17 +10,16 @@ const MAX_PAGE_SIZE = 10; export function useGetDynamicFields(parentId: string, maxPageSize = MAX_PAGE_SIZE) { const client = useSuiClient(); - return useInfiniteQuery( - ['dynamic-fields', parentId], - ({ pageParam = null }) => + return useInfiniteQuery({ + queryKey: ['dynamic-fields', { maxPageSize, parentId }], + queryFn: ({ pageParam = null }) => client.getDynamicFields({ parentId: normalizeSuiAddress(parentId), - cursor: pageParam, + cursor: pageParam as string | null, limit: maxPageSize, }), - { - enabled: !!parentId, - getNextPageParam: ({ nextCursor, hasNextPage }) => (hasNextPage ? nextCursor : null), - }, - ); + enabled: !!parentId, + initialPageParam: null, + getNextPageParam: ({ nextCursor, hasNextPage }) => (hasNextPage ? nextCursor : null), + }); } diff --git a/apps/core/src/hooks/useGetOwnedObjects.ts b/apps/core/src/hooks/useGetOwnedObjects.ts index 05bf2acf914bc..e0a87d1203008 100644 --- a/apps/core/src/hooks/useGetOwnedObjects.ts +++ b/apps/core/src/hooks/useGetOwnedObjects.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { useSuiClient } from '@mysten/dapp-kit'; -import { type SuiObjectDataFilter } from '@mysten/sui.js/client'; +import { PaginatedObjectsResponse, type SuiObjectDataFilter } from '@mysten/sui.js/client'; import { useInfiniteQuery } from '@tanstack/react-query'; const MAX_OBJECTS_PER_REQ = 6; @@ -13,9 +13,10 @@ export function useGetOwnedObjects( maxObjectRequests = MAX_OBJECTS_PER_REQ, ) { const client = useSuiClient(); - return useInfiniteQuery( - ['get-owned-objects', address, filter, maxObjectRequests], - ({ pageParam }) => + return useInfiniteQuery({ + initialPageParam: null, + queryKey: ['get-owned-objects', address, filter, maxObjectRequests], + queryFn: ({ pageParam }) => client.getOwnedObjects({ owner: address!, filter, @@ -25,12 +26,11 @@ export function useGetOwnedObjects( showDisplay: true, }, limit: maxObjectRequests, - cursor: pageParam, + cursor: pageParam as string | null, }), - { - staleTime: 10 * 1000, - enabled: !!address, - getNextPageParam: (lastPage) => (lastPage?.hasNextPage ? lastPage.nextCursor : null), - }, - ); + + staleTime: 10 * 1000, + enabled: !!address, + getNextPageParam: ({ hasNextPage, nextCursor }) => (hasNextPage ? nextCursor : null), + }); } diff --git a/apps/core/src/hooks/useMultiGetObjects.ts b/apps/core/src/hooks/useMultiGetObjects.ts index 2b857479427e8..6d04fea411562 100644 --- a/apps/core/src/hooks/useMultiGetObjects.ts +++ b/apps/core/src/hooks/useMultiGetObjects.ts @@ -2,18 +2,19 @@ // SPDX-License-Identifier: Apache-2.0 import { useSuiClient } from '@mysten/dapp-kit'; -import { SuiObjectDataOptions } from '@mysten/sui.js/src/client'; -import { useQuery } from '@tanstack/react-query'; +import { SuiObjectDataOptions, SuiObjectResponse } from '@mysten/sui.js/client'; +import { useQuery, UseQueryOptions } from '@tanstack/react-query'; import { chunkArray } from '../utils/chunkArray'; export function useMultiGetObjects( ids: string[], options: SuiObjectDataOptions, - queryOptions?: { keepPreviousData?: boolean }, + queryOptions?: Omit, 'queryKey' | 'queryFn'>, ) { const client = useSuiClient(); return useQuery({ + ...queryOptions, queryKey: ['multiGetObjects', ids], queryFn: async () => { const responses = await Promise.all( @@ -27,6 +28,5 @@ export function useMultiGetObjects( return responses.flat(); }, enabled: !!ids?.length, - ...queryOptions, }); } diff --git a/apps/core/src/hooks/useProductAnalyticsConfig.ts b/apps/core/src/hooks/useProductAnalyticsConfig.ts index 8fae1acf08255..faa856854e030 100644 --- a/apps/core/src/hooks/useProductAnalyticsConfig.ts +++ b/apps/core/src/hooks/useProductAnalyticsConfig.ts @@ -13,6 +13,6 @@ export function useProductAnalyticsConfig() { queryKey: ['apps-backend', 'product-analytics-config'], queryFn: () => request('product-analytics'), staleTime: 24 * 60 * 60 * 1000, - cacheTime: Infinity, + gcTime: Infinity, }); } diff --git a/apps/core/src/hooks/useSuiCoinData.ts b/apps/core/src/hooks/useSuiCoinData.ts index 880cbaedf0fbf..d09b4fd519519 100644 --- a/apps/core/src/hooks/useSuiCoinData.ts +++ b/apps/core/src/hooks/useSuiCoinData.ts @@ -22,7 +22,7 @@ export function useSuiCoinData() { return useQuery({ queryKey: ['sui-coin-data'], queryFn: () => request('coins/sui', {}), - cacheTime: 24 * 60 * 60 * 1000, + gcTime: 24 * 60 * 60 * 1000, staleTime: Infinity, }); } diff --git a/apps/explorer/package.json b/apps/explorer/package.json index a9a6232669efe..3f85ede816c1d 100644 --- a/apps/explorer/package.json +++ b/apps/explorer/package.json @@ -42,8 +42,8 @@ "@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-tabs": "^1.0.4", "@sentry/react": "^7.59.2", - "@tanstack/react-query": "^4.29.25", - "@tanstack/react-query-devtools": "^4.29.25", + "@tanstack/react-query": "^5.0.0", + "@tanstack/react-query-devtools": "^5.0.1", "@tanstack/react-table": "^8.9.3", "@types/d3-array": "^3.0.5", "@types/throttle-debounce": "^5.0.0", diff --git a/apps/explorer/src/components/AccountCardGraph.tsx b/apps/explorer/src/components/AccountCardGraph.tsx index 366b76579cc7b..04c83569477fd 100644 --- a/apps/explorer/src/components/AccountCardGraph.tsx +++ b/apps/explorer/src/components/AccountCardGraph.tsx @@ -38,7 +38,7 @@ function TooltipContent({ data }: { data: AllEpochsAddressMetrics[number] }) { export function AccountsCardGraph() { const { data: addressMetrics } = useGetAddressMetrics(); - const { data: allEpochMetrics, isLoading } = useGetAllEpochAddressMetrics({ + const { data: allEpochMetrics, isPending } = useGetAllEpochAddressMetrics({ descendingOrder: false, }); const adjEpochAddressMetrics = useMemo(() => allEpochMetrics?.slice(-30), [allEpochMetrics]); @@ -77,7 +77,7 @@ export function AccountsCardGraph() { !adjEpochAddressMetrics?.length && 'bg-gray-40', )} > - {isLoading ? ( + {isPending ? (
diff --git a/apps/explorer/src/components/Activity/EpochsActivityTable.tsx b/apps/explorer/src/components/Activity/EpochsActivityTable.tsx index 41fc1e85840f7..9e2ef89c0765f 100644 --- a/apps/explorer/src/components/Activity/EpochsActivityTable.tsx +++ b/apps/explorer/src/components/Activity/EpochsActivityTable.tsx @@ -37,7 +37,7 @@ export function EpochsActivityTable({ }); const epochs = useGetEpochs(limit); - const { data, isFetching, pagination, isLoading, isError } = useCursorPagination(epochs); + const { data, isFetching, pagination, isPending, isError } = useCursorPagination(epochs); const cardData = data ? genTableDataFromEpochsData(data) : undefined; @@ -46,7 +46,7 @@ export function EpochsActivityTable({ {isError && (
Failed to load Epochs
)} - {isLoading || isFetching || !cardData ? ( + {isPending || isFetching || !cardData ? ( client.getTotalTransactionBlocks(), - cacheTime: 24 * 60 * 60 * 1000, + gcTime: 24 * 60 * 60 * 1000, staleTime: Infinity, retry: false, }); @@ -44,7 +44,7 @@ export function TransactionsActivityTable({ limit, refetchInterval, ); - const { data, isFetching, pagination, isLoading, isError } = useCursorPagination(transactions); + const { data, isFetching, pagination, isPending, isError } = useCursorPagination(transactions); const goToFirstPageRef = useRef(pagination.onFirst); goToFirstPageRef.current = pagination.onFirst; const cardData = data ? genTableDataFromTxData(data.data) : undefined; @@ -60,7 +60,7 @@ export function TransactionsActivityTable({
)}
- {isLoading || isFetching || !cardData ? ( + {isPending || isFetching || !cardData ? ( diff --git a/apps/explorer/src/components/Object/UnderlyingObjectCard.tsx b/apps/explorer/src/components/Object/UnderlyingObjectCard.tsx index 081e57a436b2c..c636194a33840 100644 --- a/apps/explorer/src/components/Object/UnderlyingObjectCard.tsx +++ b/apps/explorer/src/components/Object/UnderlyingObjectCard.tsx @@ -20,7 +20,7 @@ export function UnderlyingObjectCard({ name, dynamicFieldType, }: UnderlyingObjectCardProps) { - const { data, isLoading, isError, isFetched } = useSuiClientQuery('getDynamicFieldObject', { + const { data, isPending, isError, isFetched } = useSuiClientQuery('getDynamicFieldObject', { parentId, name, }); @@ -35,14 +35,14 @@ export function UnderlyingObjectCard({ const { data: normalizedStruct, isFetched: normalizedStructFetched, - isLoading: loadingNormalizedStruct, + isPending: loadingNormalizedStruct, } = useSuiClientQuery('getNormalizedMoveStruct', { package: packageId, module: moduleName, struct: functionName, }); - const isDataLoading = isLoading || loadingNormalizedStruct; + const isDataLoading = isPending || loadingNormalizedStruct; // Check for error first before showing the loading spinner to avoid infinite loading if GetDynamicFieldObject fails if ( diff --git a/apps/explorer/src/components/OwnedCoins/OwnedCoinsPanel.tsx b/apps/explorer/src/components/OwnedCoins/OwnedCoinsPanel.tsx index 22998f8baee22..0a7789e440cc5 100644 --- a/apps/explorer/src/components/OwnedCoins/OwnedCoinsPanel.tsx +++ b/apps/explorer/src/components/OwnedCoins/OwnedCoinsPanel.tsx @@ -19,10 +19,10 @@ export default function CoinsPanel({ coinType, id }: CoinsPanelProps) { const containerRef = useRef(null); const coinsSectionRef = useRef(null); const { isIntersecting } = useOnScreen(containerRef); - const { data, isLoading, isFetching, fetchNextPage, hasNextPage } = useGetCoins(coinType, id); + const { data, isPending, isFetching, fetchNextPage, hasNextPage } = useGetCoins(coinType, id); const [_, containerWidth] = useElementDimensions(coinsSectionRef); - const isSpinnerVisible = hasNextPage || isLoading || isFetching; + const isSpinnerVisible = hasNextPage || isPending || isFetching; useEffect(() => { if (isIntersecting && hasNextPage && !isFetching) { diff --git a/apps/explorer/src/components/OwnedCoins/index.tsx b/apps/explorer/src/components/OwnedCoins/index.tsx index f28831e0aa806..9f2034280780c 100644 --- a/apps/explorer/src/components/OwnedCoins/index.tsx +++ b/apps/explorer/src/components/OwnedCoins/index.tsx @@ -27,7 +27,7 @@ export function OwnedCoins({ id }: { id: string }) { const [currentSlice, setCurrentSlice] = useState(1); const [limit, setLimit] = useState(20); const [filterValue, setFilterValue] = useState(COIN_FILTERS.RECOGNIZED); - const { isLoading, data, isError } = useSuiClientQuery('getAllBalances', { + const { isPending, data, isError } = useSuiClientQuery('getAllBalances', { owner: normalizeSuiAddress(id), }); const recognizedPackages = useRecognizedPackages(); @@ -97,7 +97,7 @@ export function OwnedCoins({ id }: { id: string }) { return (
- {isLoading ? ( + {isPending ? (
diff --git a/apps/explorer/src/components/OwnedObjects/index.tsx b/apps/explorer/src/components/OwnedObjects/index.tsx index 9e48c9675f576..d2e1cdde96631 100644 --- a/apps/explorer/src/components/OwnedObjects/index.tsx +++ b/apps/explorer/src/components/OwnedObjects/index.tsx @@ -79,17 +79,17 @@ export function OwnedObjects({ id }: { id: string }) { const { data, isError, isFetching, pagination } = useCursorPagination(ownedObjects); - const isLoading = filter === FILTER_VALUES.ALL ? isFetching : kioskDataFetching; + const isPending = filter === FILTER_VALUES.ALL ? isFetching : kioskDataFetching; useEffect(() => { - if (!isLoading) { + if (!isPending) { setFilter( kioskData?.list?.length && filter === FILTER_VALUES.KIOSKS ? FILTER_VALUES.KIOSKS : FILTER_VALUES.ALL, ); } - }, [filter, isLoading, kioskData?.list?.length, setFilter]); + }, [filter, isPending, kioskData?.list?.length, setFilter]); const filteredData = useMemo( () => (filter === FILTER_VALUES.ALL ? data?.data : kioskData?.list), @@ -131,7 +131,7 @@ export function OwnedObjects({ id }: { id: string }) { ); const hasAssets = sortedDataByDisplayImages.length > 0; - const noAssets = !hasAssets && !isLoading; + const noAssets = !hasAssets && !isPending; if (isError) { return
Failed to load NFTs
; @@ -188,7 +188,7 @@ export function OwnedObjects({ id }: { id: string }) { label={filter.label} disabled={ (filter.value === FILTER_VALUES.KIOSKS && !kioskData?.list?.length) || - isLoading + isPending } /> ))} @@ -206,23 +206,23 @@ export function OwnedObjects({ id }: { id: string }) { )} {viewMode === OBJECT_VIEW_MODES.LIST && ( - + )} {viewMode === OBJECT_VIEW_MODES.SMALL_THUMBNAILS && ( )} {viewMode === OBJECT_VIEW_MODES.THUMBNAILS && ( - + )} {showPagination && (
- {!isLoading && ( + {!isPending && ( Showing {start} - {end} diff --git a/apps/explorer/src/components/TransactionBlocksForAddress/TransactionBlocksForAddress.tsx b/apps/explorer/src/components/TransactionBlocksForAddress/TransactionBlocksForAddress.tsx index 10617a06ce73d..6fd49b5d4173c 100644 --- a/apps/explorer/src/components/TransactionBlocksForAddress/TransactionBlocksForAddress.tsx +++ b/apps/explorer/src/components/TransactionBlocksForAddress/TransactionBlocksForAddress.tsx @@ -79,7 +79,7 @@ function TransactionBlocksForAddress({ ChangedObject: 0, }); - const { data, isLoading, isFetching, isFetchingNextPage, fetchNextPage, hasNextPage } = + const { data, isPending, isFetching, isFetchingNextPage, fetchNextPage, hasNextPage } = useGetTransactionBlocks({ [filterValue]: address, } as TransactionFilter); @@ -111,7 +111,7 @@ function TransactionBlocksForAddress({
- {isLoading || isFetching || isFetchingNextPage || !cardData ? ( + {isPending || isFetching || isFetchingNextPage || !cardData ? ( 1)) && ( { - if (isLoading || isFetching) { + if (isPending || isFetching) { return; } @@ -135,7 +135,7 @@ function TransactionBlocksForAddress({ if ( data && currentPageState[filterValue] === data?.pages.length - 1 && - !isLoading && + !isPending && !isFetching ) { fetchNextPage(); diff --git a/apps/explorer/src/components/TransactionsCardGraph.tsx b/apps/explorer/src/components/TransactionsCardGraph.tsx index 8015dc1523c73..f327f815c6bd5 100644 --- a/apps/explorer/src/components/TransactionsCardGraph.tsx +++ b/apps/explorer/src/components/TransactionsCardGraph.tsx @@ -68,12 +68,12 @@ export function TransactionsCardGraph() { 'getTotalTransactionBlocks', {}, { - cacheTime: 24 * 60 * 60 * 1000, + gcTime: 24 * 60 * 60 * 1000, staleTime: Infinity, retry: 5, }, ); - const { data: epochMetrics, isLoading } = useEpochTransactions(); + const { data: epochMetrics, isPending } = useEpochTransactions(); const lastEpochTotalTransactions = epochMetrics?.[epochMetrics.length - 1]?.epochTotalTransactions; @@ -104,7 +104,7 @@ export function TransactionsCardGraph() { !epochMetrics?.length && 'bg-gray-40', )} > - {isLoading ? ( + {isPending ? (
diff --git a/apps/explorer/src/components/checkpoints/CheckpointsTable.tsx b/apps/explorer/src/components/checkpoints/CheckpointsTable.tsx index 2fcfc499e3731..00d3d43b4f24f 100644 --- a/apps/explorer/src/components/checkpoints/CheckpointsTable.tsx +++ b/apps/explorer/src/components/checkpoints/CheckpointsTable.tsx @@ -36,7 +36,7 @@ export function CheckpointsTable({ const checkpoints = useGetCheckpoints(initialCursor, limit); - const { data, isFetching, pagination, isLoading, isError } = useCursorPagination(checkpoints); + const { data, isFetching, pagination, isPending, isError } = useCursorPagination(checkpoints); const count = useMemo(() => { if (maxCursor) { @@ -60,7 +60,7 @@ export function CheckpointsTable({ Failed to load Checkpoints
)} - {isLoading || isFetching || !cardData ? ( + {isPending || isFetching || !cardData ? ( Execute diff --git a/apps/explorer/src/components/module/module-functions-interaction/index.tsx b/apps/explorer/src/components/module/module-functions-interaction/index.tsx index 9da14c2aba4c9..0c55acffd8e45 100644 --- a/apps/explorer/src/components/module/module-functions-interaction/index.tsx +++ b/apps/explorer/src/components/module/module-functions-interaction/index.tsx @@ -20,7 +20,7 @@ export function ModuleFunctionsInteraction({ const { data: normalizedModule, error, - isLoading, + isPending, } = useNormalizedMoveModule(packageId, moduleName); const executableFunctions = useMemo(() => { if (!normalizedModule) { @@ -30,8 +30,8 @@ export function ModuleFunctionsInteraction({ .filter(([_, anFn]) => anFn.isEntry) .map(([fnName, details]) => ({ name: fnName, details })); }, [normalizedModule]); - const isEmpty = !isLoading && !executableFunctions.length && !error; - if (isEmpty || error || isLoading) { + const isEmpty = !isPending && !executableFunctions.length && !error; + if (isEmpty || error || isPending) { return (
{error ? ( diff --git a/apps/explorer/src/components/search/Search.tsx b/apps/explorer/src/components/search/Search.tsx index 837984ac6cc21..56f7bcca58155 100644 --- a/apps/explorer/src/components/search/Search.tsx +++ b/apps/explorer/src/components/search/Search.tsx @@ -11,7 +11,7 @@ import { ampli } from '~/utils/analytics/ampli'; function Search() { const [query, setQuery] = useState(''); const debouncedQuery = useDebouncedValue(query); - const { isLoading, data: results } = useSearch(debouncedQuery); + const { isPending, data: results } = useSearch(debouncedQuery); const navigate = useNavigateWithQuery(); const handleSelectResult = useCallback( (result: SearchResult) => { @@ -42,7 +42,7 @@ function Search() { onChange={(value) => setQuery(value?.trim() ?? '')} onSelectResult={handleSelectResult} placeholder="Search" - isLoading={isLoading || debouncedQuery !== query} + isLoading={isPending || debouncedQuery !== query} options={results} />
diff --git a/apps/explorer/src/components/top-packages/TopPackagesCard.tsx b/apps/explorer/src/components/top-packages/TopPackagesCard.tsx index 1cfa4837feaa8..79c341fbbee27 100644 --- a/apps/explorer/src/components/top-packages/TopPackagesCard.tsx +++ b/apps/explorer/src/components/top-packages/TopPackagesCard.tsx @@ -22,7 +22,7 @@ export function TopPackagesCard() { const rpc = useEnhancedRpcClient(); const [selectedFilter, setSelectedFilter] = useState('3D'); - const { data, isLoading } = useQuery({ + const { data, isPending } = useQuery({ queryKey: ['top-packages', selectedFilter], queryFn: async () => rpc.getMoveCallMetrics(), }); @@ -44,7 +44,7 @@ export function TopPackagesCard() { tooltip="Popular packages is recomputed on epoch changes." > - +
diff --git a/apps/explorer/src/components/top-validators-card/TopValidatorsCard.tsx b/apps/explorer/src/components/top-validators-card/TopValidatorsCard.tsx index a308db82d2395..a0b6640551488 100644 --- a/apps/explorer/src/components/top-validators-card/TopValidatorsCard.tsx +++ b/apps/explorer/src/components/top-validators-card/TopValidatorsCard.tsx @@ -105,14 +105,14 @@ type TopValidatorsCardProps = { }; export function TopValidatorsCard({ limit, showIcon }: TopValidatorsCardProps) { - const { data, isLoading, isSuccess, isError } = useSuiClientQuery('getLatestSuiSystemState'); + const { data, isPending, isSuccess, isError } = useSuiClientQuery('getLatestSuiSystemState'); const tableData = useMemo( () => (data ? validatorsTable(data.activeValidators, limit, showIcon) : null), [data, limit, showIcon], ); - if (isError || (!isLoading && !tableData?.data.length)) { + if (isError || (!isPending && !tableData?.data.length)) { return ( Validator data could not be loaded @@ -122,7 +122,7 @@ export function TopValidatorsCard({ limit, showIcon }: TopValidatorsCardProps) { return ( <> - {isLoading && ( + {isPending && ( { const filters = @@ -55,7 +55,7 @@ export function TransactionsForAddress({ address, type }: Props) { }, }); - if (isLoading) { + if (isPending) { return (
diff --git a/apps/explorer/src/components/validator-map/index.tsx b/apps/explorer/src/components/validator-map/index.tsx index af3ca0c9eadcf..eb14fdb3c8490 100644 --- a/apps/explorer/src/components/validator-map/index.tsx +++ b/apps/explorer/src/components/validator-map/index.tsx @@ -44,7 +44,7 @@ export default function ValidatorMap({ minHeight }: Props) { const { request } = useAppsBackend(); - const { data, isLoading, isError } = useQuery({ + const { data, isPending, isError } = useQuery({ queryKey: ['validator-map'], queryFn: () => request('validator-map', { @@ -122,7 +122,7 @@ export default function ValidatorMap({ minHeight }: Props) {
Countries - {isLoading && } + {isPending && } {(!isError && countryCount && numberFormatter.format(countryCount)) || '--'} @@ -131,7 +131,7 @@ export default function ValidatorMap({ minHeight }: Props) {
- {isLoading && } + {isPending && } { // Fetch received response with no errors and the value was not null (!systemStateError && @@ -143,7 +143,7 @@ export default function ValidatorMap({ minHeight }: Props) { {network === Network.MAINNET && ( - {isLoading && } + {isPending && } {(data?.nodeCount && numberFormatter.format(data?.nodeCount)) || '--'} )} diff --git a/apps/explorer/src/hooks/useGetAddressMetrics.ts b/apps/explorer/src/hooks/useGetAddressMetrics.ts index c46f80676e1e3..0eb1c55727a0a 100644 --- a/apps/explorer/src/hooks/useGetAddressMetrics.ts +++ b/apps/explorer/src/hooks/useGetAddressMetrics.ts @@ -9,7 +9,7 @@ export function useGetAddressMetrics() { return useQuery({ queryKey: ['home', 'addresses'], queryFn: () => client.getAddressMetrics(), - cacheTime: 24 * 60 * 60 * 1000, + gcTime: 24 * 60 * 60 * 1000, staleTime: Infinity, retry: 5, }); diff --git a/apps/explorer/src/hooks/useGetCheckpoints.ts b/apps/explorer/src/hooks/useGetCheckpoints.ts index b178f62ab0888..ad81907d32adc 100644 --- a/apps/explorer/src/hooks/useGetCheckpoints.ts +++ b/apps/explorer/src/hooks/useGetCheckpoints.ts @@ -2,7 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 import { useSuiClient } from '@mysten/dapp-kit'; -import { useInfiniteQuery } from '@tanstack/react-query'; +import { type CheckpointPage } from '@mysten/sui.js/client'; +import { keepPreviousData, useInfiniteQuery } from '@tanstack/react-query'; export const DEFAULT_CHECKPOINTS_LIMIT = 20; @@ -10,20 +11,19 @@ export const DEFAULT_CHECKPOINTS_LIMIT = 20; export function useGetCheckpoints(cursor?: string, limit = DEFAULT_CHECKPOINTS_LIMIT) { const client = useSuiClient(); - return useInfiniteQuery( - ['get-checkpoints', limit, cursor], - async ({ pageParam }) => + return useInfiniteQuery({ + queryKey: ['get-checkpoints', limit, cursor], + queryFn: async ({ pageParam }) => await client.getCheckpoints({ descendingOrder: true, - cursor: pageParam ?? cursor, + cursor: (pageParam as string | null) ?? cursor, limit, }), - { - getNextPageParam: (lastPage) => (lastPage?.hasNextPage ? lastPage.nextCursor : false), - staleTime: 10 * 1000, - cacheTime: 24 * 60 * 60 * 1000, - retry: false, - keepPreviousData: true, - }, - ); + initialPageParam: null, + getNextPageParam: ({ hasNextPage, nextCursor }) => (hasNextPage ? nextCursor : null), + staleTime: 10 * 1000, + gcTime: 24 * 60 * 60 * 1000, + retry: false, + placeholderData: keepPreviousData, + }); } diff --git a/apps/explorer/src/hooks/useGetEpochs.ts b/apps/explorer/src/hooks/useGetEpochs.ts index 84f8575792b77..9d860f6f5722a 100644 --- a/apps/explorer/src/hooks/useGetEpochs.ts +++ b/apps/explorer/src/hooks/useGetEpochs.ts @@ -2,7 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 import { useSuiClient } from '@mysten/dapp-kit'; -import { useInfiniteQuery } from '@tanstack/react-query'; +import { type EpochPage } from '@mysten/sui.js/client'; +import { keepPreviousData, useInfiniteQuery } from '@tanstack/react-query'; export const DEFAULT_EPOCHS_LIMIT = 20; @@ -10,20 +11,19 @@ export const DEFAULT_EPOCHS_LIMIT = 20; export function useGetEpochs(limit = DEFAULT_EPOCHS_LIMIT) { const client = useSuiClient(); - return useInfiniteQuery( - ['get-epochs-blocks', limit], - ({ pageParam = null }) => + return useInfiniteQuery({ + queryKey: ['get-epochs-blocks', limit], + queryFn: ({ pageParam }) => client.getEpochs({ descendingOrder: true, - cursor: pageParam, + cursor: pageParam as string | null, limit, }), - { - getNextPageParam: ({ nextCursor, hasNextPage }) => (hasNextPage ? nextCursor : null), - staleTime: 10 * 1000, - cacheTime: 24 * 60 * 60 * 1000, - retry: false, - keepPreviousData: true, - }, - ); + initialPageParam: null, + getNextPageParam: ({ nextCursor, hasNextPage }) => (hasNextPage ? nextCursor : null), + staleTime: 10 * 1000, + gcTime: 24 * 60 * 60 * 1000, + retry: false, + placeholderData: keepPreviousData, + }); } diff --git a/apps/explorer/src/hooks/useGetNetworkMetrics.ts b/apps/explorer/src/hooks/useGetNetworkMetrics.ts index 5b0dfc5634c2c..23acdd2e9e6e2 100644 --- a/apps/explorer/src/hooks/useGetNetworkMetrics.ts +++ b/apps/explorer/src/hooks/useGetNetworkMetrics.ts @@ -9,7 +9,7 @@ export function useGetNetworkMetrics() { return useQuery({ queryKey: ['home', 'metrics'], queryFn: () => client.getNetworkMetrics(), - cacheTime: 24 * 60 * 60 * 1000, + gcTime: 24 * 60 * 60 * 1000, staleTime: Infinity, retry: 5, }); diff --git a/apps/explorer/src/hooks/useGetTransactionBlocks.ts b/apps/explorer/src/hooks/useGetTransactionBlocks.ts index 54d73ddd38632..764ff49ecc39d 100644 --- a/apps/explorer/src/hooks/useGetTransactionBlocks.ts +++ b/apps/explorer/src/hooks/useGetTransactionBlocks.ts @@ -2,9 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 import { useSuiClient } from '@mysten/dapp-kit'; -import { useInfiniteQuery } from '@tanstack/react-query'; +import { keepPreviousData, useInfiniteQuery } from '@tanstack/react-query'; -import type { TransactionFilter } from '@mysten/sui.js/client'; +import { type PaginatedTransactionResponse, type TransactionFilter } from '@mysten/sui.js/client'; export const DEFAULT_TRANSACTIONS_LIMIT = 20; @@ -16,12 +16,12 @@ export function useGetTransactionBlocks( ) { const client = useSuiClient(); - return useInfiniteQuery( - ['get-transaction-blocks', filter, limit], - async ({ pageParam }) => + return useInfiniteQuery({ + queryKey: ['get-transaction-blocks', filter, limit], + queryFn: async ({ pageParam }) => await client.queryTransactionBlocks({ filter, - cursor: pageParam, + cursor: pageParam as string | null, order: 'descending', limit, options: { @@ -29,12 +29,11 @@ export function useGetTransactionBlocks( showInput: true, }, }), - { - getNextPageParam: (lastPage) => (lastPage?.hasNextPage ? lastPage.nextCursor : false), - staleTime: 10 * 1000, - retry: false, - keepPreviousData: true, - refetchInterval, - }, - ); + initialPageParam: null, + getNextPageParam: ({ hasNextPage, nextCursor }) => (hasNextPage ? nextCursor : null), + staleTime: 10 * 1000, + retry: false, + placeholderData: keepPreviousData, + refetchInterval, + }); } diff --git a/apps/explorer/src/hooks/useImageMod.ts b/apps/explorer/src/hooks/useImageMod.ts index 861125ff6e277..eb7f84b50b2be 100644 --- a/apps/explorer/src/hooks/useImageMod.ts +++ b/apps/explorer/src/hooks/useImageMod.ts @@ -62,6 +62,6 @@ export function useImageMod({ url = '', enabled = true }: { url?: string; enable }, placeholderData, staleTime: 24 * 60 * 60 * 1000, - cacheTime: Infinity, + gcTime: Infinity, }); } diff --git a/apps/explorer/src/hooks/useSearch.ts b/apps/explorer/src/hooks/useSearch.ts index bf26e02306fed..4e2a9e06733a7 100644 --- a/apps/explorer/src/hooks/useSearch.ts +++ b/apps/explorer/src/hooks/useSearch.ts @@ -145,6 +145,6 @@ export function useSearch(query: string) { return results.map(({ value }) => value).flat(); }, enabled: !!query, - cacheTime: 10000, + gcTime: 10000, }); } diff --git a/apps/explorer/src/pages/address-result/AddressResult.tsx b/apps/explorer/src/pages/address-result/AddressResult.tsx index 68d1fe7d79bde..b6f1bc238d402 100644 --- a/apps/explorer/src/pages/address-result/AddressResult.tsx +++ b/apps/explorer/src/pages/address-result/AddressResult.tsx @@ -22,11 +22,11 @@ const LEFT_RIGHT_PANEL_MIN_SIZE = 30; const TOP_PANEL_MIN_SIZE = 20; function AddressResultPageHeader({ address, loading }: { address: string; loading?: boolean }) { - const { data: domainName, isFetching } = useResolveSuiNSName(address); + const { data: domainName, isLoading } = useResolveSuiNSName(address); return ( ; + return ; } function AddressResult({ address }: { address: string }) { diff --git a/apps/explorer/src/pages/checkpoints/CheckpointDetail.tsx b/apps/explorer/src/pages/checkpoints/CheckpointDetail.tsx index cc0e0d1613b9f..f0e63004b8f91 100644 --- a/apps/explorer/src/pages/checkpoints/CheckpointDetail.tsx +++ b/apps/explorer/src/pages/checkpoints/CheckpointDetail.tsx @@ -20,7 +20,7 @@ export default function CheckpointDetail() { const digestOrSequenceNumber = /^\d+$/.test(id!) ? parseInt(id!, 10) : id; const client = useSuiClient(); - const { data, isError, isLoading } = useQuery({ + const { data, isError, isPending } = useQuery({ queryKey: ['checkpoints', digestOrSequenceNumber], queryFn: () => client.getCheckpoint({ id: String(digestOrSequenceNumber!) }), }); @@ -31,7 +31,7 @@ export default function CheckpointDetail() { There was an issue retrieving data for checkpoint: {id} - ) : isLoading ? ( + ) : isPending ? ( ) : (
diff --git a/apps/explorer/src/pages/checkpoints/CheckpointTransactionBlocks.tsx b/apps/explorer/src/pages/checkpoints/CheckpointTransactionBlocks.tsx index 9d44d2fd1839c..83d30f44c7689 100644 --- a/apps/explorer/src/pages/checkpoints/CheckpointTransactionBlocks.tsx +++ b/apps/explorer/src/pages/checkpoints/CheckpointTransactionBlocks.tsx @@ -20,13 +20,13 @@ export function CheckpointTransactionBlocks({ id }: { id: string }) { limit, ); - const { data, isFetching, pagination, isLoading } = useCursorPagination(transactions); + const { data, isFetching, pagination, isPending } = useCursorPagination(transactions); const cardData = data ? genTableDataFromTxData(data.data) : undefined; return (
- {isLoading || isFetching || !cardData ? ( + {isPending || isFetching || !cardData ? ( enhancedRpc.getEpochs({ @@ -69,7 +69,7 @@ export default function EpochDetail() { ); }, [epochData]); - if (isLoading) return } />; + if (isPending) return } />; if (isError || !epochData) return ( diff --git a/apps/explorer/src/pages/object-result/ObjectResult.tsx b/apps/explorer/src/pages/object-result/ObjectResult.tsx index ac080274b37de..b61b0aedaf3ee 100644 --- a/apps/explorer/src/pages/object-result/ObjectResult.tsx +++ b/apps/explorer/src/pages/object-result/ObjectResult.tsx @@ -20,9 +20,9 @@ const PACKAGE_TYPE_NAME = 'Move Package'; export function ObjectResult() { const { id: objID } = useParams(); - const { data, isLoading, isError, isFetched } = useGetObject(objID!); + const { data, isPending, isError, isFetched } = useGetObject(objID!); - if (isLoading) { + if (isPending) { return ( ; } const viewedData = { diff --git a/apps/explorer/src/pages/object-result/views/TokenView.tsx b/apps/explorer/src/pages/object-result/views/TokenView.tsx index ab28bb9b96190..fb872b6d8f159 100644 --- a/apps/explorer/src/pages/object-result/views/TokenView.tsx +++ b/apps/explorer/src/pages/object-result/views/TokenView.tsx @@ -26,7 +26,7 @@ enum TABS_VALUES { } function useObjectFieldsCard(id: string) { - const { data: suiObjectResponseData, isLoading, isError } = useGetObject(id); + const { data: suiObjectResponseData, isPending, isError } = useGetObject(id); const objectType = suiObjectResponseData?.data?.type ?? @@ -39,7 +39,7 @@ function useObjectFieldsCard(id: string) { // Get the normalized struct for the object const { data: normalizedStructData, - isLoading: loadingNormalizedStruct, + isPending: loadingNormalizedStruct, isError: errorNormalizedMoveStruct, } = useSuiClientQuery( 'getNormalizedMoveStruct', @@ -54,7 +54,7 @@ function useObjectFieldsCard(id: string) { ); return { - loading: isLoading || loadingNormalizedStruct, + loading: isPending || loadingNormalizedStruct, error: isError || errorNormalizedMoveStruct, normalizedStructData, suiObjectResponseData, diff --git a/apps/explorer/src/pages/transaction-result/TransactionResult.tsx b/apps/explorer/src/pages/transaction-result/TransactionResult.tsx index 0ff3cb9377763..e6573e919a8dd 100644 --- a/apps/explorer/src/pages/transaction-result/TransactionResult.tsx +++ b/apps/explorer/src/pages/transaction-result/TransactionResult.tsx @@ -41,7 +41,7 @@ function TransactionResultPageHeader({ export default function TransactionResult() { const { id } = useParams(); const { - isLoading, + isPending, isError: getTxnErrorBool, data, error: getTxnError, @@ -52,13 +52,13 @@ export default function TransactionResult() { return ( ), size: 'md', diff --git a/apps/explorer/src/pages/validator/ValidatorDetails.tsx b/apps/explorer/src/pages/validator/ValidatorDetails.tsx index 589a8cf40fc94..39e074a79da3e 100644 --- a/apps/explorer/src/pages/validator/ValidatorDetails.tsx +++ b/apps/explorer/src/pages/validator/ValidatorDetails.tsx @@ -26,7 +26,7 @@ const getAtRiskRemainingEpochs = ( function ValidatorDetails() { const { id } = useParams(); - const { data, isLoading } = useSuiClientQuery('getLatestSuiSystemState'); + const { data, isPending } = useSuiClientQuery('getLatestSuiSystemState'); const validatorData = useMemo(() => { if (!data) return null; @@ -40,9 +40,9 @@ function ValidatorDetails() { const atRiskRemainingEpochs = getAtRiskRemainingEpochs(data, id); const numberOfValidators = data?.activeValidators.length ?? null; - const { data: rollingAverageApys, isLoading: validatorsApysLoading } = useGetValidatorsApy(); + const { data: rollingAverageApys, isPending: validatorsApysLoading } = useGetValidatorsApy(); - const { data: validatorEvents, isLoading: validatorsEventsLoading } = useGetValidatorsEvents({ + const { data: validatorEvents, isPending: validatorsEventsLoading } = useGetValidatorsEvents({ limit: numberOfValidators, order: 'descending', }); @@ -55,7 +55,7 @@ function ValidatorDetails() { return rewards ? Number(rewards) : null; }, [id, validatorEvents]); - if (isLoading || validatorsEventsLoading || validatorsApysLoading) { + if (isPending || validatorsEventsLoading || validatorsApysLoading) { return ( All Validators - {(isLoading || validatorsEventsLoading) && ( + {(isPending || validatorsEventsLoading) && ( { hasNextPage: boolean; } -export function useCursorPagination(query: UseInfiniteQueryResult) { +export function useCursorPagination(query: UseInfiniteQueryResult>) { const [currentPage, setCurrentPage] = useState(0); return { diff --git a/apps/wallet/package.json b/apps/wallet/package.json index d18133b22451c..8142d10ac69f0 100644 --- a/apps/wallet/package.json +++ b/apps/wallet/package.json @@ -134,7 +134,7 @@ "@scure/bip32": "^1.3.1", "@scure/bip39": "^1.2.1", "@sentry/browser": "^7.61.0", - "@tanstack/react-query": "^4.29.25", + "@tanstack/react-query": "^5.0.0", "@tanstack/react-query-persist-client": "^4.29.25", "bignumber.js": "^9.1.1", "bootstrap-icons": "^1.10.5", diff --git a/apps/wallet/src/ui/app/background-client/index.ts b/apps/wallet/src/ui/app/background-client/index.ts index 3d97c86989e79..445458929488b 100644 --- a/apps/wallet/src/ui/app/background-client/index.ts +++ b/apps/wallet/src/ui/app/background-client/index.ts @@ -611,7 +611,7 @@ export class BackgroundClient { } else if (isMethodPayload(payload, 'entitiesUpdated')) { const entitiesQueryKey = entitiesToClientQueryKeys[payload.args.type]; if (entitiesQueryKey) { - queryClient.invalidateQueries(entitiesQueryKey); + queryClient.invalidateQueries({ queryKey: entitiesQueryKey }); } } if (action) { diff --git a/apps/wallet/src/ui/app/components/DAppInfoCard.tsx b/apps/wallet/src/ui/app/components/DAppInfoCard.tsx index 9fa64977a660c..b9c483e642ed4 100644 --- a/apps/wallet/src/ui/app/components/DAppInfoCard.tsx +++ b/apps/wallet/src/ui/app/components/DAppInfoCard.tsx @@ -34,7 +34,7 @@ export function DAppInfoCard({ const validDAppUrl = getValidDAppUrl(url); const appHostname = validDAppUrl?.hostname ?? url; const { data: account } = useAccountByAddress(connectedAddress); - const { unlockAccount, lockAccount, isLoading, accountToUnlock } = useUnlockAccount(); + const { unlockAccount, lockAccount, isPending, accountToUnlock } = useUnlockAccount(); return (
@@ -70,7 +70,7 @@ export function DAppInfoCard({
{ // prevent the account from being selected when clicking the lock button e.stopPropagation(); diff --git a/apps/wallet/src/ui/app/components/accounts/AccountListItem.tsx b/apps/wallet/src/ui/app/components/accounts/AccountListItem.tsx index 90cc7575c58f4..ac07b3e812ef4 100644 --- a/apps/wallet/src/ui/app/components/accounts/AccountListItem.tsx +++ b/apps/wallet/src/ui/app/components/accounts/AccountListItem.tsx @@ -25,7 +25,7 @@ export function AccountListItem({ hideExplorerLink, }: AccountListItemProps) { const activeAccount = useActiveAccount(); - const { unlockAccount, lockAccount, isLoading, accountToUnlock } = useUnlockAccount(); + const { unlockAccount, lockAccount, isPending, accountToUnlock } = useUnlockAccount(); return ( { // prevent the account from being selected when clicking the lock button e.stopPropagation(); diff --git a/apps/wallet/src/ui/app/components/accounts/UnlockAccountButton.tsx b/apps/wallet/src/ui/app/components/accounts/UnlockAccountButton.tsx index 92d8ade486669..a2787bbf447b8 100644 --- a/apps/wallet/src/ui/app/components/accounts/UnlockAccountButton.tsx +++ b/apps/wallet/src/ui/app/components/accounts/UnlockAccountButton.tsx @@ -17,7 +17,7 @@ export function UnlockAccountButton({ title = 'Unlock Account', }: UnlockAccountButtonProps) { const { isPasswordUnlockable } = account; - const { unlockAccount, isLoading } = useUnlockAccount(); + const { unlockAccount, isPending } = useUnlockAccount(); if (isPasswordUnlockable) { return
diff --git a/apps/wallet/src/ui/app/pages/accounts/BackupMnemonicPage.tsx b/apps/wallet/src/ui/app/pages/accounts/BackupMnemonicPage.tsx index 90d6a02aec690..d51db00537ab8 100644 --- a/apps/wallet/src/ui/app/pages/accounts/BackupMnemonicPage.tsx +++ b/apps/wallet/src/ui/app/pages/accounts/BackupMnemonicPage.tsx @@ -19,7 +19,7 @@ export function BackupMnemonicPage() { const [passwordCopied, setPasswordCopied] = useState(false); const { state } = useLocation(); const { accountSourceID } = useParams(); - const { data: accountSources, isLoading } = useAccountSources(); + const { data: accountSources, isPending } = useAccountSources(); const selectedSource = useMemo( () => accountSources?.find(({ id }) => accountSourceID === id), [accountSources, accountSourceID], @@ -47,11 +47,11 @@ export function BackupMnemonicPage() { } }, [requirePassword, passwordConfirmed, showPasswordDialog]); const navigate = useNavigate(); - if (!isLoading && selectedSource?.type !== 'mnemonic') { + if (!isPending && selectedSource?.type !== 'mnemonic') { return ; } return ( - + {showPasswordDialog ? (
- + {passphraseMutation.data ? ( ) : ( diff --git a/apps/wallet/src/ui/app/pages/accounts/ExportAccountPage.tsx b/apps/wallet/src/ui/app/pages/accounts/ExportAccountPage.tsx index bdcb8a922b126..449cb39a72b9c 100644 --- a/apps/wallet/src/ui/app/pages/accounts/ExportAccountPage.tsx +++ b/apps/wallet/src/ui/app/pages/accounts/ExportAccountPage.tsx @@ -16,7 +16,7 @@ import { useAccounts } from '../../hooks/useAccounts'; export function ExportAccountPage() { const { accountID } = useParams(); - const { data: allAccounts, isLoading } = useAccounts(); + const { data: allAccounts, isPending } = useAccounts(); const account = allAccounts?.find(({ id }) => accountID === id) || null; const backgroundClient = useBackgroundClient(); const exportMutation = useMutation({ @@ -35,12 +35,12 @@ export function ExportAccountPage() { }, }); const navigate = useNavigate(); - if (!account && !isLoading) { + if (!account && !isPending) { return ; } return ( navigate(-1)} showModal> - + {exportMutation.data ? (
diff --git a/apps/wallet/src/ui/app/pages/accounts/ExportPassphrasePage.tsx b/apps/wallet/src/ui/app/pages/accounts/ExportPassphrasePage.tsx index 4b3f42fab4d75..4c7766e8aec4c 100644 --- a/apps/wallet/src/ui/app/pages/accounts/ExportPassphrasePage.tsx +++ b/apps/wallet/src/ui/app/pages/accounts/ExportPassphrasePage.tsx @@ -13,16 +13,16 @@ import { useExportPassphraseMutation } from '../../hooks/useExportPassphraseMuta export function ExportPassphrasePage() { const { accountSourceID } = useParams(); - const { data: allAccountSources, isLoading } = useAccountSources(); + const { data: allAccountSources, isPending } = useAccountSources(); const accountSource = allAccountSources?.find(({ id }) => id === accountSourceID) || null; const navigate = useNavigate(); const exportMutation = useExportPassphraseMutation(); - if (!isLoading && accountSource?.type !== 'mnemonic') { + if (!isPending && accountSource?.type !== 'mnemonic') { return ; } return ( navigate(-1)} showModal> - + {exportMutation.data ? (
diff --git a/apps/wallet/src/ui/app/pages/accounts/ImportLedgerAccountsPage.tsx b/apps/wallet/src/ui/app/pages/accounts/ImportLedgerAccountsPage.tsx index ef091ac139a9a..10cffcb803f20 100644 --- a/apps/wallet/src/ui/app/pages/accounts/ImportLedgerAccountsPage.tsx +++ b/apps/wallet/src/ui/app/pages/accounts/ImportLedgerAccountsPage.tsx @@ -9,7 +9,7 @@ import { ThumbUpStroke32 as ThumbUpIcon, LockUnlocked16 as UnlockedLockIcon, } from '@mysten/icons'; -import { useCallback, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import toast from 'react-hot-toast'; import { useNavigate, useSearchParams } from 'react-router-dom'; @@ -36,7 +36,8 @@ export function ImportLedgerAccountsPage() { const [selectedLedgerAccounts, setSelectedLedgerAccounts] = useState([]); const { data: ledgerAccounts, - isLoading: areLedgerAccountsLoading, + error: ledgerError, + isPending: areLedgerAccountsLoading, isError: encounteredDerviceAccountsError, } = useDeriveLedgerAccounts({ numAccountsToDerive: numLedgerAccountsToDeriveByDefault, @@ -45,11 +46,15 @@ export function ImportLedgerAccountsPage() { ({ address }) => !existingAccounts?.some((account) => account.address === address), ); }, - onError: (error) => { - toast.error(getSuiApplicationErrorMessage(error) || 'Something went wrong.'); - navigate(-1); - }, }); + + useEffect(() => { + if (ledgerError) { + toast.error(getSuiApplicationErrorMessage(ledgerError) || 'Something went wrong.'); + navigate(-1); + } + }, [ledgerError, navigate]); + const onAccountClick = useCallback( (targetAccount: SelectableLedgerAccount) => { if (targetAccount.isSelected) { diff --git a/apps/wallet/src/ui/app/pages/accounts/ProtectAccountPage.tsx b/apps/wallet/src/ui/app/pages/accounts/ProtectAccountPage.tsx index d10498367eb4f..0b3f762a7657b 100644 --- a/apps/wallet/src/ui/app/pages/accounts/ProtectAccountPage.tsx +++ b/apps/wallet/src/ui/app/pages/accounts/ProtectAccountPage.tsx @@ -46,11 +46,11 @@ export function ProtectAccountPage() { useEffect(() => { if ( typeof hasPasswordAccounts !== 'undefined' && - !(createMutation.isSuccess || createMutation.isLoading) + !(createMutation.isSuccess || createMutation.isPending) ) { setShowVerifyPasswordView(hasPasswordAccounts); } - }, [hasPasswordAccounts, createMutation.isSuccess, createMutation.isLoading]); + }, [hasPasswordAccounts, createMutation.isSuccess, createMutation.isPending]); const createAccountCallback = useCallback( async (password: string, type: CreateType) => { try { diff --git a/apps/wallet/src/ui/app/pages/accounts/WelcomePage.tsx b/apps/wallet/src/ui/app/pages/accounts/WelcomePage.tsx index 777493775330b..94775feeeca62 100644 --- a/apps/wallet/src/ui/app/pages/accounts/WelcomePage.tsx +++ b/apps/wallet/src/ui/app/pages/accounts/WelcomePage.tsx @@ -20,7 +20,7 @@ export function WelcomePage() { const isFullscreenGuardLoading = useFullscreenGuard(true); const isInitializedLoading = useInitializedGuard( false, - !(createAccountsMutation.isLoading || createAccountsMutation.isSuccess), + !(createAccountsMutation.isPending || createAccountsMutation.isSuccess), ); const [, setAccountsFormValues] = useAccountsFormContext(); const navigate = useNavigate(); @@ -75,7 +75,7 @@ export function WelcomePage() { size="tall" variant="secondary" text="More Options" - disabled={createAccountsMutation.isLoading || createAccountsMutation.isSuccess} + disabled={createAccountsMutation.isPending || createAccountsMutation.isSuccess} />
diff --git a/apps/wallet/src/ui/app/pages/accounts/forgot-password/ForgotPasswordIndexPage.tsx b/apps/wallet/src/ui/app/pages/accounts/forgot-password/ForgotPasswordIndexPage.tsx index 3219e5774f1ca..04fff295519d1 100644 --- a/apps/wallet/src/ui/app/pages/accounts/forgot-password/ForgotPasswordIndexPage.tsx +++ b/apps/wallet/src/ui/app/pages/accounts/forgot-password/ForgotPasswordIndexPage.tsx @@ -12,12 +12,12 @@ export function ForgotPasswordIndexPage() { const totalRecoverable = allAccountSources.data?.filter(({ type }) => type === 'mnemonic').length || 0; useEffect(() => { - if (allAccountSources.isLoading) { + if (allAccountSources.isPending) { return; } const url = totalRecoverable === 0 ? '/' : totalRecoverable === 1 ? './recover' : './recover-many'; navigate(url, { replace: true }); - }, [allAccountSources.isLoading, totalRecoverable, navigate]); + }, [allAccountSources.isPending, totalRecoverable, navigate]); return null; } diff --git a/apps/wallet/src/ui/app/pages/accounts/forgot-password/RecoverManyPage.tsx b/apps/wallet/src/ui/app/pages/accounts/forgot-password/RecoverManyPage.tsx index 985394dae0746..f469f18b00251 100644 --- a/apps/wallet/src/ui/app/pages/accounts/forgot-password/RecoverManyPage.tsx +++ b/apps/wallet/src/ui/app/pages/accounts/forgot-password/RecoverManyPage.tsx @@ -23,12 +23,12 @@ export function RecoverManyPage() { const navigate = useNavigate(); useEffect(() => { if ( - !allAccountSources.isLoading && + !allAccountSources.isPending && !allAccountSources.data?.find(({ type }) => type === 'mnemonic') ) { navigate('/', { replace: true }); } - }, [allAccountSources.isLoading, allAccountSources.data, navigate]); + }, [allAccountSources.isPending, allAccountSources.data, navigate]); const { value } = useForgotPasswordContext(); const addRecoveryDataMutation = useRecoveryDataMutation(); const [recoverInfo, setRecoverInfo] = useState<{ title: string; accountSourceID: string } | null>( @@ -78,7 +78,7 @@ export function RecoverManyPage() { title={recoverInfo?.title} showModal={!!recoverInfo} closeOverlay={() => { - if (addRecoveryDataMutation.isLoading) { + if (addRecoveryDataMutation.isPending) { return; } setRecoverInfo(null); diff --git a/apps/wallet/src/ui/app/pages/accounts/forgot-password/RecoverPage.tsx b/apps/wallet/src/ui/app/pages/accounts/forgot-password/RecoverPage.tsx index 7d471a3d92fe1..5e0b94dee5085 100644 --- a/apps/wallet/src/ui/app/pages/accounts/forgot-password/RecoverPage.tsx +++ b/apps/wallet/src/ui/app/pages/accounts/forgot-password/RecoverPage.tsx @@ -17,10 +17,10 @@ export function RecoverPage() { const navigate = useNavigate(); const mnemonicAccountSource = allAccountSources.data?.find(({ type }) => type === 'mnemonic'); useEffect(() => { - if (!allAccountSources.isLoading && !mnemonicAccountSource) { + if (!allAccountSources.isPending && !mnemonicAccountSource) { navigate('/', { replace: true }); } - }, [allAccountSources.isLoading, mnemonicAccountSource, navigate]); + }, [allAccountSources.isPending, mnemonicAccountSource, navigate]); const recoveryDataMutation = useRecoveryDataMutation(); if (!mnemonicAccountSource) { return null; diff --git a/apps/wallet/src/ui/app/pages/accounts/forgot-password/ResetWarningPage.tsx b/apps/wallet/src/ui/app/pages/accounts/forgot-password/ResetWarningPage.tsx index 6d69b6c23a792..d582dda9d8fa9 100644 --- a/apps/wallet/src/ui/app/pages/accounts/forgot-password/ResetWarningPage.tsx +++ b/apps/wallet/src/ui/app/pages/accounts/forgot-password/ResetWarningPage.tsx @@ -26,11 +26,11 @@ export function ResetWarningPage() { !value.find(({ accountSourceID }) => accountSourceID === sourceID), ), ); - const { isLoading } = useAccounts(); + const { isPending } = useAccounts(); if (!value.length) { return ; } - if (!accountGroupsToRemove.length && !isLoading) { + if (!accountGroupsToRemove.length && !isPending) { return ; } return ( diff --git a/apps/wallet/src/ui/app/pages/accounts/manage/AccountGroup.tsx b/apps/wallet/src/ui/app/pages/accounts/manage/AccountGroup.tsx index 148438bc2ffb2..14acb0573c361 100644 --- a/apps/wallet/src/ui/app/pages/accounts/manage/AccountGroup.tsx +++ b/apps/wallet/src/ui/app/pages/accounts/manage/AccountGroup.tsx @@ -91,7 +91,7 @@ function AccountFooter({ accountID, showExport }: { accountID: string; showExpor {showExport ? ( Export Private Key ) : null} - {allAccounts.isLoading ? null : ( + {allAccounts.isPending ? null : ( setIsConfirmationVisible(true)} disabled={isConfirmationVisible} @@ -125,7 +125,7 @@ function AccountFooter({ accountID, showExport }: { accountID: string; showExpor variant="warning" size="tall" text="Remove" - loading={removeAccountMutation.isLoading} + loading={removeAccountMutation.isPending} onClick={() => { removeAccountMutation.mutate(undefined, { onSuccess: () => toast.success('Account removed'), @@ -169,7 +169,7 @@ export function AccountGroup({
{isMnemonicDerivedGroup && accountSource ? ( { // prevent the collapsible from closing when clicking the "new" button e.stopPropagation(); diff --git a/apps/wallet/src/ui/app/pages/approval-request/transaction-request/GasFees.tsx b/apps/wallet/src/ui/app/pages/approval-request/transaction-request/GasFees.tsx index e3abe7cb4cce2..87c48268a3a79 100644 --- a/apps/wallet/src/ui/app/pages/approval-request/transaction-request/GasFees.tsx +++ b/apps/wallet/src/ui/app/pages/approval-request/transaction-request/GasFees.tsx @@ -16,7 +16,7 @@ interface Props { export function GasFees({ sender, transaction }: Props) { const { data: transactionData } = useTransactionData(sender, transaction); - const { data: gasBudget, isLoading, isError } = useTransactionGasBudget(sender, transaction); + const { data: gasBudget, isPending, isError } = useTransactionGasBudget(sender, transaction); const isSponsored = transactionData?.gasConfig.owner && transactionData.sender !== transactionData.gasConfig.owner; return ( @@ -33,7 +33,7 @@ export function GasFees({ sender, transaction }: Props) { > - {isLoading + {isPending ? 'Estimating...' : isError ? 'Gas estimation failed' diff --git a/apps/wallet/src/ui/app/pages/approval-request/transaction-request/TransactionDetails/index.tsx b/apps/wallet/src/ui/app/pages/approval-request/transaction-request/TransactionDetails/index.tsx index d1cfe85fb45b5..d833ededa11b9 100644 --- a/apps/wallet/src/ui/app/pages/approval-request/transaction-request/TransactionDetails/index.tsx +++ b/apps/wallet/src/ui/app/pages/approval-request/transaction-request/TransactionDetails/index.tsx @@ -22,15 +22,15 @@ const Tab = (props: TabProps<'div'>) => ( ); export function TransactionDetails({ sender, transaction }: Props) { - const { data: transactionData, isLoading, isError } = useTransactionData(sender, transaction); + const { data: transactionData, isPending, isError } = useTransactionData(sender, transaction); if (transactionData?.transactions.length === 0 && transactionData.inputs.length === 0) { return null; } return ( - {isLoading || isError ? ( + {isPending || isError ? (
- {isLoading ? 'Gathering data...' : "Couldn't gather data"} + {isPending ? 'Gathering data...' : "Couldn't gather data"}
) : transactionData ? (
diff --git a/apps/wallet/src/ui/app/pages/approval-request/transaction-request/index.tsx b/apps/wallet/src/ui/app/pages/approval-request/transaction-request/index.tsx index 56e2c8f17e5bd..03c01a14da4d2 100644 --- a/apps/wallet/src/ui/app/pages/approval-request/transaction-request/index.tsx +++ b/apps/wallet/src/ui/app/pages/approval-request/transaction-request/index.tsx @@ -43,13 +43,13 @@ export function TransactionRequest({ txRequest }: TransactionRequestProps) { } return tx; }, [txRequest.tx.data, addressForTransaction]); - const { isLoading, isError } = useTransactionData(addressForTransaction, transaction); + const { isPending, isError } = useTransactionData(addressForTransaction, transaction); const [isConfirmationVisible, setConfirmationVisible] = useState(false); const { data, isError: isDryRunError, - isLoading: isDryRunLoading, + isPending: isDryRunLoading, } = useTransactionDryRun(addressForTransaction, transaction); const recognizedPackagesList = useRecognizedPackages(); @@ -70,7 +70,7 @@ export function TransactionRequest({ txRequest }: TransactionRequestProps) { approveTitle="Approve" rejectTitle="Reject" onSubmit={async (approved: boolean) => { - if (isLoading) return; + if (isPending) return; if (approved && isError) { setConfirmationVisible(true); return; @@ -92,7 +92,7 @@ export function TransactionRequest({ txRequest }: TransactionRequestProps) { } }} address={addressForTransaction} - approveLoading={isLoading || isConfirmationVisible} + approveLoading={isPending || isConfirmationVisible} checkAccountLock > diff --git a/apps/wallet/src/ui/app/pages/home/hidden-assets/index.tsx b/apps/wallet/src/ui/app/pages/home/hidden-assets/index.tsx index 74920d66b8dfd..e76a69b15db8b 100644 --- a/apps/wallet/src/ui/app/pages/home/hidden-assets/index.tsx +++ b/apps/wallet/src/ui/app/pages/home/hidden-assets/index.tsx @@ -11,6 +11,7 @@ import { Button } from '_src/ui/app/shared/ButtonUI'; import PageTitle from '_src/ui/app/shared/PageTitle'; import { getKioskIdFromOwnerCap, isKioskOwnerToken, useMultiGetObjects } from '@mysten/core'; import { EyeClose16 } from '@mysten/icons'; +import { keepPreviousData } from '@tanstack/react-query'; import { useMemo } from 'react'; import { Link } from 'react-router-dom'; @@ -19,13 +20,13 @@ import { useHiddenAssets } from './HiddenAssetsProvider'; function HiddenNftsPage() { const { hiddenAssetIds, showAsset } = useHiddenAssets(); - const { data, isInitialLoading, isLoading, isError, error } = useMultiGetObjects( + const { data, isLoading, isPending, isError, error } = useMultiGetObjects( hiddenAssetIds, { showDisplay: true, showType: true, }, - { keepPreviousData: true }, + { placeholderData: keepPreviousData }, ); const filteredAndSortedNfts = useMemo(() => { @@ -52,7 +53,7 @@ function HiddenNftsPage() { }); }, [hiddenAssetIds, data]); - if (isInitialLoading) { + if (isLoading) { return (
@@ -63,7 +64,7 @@ function HiddenNftsPage() { return (
- + {isError ? (
diff --git a/apps/wallet/src/ui/app/pages/home/kiosk-details/index.tsx b/apps/wallet/src/ui/app/pages/home/kiosk-details/index.tsx index 96787e3e7e485..a189f82ed82cb 100644 --- a/apps/wallet/src/ui/app/pages/home/kiosk-details/index.tsx +++ b/apps/wallet/src/ui/app/pages/home/kiosk-details/index.tsx @@ -20,7 +20,7 @@ function KioskDetailsPage() { const [searchParams] = useSearchParams(); const kioskId = searchParams.get('kioskId'); const accountAddress = useActiveAddress(); - const { data: kioskData, isLoading } = useGetKioskContents(accountAddress); + const { data: kioskData, isPending } = useGetKioskContents(accountAddress); const kiosk = kioskData?.kiosks.get(kioskId!); const items = kiosk?.items; @@ -31,7 +31,7 @@ function KioskDetailsPage() { return (
- + {!items?.length ? (
Kiosk is empty diff --git a/apps/wallet/src/ui/app/pages/home/nft-details/index.tsx b/apps/wallet/src/ui/app/pages/home/nft-details/index.tsx index d5f8b50005040..1b9e3976e488b 100644 --- a/apps/wallet/src/ui/app/pages/home/nft-details/index.tsx +++ b/apps/wallet/src/ui/app/pages/home/nft-details/index.tsx @@ -28,7 +28,7 @@ function NFTDetailsPage() { const [searchParams] = useSearchParams(); const nftId = searchParams.get('objectId'); const accountAddress = useActiveAddress(); - const { data: objectData, isLoading: isNftLoading } = useOwnedNFT(nftId || '', accountAddress); + const { data: objectData, isPending: isNftLoading } = useOwnedNFT(nftId || '', accountAddress); const isTransferable = !!objectData && objectData.content?.dataType === 'moveObject' && @@ -55,7 +55,7 @@ function NFTDetailsPage() { ); const metaKeys: string[] = metaFields ? metaFields.keys : []; const metaValues = metaFields ? metaFields.values : []; - const { data: nftDisplayData, isLoading: isLoadingDisplay } = useGetNFTMeta(nftId || ''); + const { data: nftDisplayData, isPending: isPendingDisplay } = useGetNFTMeta(nftId || ''); const objectExplorerLink = useExplorerLink({ type: ExplorerLinkType.object, objectID: nftId || '', @@ -71,15 +71,15 @@ function NFTDetailsPage() { address: ownerAddress, }); const isGuardLoading = useUnlockedGuard(); - const isLoading = isNftLoading || isLoadingDisplay || isGuardLoading; + const isPending = isNftLoading || isPendingDisplay || isGuardLoading; return (
- + {objectData ? ( <> diff --git a/apps/wallet/src/ui/app/pages/home/nft-transfer/TransferNFTForm.tsx b/apps/wallet/src/ui/app/pages/home/nft-transfer/TransferNFTForm.tsx index 803e52fda5b7d..ac4f800fef8af 100644 --- a/apps/wallet/src/ui/app/pages/home/nft-transfer/TransferNFTForm.tsx +++ b/apps/wallet/src/ui/app/pages/home/nft-transfer/TransferNFTForm.tsx @@ -80,9 +80,9 @@ export function TransferNFTForm({ ); }, onSuccess: (response) => { - queryClient.invalidateQueries(['object', objectId]); - queryClient.invalidateQueries(['get-kiosk-contents']); - queryClient.invalidateQueries(['get-owned-objects']); + queryClient.invalidateQueries({ queryKey: ['object', objectId] }); + queryClient.invalidateQueries({ queryKey: ['get-kiosk-contents'] }); + queryClient.invalidateQueries({ queryKey: ['get-owned-objects'] }); ampli.sentCollectible({ objectId }); @@ -141,7 +141,7 @@ export function TransferNFTForm({