import { useQuery } from "@tanstack/react-query"; import type { Chain } from "../../../../../chains/types.js"; import { getCachedChain } from "../../../../../chains/utils.js"; import type { ThirdwebClient } from "../../../../../client/client.js"; import { getContract } from "../../../../../contract/contract.js"; import { getOwnedNFTs as getErc721OwnedNFTs } from "../../../../../extensions/erc721/read/getOwnedNFTs.js"; import { isERC721 } from "../../../../../extensions/erc721/read/isERC721.js"; import { getOwnedNFTs as getErc1155OwnedNFTs } from "../../../../../extensions/erc1155/read/getOwnedNFTs.js"; import { isERC1155 } from "../../../../../extensions/erc1155/read/isERC1155.js"; import { getOwnedNFTs } from "../../../../../insight/get-nfts.js"; import type { Address } from "../../../../../utils/address.js"; import type { NFT } from "../../../../../utils/nft/parseNft.js"; import type { Theme } from "../../../../core/design-system/index.js"; import { useActiveAccount } from "../../../../core/hooks/wallets/useActiveAccount.js"; import { useActiveWalletChain } from "../../../../core/hooks/wallets/useActiveWalletChain.js"; import type { SupportedNFTs } from "../../../../core/utils/defaultTokens.js"; import { Container, Line, ModalHeader } from "../../components/basic.js"; import { Skeleton } from "../../components/Skeleton.js"; import { Spacer } from "../../components/Spacer.js"; import { Text } from "../../components/text.js"; import { MediaRenderer } from "../../MediaRenderer/MediaRenderer.js"; import type { ConnectLocale } from "../locale/types.js"; const fetchNFTs = async ( client: ThirdwebClient, chain: Chain, nftAddress: string, owner: string, ) => { const contract = getContract({ address: nftAddress, chain, client, }); const erc721 = await isERC721({ contract }).catch(() => { throw new Error( `Failed to read contract bytecode for NFT ${nftAddress} on ${chain.name || chain.id}, is this NFT on the correct chain?`, ); }); if (erc721) { const result = await getErc721OwnedNFTs({ contract, owner: owner, }); return result.map((nft) => ({ ...nft, address: contract.address, chain, quantityOwned: BigInt(1), })); } const erc1155 = await isERC1155({ contract }).catch(() => false); if (erc1155) { const result = await getErc1155OwnedNFTs({ address: owner, contract, }); return result.map((nft) => ({ ...nft, address: contract.address, chain })); } throw new Error( `NFT at ${nftAddress} on chain ${chain.id} is not ERC721 or ERC1155, or does not properly identify itself as supporting either interface`, ); }; /** * @internal */ export function ViewNFTs(props: { supportedNFTs?: SupportedNFTs; theme: Theme | "light" | "dark"; onBack: () => void; client: ThirdwebClient; connectLocale: ConnectLocale; }) { return ( ); } export function ViewNFTsContent(props: { supportedNFTs?: SupportedNFTs; client: ThirdwebClient; theme: Theme | "light" | "dark"; connectLocale: ConnectLocale; }) { const activeAccount = useActiveAccount(); const activeChain = useActiveWalletChain(); const nftQuery = useQuery({ enabled: !!activeChain && !!activeAccount, queryFn: async (): Promise< (NFT & { chain: Chain; address: Address; quantityOwned: bigint })[] > => { if (!activeAccount) { throw new Error("No active account"); } if (!activeChain) { throw new Error("No active chain"); } const result = await getOwnedNFTs({ chains: [activeChain], client: props.client, ownerAddress: activeAccount.address, contractAddresses: props.supportedNFTs?.[activeChain.id]?.map((nft) => nft.toLowerCase(), ), }); return result .filter((nft) => !!nft.metadata.name && !!nft.metadata.image) .map((nft) => { return { address: nft.tokenAddress as Address, chain: getCachedChain(nft.chainId), ...nft, }; }); }, queryKey: [ "nfts", activeChain?.id, activeAccount?.address, props.supportedNFTs, ], }); if (!activeChain?.id || !activeAccount?.address) { return null; } const filteredNFTs = nftQuery.data; return ( <> {nftQuery.error ? ( Error loading NFTs ) : nftQuery.data?.length === 0 && !nftQuery.isLoading ? ( No NFTs found on this chain ) : ( {nftQuery.isLoading || !filteredNFTs ? ( <> > ) : ( filteredNFTs.map((nft) => ( )) )} )} > ); } function NftCard( props: Awaited>[number] & { client: ThirdwebClient; chain: Chain; theme: Theme | "light" | "dark"; }, ) { const theme = typeof props.theme === "string" ? props.theme : props.theme.type; const themeObject = typeof props.theme === "string" ? undefined : props.theme; const content = ( {props.metadata.image && ( )} {props.quantityOwned > 1 && ( {props.quantityOwned.toString()} )} {props.chain.icon && ( )} {props.metadata.name} ); if (props.chain.name) { return ( {content} ); } return content; }