From 0cb1948613da559e4572258311a1be5e391ee1fb Mon Sep 17 00:00:00 2001 From: Joaquim Verges Date: Wed, 30 Jul 2025 21:56:41 +1200 Subject: [PATCH] Fix CheckoutWidget transaction invalidation and NFT filtering in connect UI --- .changeset/petite-wasps-leave.md | 5 +++++ .../extensions/erc1155/read/getOwnedNFTs.ts | 2 +- .../src/extensions/erc721/read/getOwnedNFTs.ts | 2 +- packages/thirdweb/src/insight/get-nfts.ts | 7 ++++--- packages/thirdweb/src/insight/get-tokens.ts | 7 ++++--- .../react/core/hooks/useTransactionDetails.ts | 5 ++--- .../core/providers/invalidateWalletBalance.ts | 8 ++++++-- .../web/ui/ConnectWallet/screens/ViewNFTs.tsx | 18 ++++++++++-------- 8 files changed, 33 insertions(+), 21 deletions(-) create mode 100644 .changeset/petite-wasps-leave.md diff --git a/.changeset/petite-wasps-leave.md b/.changeset/petite-wasps-leave.md new file mode 100644 index 00000000000..4d356625fd4 --- /dev/null +++ b/.changeset/petite-wasps-leave.md @@ -0,0 +1,5 @@ +--- +"thirdweb": patch +--- + +Fix CheckoutWidget transaction invalidation and fix nft filtering in connect UI diff --git a/packages/thirdweb/src/extensions/erc1155/read/getOwnedNFTs.ts b/packages/thirdweb/src/extensions/erc1155/read/getOwnedNFTs.ts index 9959a7a214b..6accdb41523 100644 --- a/packages/thirdweb/src/extensions/erc1155/read/getOwnedNFTs.ts +++ b/packages/thirdweb/src/extensions/erc1155/read/getOwnedNFTs.ts @@ -62,7 +62,7 @@ async function getOwnedNFTsFromInsight( chains: [options.contract.chain], client: options.contract.client, ownerAddress: options.address, - contractAddress: options.contract.address, + contractAddresses: [options.contract.address], queryOptions: { limit, page, diff --git a/packages/thirdweb/src/extensions/erc721/read/getOwnedNFTs.ts b/packages/thirdweb/src/extensions/erc721/read/getOwnedNFTs.ts index fc1ea0b35a2..ce6cb3c5a64 100644 --- a/packages/thirdweb/src/extensions/erc721/read/getOwnedNFTs.ts +++ b/packages/thirdweb/src/extensions/erc721/read/getOwnedNFTs.ts @@ -78,7 +78,7 @@ async function getOwnedNFTsFromInsight( chains: [options.contract.chain], client: options.contract.client, ownerAddress: options.owner, - contractAddress: options.contract.address, + contractAddresses: [options.contract.address], queryOptions: { limit, page, diff --git a/packages/thirdweb/src/insight/get-nfts.ts b/packages/thirdweb/src/insight/get-nfts.ts index 5384b94bb54..b56783d1e38 100644 --- a/packages/thirdweb/src/insight/get-nfts.ts +++ b/packages/thirdweb/src/insight/get-nfts.ts @@ -33,7 +33,7 @@ export async function getOwnedNFTs(args: { client: ThirdwebClient; chains: Chain[]; ownerAddress: string; - contractAddress?: string; + contractAddresses?: string[]; includeMetadata?: boolean; queryOptions?: Omit; }): Promise<(NFT & { quantityOwned: bigint })[]> { @@ -51,7 +51,8 @@ export async function getOwnedNFTs(args: { import("viem"), ]); - const { client, chains, ownerAddress, contractAddress, queryOptions } = args; + const { client, chains, ownerAddress, contractAddresses, queryOptions } = + args; await assertInsightEnabled(chains); @@ -60,7 +61,7 @@ export async function getOwnedNFTs(args: { // metadata: includeMetadata ? "true" : "false", TODO (insight): add support for this limit: 50, owner_address: [ownerAddress], - contract_address: contractAddress ? [contractAddress] : undefined, + contract_address: contractAddresses ? contractAddresses : undefined, }; const result = await getV1Nfts({ diff --git a/packages/thirdweb/src/insight/get-tokens.ts b/packages/thirdweb/src/insight/get-tokens.ts index 14d9c02b2cc..13f4e4a813f 100644 --- a/packages/thirdweb/src/insight/get-tokens.ts +++ b/packages/thirdweb/src/insight/get-tokens.ts @@ -26,7 +26,7 @@ export async function getOwnedTokens(args: { client: ThirdwebClient; chains: Chain[]; ownerAddress: string; - tokenAddress?: string; + tokenAddresses?: string[]; queryOptions?: Omit< GetV1TokensData["query"], "owner_address" | "chain_id" | "chain" @@ -46,7 +46,7 @@ export async function getOwnedTokens(args: { import("../utils/json.js"), ]); - const { client, chains, ownerAddress, tokenAddress, queryOptions } = args; + const { client, chains, ownerAddress, tokenAddresses, queryOptions } = args; await assertInsightEnabled(chains); @@ -57,7 +57,8 @@ export async function getOwnedTokens(args: { limit: 50, metadata: "true", owner_address: [ownerAddress], - token_address: tokenAddress ? [tokenAddress] : undefined, + token_address: tokenAddresses ? tokenAddresses : undefined, + sort_by: "balance", }; const result = await getV1Tokens({ diff --git a/packages/thirdweb/src/react/core/hooks/useTransactionDetails.ts b/packages/thirdweb/src/react/core/hooks/useTransactionDetails.ts index a251e954a0a..da8f3360e68 100644 --- a/packages/thirdweb/src/react/core/hooks/useTransactionDetails.ts +++ b/packages/thirdweb/src/react/core/hooks/useTransactionDetails.ts @@ -13,6 +13,7 @@ import type { SupportedFiatCurrency } from "../../../pay/convert/type.js"; import { encode } from "../../../transaction/actions/encode.js"; import type { PreparedTransaction } from "../../../transaction/prepare-transaction.js"; import { getTransactionGasCost } from "../../../transaction/utils.js"; +import { stringify } from "../../../utils/json.js"; import { resolvePromisedValue } from "../../../utils/promise/resolve-promised-value.js"; import { toTokens } from "../../../utils/units.js"; import type { Wallet } from "../../../wallets/interfaces/wallet.js"; @@ -180,9 +181,7 @@ export function useTransactionDetails({ }, queryKey: [ "transaction-details", - transaction.to, - transaction.chain.id, - transaction.erc20Value?.toString(), + stringify(transaction), hasSponsoredTransactions, ], }); diff --git a/packages/thirdweb/src/react/core/providers/invalidateWalletBalance.ts b/packages/thirdweb/src/react/core/providers/invalidateWalletBalance.ts index 7fd4ccd2a61..b9a5a7159d4 100644 --- a/packages/thirdweb/src/react/core/providers/invalidateWalletBalance.ts +++ b/packages/thirdweb/src/react/core/providers/invalidateWalletBalance.ts @@ -5,8 +5,6 @@ export function invalidateWalletBalance( chainId?: number, ) { queryClient.invalidateQueries({ - // invalidate any walletBalance queries for this chainId - // TODO: add wallet address in here if we can get it somehow queryKey: chainId ? ["walletBalance", chainId] : ["walletBalance"], }); queryClient.invalidateQueries({ @@ -14,4 +12,10 @@ export function invalidateWalletBalance( ? ["internal_account_balance", chainId] : ["internal_account_balance"], }); + queryClient.invalidateQueries({ + queryKey: chainId ? ["nfts", chainId] : ["nfts"], + }); + queryClient.invalidateQueries({ + queryKey: chainId ? ["tokens", chainId] : ["tokens"], + }); } diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/ViewNFTs.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/ViewNFTs.tsx index 5d485bca09a..d954ca7c68c 100644 --- a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/ViewNFTs.tsx +++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/ViewNFTs.tsx @@ -127,6 +127,9 @@ export function ViewNFTsContent(props: { chains: [activeChain], client: props.client, ownerAddress: activeAccount.address, + contractAddresses: props.supportedNFTs?.[activeChain.id]?.map((nft) => + nft.toLowerCase(), + ), }); return result @@ -139,20 +142,19 @@ export function ViewNFTsContent(props: { }; }); }, - queryKey: ["nfts", activeChain?.id, activeAccount?.address], + queryKey: [ + "nfts", + activeChain?.id, + activeAccount?.address, + props.supportedNFTs, + ], }); if (!activeChain?.id || !activeAccount?.address) { return null; } - const filteredNFTs = props.supportedNFTs?.[activeChain.id] - ? nftQuery.data?.filter((nft) => - props.supportedNFTs?.[activeChain.id] - ?.map((supportedNFTAddress) => supportedNFTAddress.toLowerCase()) - .includes(nft.address.toLowerCase()), - ) - : nftQuery.data; + const filteredNFTs = nftQuery.data; return ( <>