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:
@@ -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"],
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
+4
-5
@@ -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" />
|
||||
</>
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
|
||||
+6
-7
@@ -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);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
-2
@@ -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
|
||||
}
|
||||
>
|
||||
|
||||
+2
-2
@@ -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"
|
||||
|
||||
+8
-4
@@ -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;
|
||||
|
||||
+3
-3
@@ -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>
|
||||
|
||||
+8
-7
@@ -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
|
||||
|
||||
+4
-8
@@ -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 };
|
||||
}
|
||||
|
||||
+4
-8
@@ -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 };
|
||||
}
|
||||
|
||||
+4
-8
@@ -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 };
|
||||
}
|
||||
|
||||
+4
-8
@@ -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 };
|
||||
}
|
||||
|
||||
+3
-3
@@ -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>
|
||||
)}
|
||||
|
||||
+4
-4
@@ -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 };
|
||||
}
|
||||
|
||||
+8
-4
@@ -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">
|
||||
|
||||
+2
-2
@@ -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,
|
||||
});
|
||||
|
||||
+5
-5
@@ -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>
|
||||
|
||||
+2
-2
@@ -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 {
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
Generated
+11
-29
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user