react-query v4 -> v5 (#4600)

<!-- start pr-codex -->

## PR-Codex overview
This PR updates loading states in various components to use `isPending` instead of `isLoading`.

### Detailed summary
- Replaced `isLoading` with `isPending` in multiple components for loading state handling.

> The following files were skipped due to too many changes: `apps/dashboard/src/contract-ui/tabs/manage/components/InstalledModulesTable.tsx`, `apps/dashboard/src/components/pay/PayAnalytics/hooks/usePayCustomers.ts`, `apps/dashboard/src/components/pay/PayConfig.tsx`, `apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/(chainPage)/components/server/chain-header.tsx`, `apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/[slug]/(active)/components/client/add-partner-form.client.tsx`, `apps/dashboard/src/components/pay/PayAnalytics/components/PaymentHistory.tsx`, `apps/dashboard/src/contract-ui/tabs/split/components/distribute-button.tsx`, `apps/dashboard/src/components/onboarding/LinkWallet.tsx`, `apps/dashboard/src/components/pay/PayAnalytics/components/TotalVolumePieChart.tsx`, `apps/dashboard/package.json`, `apps/dashboard/src/components/pay/PayAnalytics/hooks/usePayPurchases.ts`, `apps/dashboard/src/components/engine/configuration/local-config.tsx.tsx`, `apps/dashboard/src/components/settings/ApiKeys/Create/index.tsx`, `apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/[slug]/(active)/components/server/partners-table.tsx`, `apps/dashboard/src/contract-ui/components/solidity-inputs/string-input.tsx`, `apps/dashboard/src/components/settings/Account/Billing/index.tsx`, `apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/[slug]/(active)/components/client/update-partner-form.client.tsx`, `apps/dashboard/src/contract-ui/tabs/nfts/page.tsx`, `apps/dashboard/src/components/configure-networks/Form/IconUpload.tsx`, `apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/create/hooks/use-create-ecosystem.ts`, `apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/create/components/client/create-ecosystem-form.client.tsx`, `apps/dashboard/src/components/engine/engine-instances-table.tsx`, `apps/dashboard/src/components/engine/contract-subscription/contract-subscriptions-table.tsx`, `apps/dashboard/src/components/pay/PayAnalytics/components/PayCustomersTable.tsx`, `apps/dashboard/src/pages/api/revalidate/publish.ts`, `apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/[slug]/(active)/hooks/use-update-ecosystem.ts`, `apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/[slug]/(active)/hooks/use-add-partner.ts`, `apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/[slug]/(active)/hooks/use-delete-partner.ts`, `apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/[slug]/(active)/hooks/use-update-partner.ts`, `apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/live-stats.tsx`, `apps/dashboard/src/contract-ui/tabs/shared-components/marketplace-table.tsx`, `apps/dashboard/src/@3rdweb-sdk/react/hooks/query/useQueryWithNetwork.ts`, `apps/dashboard/src/app/(dashboard)/dashboard/connect/pay/components/webhooks.client.tsx`, `apps/dashboard/src/components/contract-components/tables/deployed-contracts.tsx`, `apps/dashboard/src/contract-ui/tabs/proposals/components/proposal.tsx`, `apps/dashboard/src/components/app-layouts/app.tsx`, `apps/dashboard/src/app/(dashboard)/dashboard/connect/ecosystem/[slug]/(active)/components/client/integration-permissions-toggle.client.tsx`, `apps/dashboard/src/app/account/settings/AccountSettingsPageUI.tsx`, `apps/dashboard/src/components/cmd-k-search/index.tsx`, `apps/dashboard/src/@3rdweb-sdk/react/hooks/useLoggedInUser.ts`, `apps/dashboard/src/components/contract-components/hooks.ts`, `apps/dashboard/src/@3rdweb-sdk/react/hooks/useRegistry.ts`, `apps/dashboard/src/contract-ui/tabs/manage/components/ModuleForm.tsx`, `apps/dashboard/src/app/team/[team_slug]/(team)/~/settings/general/GeneralSettingsPage.tsx`, `apps/dashboard/src/components/storage/your-files.tsx`, `apps/dashboard/src/components/contract-functions/interactive-abi-function.tsx`, `apps/dashboard/src/components/ipfs-upload/dropzone.tsx`, `apps/dashboard/src/core-ui/nft-drawer/useNftDrawerTabs.tsx`, `apps/dashboard/src/@3rdweb-sdk/react/hooks/useApi.ts`, `pnpm-lock.yaml`, `apps/dashboard/src/contract-ui/hooks/useRouteConfig.tsx`, `apps/dashboard/src/@3rdweb-sdk/react/hooks/useEngine.ts`

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
This commit is contained in:
jnsdls
2024-09-15 21:32:49 +00:00
parent a4a41364cd
commit 575c3e3141
93 changed files with 602 additions and 589 deletions
+1 -2
View File
@@ -50,7 +50,7 @@
"@shazow/whatsabi": "^0.14.1",
"@stripe/react-stripe-js": "^2.7.3",
"@stripe/stripe-js": "^3.5.0",
"@tanstack/react-query": "^4.36.1",
"@tanstack/react-query": "5.55.4",
"@tanstack/react-table": "^8.17.3",
"@thirdweb-dev/sdk": "workspace:*",
"@thirdweb-dev/service-utils": "workspace:*",
@@ -93,7 +93,6 @@
"react-intersection-observer": "^9.10.3",
"react-markdown": "^9.0.1",
"react-otp-input": "^3.1.1",
"react-query-v5": "npm:@tanstack/[email protected]",
"react-responsive-carousel": "^3.2.23",
"react-table": "^7.8.0",
"recharts": "^2.12.7",
@@ -39,7 +39,11 @@ export function useQueryWithNetwork<
networkKeys.chain(activeChainId) as readonly unknown[]
).concat(queryKey) as unknown as TQueryKey;
return useQuery(combinedQueryKey, queryFn, mergedOptions);
return useQuery({
...mergedOptions,
queryKey: combinedQueryKey,
queryFn,
});
}
export function useMutationWithInvalidate<
TData = unknown,
@@ -71,19 +75,20 @@ export function useMutationWithInvalidate<
(cacheKeysToInvalidate: TQueryKey[]) => {
return Promise.all(
cacheKeysToInvalidate.map((cacheKey) => {
return queryClient.invalidateQueries(
(networkKeys.chain(activeChainId) as readonly unknown[]).concat(
cacheKey,
) as unknown[],
);
return queryClient.invalidateQueries({
queryKey: (
networkKeys.chain(activeChainId) as readonly unknown[]
).concat(cacheKey) as unknown[],
});
}),
);
},
[queryClient, activeChainId],
);
return useMutation(mutationFn, {
return useMutation({
...options,
mutationFn,
onSuccess: (...args) => {
if (options?.onSuccess) {
options.onSuccess(...args, invalidate);
@@ -254,15 +254,16 @@ export interface BillingCredit {
interface UseAccountInput {
refetchInterval?:
| number
| false
| ((
data: Account | undefined,
query: Query<
Account,
unknown,
Error,
Account,
readonly ["account", string, "me"]
>,
) => number | false);
) => number | false | undefined)
| undefined;
}
export function useAccount({ refetchInterval }: UseAccountInput = {}) {
@@ -286,7 +287,7 @@ export function useAccount({ refetchInterval }: UseAccountInput = {}) {
return json.data as Account;
},
enabled: !!user?.address && isLoggedIn,
refetchInterval: refetchInterval ?? false,
refetchInterval,
});
}
@@ -444,8 +445,8 @@ export function useUpdateAccount() {
const { user } = useLoggedInUser();
const queryClient = useQueryClient();
return useMutationWithInvalidate(
async (input: UpdateAccountInput) => {
return useMutation({
mutationFn: async (input: UpdateAccountInput) => {
invariant(user?.address, "walletAddress is required");
const res = await fetch(`${THIRDWEB_API_HOST}/v1/account`, {
@@ -465,14 +466,13 @@ export function useUpdateAccount() {
return json.data;
},
{
onSuccess: () => {
return queryClient.invalidateQueries(
accountKeys.me(user?.address as string),
);
},
onSuccess: () => {
return queryClient.invalidateQueries({
queryKey: accountKeys.me(user?.address as string),
});
},
);
});
}
export function useUpdateAccountPlan(waitForWebhook?: boolean) {
@@ -507,13 +507,15 @@ export function useUpdateAccountPlan(waitForWebhook?: boolean) {
return json.data;
},
{
onSuccess: () => {
onSuccess: async () => {
// invalidate usage data as limits are different
queryClient.invalidateQueries(accountKeys.me(user?.address as string));
await queryClient.invalidateQueries({
queryKey: accountKeys.me(user?.address as string),
});
return queryClient.invalidateQueries(
accountKeys.usage(user?.address as string),
);
return queryClient.invalidateQueries({
queryKey: accountKeys.usage(user?.address as string),
});
},
},
);
@@ -545,9 +547,9 @@ export function useUpdateNotifications() {
},
{
onSuccess: () => {
return queryClient.invalidateQueries(
accountKeys.me(user?.address as string),
);
return queryClient.invalidateQueries({
queryKey: accountKeys.me(user?.address as string),
});
},
},
);
@@ -608,16 +610,19 @@ export function useConfirmEmail() {
return json.data;
},
{
onSuccess: () => {
onSuccess: async () => {
// invalidate related cache, since could be relinking account
queryClient.invalidateQueries(apiKeys.keys(user?.address as string));
queryClient.invalidateQueries(
accountKeys.usage(user?.address as string),
);
return queryClient.invalidateQueries(
accountKeys.me(user?.address as string),
);
return Promise.all([
queryClient.invalidateQueries({
queryKey: apiKeys.keys(user?.address as string),
}),
queryClient.invalidateQueries({
queryKey: accountKeys.usage(user?.address as string),
}),
queryClient.invalidateQueries({
queryKey: accountKeys.me(user?.address as string),
}),
]);
},
},
);
@@ -652,9 +657,9 @@ export function useResendEmailConfirmation() {
},
{
onSuccess: () => {
return queryClient.invalidateQueries(
accountKeys.me(user?.address as string),
);
return queryClient.invalidateQueries({
queryKey: accountKeys.me(user?.address as string),
});
},
},
);
@@ -688,9 +693,9 @@ export function useCreatePaymentMethod() {
},
{
onSuccess: () => {
return queryClient.invalidateQueries(
accountKeys.me(user?.address as string),
);
return queryClient.invalidateQueries({
queryKey: accountKeys.me(user?.address as string),
});
},
},
);
@@ -723,8 +728,8 @@ export function useCreateApiKey() {
const { user } = useLoggedInUser();
const queryClient = useQueryClient();
return useMutation(
async (input: CreateKeyInput) => {
return useMutation({
mutationFn: async (input: CreateKeyInput) => {
invariant(user?.address, "walletAddress is required");
const res = await fetch(`${THIRDWEB_API_HOST}/v1/keys`, {
@@ -743,14 +748,13 @@ export function useCreateApiKey() {
return json.data as ApiKey;
},
{
onSuccess: () => {
return queryClient.invalidateQueries(
apiKeys.keys(user?.address as string),
);
},
onSuccess: () => {
return queryClient.invalidateQueries({
queryKey: apiKeys.keys(user?.address as string),
});
},
);
});
}
export function useUpdateApiKey() {
@@ -780,9 +784,9 @@ export function useUpdateApiKey() {
},
{
onSuccess: () => {
return queryClient.invalidateQueries(
apiKeys.keys(user?.address as string),
);
return queryClient.invalidateQueries({
queryKey: apiKeys.keys(user?.address as string),
});
},
},
);
@@ -814,9 +818,9 @@ export function useRevokeApiKey() {
},
{
onSuccess: () => {
return queryClient.invalidateQueries(
apiKeys.keys(user?.address as string),
);
return queryClient.invalidateQueries({
queryKey: apiKeys.keys(user?.address as string),
});
},
},
);
@@ -869,7 +873,9 @@ export const useUpdatePolicies = () => {
},
{
onSuccess: (_, variables) => {
return queryClient.invalidateQueries(["policies", variables.serviceId]);
return queryClient.invalidateQueries({
queryKey: ["policies", variables.serviceId],
});
},
},
);
@@ -906,9 +912,11 @@ export function useRevokeAuthorizedWallet() {
},
{
onSuccess: () => {
return queryClient.invalidateQueries(
authorizedWallets.authorizedWallets(user?.address as string),
);
return queryClient.invalidateQueries({
queryKey: authorizedWallets.authorizedWallets(
user?.address as string,
),
});
},
},
);
@@ -936,7 +944,7 @@ export function useAuthorizedWallets() {
return json.data as AuthorizedWallet[];
},
enabled: !!user?.address && isLoggedIn,
cacheTime: 0,
gcTime: 0,
});
}
@@ -191,24 +191,26 @@ interface UpdateVersionInput {
}
export function useEngineUpdateVersion() {
return useMutation(async (input: UpdateVersionInput) => {
invariant(input.engineId, "engineId is required");
return useMutation({
mutationFn: async (input: UpdateVersionInput) => {
invariant(input.engineId, "engineId is required");
const res = await fetch(`${THIRDWEB_API_HOST}/v1/engine/update-version`, {
method: "POST",
const res = await fetch(`${THIRDWEB_API_HOST}/v1/engine/update-version`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
engineId: input.engineId,
}),
});
// we never use the response body
res.body?.cancel();
if (!res.ok) {
throw new Error(`Unexpected status ${res.status}: ${await res.text()}`);
}
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
engineId: input.engineId,
}),
});
// we never use the response body
res.body?.cancel();
if (!res.ok) {
throw new Error(`Unexpected status ${res.status}: ${await res.text()}`);
}
},
});
}
@@ -216,8 +218,8 @@ export function useEngineRemoveFromDashboard() {
const { user } = useLoggedInUser();
const queryClient = useQueryClient();
return useMutation(
async (instanceId: string) => {
return useMutation({
mutationFn: async (instanceId: string) => {
invariant(instanceId, "instance is required");
const res = await fetch(`${THIRDWEB_API_HOST}/v1/engine/${instanceId}`, {
@@ -229,14 +231,13 @@ export function useEngineRemoveFromDashboard() {
throw new Error(`Unexpected status ${res.status}: ${await res.text()}`);
}
},
{
onSuccess: () => {
return queryClient.invalidateQueries(
engineKeys.instances(user?.address as string),
);
},
onSuccess: () => {
return queryClient.invalidateQueries({
queryKey: engineKeys.instances(user?.address as string),
});
},
);
});
}
export interface RemoveCloudHostedInput {
@@ -249,8 +250,12 @@ export function useEngineRemoveCloudHosted() {
const { user } = useLoggedInUser();
const queryClient = useQueryClient();
return useMutation(
async ({ instanceId, reason, feedback }: RemoveCloudHostedInput) => {
return useMutation({
mutationFn: async ({
instanceId,
reason,
feedback,
}: RemoveCloudHostedInput) => {
const res = await fetch(
`${THIRDWEB_API_HOST}/v1/engine/${instanceId}/remove-cloud-hosted`,
{
@@ -268,14 +273,13 @@ export function useEngineRemoveCloudHosted() {
throw new Error(`Unexpected status ${res.status}: ${await res.text()}`);
}
},
{
onSuccess: () => {
return queryClient.invalidateQueries(
engineKeys.instances(user?.address as string),
);
},
onSuccess: () => {
return queryClient.invalidateQueries({
queryKey: engineKeys.instances(user?.address as string),
});
},
);
});
}
export interface EditEngineInstanceInput {
@@ -288,8 +292,8 @@ export function useEngineEditInstance() {
const { user } = useLoggedInUser();
const queryClient = useQueryClient();
return useMutation(
async ({ instanceId, name, url }: EditEngineInstanceInput) => {
return useMutation({
mutationFn: async ({ instanceId, name, url }: EditEngineInstanceInput) => {
const res = await fetch(`${THIRDWEB_API_HOST}/v1/engine/${instanceId}`, {
method: "PUT",
@@ -304,14 +308,13 @@ export function useEngineEditInstance() {
throw new Error(`Unexpected status ${res.status}: ${await res.text()}`);
}
},
{
onSuccess: () => {
return queryClient.invalidateQueries(
engineKeys.instances(user?.address as string),
);
},
onSuccess: () => {
return queryClient.invalidateQueries({
queryKey: engineKeys.instances(user?.address as string),
});
},
);
});
}
export type Transaction = {
@@ -586,7 +589,9 @@ export function useEngineAddKeypair(instance: string) {
},
{
onSuccess: () => {
return queryClient.invalidateQueries(engineKeys.keypairs(instance));
return queryClient.invalidateQueries({
queryKey: engineKeys.keypairs(instance),
});
},
},
);
@@ -619,7 +624,9 @@ export function useEngineRemoveKeypair(instance: string) {
},
{
onSuccess: () => {
return queryClient.invalidateQueries(engineKeys.keypairs(instance));
return queryClient.invalidateQueries({
queryKey: engineKeys.keypairs(instance),
});
},
},
);
@@ -684,7 +691,9 @@ export function useEngineCreateRelayer(instance: string) {
},
{
onSuccess: () => {
return queryClient.invalidateQueries(engineKeys.relayers(instance));
return queryClient.invalidateQueries({
queryKey: engineKeys.relayers(instance),
});
},
},
);
@@ -717,7 +726,9 @@ export function useEngineRevokeRelayer(instance: string) {
},
{
onSuccess: () => {
return queryClient.invalidateQueries(engineKeys.relayers(instance));
return queryClient.invalidateQueries({
queryKey: engineKeys.relayers(instance),
});
},
},
);
@@ -755,7 +766,9 @@ export function useEngineUpdateRelayer(instance: string) {
},
{
onSuccess: () => {
return queryClient.invalidateQueries(engineKeys.relayers(instance));
return queryClient.invalidateQueries({
queryKey: engineKeys.relayers(instance),
});
},
},
);
@@ -833,7 +846,9 @@ export function useEngineSetWalletConfig(instance: string) {
},
{
onSuccess: () => {
return queryClient.invalidateQueries(engineKeys.walletConfig(instance));
return queryClient.invalidateQueries({
queryKey: engineKeys.walletConfig(instance),
});
},
},
);
@@ -866,9 +881,9 @@ export function useEngineCreateBackendWallet(instance: string) {
},
{
onSuccess: () => {
return queryClient.invalidateQueries(
engineKeys.backendWallets(instance),
);
return queryClient.invalidateQueries({
queryKey: engineKeys.backendWallets(instance),
});
},
},
);
@@ -902,9 +917,9 @@ export function useEngineUpdateBackendWallet(instance: string) {
},
{
onSuccess: () => {
return queryClient.invalidateQueries(
engineKeys.backendWallets(instance),
);
return queryClient.invalidateQueries({
queryKey: engineKeys.backendWallets(instance),
});
},
},
);
@@ -953,9 +968,9 @@ export function useEngineImportBackendWallet(instance: string) {
},
{
onSuccess: () => {
return queryClient.invalidateQueries(
engineKeys.backendWallets(instance),
);
return queryClient.invalidateQueries({
queryKey: engineKeys.backendWallets(instance),
});
},
},
);
@@ -984,7 +999,9 @@ export function useEngineGrantPermissions(instance: string) {
},
{
onSuccess: () => {
return queryClient.invalidateQueries(engineKeys.permissions(instance));
return queryClient.invalidateQueries({
queryKey: engineKeys.permissions(instance),
});
},
},
);
@@ -1017,7 +1034,9 @@ export function useEngineRevokePermissions(instance: string) {
},
{
onSuccess: () => {
return queryClient.invalidateQueries(engineKeys.permissions(instance));
return queryClient.invalidateQueries({
queryKey: engineKeys.permissions(instance),
});
},
},
);
@@ -1050,7 +1069,9 @@ export function useEngineCreateAccessToken(instance: string) {
},
{
onSuccess: () => {
return queryClient.invalidateQueries(engineKeys.accessTokens(instance));
return queryClient.invalidateQueries({
queryKey: engineKeys.accessTokens(instance),
});
},
},
);
@@ -1083,7 +1104,9 @@ export function useEngineRevokeAccessToken(instance: string) {
},
{
onSuccess: () => {
return queryClient.invalidateQueries(engineKeys.accessTokens(instance));
return queryClient.invalidateQueries({
queryKey: engineKeys.accessTokens(instance),
});
},
},
);
@@ -1117,7 +1140,9 @@ export function useEngineUpdateAccessToken(instance: string) {
},
{
onSuccess: () => {
return queryClient.invalidateQueries(engineKeys.accessTokens(instance));
return queryClient.invalidateQueries({
queryKey: engineKeys.accessTokens(instance),
});
},
},
);
@@ -1152,7 +1177,9 @@ export function useEngineCreateWebhook(instance: string) {
},
{
onSuccess: () => {
return queryClient.invalidateQueries(engineKeys.webhooks(instance));
return queryClient.invalidateQueries({
queryKey: engineKeys.webhooks(instance),
});
},
},
);
@@ -1185,7 +1212,9 @@ export function useEngineRevokeWebhook(instance: string) {
},
{
onSuccess: () => {
return queryClient.invalidateQueries(engineKeys.webhooks(instance));
return queryClient.invalidateQueries({
queryKey: engineKeys.webhooks(instance),
});
},
},
);
@@ -1202,31 +1231,33 @@ type SendTokensInput = {
export function useEngineSendTokens(instance: string) {
const token = useLoggedInUser().user?.jwt ?? null;
return useMutation(async (input: SendTokensInput) => {
invariant(instance, "instance is required");
return useMutation({
mutationFn: async (input: SendTokensInput) => {
invariant(instance, "instance is required");
const res = await fetch(
`${instance}backend-wallet/${input.chainId}/transfer`,
{
method: "POST",
headers: {
...getEngineRequestHeaders(token),
"x-backend-wallet-address": input.fromAddress,
const res = await fetch(
`${instance}backend-wallet/${input.chainId}/transfer`,
{
method: "POST",
headers: {
...getEngineRequestHeaders(token),
"x-backend-wallet-address": input.fromAddress,
},
body: JSON.stringify({
to: input.toAddress,
amount: input.amount.toString(),
currencyAddress: input.currencyAddress,
}),
},
body: JSON.stringify({
to: input.toAddress,
amount: input.amount.toString(),
currencyAddress: input.currencyAddress,
}),
},
);
const json = await res.json();
);
const json = await res.json();
if (json.error) {
throw new Error(json.error.message);
}
if (json.error) {
throw new Error(json.error.message);
}
return json.result;
return json.result;
},
});
}
@@ -1257,8 +1288,8 @@ export function useEngineSetCorsConfiguration(instance: string) {
const queryClient = useQueryClient();
const token = useLoggedInUser().user?.jwt ?? null;
return useMutation(
async (input: SetCorsUrlInput) => {
return useMutation({
mutationFn: async (input: SetCorsUrlInput) => {
invariant(instance, "instance is required");
const res = await fetch(`${instance}configuration/cors`, {
@@ -1274,12 +1305,13 @@ export function useEngineSetCorsConfiguration(instance: string) {
return json.result;
},
{
onSuccess: () => {
return queryClient.invalidateQueries(engineKeys.corsUrls(instance));
},
onSuccess: () => {
return queryClient.invalidateQueries({
queryKey: engineKeys.corsUrls(instance),
});
},
);
});
}
export function useEngineIpAllowlistConfiguration(instance: string) {
@@ -1314,8 +1346,8 @@ export function useEngineSetIpAllowlistConfiguration(instance: string) {
const queryClient = useQueryClient();
const token = useLoggedInUser().user?.jwt ?? null;
return useMutation(
async (input: SetIpAllowlistInput) => {
return useMutation({
mutationFn: async (input: SetIpAllowlistInput) => {
invariant(instance, "instance is required");
const res = await fetch(`${instance}configuration/ip-allowlist`, {
@@ -1331,12 +1363,13 @@ export function useEngineSetIpAllowlistConfiguration(instance: string) {
return json.result;
},
{
onSuccess: () => {
return queryClient.invalidateQueries(engineKeys.ipAllowlist(instance));
},
onSuccess: () => {
return queryClient.invalidateQueries({
queryKey: engineKeys.ipAllowlist(instance),
});
},
);
});
}
export interface EngineContractSubscription {
@@ -1386,8 +1419,8 @@ export function useEngineAddContractSubscription(instance: string) {
const queryClient = useQueryClient();
const token = useLoggedInUser().user?.jwt ?? null;
return useMutation(
async (input: AddContractSubscriptionInput) => {
return useMutation({
mutationFn: async (input: AddContractSubscriptionInput) => {
invariant(instance, "instance is required");
const res = await fetch(`${instance}contract-subscriptions/add`, {
@@ -1403,14 +1436,13 @@ export function useEngineAddContractSubscription(instance: string) {
return json.result;
},
{
onSuccess: () => {
return queryClient.invalidateQueries(
engineKeys.contractSubscriptions(instance),
);
},
onSuccess: () => {
return queryClient.invalidateQueries({
queryKey: engineKeys.contractSubscriptions(instance),
});
},
);
});
}
interface RemoveContractSubscriptionInput {
@@ -1421,8 +1453,8 @@ export function useEngineRemoveContractSubscription(instance: string) {
const queryClient = useQueryClient();
const token = useLoggedInUser().user?.jwt ?? null;
return useMutation(
async (input: RemoveContractSubscriptionInput) => {
return useMutation({
mutationFn: async (input: RemoveContractSubscriptionInput) => {
invariant(instance, "instance is required");
const res = await fetch(`${instance}contract-subscriptions/remove`, {
@@ -1438,14 +1470,13 @@ export function useEngineRemoveContractSubscription(instance: string) {
return json.result;
},
{
onSuccess: () => {
return queryClient.invalidateQueries(
engineKeys.contractSubscriptions(instance),
);
},
onSuccess: () => {
return queryClient.invalidateQueries({
queryKey: engineKeys.contractSubscriptions(instance),
});
},
);
});
}
export function useEngineSubscriptionsLastBlock(
@@ -3,7 +3,7 @@ import { useDashboardRouter } from "@/lib/DashboardRouter";
import { useQuery } from "@tanstack/react-query";
import type { EnsureLoginResponse } from "app/api/auth/ensure-login/route";
import { usePathname } from "next/navigation";
import { useRef } from "react";
import { useEffect, useRef } from "react";
import {
useActiveAccount,
useActiveWalletConnectionStatus,
@@ -63,20 +63,23 @@ export function useLoggedInUser(): {
return (await res.json()) as EnsureLoginResponse;
},
onSuccess: (data) => {
if (data.redirectTo) {
router.replace(data.redirectTo);
}
if (data.jwt) {
// necessary for legacy things for now (SDK picks it up from there)
// eslint-disable-next-line react-compiler/react-compiler
window.TW_AUTH_TOKEN = data.jwt;
} else {
window.TW_AUTH_TOKEN = undefined;
}
},
});
// legit use-case for now
// eslint-disable-next-line no-restricted-syntax
useEffect(() => {
if (query.data?.redirectTo) {
router.replace(query.data.redirectTo);
}
if (query.data?.jwt) {
// necessary for legacy things for now (SDK picks it up from there)
// eslint-disable-next-line react-compiler/react-compiler
window.TW_AUTH_TOKEN = query.data.jwt;
} else {
window.TW_AUTH_TOKEN = undefined;
}
}, [query.data?.redirectTo, query.data?.jwt, router]);
// if we are "disconnected" we are not logged in
if (connectionStatus === "disconnected") {
return {
@@ -88,8 +88,8 @@ export function useRemoveContractMutation() {
const { chainIdToChainRecord } = useAllChainsData();
const queryClient = useQueryClient();
const account = useActiveAccount();
return useMutation(
async (data: RemoveContractParams) => {
return useMutation({
mutationFn: async (data: RemoveContractParams) => {
invariant(chainIdToChainRecord, "chains not initialzed yet");
invariant(data.chainId, "chainId not provided");
invariant(account, "No wallet connected");
@@ -111,12 +111,13 @@ export function useRemoveContractMutation() {
},
});
},
{
onSettled: () => {
return queryClient.invalidateQueries(["dashboard-registry"]);
},
onSettled: () => {
return queryClient.invalidateQueries({
queryKey: ["dashboard-registry"],
});
},
);
});
}
type AddContractParams = {
@@ -129,8 +130,8 @@ export function useAddContractMutation() {
const queryClient = useQueryClient();
return useMutation(
async (data: AddContractParams) => {
return useMutation({
mutationFn: async (data: AddContractParams) => {
invariant(account, "cannot add a contract without an address");
return await addContractToMultiChainRegistry(
@@ -142,10 +143,11 @@ export function useAddContractMutation() {
300000n,
);
},
{
onSettled: () => {
return queryClient.invalidateQueries(["dashboard-registry"]);
},
onSettled: () => {
return queryClient.invalidateQueries({
queryKey: ["dashboard-registry"],
});
},
);
});
}
@@ -92,10 +92,9 @@ export function FaucetButton({
});
},
onSettled: () => {
return queryClient.invalidateQueries([
"testnet-faucet-can-claim",
chainId,
]);
return queryClient.invalidateQueries({
queryKey: ["testnet-faucet-can-claim", chainId],
});
},
});
@@ -175,7 +174,7 @@ export function FaucetButton({
});
}}
>
{claimMutation.isLoading ? (
{claimMutation.isPending ? (
<>
Claiming <Spinner className="size-3" />
</>
@@ -30,7 +30,7 @@ export const AddChainToWallet: React.FC<AddChainToWalletProps> = (props) => {
},
});
const [debouncedLoading] = useDebounce(switchChainMutation.isLoading, 50);
const [debouncedLoading] = useDebounce(switchChainMutation.isPending, 50);
const disabled = debouncedLoading || activeWalletChainId === props.chain?.id;
@@ -7,13 +7,10 @@ import { thirdwebClient } from "@/constants/client";
import { isProd } from "@/constants/env";
import { useQuery } from "@tanstack/react-query";
import { CircleCheck, XIcon } from "lucide-react";
import { useState } from "react";
import { hostnameEndsWith } from "utils/url";
import { PrimaryInfoItem } from "../server/primary-info-item";
function useChainStatswithRPC(_rpcUrl: string) {
const [shouldRefetch, setShouldRefetch] = useState(true);
let rpcUrl = _rpcUrl.replace(
// eslint-disable-next-line no-template-curly-in-string
"${THIRDWEB_API_KEY}",
@@ -49,12 +46,14 @@ function useChainStatswithRPC(_rpcUrl: string) {
blockNumber: Number.parseInt(json.result, 16),
};
},
refetchInterval: shouldRefetch ? 5 * 1000 : undefined,
refetchInterval: (query) => {
if (query.state.error) {
return false;
}
return 5 * 1000;
},
enabled: !!rpcUrl,
refetchOnWindowFocus: false,
onError: () => {
setShouldRefetch(false);
},
});
}
@@ -20,7 +20,6 @@ export function ChainHeader(props: ChainHeaderProps) {
// force the banner image to be 4:1 aspect ratio and full-width on mobile devices
<div className="flex flex-col">
{!props.headerImageUrl && <div className="h-8 md:hidden" />}
<AspectRatio
ratio={props.headerImageUrl ? 4 : 8}
className="border-b border-border max-sm:-mx-4"
@@ -34,7 +33,6 @@ export function ChainHeader(props: ChainHeaderProps) {
/>
)}
</AspectRatio>
{/* below header */}
<div className="relative flex flex-row justify-end items-end">
{/* chain logo */}
@@ -91,7 +91,7 @@ export function StarButton(props: {
}}
disabled={
!loggedInUser.user?.address ||
mutation.isLoading ||
mutation.isPending ||
favChainsQuery.isLoading
}
>
@@ -31,7 +31,7 @@ export function AddPartnerForm({ ecosystem }: { ecosystem: Ecosystem }) {
resolver: zodResolver(partnerFormSchema),
});
const { addPartner, isLoading } = useAddPartner({
const { mutateAsync: addPartner, isPending } = useAddPartner({
onSuccess: () => {
form.reset();
},
@@ -182,7 +182,7 @@ export function AddPartnerForm({ ecosystem }: { ecosystem: Ecosystem }) {
/>
</div>
<Button
disabled={isLoading}
disabled={isPending}
type="submit"
variant="outline"
className="w-full lg:w-auto"
@@ -20,7 +20,11 @@ export function IntegrationPermissionsToggle({
}
| undefined
>();
const { updateEcosystem, variables, isLoading } = useUpdateEcosystem({
const {
mutateAsync: updateEcosystem,
variables,
isPending,
} = useUpdateEcosystem({
onError: (error) => {
const message =
error instanceof Error ? error.message : "Failed to create ecosystem";
@@ -31,14 +35,14 @@ export function IntegrationPermissionsToggle({
return (
<RadioGroup
defaultValue={ecosystem.permission}
value={isLoading ? variables?.permission : ecosystem.permission}
value={isPending ? variables?.permission : ecosystem.permission}
className="flex flex-col gap-2 py-2 md:flex-row md:gap-4"
>
<RadioGroupItemButton
value="PARTNER_WHITELIST"
id="PARTNER_WHITELIST"
className={cn(
isLoading &&
isPending &&
variables?.permission === "PARTNER_WHITELIST" &&
"animate-pulse",
)}
@@ -59,7 +63,7 @@ export function IntegrationPermissionsToggle({
value="ANYONE"
id="ANYONE"
className={cn(
isLoading && variables?.permission === "ANYONE" && "animate-pulse",
isPending && variables?.permission === "ANYONE" && "animate-pulse",
)}
onClick={() => {
if (ecosystem.permission === "ANYONE") return;
@@ -42,7 +42,7 @@ export function UpdatePartnerForm({
},
});
const { updatePartner, isLoading } = useUpdatePartner({
const { mutateAsync: updatePartner, isPending } = useUpdatePartner({
onSuccess: () => {
form.reset();
onSuccess();
@@ -195,12 +195,12 @@ export function UpdatePartnerForm({
/>
</div>
<Button
disabled={isLoading}
disabled={isPending}
type="submit"
variant="outline"
className="w-full"
>
{isLoading && <Loader2 className="size-4 mr-1 animate-spin" />}
{isPending && <Loader2 className="size-4 mr-1 animate-spin" />}
Update
</Button>
</form>
@@ -69,13 +69,14 @@ function EcosystemRow(props: {
partner: Partner;
ecosystem: Ecosystem;
}) {
const { deletePartner, isLoading: isDeleting } = useDeletePartner({
onError: (error) => {
const message =
error instanceof Error ? error.message : "Failed to delete partner";
toast.error(message);
},
});
const { mutateAsync: deletePartner, isPending: isDeleting } =
useDeletePartner({
onError: (error) => {
const message =
error instanceof Error ? error.message : "Failed to delete partner";
toast.error(message);
},
});
return (
<TableRow
@@ -24,7 +24,7 @@ export function useAddPartner(
const { isLoggedIn, user } = useLoggedInUser();
const queryClient = useQueryClient();
const { mutateAsync: addPartner, isLoading } = useMutation({
return useMutation({
// Returns the created partner object
mutationFn: async (params: AddPartnerParams): Promise<Partner> => {
if (!isLoggedIn || !user?.jwt) {
@@ -74,11 +74,9 @@ export function useAddPartner(
return data;
},
onSuccess: async (partner, variables, context) => {
await queryClient.invalidateQueries([
"ecosystem",
variables.ecosystem.id,
"partners",
]);
await queryClient.invalidateQueries({
queryKey: ["ecosystem", variables.ecosystem.id, "partners"],
});
if (onSuccess) {
return onSuccess(partner, variables, context);
}
@@ -86,6 +84,4 @@ export function useAddPartner(
},
...queryOptions,
});
return { addPartner, isLoading };
}
@@ -21,7 +21,7 @@ export function useDeletePartner(
const { isLoggedIn, user } = useLoggedInUser();
const queryClient = useQueryClient();
const { mutateAsync: deletePartner, isLoading } = useMutation({
return useMutation({
// Returns true on success
mutationFn: async (params: DeletePartnerParams): Promise<boolean> => {
if (!isLoggedIn || !user?.jwt) {
@@ -58,11 +58,9 @@ export function useDeletePartner(
return true;
},
onSuccess: async (partner, variables, context) => {
await queryClient.invalidateQueries([
"ecosystem",
variables.ecosystem.id,
"partners",
]);
await queryClient.invalidateQueries({
queryKey: ["ecosystem", variables.ecosystem.id, "partners"],
});
if (onSuccess) {
return onSuccess(partner, variables, context);
}
@@ -70,6 +68,4 @@ export function useDeletePartner(
},
...queryOptions,
});
return { deletePartner, isLoading };
}
@@ -21,11 +21,7 @@ export function useUpdateEcosystem(
const { isLoggedIn, user } = useLoggedInUser();
const queryClient = useQueryClient();
const {
mutateAsync: updateEcosystem,
isLoading,
variables,
} = useMutation({
return useMutation({
// Returns true if the update was successful
mutationFn: async (params: UpdateEcosystemParams): Promise<boolean> => {
if (!isLoggedIn || !user?.jwt) {
@@ -65,7 +61,9 @@ export function useUpdateEcosystem(
return true;
},
onSuccess: async (partner, variables, context) => {
await queryClient.invalidateQueries(["ecosystems"]);
await queryClient.invalidateQueries({
queryKey: ["ecosystems"],
});
if (onSuccess) {
return onSuccess(partner, variables, context);
}
@@ -73,6 +71,4 @@ export function useUpdateEcosystem(
},
...queryOptions,
});
return { updateEcosystem, isLoading, variables };
}
@@ -25,7 +25,7 @@ export function useUpdatePartner(
const { isLoggedIn, user } = useLoggedInUser();
const queryClient = useQueryClient();
const { mutateAsync: updatePartner, isLoading } = useMutation({
return useMutation({
// Returns the created partner object
mutationFn: async (params: UpdatePartnerParams): Promise<Partner> => {
if (!isLoggedIn || !user?.jwt) {
@@ -73,11 +73,9 @@ export function useUpdatePartner(
return data;
},
onSuccess: async (partner, variables, context) => {
await queryClient.invalidateQueries([
"ecosystem",
variables.ecosystem.id,
"partners",
]);
await queryClient.invalidateQueries({
queryKey: ["ecosystem", variables.ecosystem.id, "partners"],
});
if (onSuccess) {
return onSuccess(partner, variables, context);
}
@@ -85,6 +83,4 @@ export function useUpdatePartner(
},
...queryOptions,
});
return { updatePartner, isLoading };
}
@@ -59,7 +59,7 @@ export function CreateEcosystemForm(props: {
},
});
const { createEcosystem, isLoading } = useCreateEcosystem({
const { mutateAsync: createEcosystem, isPending } = useCreateEcosystem({
onError: (error) => {
const message =
error instanceof Error ? error.message : "Failed to create ecosystem";
@@ -181,9 +181,9 @@ export function CreateEcosystemForm(props: {
type="submit"
variant="primary"
className="w-full"
disabled={isLoading}
disabled={isPending}
>
{isLoading && <Loader2 className="w-4 h-4 mr-1 animate-spin" />}
{isPending && <Loader2 className="w-4 h-4 mr-1 animate-spin" />}
Create
</Button>
)}
@@ -24,7 +24,7 @@ export function useCreateEcosystem(
const { isLoggedIn } = useLoggedInUser();
const queryClient = useQueryClient();
const { mutateAsync: createEcosystem, isLoading } = useMutation({
return useMutation({
// Returns the created ecosystem slug
mutationFn: async (params: CreateEcosystemParams): Promise<string> => {
if (!isLoggedIn) {
@@ -75,10 +75,10 @@ export function useCreateEcosystem(
if (onSuccess) {
await onSuccess(id, variables, context);
}
return queryClient.invalidateQueries(["ecosystems"]);
return queryClient.invalidateQueries({
queryKey: ["ecosystems"],
});
},
...queryOptions,
});
return { createEcosystem, isLoading };
}
@@ -177,7 +177,9 @@ function CreateWebhookButton(props: PropsWithChildren<WebhooksPageProps>) {
return json.result as string;
},
onSuccess: () => {
return queryClient.invalidateQueries(["webhooks", props.clientId]);
return queryClient.invalidateQueries({
queryKey: ["webhooks", props.clientId],
});
},
});
return (
@@ -264,7 +266,7 @@ function CreateWebhookButton(props: PropsWithChildren<WebhooksPageProps>) {
</FormItem>
<DialogFooter>
<Button type="submit" disabled={createMutation.isLoading}>
<Button type="submit" disabled={createMutation.isPending}>
Create
</Button>
</DialogFooter>
@@ -293,7 +295,9 @@ function DeleteWebhookButton(
return json.result as string;
},
onSuccess: () => {
return queryClient.invalidateQueries(["webhooks", props.clientId]);
return queryClient.invalidateQueries({
queryKey: ["webhooks", props.clientId],
});
},
});
return (
@@ -325,7 +329,7 @@ function DeleteWebhookButton(
},
);
}}
disabled={deleteMutation.isLoading}
disabled={deleteMutation.isPending}
>
Yes, Delete Webhook
</Button>
@@ -85,7 +85,7 @@ function AccountAvatarFormControl() {
saveButton={{
onClick: handleSave,
disabled: false,
isLoading: updateAvatarMutation.isLoading,
isLoading: updateAvatarMutation.isPending,
}}
noPermissionText={undefined}
errorText={undefined}
@@ -143,7 +143,7 @@ function AccountNameFormControl(props: {
saveButton={{
onClick: handleSave,
disabled: accountName.length === 0,
isLoading: updateAccountNameMutation.isLoading,
isLoading: updateAccountNameMutation.isPending,
}}
errorText={undefined}
noPermissionText={undefined} // TODO
@@ -191,7 +191,7 @@ function DeleteAccountCard() {
description={description}
buttonLabel={title}
buttonOnClick={handleDelete}
isLoading={deleteAccount.isLoading}
isLoading={deleteAccount.isPending}
confirmationDialog={{
title: "Are you sure you want to delete your account?",
description:
@@ -321,10 +321,10 @@ function EmailUpdateDialog(props: {
<Button variant="outline"> Cancel </Button>
</DialogClose>
<Button className="min-w-24 gap-2" type="submit">
{updateEmailMutation.isLoading && (
{updateEmailMutation.isPending && (
<Spinner className="size-4" />
)}
{updateEmailMutation.isLoading ? "Saving" : "Save"}
{updateEmailMutation.isPending ? "Saving" : "Save"}
</Button>
</DialogFooter>
</form>
@@ -35,7 +35,6 @@ export function DashboardHeader() {
))}
</div>
</div>
{/* Right */}
<div className="flex items-center gap-4">
<div className="items-center gap-2 lg:flex">
@@ -6,11 +6,11 @@ import { Billing } from "components/settings/Account/Billing";
export const SettingsBillingPage = () => {
const meQuery = useAccount({
refetchInterval: (account) =>
refetchInterval: (query) =>
[
AccountStatus.InvalidPayment,
AccountStatus.InvalidPaymentMethod,
].includes(account?.status as AccountStatus)
].includes(query.state?.status as AccountStatus)
? 1000
: false,
});
@@ -63,7 +63,7 @@ function TeamNameFormControl(props: {
saveButton={{
onClick: handleSave,
disabled: teamName.length === 0,
isLoading: updateTeamMutation.isLoading,
isLoading: updateTeamMutation.isPending,
}}
errorText={undefined}
noPermissionText={undefined} // TODO
@@ -121,7 +121,7 @@ function TeamSlugFormControl(props: {
saveButton={{
onClick: handleSave,
disabled: teamSlug.length === 0,
isLoading: updateTeamMutation.isLoading,
isLoading: updateTeamMutation.isPending,
}}
noPermissionText={undefined} // TODO
>
@@ -168,7 +168,7 @@ function TeamAvatarFormControl() {
saveButton={{
onClick: handleSave,
disabled: false,
isLoading: updateTeamAvatarMutation.isLoading,
isLoading: updateTeamAvatarMutation.isPending,
}}
noPermissionText={undefined} // TODO
errorText={undefined}
@@ -250,7 +250,7 @@ export function LeaveTeamCard(props: {
description={description}
buttonLabel={title}
buttonOnClick={handleLeave}
isLoading={leaveTeam.isLoading}
isLoading={leaveTeam.isPending}
confirmationDialog={{
title: `Are you sure you want to leave team "${props.teamName}" ?`,
description:
@@ -311,7 +311,7 @@ export function DeleteTeamCard(props: {
description={description}
buttonLabel={title}
buttonOnClick={handleDelete}
isLoading={deleteTeam.isLoading}
isLoading={deleteTeam.isPending}
confirmationDialog={{
title: `Are you sure you want to delete team "${props.teamName}" ?`,
description: description,
@@ -31,9 +31,7 @@ export function TeamSelectionUI(props: {
value={searchTeamTerm}
onValueChange={setSearchTeamTerm}
/>
<Separator />
<ScrollShadow
scrollableClassName="max-h-[400px] lg:max-h-[600px]"
className="grow"
@@ -108,7 +106,6 @@ export function TeamSelectionUI(props: {
</ul>
</div>
</ScrollShadow>
{/* TODO - what do we do on this button click? */}
{/* Bottom */}
{teamPlan && teamPlan !== "pro" && (
@@ -7,7 +7,7 @@ import { CustomConnectWallet } from "@3rdweb-sdk/react/components/connect-wallet
import { Flex, SimpleGrid } from "@chakra-ui/react";
import {
type DehydratedState,
Hydrate,
HydrationBoundary,
QueryClient,
QueryClientProvider,
} from "@tanstack/react-query";
@@ -38,7 +38,7 @@ interface AppLayoutProps extends AppShellProps {
export const AppLayout: ComponentWithChildren<AppLayoutProps> = (props) => {
// has to be constructed in here because it may otherwise share state between SSR'd pages
const [queryClient] = useState(() => new QueryClient());
const [queryClient] = useState(() => new QueryClient({}));
// will be deleted as part of: https://github.com/thirdweb-dev/dashboard/pull/2648
// eslint-disable-next-line no-restricted-syntax
@@ -54,7 +54,7 @@ export const AppLayout: ComponentWithChildren<AppLayoutProps> = (props) => {
return (
<QueryClientProvider client={queryClient}>
<Hydrate state={props.dehydratedState}>
<HydrationBoundary state={props.dehydratedState}>
<ErrorProvider>
<AllChainsProvider>
<ChainsProvider>
@@ -74,7 +74,7 @@ export const AppLayout: ComponentWithChildren<AppLayoutProps> = (props) => {
</ChainsProvider>
</AllChainsProvider>
</ErrorProvider>
</Hydrate>
</HydrationBoundary>
</QueryClientProvider>
);
};
@@ -337,7 +337,6 @@ function NoFundsDialogContent(props: {
</div>
)}
</div>
{/* Footer */}
<div className="border-t border-border p-6 flex justify-between gap-4">
<ButtonShadcn variant="outline" onClick={props.onCloseModal}>
@@ -16,6 +16,8 @@ import { useDashboardRouter } from "@/lib/DashboardRouter";
import { cn } from "@/lib/utils";
import {
type QueryClient,
keepPreviousData,
queryOptions,
useQuery,
useQueryClient,
} from "@tanstack/react-query";
@@ -38,7 +40,7 @@ function contractTypesenseSearchQuery(
queryClient: QueryClient,
trackEvent: ReturnType<typeof useTrack>,
) {
return {
return queryOptions({
queryKey: ["typesense-contract-search", { search: searchQuery }],
queryFn: async () => {
trackEvent({
@@ -55,26 +57,8 @@ function contractTypesenseSearchQuery(
});
},
enabled: !!searchQuery && !!queryClient && !!typesenseApiKey,
onSuccess: (d: unknown) => {
trackEvent({
category: TRACKING_CATEGORY,
action: "query",
label: "success",
searchQuery,
response: d,
});
},
onError: (err: unknown) => {
trackEvent({
category: TRACKING_CATEGORY,
action: "query",
label: "failure",
searchQuery,
error: err,
});
},
keepPreviousData: true,
};
placeholderData: keepPreviousData,
});
}
export const CmdKSearchModal = (props: {
@@ -103,7 +87,7 @@ export const CmdKSearchModal = (props: {
// debounce 500ms
const [debouncedSearchValue] = useDebounce(searchValue, 500);
const typesenseSearchQuery = useQuery<TrendingContract[]>(
const typesenseSearchQuery = useQuery(
contractTypesenseSearchQuery(debouncedSearchValue, queryClient, trackEvent),
);
@@ -24,7 +24,9 @@ export const IconUpload: React.FC<{ onUpload: (url: string) => void }> = ({
onSuccess([uri]) {
onUpload(uri);
// also refetch the files list
queryClient.invalidateQueries([PINNED_FILES_QUERY_KEY_ROOT]);
queryClient.invalidateQueries({
queryKey: [PINNED_FILES_QUERY_KEY_ROOT],
});
},
onError(error) {
console.error(error);
@@ -36,7 +38,7 @@ export const IconUpload: React.FC<{ onUpload: (url: string) => void }> = ({
return (
<FileInput setValue={handleIconUpload} accept={{ "image/*": [] }}>
<Button variant="ghost" className="gap-2 px-2" size="sm">
{storageUpload.isLoading ? (
{storageUpload.isPending ? (
<Spinner className="size-4" />
) : (
<FiUpload className="size-4" />
@@ -57,7 +57,6 @@ export const NetworkIDInput: React.FC<{
},
})}
/>
<FormErrorMessage>
Can not use Network ID {`"${slug}"`}.
{slug && slug in slugToChainRecord && (
@@ -296,7 +296,7 @@ export const ContractPublishForm: React.FC<ContractPublishFormProps> = ({
);
// during loading and after success we should stay in loading state
const isLoading = publishMutation.isLoading || publishMutation.isSuccess;
const isLoading = publishMutation.isPending || publishMutation.isSuccess;
useIsomorphicLayoutEffect(() => {
window?.scrollTo({
@@ -3,6 +3,7 @@ import { networkKeys, useDashboardEVMChainId } from "@3rdweb-sdk/react";
import { useMutationWithInvalidate } from "@3rdweb-sdk/react/hooks/query/useQueryWithNetwork";
import {
type QueryClient,
queryOptions,
useQuery,
useQueryClient,
} from "@tanstack/react-query";
@@ -169,7 +170,7 @@ export function useContractFullPublishMetadata(uri: string) {
}
export function publisherProfileQuery(publisherAddress?: string) {
return {
return queryOptions({
queryKey: ["releaser-profile", publisherAddress],
queryFn: () => {
if (!publisherAddress) {
@@ -179,10 +180,10 @@ export function publisherProfileQuery(publisherAddress?: string) {
},
enabled: !!publisherAddress,
// 24h
cacheTime: 60 * 60 * 24 * 1000,
gcTime: 60 * 60 * 24 * 1000,
// 1h
staleTime: 60 * 60 * 1000,
};
});
}
export function usePublisherProfile(publisherAddress?: string) {
@@ -515,7 +516,7 @@ export function ensQuery(addressOrEnsName?: string) {
: null,
ensName: null,
};
return {
return queryOptions({
queryKey: ["ens", addressOrEnsName],
queryFn: async () => {
if (!addressOrEnsName) {
@@ -548,13 +549,13 @@ export function ensQuery(addressOrEnsName?: string) {
!!addressOrEnsName &&
(isAddress(addressOrEnsName) || isEnsName(addressOrEnsName)),
// 24h
cacheTime: 60 * 60 * 24 * 1000,
gcTime: 60 * 60 * 24 * 1000,
// 1h
staleTime: 60 * 60 * 1000,
// default to the one we know already
placeholderData,
retry: false,
} as const;
});
}
export function useEns(addressOrEnsName?: string) {
@@ -98,7 +98,7 @@ function ImportForm() {
const isLoading =
form.formState.isSubmitting ||
addToDashboard.isLoading ||
addToDashboard.isPending ||
addToDashboard.isSuccess ||
isRedirecting;
@@ -120,7 +120,7 @@ export const EditProfile: React.FC<EditProfileProps> = ({
role="group"
colorScheme="primary"
type="submit"
isLoading={editProfile.isLoading}
isLoading={editProfile.isPending}
form={FORM_ID}
>
Save
@@ -145,10 +145,10 @@ const RemoveFromDashboardButton: React.FC<RemoveFromDashboardButtonProps> = ({
e.stopPropagation();
mutation.mutate({ chainId, contractAddress });
}}
disabled={mutation.isLoading}
disabled={mutation.isPending}
className="!bg-background hover:!bg-accent gap-2"
>
{mutation.isLoading ? (
{mutation.isPending ? (
<Spinner className="size-4" />
) : (
<XIcon className="size-4 text-destructive-text" />
@@ -341,7 +341,6 @@ const ContractTable: React.FC<ContractTableProps> = ({
return (
<TableContainer>
{isFetching && <Spinner className="size-3 absolute top-2 right-4" />}
<Table {...getTableProps()}>
<TableHeader>
{headerGroups.map((headerGroup, index) => (
@@ -378,7 +377,6 @@ const ContractTable: React.FC<ContractTableProps> = ({
})}
</TableBody>
</Table>
{canNextPage && (
<ShowMoreButton
limit={limit}
@@ -386,7 +384,6 @@ const ContractTable: React.FC<ContractTableProps> = ({
setShowMoreLimit={setNumRowsOnPage}
/>
)}
{loading && (
<div className="flex items-center justify-center py-4">
<div className="flex gap-2 items-center text-muted-foreground">
@@ -122,8 +122,11 @@ interface InteractiveAbiFunctionProps {
}
function useAsyncRead(contract: ThirdwebContract, functionName: string) {
return useMutation(
async ({ args, types }: { args: unknown[]; types: string[] }) => {
return useMutation({
mutationFn: async ({
args,
types,
}: { args: unknown[]; types: string[] }) => {
const params = parseAbiParams(types, args);
return readContract({
contract,
@@ -131,13 +134,13 @@ function useAsyncRead(contract: ThirdwebContract, functionName: string) {
params,
});
},
);
});
}
function useSimulateTransaction() {
const from = useActiveAccount()?.address;
return useMutation(
async ({
return useMutation({
mutationFn: async ({
contract,
functionName,
params,
@@ -185,7 +188,7 @@ ${Object.keys(populatedTransaction)
${(err as Error).message || ""}`);
}
},
);
});
}
export const InteractiveAbiFunction: React.FC<InteractiveAbiFunctionProps> = ({
@@ -237,7 +240,7 @@ export const InteractiveAbiFunction: React.FC<InteractiveAbiFunctionProps> = ({
const {
mutate: readFn,
data: readData,
isLoading: readLoading,
isPending: readLoading,
error: readError,
} = useAsyncRead(contract, abiFunction.name);
@@ -464,9 +467,9 @@ export const InteractiveAbiFunction: React.FC<InteractiveAbiFunctionProps> = ({
<Button
onClick={handleContractSimulation}
isDisabled={
!abiFunction || txSimulation.isLoading || mutationLoading
!abiFunction || txSimulation.isPending || mutationLoading
}
isLoading={txSimulation.isLoading}
isLoading={txSimulation.isPending}
>
<ToolTipLabel label="Simulate the transaction to see its potential outcome without actually sending it to the network. This action doesn't cost gas.">
<span className="mr-3">
@@ -477,7 +480,7 @@ export const InteractiveAbiFunction: React.FC<InteractiveAbiFunctionProps> = ({
</Button>
<TransactionButton
isDisabled={
!abiFunction || txSimulation.isLoading || mutationLoading
!abiFunction || txSimulation.isPending || mutationLoading
}
colorScheme="primary"
transactionCount={1}
@@ -106,7 +106,7 @@ export const Configure: React.FC<ConfigureProps> = (props) => {
{...props}
canEditAdvancedFeatures={dashboardAccount.advancedEnabled}
updateApiKey={handleAPIKeyUpdate}
isUpdating={mutation.isLoading}
isUpdating={mutation.isPending}
/>
);
};
@@ -153,7 +153,7 @@ const UpdateVersionModal = (props: {
variant="primary"
className="gap-2"
>
{updateEngine.isLoading ? (
{updateEngine.isPending ? (
<Spinner className="size-4" />
) : (
<CloudDownloadIcon className="size-4" />
@@ -13,7 +13,7 @@ interface LocalConfigProps {
export const LocalConfig: React.FC<LocalConfigProps> = ({ instanceUrl }) => {
const { data: walletConfig } = useEngineWalletConfig(instanceUrl);
const { mutate: setLocalConfig, isLoading } =
const { mutate: setLocalConfig, isPending } =
useEngineSetWalletConfig(instanceUrl);
const trackEvent = useTrack();
@@ -68,7 +68,7 @@ export const LocalConfig: React.FC<LocalConfigProps> = ({ instanceUrl }) => {
);
}}
>
{isLoading ? "Saving..." : "Save"}
{isPending ? "Saving..." : "Save"}
</Button>
</Flex>
</Flex>
@@ -19,7 +19,7 @@ import {
type UseDisclosureReturn,
useDisclosure,
} from "@chakra-ui/react";
import { useQuery } from "@tanstack/react-query";
import { keepPreviousData, useQuery } from "@tanstack/react-query";
import { createColumnHelper } from "@tanstack/react-table";
import { ChainIcon } from "components/icons/ChainIcon";
import { TWTable } from "components/shared/TWTable";
@@ -254,7 +254,7 @@ const ChainLastBlockTimestamp = ({
const ethBlockQuery = useQuery({
queryKey: ["block_timestamp", chainId, Number(blockNumber)],
// keep the previous data while fetching new data
keepPreviousData: true,
placeholderData: keepPreviousData,
queryFn: async () => {
const rpcRequest = getRpcClient({
client: thirdwebClient,
@@ -270,7 +270,7 @@ const EditModal = (props: {
className="gap-2"
disabled={!form.formState.isDirty}
>
{editInstance.isLoading ? (
{editInstance.isPending ? (
<Spinner className="size-4" />
) : (
<SendIcon className="size-4" />
@@ -363,7 +363,7 @@ function RemoveFromDashboardModalContent(props: {
variant="destructive"
className="gap-2"
>
{removeFromDashboard.isLoading ? (
{removeFromDashboard.isPending ? (
<Spinner className="size-4" />
) : (
<Trash2Icon className="size-4" />
@@ -493,7 +493,7 @@ function CancelSubscriptionModalContent(props: {
disabled={!form.formState.isValid}
className="gap-2"
>
{removeCloudHosted.isLoading ? (
{removeCloudHosted.isPending ? (
<Spinner className="size-4" />
) : (
<SendIcon className="size-4" />
@@ -316,7 +316,7 @@ const ReceiveFundsModal = ({
// only run this if we have a backendWallet address
enabled: !!backendWallet.address,
// start out with empty string
initialData: "",
placeholderData: "",
queryFn: async () => {
return new Promise<string>((resolve, reject) => {
QRCode.toDataURL(
@@ -136,7 +136,6 @@ export const TransactionTimeline = ({
<StepIndicator>
<StepStatus complete={<FiCheck />} active={<FiCheck />} />
</StepIndicator>
<Flex justify="space-between" w="full" mt={-1}>
<Stack>
{isFilled ? (
@@ -152,7 +151,6 @@ export const TransactionTimeline = ({
</Text>
)}
</Flex>
<StepSeparator />
</Step>
);
@@ -33,7 +33,7 @@ export const IpfsUploadButton: ComponentWithChildren<IpfsUploadButtonProps> = ({
variant="solid"
aria-label="Upload to IPFS"
rightIcon={<Icon as={FiUpload} />}
isLoading={storageUpload.isLoading}
isLoading={storageUpload.isPending}
{...buttonProps}
>
{children}
@@ -310,7 +310,7 @@ const FileUpload: React.FC<FileUploadProps> = ({ files, updateFiles }) => {
e.stopPropagation();
updateFiles((prev) => prev.filter((f) => f !== file));
}}
isDisabled={storageUpload.isLoading}
isDisabled={storageUpload.isPending}
/>
</Tooltip>
)}
@@ -361,7 +361,6 @@ const FileUpload: React.FC<FileUploadProps> = ({ files, updateFiles }) => {
);
})}
</SimpleGrid>
{showPagination && (
<Flex
gap={2}
@@ -391,7 +390,6 @@ const FileUpload: React.FC<FileUploadProps> = ({ files, updateFiles }) => {
</Button>
</Flex>
)}
<Flex direction="column">
<Divider flexShrink={0} />
<Flex
@@ -407,7 +405,7 @@ const FileUpload: React.FC<FileUploadProps> = ({ files, updateFiles }) => {
{/* If user is uploading just one file,
we allow them to choose if they want to upload without a folder */}
{files.length === 1 &&
!storageUpload.isLoading &&
!storageUpload.isPending &&
ipfsHashes.length === 0 && (
<Flex direction={"row"} gap={"2"}>
<Checkbox
@@ -423,7 +421,7 @@ const FileUpload: React.FC<FileUploadProps> = ({ files, updateFiles }) => {
</Label>
</Flex>
)}
{storageUpload.isLoading && (
{storageUpload.isPending && (
<Flex
w="100%"
direction="column"
@@ -437,7 +435,7 @@ const FileUpload: React.FC<FileUploadProps> = ({ files, updateFiles }) => {
size={{ base: "xs", md: "lg" }}
w="100%"
borderRadius="full"
isIndeterminate={storageUpload.isLoading}
isIndeterminate={storageUpload.isPending}
position="relative"
/>
<Center
@@ -479,7 +477,7 @@ const FileUpload: React.FC<FileUploadProps> = ({ files, updateFiles }) => {
)}
<ButtonGroup ml={{ base: "0", md: "auto" }}>
<Button
isDisabled={storageUpload.isLoading}
isDisabled={storageUpload.isPending}
onClick={() => {
updateFiles([]);
setIpfsHashes([]);
@@ -508,7 +506,7 @@ const FileUpload: React.FC<FileUploadProps> = ({ files, updateFiles }) => {
</Button>
) : (
<Button
isLoading={storageUpload.isLoading}
isLoading={storageUpload.isPending}
loadingText="Uploading..."
colorScheme="green"
leftIcon={<Icon as={FiUploadCloud} />}
@@ -542,9 +540,9 @@ const FileUpload: React.FC<FileUploadProps> = ({ files, updateFiles }) => {
});
setIpfsHashes(uris);
// also refetch the files list
queryClient.invalidateQueries([
PINNED_FILES_QUERY_KEY_ROOT,
]);
queryClient.invalidateQueries({
queryKey: [PINNED_FILES_QUERY_KEY_ROOT],
});
},
});
}}
@@ -71,7 +71,6 @@ const ReasonWeb3Section = () => {
Web3 will unlock the true potential of the internet by enabling digital
ownership for users and generating more revenue for builders.
</Text>
<SimpleGrid
columns={{ base: 1, lg: 5 }}
mt={14}
@@ -94,11 +93,9 @@ const ReasonWeb3Section = () => {
maxH="205px"
alt="web-generation"
/>
<Heading size="title.sm" mt={14}>
{reason.title}
</Heading>
<List marginTop={6} listStyleType="initial">
{reason.list.map((list, _idx) => {
// biome-ignore lint/suspicious/noArrayIndexKey: FIXME
@@ -88,9 +88,9 @@ const OnboardingBilling: React.FC<OnboardingBillingProps> = ({
>
<OnboardingPaymentForm
onSave={() => {
queryClient.invalidateQueries(
accountKeys.me(user?.address as string),
);
queryClient.invalidateQueries({
queryKey: accountKeys.me(user?.address as string),
});
onSave();
}}
onCancel={handleCancel}
@@ -96,8 +96,8 @@ const OnboardingLinkWallet: React.FC<OnboardingLinkWalletProps> = ({
colorScheme="blue"
type="button"
onClick={handleSubmit}
isLoading={updateMutation.isLoading}
isDisabled={updateMutation.isLoading}
isLoading={updateMutation.isPending}
isDisabled={updateMutation.isPending}
>
Yes, link them
</Button>
@@ -107,7 +107,7 @@ const OnboardingLinkWallet: React.FC<OnboardingLinkWalletProps> = ({
fontSize="md"
variant="outline"
onClick={onBack}
isDisabled={updateMutation.isLoading}
isDisabled={updateMutation.isPending}
>
Use another email
</Button>
@@ -31,7 +31,7 @@ export function ExportToCSVButton(props: {
exportMutation.mutate();
}}
>
{exportMutation.isLoading ? (
{exportMutation.isPending ? (
<>
Downloading
<Spinner className="size-3" />
@@ -48,11 +48,15 @@ function processQuery(
return { isError: true };
}
if (!topCustomersQuery.data) {
return { isEmpty: true };
}
let customers = topCustomersQuery.data.pages.flatMap(
(x) => x.pageData.customers,
);
customers = customers.filter((x) => x.totalSpendUSDCents > 0);
customers = customers?.filter((x) => x.totalSpendUSDCents > 0);
if (customers.length === 0) {
return { isEmpty: true };
@@ -169,13 +173,11 @@ function RenderData(props: { query: ProcessedQuery; loadMore: () => void }) {
)}
</tbody>
</table>
{props.query.isEmpty && (
<div className="min-h-[240px] flex items-center justify-center w-full text-muted-foreground text-sm">
No data available
</div>
)}
{props.query.data?.showLoadMore && (
<div className="flex justify-center py-3">
<Button
@@ -40,6 +40,10 @@ function processQuery(
return { isError: true };
}
if (!newCustomersQuery.data) {
return { isEmpty: true };
}
if (newCustomersQuery.data.intervalResults.length === 0) {
return { isEmpty: true };
}
@@ -43,6 +43,9 @@ function processQuery(
if (purchasesQuery.isError) {
return { isError: true };
}
if (!purchasesQuery.data) {
return { isEmpty: true };
}
const purchases = purchasesQuery.data.purchases;
const totalCount = purchasesQuery.data.count;
@@ -161,9 +164,7 @@ function RenderData(props: {
</tbody>
</table>
</ScrollShadow>
<div className="h-8" />
{props.query.isEmpty ? (
<div className="min-h-[150px] flex items-center justify-center w-full text-muted-foreground text-sm">
No data available
@@ -39,7 +39,12 @@ function processQuery(
return { isError: true };
}
const aggregated = volumeQuery.data.aggregate;
const aggregated = volumeQuery.data?.aggregate;
if (!aggregated) {
return {
isEmpty: true,
};
}
let succeeded = 0;
let failed = 0;
@@ -37,6 +37,9 @@ function processQuery(query: ReturnType<typeof usePayVolume>): ProcessedQuery {
if (query.isError) {
return { isError: true };
}
if (!query.data) {
return { isEmpty: true };
}
if (query.data.intervalResults.length === 0) {
return { isEmpty: true };
@@ -40,6 +40,9 @@ function processQuery(
if (volumeQuery.isError) {
return { isError: true };
}
if (!volumeQuery.data) {
return { isEmpty: true };
}
if (volumeQuery.data.intervalResults.length === 0) {
return { isEmpty: true };
@@ -31,6 +31,9 @@ function processQuery(
if (volumeQuery.isError) {
return { isError: true };
}
if (!volumeQuery.data) {
return { isEmpty: true };
}
if (volumeQuery.data.aggregate.sum.succeeded.amountUSDCents === 0) {
return { isEmpty: true };
@@ -162,7 +165,6 @@ function RenderData(props: { query: ProcessedQuery }) {
</div>
</div>
</div>
{/* Right */}
<div className="lg:flex items-center border-t border-border pt-5 lg:pt-0 lg:border-none lg:pr-10">
<div className="flex lg:flex-col gap-10 lg:gap-4 justify-center">
@@ -26,7 +26,7 @@ export function usePayCustomers(options: {
return useInfiniteQuery({
queryKey: ["usePayCustomers", user?.address, options],
queryFn: async ({ pageParam = 0 }) => {
queryFn: async ({ pageParam }) => {
const endpoint =
options.type === "new-customers"
? "/stats/new-customers/v1"
@@ -73,6 +73,7 @@ export function usePayCustomers(options: {
};
},
enabled: !!user?.jwt,
initialPageParam: 0,
getNextPageParam: (lastPage) => {
return lastPage.nextPageIndex;
},
@@ -1,5 +1,5 @@
import { useLoggedInUser } from "@3rdweb-sdk/react/hooks/useLoggedInUser";
import { useQuery } from "@tanstack/react-query";
import { keepPreviousData, useQuery } from "@tanstack/react-query";
export type PayPurchasesData = {
count: number;
@@ -67,7 +67,8 @@ export function usePayPurchases(options: PayPurcaseOptions) {
queryKey: ["usePayPurchases", user?.address, options],
queryFn: async () => getPayPurchases(options),
enabled: !!user?.jwt,
keepPreviousData: true,
// keep the previous data while fetching new data
placeholderData: keepPreviousData,
});
}
@@ -152,11 +152,11 @@ export const PayConfig: React.FC<PayConfigProps> = ({ apiKey }) => {
<Button
type="submit"
variant="primary"
disabled={!apiKey.services || mutation.isLoading}
disabled={!apiKey.services || mutation.isPending}
className="flex flex-row gap-2"
>
{mutation.isLoading && <Spinner className="size-4" />}
<span>{mutation.isLoading ? "Saving ..." : "Save changes"}</span>
{mutation.isPending && <Spinner className="size-4" />}
<span>{mutation.isPending ? "Saving ..." : "Save changes"}</span>
</Button>
</form>
</Form>
@@ -243,10 +243,10 @@ export const AccountForm: React.FC<AccountFormProps> = ({
onClick={handleSubmit}
colorScheme={buttonProps?.variant ? undefined : "blue"}
isDisabled={
updateMutation.isLoading ||
updateMutation.isPending ||
(disableUnchanged && !form.formState.isDirty)
}
isLoading={updateMutation.isLoading}
isLoading={updateMutation.isPending}
>
{buttonText}
</Button>
@@ -48,7 +48,7 @@ export const BillingAlerts = () => {
AccountStatus.InvalidPayment,
AccountStatus.InvalidPaymentMethod,
AccountStatus.PaymentVerification,
].includes(account?.status as AccountStatus)
].includes(account.state.data?.status as AccountStatus)
? 1000
: false,
});
@@ -276,7 +276,7 @@ export const Billing: React.FC<BillingProps> = ({ account }) => {
validPayment={validPayment}
paymentVerification={paymentVerification}
invalidPayment={invalidPayment}
loading={paymentMethodSaving || updatePlanMutation.isLoading}
loading={paymentMethodSaving || updatePlanMutation.isPending}
onSelect={handlePlanSelect}
/>
@@ -301,7 +301,7 @@ export const Billing: React.FC<BillingProps> = ({ account }) => {
oldPlanFeatures={PLANS[account.plan].features}
onClose={handleDowngradeAlertClose}
onConfirm={(feedback) => handleUpdatePlan(downgradePlan, feedback)}
loading={updatePlanMutation.isLoading}
loading={updatePlanMutation.isPending}
/>
)}
</Flex>
@@ -214,7 +214,7 @@ function CreateAPIKeyForm(props: {
return (
<DomainsAlert
type={showAlert}
isCreating={props.createKeyMutation.isLoading}
isCreating={props.createKeyMutation.isPending}
onProceed={() => {
handleAPICreation({
name: form.getValues("name"),
@@ -338,10 +338,10 @@ function CreateAPIKeyForm(props: {
</DialogClose>
<Button
type="submit"
disabled={props.createKeyMutation.isLoading}
disabled={props.createKeyMutation.isPending}
className="gap-2 min-w-28"
>
{props.createKeyMutation.isLoading && (
{props.createKeyMutation.isPending && (
<Spinner className="size-4" />
)}
Create
@@ -97,7 +97,7 @@ export const RevokeApiKeyButton: React.FC<RevokeApiKeyButtonProps> = ({
colorScheme="red"
onClick={handleRevoke}
ml={3}
isLoading={mutation.isLoading}
isLoading={mutation.isPending}
>
Delete
</Button>
@@ -194,7 +194,6 @@ export const SponsorshipPolicies: React.FC<SponsorshipPoliciesProps> = ({
</Text>
</Flex>
</Flex>
<Flex
flexDir="column"
gap={6}
@@ -1,6 +1,11 @@
import { useLoggedInUser } from "@3rdweb-sdk/react/hooks/useLoggedInUser";
import { Center, Flex, Tooltip } from "@chakra-ui/react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import {
keepPreviousData,
useMutation,
useQuery,
useQueryClient,
} from "@tanstack/react-query";
import { createColumnHelper } from "@tanstack/react-table";
import { TWQueryTable } from "components/shared/TWQueryTable";
import { formatDistance } from "date-fns/formatDistance";
@@ -68,8 +73,8 @@ function usePinnedFilesQuery({
return (await res.json()) as PinnedFilesResponse;
},
enabled: user.isLoggedIn && !!user.user?.address && !!user.user.jwt,
// keep the previous data when fetching new data
keepPreviousData: true,
// keep the previous data while fetching new data
placeholderData: keepPreviousData,
});
}
@@ -91,7 +96,9 @@ function useUnpinFileMutation() {
},
onSuccess: () => {
// invalidate all queries to do with pinned files
return queryClient.invalidateQueries([PINNED_FILES_QUERY_KEY_ROOT]);
return queryClient.invalidateQueries({
queryKey: [PINNED_FILES_QUERY_KEY_ROOT],
});
},
});
}
@@ -154,10 +161,10 @@ const columns = [
];
const UnpinButton: React.FC<{ cid: string }> = ({ cid }) => {
const { mutateAsync, isLoading } = useUnpinFileMutation();
const { mutateAsync, isPending } = useUnpinFileMutation();
return (
<Button
isLoading={isLoading}
isLoading={isPending}
size="sm"
variant="outline"
onClick={() => mutateAsync({ cid })}
@@ -70,7 +70,7 @@ export const PrimaryDashboardButton: React.FC<AddToDashboardCardProps> = ({
opacity: 0.75,
}}
leftIcon={<Icon as={FiPlus} />}
isLoading={addContract.isLoading}
isLoading={addContract.isPending}
isDisabled={!chain?.chainId}
onClick={() => {
if (!chain) {
@@ -33,7 +33,7 @@ export const SolidityStringInput: React.FC<SolidityInputWithTypeProps> = ({
<InputGroup display="flex">
<Input
placeholder="string"
isDisabled={storageUpload.isLoading}
isDisabled={storageUpload.isPending}
pr={{ base: "90px", md: "160px" }}
{...restOfInputProps}
value={form.watch(inputName)}
@@ -57,7 +57,9 @@ export const SolidityStringInput: React.FC<SolidityInputWithTypeProps> = ({
}
form.setValue(inputName, uri, { shouldDirty: true });
// also refetch the files list
queryClient.invalidateQueries([PINNED_FILES_QUERY_KEY_ROOT]);
queryClient.invalidateQueries({
queryKey: [PINNED_FILES_QUERY_KEY_ROOT],
});
}}
storageUpload={storageUpload}
>
@@ -4,8 +4,14 @@ import type { ThirdwebContract } from "thirdweb";
export function useContractFunctionSelectors(contract: ThirdwebContract) {
return useQuery({
queryKey: ["contract-function-selectors", contract],
queryKey: [
"contract-function-selectors",
{
chainId: contract.chain.id,
address: contract.address,
},
],
queryFn: () => resolveFunctionSelectors(contract),
initialData: [],
placeholderData: [],
});
}
@@ -109,6 +109,7 @@ export function useContractRouteConfig(
): EnhancedRoute[] {
// new
const functionSelectorQuery = useContractFunctionSelectors(contract);
const functionSelectors = functionSelectorQuery.data || [];
const contractTypeQuery = useReadContract(ThirdwebExt.contractType, {
contract,
});
@@ -116,19 +117,19 @@ export function useContractRouteConfig(
const isERC721Query = useReadContract(ERC721Ext.isERC721, { contract });
const isERC1155Query = useReadContract(ERC1155Ext.isERC1155, { contract });
const isERC20 = useMemo(
() => ERC20Ext.isERC20(functionSelectorQuery.data),
[functionSelectorQuery.data],
() => ERC20Ext.isERC20(functionSelectors),
[functionSelectors],
);
const isPermissions = useMemo(() => {
// all of these need to be supported for permissions to be enabled
return [
PermissionExt.isGetRoleAdminSupported(functionSelectorQuery.data),
PermissionExt.isGrantRoleSupported(functionSelectorQuery.data),
PermissionExt.isHasRoleSupported(functionSelectorQuery.data),
PermissionExt.isRenounceRoleSupported(functionSelectorQuery.data),
PermissionExt.isRevokeRoleSupported(functionSelectorQuery.data),
PermissionExt.isGetRoleAdminSupported(functionSelectors),
PermissionExt.isGrantRoleSupported(functionSelectors),
PermissionExt.isHasRoleSupported(functionSelectors),
PermissionExt.isRenounceRoleSupported(functionSelectors),
PermissionExt.isRevokeRoleSupported(functionSelectors),
].every(Boolean);
}, [functionSelectorQuery.data]);
}, [functionSelectors]);
const isPermissionsEnumerable = useMemo(() => {
// if direct permissions isn't supported, then enumerable also isn't
@@ -137,76 +138,74 @@ export function useContractRouteConfig(
}
// all of these need to be supported for permissions to be enumerable
return [
PermissionExt.isGetRoleMemberSupported(functionSelectorQuery.data),
PermissionExt.isGetRoleMemberCountSupported(functionSelectorQuery.data),
PermissionExt.isGetRoleMemberSupported(functionSelectors),
PermissionExt.isGetRoleMemberCountSupported(functionSelectors),
].every(Boolean);
}, [isPermissions, functionSelectorQuery.data]);
}, [isPermissions, functionSelectors]);
const isAccount = useMemo(
() => ERC4337Ext.isValidateUserOpSupported(functionSelectorQuery.data),
[functionSelectorQuery.data],
() => ERC4337Ext.isValidateUserOpSupported(functionSelectors),
[functionSelectors],
);
const accountPermissions = useMemo(() => {
return [
ERC4337Ext.isGetAllActiveSignersSupported(functionSelectorQuery.data),
ERC4337Ext.isGetAllAdminsSupported(functionSelectorQuery.data),
ERC4337Ext.isGetAllSignersSupported(functionSelectorQuery.data),
ERC4337Ext.isIsActiveSignerSupported(functionSelectorQuery.data),
ERC4337Ext.isIsAdminSupported(functionSelectorQuery.data),
ERC4337Ext.isAddAdminSupported(functionSelectorQuery.data),
ERC4337Ext.isGetAllActiveSignersSupported(functionSelectors),
ERC4337Ext.isGetAllAdminsSupported(functionSelectors),
ERC4337Ext.isGetAllSignersSupported(functionSelectors),
ERC4337Ext.isIsActiveSignerSupported(functionSelectors),
ERC4337Ext.isIsAdminSupported(functionSelectors),
ERC4337Ext.isAddAdminSupported(functionSelectors),
].every(Boolean);
}, [functionSelectorQuery.data]);
}, [functionSelectors]);
const accountFactory = useMemo(() => {
return [
ERC4337Ext.isGetAllAccountsSupported(functionSelectorQuery.data),
ERC4337Ext.isGetAccountsSupported(functionSelectorQuery.data),
ERC4337Ext.isTotalAccountsSupported(functionSelectorQuery.data),
ERC4337Ext.isGetAccountsOfSignerSupported(functionSelectorQuery.data),
ERC4337Ext.isPredictAccountAddressSupported(functionSelectorQuery.data),
ERC4337Ext.isGetAllAccountsSupported(functionSelectors),
ERC4337Ext.isGetAccountsSupported(functionSelectors),
ERC4337Ext.isTotalAccountsSupported(functionSelectors),
ERC4337Ext.isGetAccountsOfSignerSupported(functionSelectors),
ERC4337Ext.isPredictAccountAddressSupported(functionSelectors),
].every(Boolean);
}, [functionSelectorQuery.data]);
}, [functionSelectors]);
const hasERC721ClaimConditions = useMemo(() => {
return [
// reads
ERC721Ext.isGetClaimConditionByIdSupported(functionSelectorQuery.data),
ERC721Ext.isGetActiveClaimConditionIdSupported(
functionSelectorQuery.data,
),
ERC721Ext.isGetClaimConditionsSupported(functionSelectorQuery.data),
ERC721Ext.isGetActiveClaimConditionSupported(functionSelectorQuery.data),
ERC721Ext.isGetClaimConditionByIdSupported(functionSelectors),
ERC721Ext.isGetActiveClaimConditionIdSupported(functionSelectors),
ERC721Ext.isGetClaimConditionsSupported(functionSelectors),
ERC721Ext.isGetActiveClaimConditionSupported(functionSelectors),
// writes
ERC721Ext.isSetClaimConditionsSupported(functionSelectorQuery.data),
ERC721Ext.isResetClaimEligibilitySupported(functionSelectorQuery.data),
ERC721Ext.isSetClaimConditionsSupported(functionSelectors),
ERC721Ext.isResetClaimEligibilitySupported(functionSelectors),
].every(Boolean);
}, [functionSelectorQuery.data]);
}, [functionSelectors]);
const hasERC20ClaimConditions = useMemo(() => {
return [
// reads
ERC20Ext.isGetClaimConditionByIdSupported(functionSelectorQuery.data),
ERC20Ext.isGetActiveClaimConditionIdSupported(functionSelectorQuery.data),
ERC20Ext.isGetClaimConditionsSupported(functionSelectorQuery.data),
ERC20Ext.isGetActiveClaimConditionSupported(functionSelectorQuery.data),
ERC20Ext.isGetClaimConditionByIdSupported(functionSelectors),
ERC20Ext.isGetActiveClaimConditionIdSupported(functionSelectors),
ERC20Ext.isGetClaimConditionsSupported(functionSelectors),
ERC20Ext.isGetActiveClaimConditionSupported(functionSelectors),
// writes
ERC20Ext.isSetClaimConditionsSupported(functionSelectorQuery.data),
ERC20Ext.isResetClaimEligibilitySupported(functionSelectorQuery.data),
ERC20Ext.isSetClaimConditionsSupported(functionSelectors),
ERC20Ext.isResetClaimEligibilitySupported(functionSelectors),
].every(Boolean);
}, [functionSelectorQuery.data]);
}, [functionSelectors]);
const hasERC1155ClaimConditions = useMemo(() => {
return [
// reads
ERC1155Ext.isGetClaimConditionByIdSupported(functionSelectorQuery.data),
ERC1155Ext.isGetClaimConditionsSupported(functionSelectorQuery.data),
ERC1155Ext.isGetActiveClaimConditionSupported(functionSelectorQuery.data),
ERC1155Ext.isGetClaimConditionByIdSupported(functionSelectors),
ERC1155Ext.isGetClaimConditionsSupported(functionSelectors),
ERC1155Ext.isGetActiveClaimConditionSupported(functionSelectors),
// writes
ERC1155Ext.isSetClaimConditionsSupported(functionSelectorQuery.data),
ERC1155Ext.isResetClaimEligibilitySupported(functionSelectorQuery.data),
ERC1155Ext.isSetClaimConditionsSupported(functionSelectors),
ERC1155Ext.isResetClaimEligibilitySupported(functionSelectors),
].every(Boolean);
}, [functionSelectorQuery.data]);
}, [functionSelectors]);
const hasClaimConditions = useMemo(() => {
return [
@@ -222,26 +221,26 @@ export function useContractRouteConfig(
const isModularCore = useMemo(() => {
return [
ModularExt.isGetInstalledModulesSupported(functionSelectorQuery.data),
ModularExt.isInstallModuleSupported(functionSelectorQuery.data),
ModularExt.isGetInstalledModulesSupported(functionSelectors),
ModularExt.isInstallModuleSupported(functionSelectors),
].every(Boolean);
}, [functionSelectorQuery.data]);
}, [functionSelectors]);
const isDirectListing = useMemo(() => {
return [
MarketplaceExt.isCreateListingSupported(functionSelectorQuery.data),
MarketplaceExt.isCancelListingSupported(functionSelectorQuery.data),
MarketplaceExt.isBuyFromListingSupported(functionSelectorQuery.data),
MarketplaceExt.isCreateListingSupported(functionSelectors),
MarketplaceExt.isCancelListingSupported(functionSelectors),
MarketplaceExt.isBuyFromListingSupported(functionSelectors),
].every(Boolean);
}, [functionSelectorQuery.data]);
}, [functionSelectors]);
const isEnglishAuction = useMemo(() => {
return [
MarketplaceExt.isCreateAuctionSupported(functionSelectorQuery.data),
MarketplaceExt.isCancelAuctionSupported(functionSelectorQuery.data),
MarketplaceExt.isBidInAuctionSupported(functionSelectorQuery.data),
MarketplaceExt.isCreateAuctionSupported(functionSelectors),
MarketplaceExt.isCancelAuctionSupported(functionSelectors),
MarketplaceExt.isBidInAuctionSupported(functionSelectors),
].every(Boolean);
}, [functionSelectorQuery.data]);
}, [functionSelectors]);
const embedType: "marketplace-v3" | "erc20" | "erc1155" | "erc721" | null =
useMemo(() => {
@@ -377,12 +376,8 @@ export function useContractRouteConfig(
<LazyContractTokensPage
contract={contract}
isERC20={isERC20}
isMintToSupported={ERC20Ext.isMintToSupported(
functionSelectorQuery.data,
)}
isClaimToSupported={ERC20Ext.isClaimToSupported(
functionSelectorQuery.data,
)}
isMintToSupported={ERC20Ext.isMintToSupported(functionSelectors)}
isClaimToSupported={ERC20Ext.isClaimToSupported(functionSelectors)}
/>
),
},
@@ -497,32 +492,20 @@ export function useContractRouteConfig(
contract={contract}
isLoading={functionSelectorQuery.isLoading}
isContractMetadataSupported={[
CommonExt.isGetContractMetadataSupported(
functionSelectorQuery.data,
),
CommonExt.isSetContractMetadataSupported(
functionSelectorQuery.data,
),
CommonExt.isGetContractMetadataSupported(functionSelectors),
CommonExt.isSetContractMetadataSupported(functionSelectors),
].every(Boolean)}
isPrimarySaleSupported={[
CommonExt.isPrimarySaleRecipientSupported(
functionSelectorQuery.data,
),
CommonExt.isSetPrimarySaleRecipientSupported(
functionSelectorQuery.data,
),
CommonExt.isPrimarySaleRecipientSupported(functionSelectors),
CommonExt.isSetPrimarySaleRecipientSupported(functionSelectors),
].every(Boolean)}
isRoyaltiesSupported={[
CommonExt.isGetDefaultRoyaltyInfoSupported(
functionSelectorQuery.data,
),
CommonExt.isSetDefaultRoyaltyInfoSupported(
functionSelectorQuery.data,
),
CommonExt.isGetDefaultRoyaltyInfoSupported(functionSelectors),
CommonExt.isSetDefaultRoyaltyInfoSupported(functionSelectors),
].every(Boolean)}
isPlatformFeesSupported={[
CommonExt.isGetPlatformFeeInfoSupported(functionSelectorQuery.data),
CommonExt.isSetPlatformFeeInfoSupported(functionSelectorQuery.data),
CommonExt.isGetPlatformFeeInfoSupported(functionSelectors),
CommonExt.isSetPlatformFeeInfoSupported(functionSelectors),
].every(Boolean)}
/>
),
@@ -562,7 +562,6 @@ const SnapshotTable: React.FC<SnapshotTableProps> = ({ data, portalRef }) => {
</Tbody>
</Table>
</TableContainer>
<Portal containerRef={portalRef}>
<Center w="100%">
<HStack>
@@ -429,7 +429,7 @@ export const EmbedSetup: React.FC<EmbedSetupProps> = ({
},
);
}}
disabled={createKeyMutation.isLoading}
disabled={createKeyMutation.isPending}
>
Create Client ID
</Button>
@@ -223,7 +223,7 @@ function ModuleRow(props: {
variant="outline"
className="text-red-500 rounded-xl p-3"
>
{uninstallMutation.isLoading ? (
{uninstallMutation.isPending ? (
<Spinner className="size-4" />
) : (
<FaRegTrashAlt className="size-4" />
@@ -267,7 +267,7 @@ function ModuleRow(props: {
<TransactionButton
transactionCount={1}
isLoading={uninstallMutation.isLoading}
isLoading={uninstallMutation.isPending}
type="submit"
colorScheme="red"
className="flex"
@@ -237,7 +237,7 @@ export const InstallModuleForm = (props: InstallModuleFormProps) => {
<FormControl isInvalid={!!errors.publisherAddress}>
<FormLabel>Publisher</FormLabel>
<Input
disabled={installMutation.isLoading}
disabled={installMutation.isPending}
bg="backgroundHighlight"
placeholder="Publisher address"
{...register("publisherAddress", {
@@ -265,7 +265,7 @@ export const InstallModuleForm = (props: InstallModuleFormProps) => {
>
<Select
disabled={
installMutation.isLoading ||
installMutation.isPending ||
publishedContractsQuery?.data?.length === 0 ||
publishedContractsQuery.isLoading
}
@@ -320,7 +320,7 @@ export const InstallModuleForm = (props: InstallModuleFormProps) => {
!allVersions.data ||
allVersions.isLoading ||
isModuleCompatibleQuery.data === false ||
installMutation.isLoading ||
installMutation.isPending ||
isModuleCompatibleQuery.isFetching
}
bg="backgroundHighlight"
@@ -350,7 +350,7 @@ export const InstallModuleForm = (props: InstallModuleFormProps) => {
<ModuleInstallParams
installParams={moduleInstallParams.data}
form={form}
disableInputs={installMutation.isLoading}
disableInputs={installMutation.isPending}
/>
)
)}
@@ -361,7 +361,7 @@ export const InstallModuleForm = (props: InstallModuleFormProps) => {
<div className="flex justify-end">
<TransactionButton
transactionCount={1}
isLoading={installMutation.isLoading}
isLoading={installMutation.isPending}
type="submit"
colorScheme="primary"
alignSelf="flex-end"
@@ -447,7 +447,6 @@ const AirdropTable: React.FC<AirdropTableProps> = ({ data, portalRef }) => {
</Tbody>
</Table>
</TableContainer>
<Portal containerRef={portalRef}>
<Center w="100%">
<HStack>
@@ -36,7 +36,7 @@ export const ContractNFTPage: React.FC<NftOverviewPageProps> = ({
);
}
if (functionSelectorQuery.isLoading) {
if (functionSelectorQuery.isLoading || !functionSelectorQuery.data) {
// TODO build a skeleton for this
return <div>Loading...</div>;
}
@@ -72,6 +72,12 @@ export const ContractNFTPage: React.FC<NftOverviewPageProps> = ({
const canCreateDelayedRevealBatch =
ERC721Ext.isCreateDelayedRevealBatchSupported(functionSelectorQuery.data);
console.log("***DEBUG*** canRenderNFTTable: ", {
isErc721,
canRenderNFTTable,
functionSelectorQuery,
});
return (
<div className="flex flex-col gap-6">
<div className="flex flex-row justify-between items-center">
@@ -31,7 +31,7 @@ export const ContractChecklist: React.FC<ContractChecklistProps> = (props) => {
return (
// if no permissions, simply return null (do not fail open)
<AdminOnly contract={props.contract} failOpen={false}>
{functionSelectorQuery.data.length > 0 && (
{functionSelectorQuery.data?.length && (
<Inner functionSelectors={functionSelectorQuery.data} {...props} />
)}
</AdminOnly>
@@ -15,7 +15,7 @@ interface VoteButtonProps {
export const DelegateButton: React.FC<VoteButtonProps> = ({ contract }) => {
const trackEvent = useTrack();
const { data: delegated, isLoading } = useTokensDelegated(contract);
const { mutate: delegate, isLoading: isDelegating } =
const { mutate: delegate, isPending: isDelegating } =
useDelegateMutation(contract);
const { onSuccess, onError } = useTxNotifications(
@@ -28,7 +28,7 @@ export const ProposalButton: React.FC<VoteButtonProps> = ({ contract }) => {
children: (
<>
<Button
isDisabled={propose.isLoading}
isDisabled={propose.isPending}
variant="outline"
mr={3}
onClick={onClose}
@@ -37,7 +37,7 @@ export const ProposalButton: React.FC<VoteButtonProps> = ({ contract }) => {
</Button>
<TransactionButton
transactionCount={1}
isLoading={propose.isLoading}
isLoading={propose.isPending}
form={PROPOSAL_FORM_ID}
type="submit"
colorScheme="primary"
@@ -45,11 +45,11 @@ export const Proposal: React.FC<IProposal> = ({ proposal, contract }) => {
proposal.proposalId,
);
const { data: delegated } = useTokensDelegated(contract);
const { mutate: execute, isLoading: isExecuting } =
const { mutate: execute, isPending: isExecuting } =
useExecuteProposalMutation(contract, proposal.proposalId);
const {
mutate: vote,
isLoading: isVoting,
isPending: isVoting,
variables,
} = useCastVoteMutation(contract, proposal.proposalId);
@@ -116,19 +116,19 @@ export const Proposal: React.FC<IProposal> = ({ proposal, contract }) => {
<>
<Text mt="16px">
<strong>For:</strong>{" "}
{decimalQuery.isLoading
{decimalQuery.isPending
? "Loading..."
: toTokens(proposal.votes.for, decimalQuery.data || 18)}
</Text>
<Text>
<strong>Against:</strong>{" "}
{decimalQuery.isLoading
{decimalQuery.isPending
? "Loading..."
: toTokens(proposal.votes.against, decimalQuery.data || 18)}
</Text>
<Text>
<strong>Abstained:</strong>{" "}
{decimalQuery.isLoading
{decimalQuery.isPending
? "Loading..."
: toTokens(proposal.votes.abstain, decimalQuery.data || 18)}
</Text>
@@ -17,6 +17,7 @@ import {
Tr,
usePrevious,
} from "@chakra-ui/react";
import type { UseQueryResult } from "@tanstack/react-query";
import { MediaCell } from "components/contract-pages/table/table-columns/cells/media-cell";
import { ListingDrawer } from "contract-ui/tabs/shared-components/listing-drawer";
import {
@@ -33,7 +34,6 @@ import {
MdNavigateBefore,
MdNavigateNext,
} from "react-icons/md";
import type { UseQueryResult } from "react-query-v5";
import { type Cell, type Column, usePagination, useTable } from "react-table";
import type { ThirdwebContract } from "thirdweb";
import type {
@@ -201,7 +201,6 @@ export const MarketplaceTable: React.FC<MarketplaceTableProps> = ({
Valid
</Button>
</ButtonGroup>
<TableContainer maxW="100%" className="relative">
{((listingsToShow === "all" && getAllQueryResult.isFetching) ||
(listingsToShow === "valid" && getValidQueryResult.isFetching)) && (
@@ -286,7 +286,7 @@ function RefreshContractMetadataButton(props: {
return (
<Button
isLoading={contractCacheMutation.isLoading}
isLoading={contractCacheMutation.isPending}
variant="outline"
onClick={() => {
toast.promise(contractCacheMutation.mutateAsync(), {
@@ -75,7 +75,7 @@ export const DistributeButton: React.FC<DistributeButtonProps> = ({
// we still want to show the button, so we'll just show the mismatch button
return (
<MismatchButton
isLoading={mutation.isLoading}
isLoading={mutation.isPending}
colorScheme="primary"
onClick={distributeFunds}
{...restButtonProps}
@@ -96,7 +96,7 @@ export const DistributeButton: React.FC<DistributeButtonProps> = ({
return (
<TransactionButton
transactionCount={numTransactions}
isLoading={mutation.isLoading}
isLoading={mutation.isPending}
colorScheme="primary"
onClick={distributeFunds}
{...restButtonProps}
@@ -209,7 +209,6 @@ export const BatchTable: React.FC<BatchTableProps> = ({
</Tbody>
</Table>
</TableContainer>
<Portal containerRef={portalRef}>
<Center w="100%">
<HStack>
@@ -42,6 +42,7 @@ export function useNFTDrawerTabs({
tokenId,
}: UseNFTDrawerTabsParams): NFTDrawerTab[] {
const functionSelectorQuery = useContractFunctionSelectors(contract);
const functionSelectors = functionSelectorQuery.data || [];
const address = useActiveAccount()?.address;
const isERC721Query = useReadContract(ERC721Ext.isERC721, { contract });
@@ -74,43 +75,41 @@ export function useNFTDrawerTabs({
const hasERC1155ClaimConditions = (() => {
return [
// reads
ERC1155Ext.isGetClaimConditionByIdSupported(functionSelectorQuery.data),
ERC1155Ext.isGetClaimConditionsSupported(functionSelectorQuery.data),
ERC1155Ext.isGetActiveClaimConditionSupported(
functionSelectorQuery.data,
),
ERC1155Ext.isGetClaimConditionByIdSupported(functionSelectors),
ERC1155Ext.isGetClaimConditionsSupported(functionSelectors),
ERC1155Ext.isGetActiveClaimConditionSupported(functionSelectors),
// writes
ERC1155Ext.isSetClaimConditionsSupported(functionSelectorQuery.data),
ERC1155Ext.isResetClaimEligibilitySupported(functionSelectorQuery.data),
ERC1155Ext.isSetClaimConditionsSupported(functionSelectors),
ERC1155Ext.isResetClaimEligibilitySupported(functionSelectors),
].every(Boolean);
})();
const isBurnable = (() => {
if (isERC721) {
return ERC721Ext.isBurnSupported(functionSelectorQuery.data);
return ERC721Ext.isBurnSupported(functionSelectors);
}
if (isERC1155) {
return ERC1155Ext.isBurnSupported(functionSelectorQuery.data);
return ERC1155Ext.isBurnSupported(functionSelectors);
}
return false;
})();
const supportsUpdateMetadata = (() => {
if (isERC721) {
return ERC721Ext.isUpdateMetadataSupported(functionSelectorQuery.data);
return ERC721Ext.isUpdateMetadataSupported(functionSelectors);
}
if (isERC1155) {
return ERC1155Ext.isUpdateMetadataSupported(functionSelectorQuery.data);
return ERC1155Ext.isUpdateMetadataSupported(functionSelectors);
}
return false;
})();
const supportsUpdateTokenURI = (() => {
if (isERC721) {
return ERC721Ext.isUpdateTokenURISupported(functionSelectorQuery.data);
return ERC721Ext.isUpdateTokenURISupported(functionSelectors);
}
if (isERC1155) {
return ERC1155Ext.isUpdateTokenURISupported(functionSelectorQuery.data);
return ERC1155Ext.isUpdateTokenURISupported(functionSelectors);
}
return false;
})();
@@ -174,9 +173,7 @@ export function useNFTDrawerTabs({
},
]);
}
if (
ERC1155Ext.isMintAdditionalSupplyToSupported(functionSelectorQuery.data)
) {
if (ERC1155Ext.isMintAdditionalSupplyToSupported(functionSelectors)) {
tabs = tabs.concat([
{
title: "Mint",
@@ -223,6 +220,6 @@ export function useNFTDrawerTabs({
tokenId,
isMinterRole,
contract,
functionSelectorQuery.data,
functionSelectors,
]);
}
@@ -16,13 +16,14 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
}
const ensNameOrAddress = getSingleQueryValue(req.query, "address");
const contractName = getSingleQueryValue(req.query, "contractName");
if (!ensNameOrAddress) {
if (ensNameOrAddress === undefined) {
return res.status(400).json({ message: "address must be provided" });
}
const queryClient = new QueryClient();
let ensResult: ENSResolveResult;
try {
ensResult = await ensQuery(ensNameOrAddress).queryFn();
ensResult = await queryClient.fetchQuery(ensQuery(ensNameOrAddress));
} catch (err) {
return res.status(500).json({ message: (err as Error).message });
}
@@ -49,7 +50,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
);
const publishedContracts = await fetchPublishedContracts(
polygonSdk,
new QueryClient(),
queryClient,
ensResult.address,
);
@@ -278,9 +278,10 @@ export const getStaticProps: GetStaticProps<UserPageProps> = async (ctx) => {
await Promise.all([
...ensQueries,
queryClient.prefetchQuery(publisherProfileQuery(address)),
queryClient.prefetchQuery(["published-contracts", address], () =>
fetchPublishedContracts(polygonSdk, queryClient, address),
),
queryClient.prefetchQuery({
queryKey: ["published-contracts", address],
queryFn: () => fetchPublishedContracts(polygonSdk, queryClient, address),
}),
]);
return {
+1 -1
View File
@@ -26,7 +26,7 @@
"@radix-ui/react-switch": "^1.1.0",
"@radix-ui/react-tabs": "^1.1.0",
"@radix-ui/react-tooltip": "1.1.2",
"@tanstack/react-query": "^5.51.23",
"@tanstack/react-query": "5.55.4",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"lucide-react": "0.439.0",
+1 -1
View File
@@ -24,7 +24,7 @@
"@radix-ui/react-dropdown-menu": "^2.1.1",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-tabs": "^1.1.0",
"@tanstack/react-query": "^5.32.0",
"@tanstack/react-query": "5.55.4",
"@tryghost/content-api": "^1.11.21",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
+1 -1
View File
@@ -17,7 +17,7 @@
"@radix-ui/react-popover": "^1.1.1",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-toast": "^1.2.1",
"@tanstack/react-query": "^5.48.0",
"@tanstack/react-query": "5.55.4",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"cmdk": "^1.0.0",
+11 -29
View File
@@ -145,7 +145,7 @@ importers:
version: 2.1.2(@chakra-ui/[email protected])
'@coinbase/onchainkit':
specifier: ^0.14.2
version: 0.14.2(@tanstack/react-query@4.36.1([email protected]([email protected]))([email protected](@babel/[email protected])(@babel/[email protected](@babel/[email protected]))(@types/[email protected])([email protected])([email protected])([email protected])([email protected]))([email protected]))(@xmtp/[email protected]([email protected])([email protected])([email protected])([email protected]))([email protected]([email protected]))([email protected])([email protected]([email protected]))([email protected])([email protected]([email protected])([email protected])([email protected])([email protected]))
version: 0.14.2(@tanstack/react-query@5.55.4([email protected]))(@xmtp/[email protected]([email protected])([email protected])([email protected])([email protected]))([email protected]([email protected]))([email protected])([email protected]([email protected]))([email protected])([email protected]([email protected])([email protected])([email protected])([email protected]))
'@emotion/react':
specifier: 11.13.3
version: 11.13.3(@types/[email protected])([email protected])
@@ -222,8 +222,8 @@ importers:
specifier: ^3.5.0
version: 3.5.0
'@tanstack/react-query':
specifier: ^4.36.1
version: 4.36.1([email protected]([email protected]))([email protected](@babel/[email protected])(@babel/[email protected](@babel/[email protected]))(@types/[email protected])([email protected])([email protected])([email protected])([email protected]))([email protected])
specifier: 5.55.4
version: 5.55.4([email protected])
'@tanstack/react-table':
specifier: ^8.17.3
version: 8.20.5([email protected]([email protected]))([email protected])
@@ -350,9 +350,6 @@ importers:
react-otp-input:
specifier: ^3.1.1
version: 3.1.1([email protected]([email protected]))([email protected])
react-query-v5:
specifier: npm:@tanstack/[email protected]
version: '@tanstack/[email protected]([email protected])'
react-responsive-carousel:
specifier: ^3.2.23
version: 3.2.23
@@ -556,8 +553,8 @@ importers:
specifier: 1.1.2
version: 1.1.2(@types/[email protected])(@types/[email protected])([email protected]([email protected]))([email protected])
'@tanstack/react-query':
specifier: ^5.51.23
version: 5.54.1([email protected])
specifier: 5.55.4
version: 5.55.4([email protected])
class-variance-authority:
specifier: ^0.7.0
version: 0.7.0
@@ -659,8 +656,8 @@ importers:
specifier: ^1.1.0
version: 1.1.0(@types/[email protected])(@types/[email protected])([email protected]([email protected]))([email protected])
'@tanstack/react-query':
specifier: ^5.32.0
version: 5.54.1([email protected])
specifier: 5.55.4
version: 5.55.4([email protected])
'@tryghost/content-api':
specifier: ^1.11.21
version: 1.11.21
@@ -825,8 +822,8 @@ importers:
specifier: ^1.2.1
version: 1.2.1(@types/[email protected])(@types/[email protected])([email protected]([email protected]))([email protected])
'@tanstack/react-query':
specifier: ^5.48.0
version: 5.54.1([email protected])
specifier: 5.55.4
version: 5.55.4([email protected])
class-variance-authority:
specifier: ^0.7.0
version: 0.7.0
@@ -8834,9 +8831,6 @@ packages:
'@tanstack/[email protected]':
resolution: {integrity: sha512-DJSilV5+ytBP1FbFcEJovv4rnnm/CokuVvrBEtW/Va9DvuJ3HksbXUJEpI0aV1KtuL4ZoO9AVE6PyNLzF7tLeA==}
'@tanstack/[email protected]':
resolution: {integrity: sha512-hKS+WRpT5zBFip21pB6Jx1C0hranWQrbv5EJ7qPoiV5MYI3C8rTCqWC9DdBseiPT1JgQWh8Y55YthuYZNiw3Xw==}
'@tanstack/[email protected]':
resolution: {integrity: sha512-uoRqNnRfzOH4OMIoxj8E2+Us89UIGXfau981qYJWsNMkFS1GXR4UIyzUTVGq4N7SDLHgFPpo6IOazqUV5gkMZA==}
@@ -8852,11 +8846,6 @@ packages:
react-native:
optional: true
'@tanstack/[email protected]':
resolution: {integrity: sha512-SuMi4JBYv49UtmiRyqjxY7XAnE1qwLht9nlkC8sioxFXz5Uzj30lepiKf2mYXuXfC7fHYjTrAPkNx+427pRHXA==}
peerDependencies:
react: ^18 || ^19
'@tanstack/[email protected]':
resolution: {integrity: sha512-e3uX5XkLD9oTV66/VsVpkYz3Ds/ps/Yk+V5d89xthAbtNIKKBEm4FdNb9yISFzGEGezUzVO68qmfmiSrtScvsg==}
peerDependencies:
@@ -25902,9 +25891,9 @@ snapshots:
optionalDependencies:
regenerator-runtime: 0.13.11
'@coinbase/[email protected](@tanstack/react-query@4.36.1([email protected]([email protected]))([email protected](@babel/[email protected])(@babel/[email protected](@babel/[email protected]))(@types/[email protected])([email protected])([email protected])([email protected])([email protected]))([email protected]))(@xmtp/[email protected]([email protected])([email protected])([email protected])([email protected]))([email protected]([email protected]))([email protected])([email protected]([email protected]))([email protected])([email protected]([email protected])([email protected])([email protected])([email protected]))':
'@coinbase/[email protected](@tanstack/react-query@5.55.4([email protected]))(@xmtp/[email protected]([email protected])([email protected])([email protected])([email protected]))([email protected]([email protected]))([email protected])([email protected]([email protected]))([email protected])([email protected]([email protected])([email protected])([email protected])([email protected]))':
dependencies:
'@tanstack/react-query': 4.36.1([email protected]([email protected]))([email protected](@babel/[email protected])(@babel/[email protected](@babel/[email protected]))(@types/[email protected])([email protected])([email protected])([email protected])([email protected]))([email protected])
'@tanstack/react-query': 5.55.4([email protected])
'@xmtp/frames-validator': 0.6.2([email protected])([email protected])([email protected])([email protected])
graphql: 16.9.0
graphql-request: 6.1.0([email protected])
@@ -32133,8 +32122,6 @@ snapshots:
'@tanstack/[email protected]': {}
'@tanstack/[email protected]': {}
'@tanstack/[email protected]': {}
'@tanstack/[email protected]([email protected]([email protected]))([email protected](@babel/[email protected])(@babel/[email protected](@babel/[email protected]))(@types/[email protected])([email protected])([email protected])([email protected])([email protected]))([email protected])':
@@ -32146,11 +32133,6 @@ snapshots:
react-dom: 18.3.1([email protected])
react-native: 0.75.2(@babel/[email protected])(@babel/[email protected](@babel/[email protected]))(@types/[email protected])([email protected])([email protected])([email protected])([email protected])
'@tanstack/[email protected]([email protected])':
dependencies:
'@tanstack/query-core': 5.54.1
react: 18.3.1
'@tanstack/[email protected]([email protected])':
dependencies:
'@tanstack/query-core': 5.55.4