diff --git a/.changeset/afraid-points-admire.md b/.changeset/afraid-points-admire.md new file mode 100644 index 00000000000..1ff6aa401bd --- /dev/null +++ b/.changeset/afraid-points-admire.md @@ -0,0 +1,5 @@ +--- +"thirdweb": patch +--- + +Expose max() & min() util methods for bigints diff --git a/apps/dashboard/src/contract-ui/tabs/listings/components/listing-stats.tsx b/apps/dashboard/src/contract-ui/tabs/listings/components/listing-stats.tsx index 4ef827abc09..3af62cad99c 100644 --- a/apps/dashboard/src/contract-ui/tabs/listings/components/listing-stats.tsx +++ b/apps/dashboard/src/contract-ui/tabs/listings/components/listing-stats.tsx @@ -1,30 +1,22 @@ import { Skeleton, Stack, Stat, StatLabel, StatNumber } from "@chakra-ui/react"; -import { - useDirectListingsCount, - useEnglishAuctionsCount, -} from "@thirdweb-dev/react"; -import type { MarketplaceV3 } from "@thirdweb-dev/sdk"; -import { BigNumber } from "ethers"; import { useMemo } from "react"; +import type { ThirdwebContract } from "thirdweb"; +import { totalAuctions, totalListings } from "thirdweb/extensions/marketplace"; +import { useReadContract } from "thirdweb/react"; import { Card } from "tw-components"; -interface ListingStatsV3Props { - contract?: MarketplaceV3; - features: string[]; -} - -const TotalListingsStat: React.FC<{ contract?: MarketplaceV3 }> = ({ +const TotalListingsStat: React.FC<{ contract: ThirdwebContract }> = ({ contract, }) => { - const directListingsQuery = useDirectListingsCount(contract); - const englishAuctionsQuery = useEnglishAuctionsCount(contract); - - const totalListings = useMemo( - () => - BigNumber.from(directListingsQuery?.data || 0).add( - BigNumber.from(englishAuctionsQuery?.data || 0), - ), - [directListingsQuery?.data, englishAuctionsQuery?.data], + const directListingsQuery = useReadContract(totalListings, { + contract, + }); + const englishAuctionsQuery = useReadContract(totalAuctions, { + contract, + }); + const combinedListingCount = useMemo( + () => (directListingsQuery.data || 0n) + (englishAuctionsQuery.data || 0n), + [directListingsQuery.data, englishAuctionsQuery.data], ); return ( @@ -32,56 +24,63 @@ const TotalListingsStat: React.FC<{ contract?: MarketplaceV3 }> = ({ Total Listings - {totalListings.toString()} + {combinedListingCount.toString()} ); }; -const DirectListingsStat: React.FC<{ contract?: MarketplaceV3 }> = ({ +const DirectListingsStat: React.FC<{ contract: ThirdwebContract }> = ({ contract, }) => { - const directListingsQuery = useDirectListingsCount(contract); + const directListingsQuery = useReadContract(totalListings, { + contract, + }); return ( Direct Listings - - {(directListingsQuery.data || 0).toString()} + + {(directListingsQuery.data || 0n).toString()} ); }; -const EnglishAuctionsStat: React.FC<{ contract?: MarketplaceV3 }> = ({ +const EnglishAuctionsStat: React.FC<{ contract: ThirdwebContract }> = ({ contract, }) => { - const englishAuctionsQuery = useEnglishAuctionsCount(contract); + const englishAuctionsQuery = useReadContract(totalAuctions, { + contract, + }); return ( English Auctions - - {(englishAuctionsQuery.data || 0).toString()} + + {(englishAuctionsQuery.data || 0n).toString()} ); }; +interface ListingStatsV3Props { + contract: ThirdwebContract; + hasDirectListings: boolean; + hasEnglishAuctions: boolean; +} + export const ListingStatsV3: React.FC = ({ contract, - features, + hasDirectListings, + hasEnglishAuctions, }) => { - const hasDirectListings = features.includes("DirectListings"); - const hasEnglishAuctions = features.includes("EnglishAuctions"); - return ( - {hasDirectListings && hasEnglishAuctions && ( + {hasDirectListings && hasEnglishAuctions && contract && ( )} {hasDirectListings && } diff --git a/apps/dashboard/src/contract-ui/tabs/overview/components/MarketplaceDetails.tsx b/apps/dashboard/src/contract-ui/tabs/overview/components/MarketplaceDetails.tsx index 9ab5773e1f9..c75772186f2 100644 --- a/apps/dashboard/src/contract-ui/tabs/overview/components/MarketplaceDetails.tsx +++ b/apps/dashboard/src/contract-ui/tabs/overview/components/MarketplaceDetails.tsx @@ -7,14 +7,10 @@ import { SkeletonText, useBreakpointValue, } from "@chakra-ui/react"; -import { useContract } from "@thirdweb-dev/react"; -import type { MarketplaceV3 } from "@thirdweb-dev/sdk"; import { ListingStatsV3 } from "contract-ui/tabs/listings/components/listing-stats"; import { useTabHref } from "contract-ui/utils"; -import { BigNumber } from "ethers"; -import { useV5DashboardChain } from "lib/v5-adapter"; import { useMemo } from "react"; -import { getContract } from "thirdweb"; +import type { ThirdwebContract } from "thirdweb"; import { type DirectListing, type EnglishAuction, @@ -24,17 +20,10 @@ import { totalListings, } from "thirdweb/extensions/marketplace"; import { useReadContract } from "thirdweb/react"; -import { - Badge, - Card, - Heading, - Text, - TrackedLink, - type TrackedLinkProps, -} from "tw-components"; +import { max } from "thirdweb/utils"; +import { Badge, Card, Heading, Text, TrackedLink } from "tw-components"; import { AddressCopyButton } from "tw-components/AddressCopyButton"; import { NFTMediaWithEmptyState } from "tw-components/nft-media"; -import { thirdwebClient } from "../../../../lib/thirdweb-client"; type ListingData = | (Pick< @@ -53,33 +42,19 @@ type ListingData = }); type MarketplaceDetailsProps = { - contractAddress: string; - contractType: "marketplace" | "marketplace-v3"; + contract: ThirdwebContract; features: string[]; - trackingCategory: TrackedLinkProps["category"]; + trackingCategory: string; }; -interface MarketplaceDetailsVersionProps { - contract: T; - trackingCategory: TrackedLinkProps["category"]; - features: MarketplaceDetailsProps["features"]; -} - export const MarketplaceDetails: React.FC = ({ - contractAddress, - contractType, + contract, trackingCategory, features, }) => { - const { contract } = useContract(contractAddress, contractType); - - if (contractType === "marketplace" && contract) { - // no longer supported - return null; - } return ( @@ -87,26 +62,25 @@ export const MarketplaceDetails: React.FC = ({ }; type ListingCardsSectionProps = { - contract: MarketplaceV3; - trackingCategory: TrackedLinkProps["category"]; + contract: ThirdwebContract; + trackingCategory: string; }; const DirectListingCards: React.FC = ({ trackingCategory, - contract: v4Contract, + contract, }) => { - const chain = useV5DashboardChain(v4Contract.chainId); - const contract = getContract({ - client: thirdwebClient, - address: v4Contract.getAddress(), - chain: chain, - }); const directListingsHref = useTabHref("direct-listings"); const countQuery = useReadContract(totalListings, { contract }); const listingsQuery = useReadContract(getAllListings, { contract, count: 3n, - start: Math.max(BigNumber.from(countQuery?.data || 3)?.toNumber() - 3, 0), + start: Math.max( + Number( + max((countQuery?.data || 3n) - 3n, BigInt(Number.MAX_SAFE_INTEGER)), + ), + 0, + ), }); const listings = useMemo( () => @@ -121,7 +95,7 @@ const DirectListingCards: React.FC = ({ [listingsQuery?.data], ); - if (!countQuery.isLoading && BigNumber.from(countQuery.data || 0).eq(0)) { + if (!countQuery.isLoading && (countQuery.data || 0n) === 0n) { return null; } if (!listingsQuery.isLoading && listings.length === 0) { @@ -156,21 +130,19 @@ const DirectListingCards: React.FC = ({ const EnglishAuctionCards: React.FC = ({ trackingCategory, - contract: v4Contract, + contract, }) => { - const chain = useV5DashboardChain(v4Contract.chainId); - const contract = getContract({ - client: thirdwebClient, - address: v4Contract.getAddress(), - chain: chain, - }); - const englishAuctionsHref = useTabHref("english-auctions"); const countQuery = useReadContract(totalAuctions, { contract }); const auctionsQuery = useReadContract(getAllAuctions, { contract, count: 3n, - start: Math.max(BigNumber.from(countQuery?.data || 3)?.toNumber() - 3, 0), + start: Math.max( + Number( + max((countQuery?.data || 3n) - 3n, BigInt(Number.MAX_SAFE_INTEGER)), + ), + 0, + ), }); const auctions = useMemo( () => @@ -185,7 +157,7 @@ const EnglishAuctionCards: React.FC = ({ [auctionsQuery?.data], ); - if (!countQuery.isLoading && BigNumber.from(countQuery.data || 0).eq(0)) { + if (!countQuery.isLoading && (countQuery.data || 0n) === 0n) { return null; } if (!auctionsQuery.isLoading && auctions.length === 0) { @@ -218,16 +190,28 @@ const EnglishAuctionCards: React.FC = ({ ); }; -const MarketplaceV3Details: React.FC< - MarketplaceDetailsVersionProps -> = ({ contract, trackingCategory, features }) => { +interface MarketplaceDetailsVersionProps { + contract: ThirdwebContract; + trackingCategory: string; + features: MarketplaceDetailsProps["features"]; +} + +const MarketplaceV3Details: React.FC = ({ + contract, + trackingCategory, + features, +}) => { const hasDirectListings = features.includes("DirectListings"); const hasEnglishAuctions = features.includes("EnglishAuctions"); return ( Listings - + {hasDirectListings && contract && ( ListingData = (idx) => ({ interface ListingCardsProps { listings: ListingData[]; isLoading: boolean; - trackingCategory: TrackedLinkProps["category"]; + trackingCategory: string; isMarketplaceV1?: boolean; } const ListingCards: React.FC = ({ diff --git a/apps/dashboard/src/contract-ui/tabs/overview/page.tsx b/apps/dashboard/src/contract-ui/tabs/overview/page.tsx index c4056cb2681..bbd68d307c5 100644 --- a/apps/dashboard/src/contract-ui/tabs/overview/page.tsx +++ b/apps/dashboard/src/contract-ui/tabs/overview/page.tsx @@ -72,11 +72,11 @@ export const ContractOverviewPage: React.FC = ({ (contractTypeData === "marketplace" || ["DirectListings", "EnglishAuctions"].some((type) => detectedFeatureNames.includes(type), - )) && ( + )) && + contractV5 && ( )} diff --git a/apps/dashboard/src/contract-ui/tabs/shared-components/marketplace-table.tsx b/apps/dashboard/src/contract-ui/tabs/shared-components/marketplace-table.tsx index 8a9844ecbcf..65b0640bcfb 100644 --- a/apps/dashboard/src/contract-ui/tabs/shared-components/marketplace-table.tsx +++ b/apps/dashboard/src/contract-ui/tabs/shared-components/marketplace-table.tsx @@ -18,7 +18,6 @@ import { } from "@chakra-ui/react"; import { MediaCell } from "components/contract-pages/table/table-columns/cells/media-cell"; import { ListingDrawer } from "contract-ui/tabs/shared-components/listing-drawer"; -import { BigNumber } from "ethers"; import { type Dispatch, type SetStateAction, @@ -40,6 +39,7 @@ import type { DirectListing, EnglishAuction, } from "thirdweb/extensions/marketplace"; +import { max } from "thirdweb/utils"; import { Button, Text } from "tw-components"; import { AddressCopyButton } from "tw-components/AddressCopyButton"; import { LISTING_STATUS } from "./types"; @@ -162,8 +162,10 @@ export const MarketplaceTable: React.FC = ({ manualPagination: true, pageCount: Math.max( Math.ceil( - BigNumber.from(totalCountQuery.data || 0).toNumber() / - queryParams.count, + Number( + // To avoid overflow issue + max(totalCountQuery.data || 0n, BigInt(Number.MAX_SAFE_INTEGER)), + ) / queryParams.count, ), 1, ), diff --git a/packages/thirdweb/src/exports/utils.ts b/packages/thirdweb/src/exports/utils.ts index 99b9c255cd6..6bb73c3d713 100644 --- a/packages/thirdweb/src/exports/utils.ts +++ b/packages/thirdweb/src/exports/utils.ts @@ -176,3 +176,8 @@ export { export type { NFTMetadata, NFTInput } from "../utils/nft/parseNft.js"; export { parseAbiParams } from "../utils/contract/parse-abi-params.js"; + +// ------------------------------------------------ +// bigint +// ------------------------------------------------ +export { max, min } from "../utils/bigint.js"; diff --git a/packages/thirdweb/src/utils/bigint.ts b/packages/thirdweb/src/utils/bigint.ts index eca3444ce69..4977d84036b 100644 --- a/packages/thirdweb/src/utils/bigint.ts +++ b/packages/thirdweb/src/utils/bigint.ts @@ -5,6 +5,7 @@ import { uint8ArrayToHex } from "./encoding/hex.js"; * @param a - The first BigInt value. * @param b - The second BigInt value. * @returns The smaller of the two BigInt values. + * @utils * @example * ```ts * min(1n, 2n) @@ -19,6 +20,7 @@ export function min(a: bigint, b: bigint) { * @param a - The first BigInt value. * @param b - The second BigInt value. * @returns The larger of the two BigInt values. + * @utils * @example * ```ts * max(1n, 2n)