diff --git a/apps/dashboard/src/@/constants/thirdweb.client.ts b/apps/dashboard/src/@/constants/thirdweb.client.ts deleted file mode 100644 index d07849c1964..00000000000 --- a/apps/dashboard/src/@/constants/thirdweb.client.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { useQuery } from "@tanstack/react-query"; -import { useMemo } from "react"; -import { useActiveAccount } from "thirdweb/react"; -import type { GetAuthTokenResponse } from "../../app/(app)/api/auth/get-auth-token/route"; -import { LAST_USED_TEAM_ID } from "../../constants/cookies"; -import { getCookie } from "../../lib/cookie"; -import { getClientThirdwebClient } from "./thirdweb-client.client"; - -// returns a thirdweb client with optional JWT passed i - -export function useThirdwebClient(jwt?: string) { - const account = useActiveAccount(); - const lastUsedTeamId = getCookie(LAST_USED_TEAM_ID); - - const query = useQuery({ - queryKey: ["jwt", account?.address], - // only enable the query if there is an account and no JWT is passed in directly - enabled: !!account && !jwt, - retry: false, - queryFn: async () => { - if (!account) { - throw new Error("No account"); - } - const res = await fetch( - `/api/auth/get-auth-token?address=${account.address}`, - ); - if (!res.ok) { - throw new Error("Failed to get auth token"); - } - const json = (await res.json()) as GetAuthTokenResponse; - if (!json.jwt) { - throw new Error("No JWT in response"); - } - return json.jwt; - }, - }); - - return useMemo( - // prefer jwt from props over the one from the token query if it exists - () => - getClientThirdwebClient({ - jwt: jwt || query.data, - teamId: lastUsedTeamId, - }), - [jwt, query.data, lastUsedTeamId], - ); -} - -/** - * DO NOT ADD ANYTHING TO THIS FILE IF YOU ARE NOT ABSOLUTELY SURE IT IS OK - */ diff --git a/apps/dashboard/src/@3rdweb-sdk/react/components/connect-wallet/index.tsx b/apps/dashboard/src/@3rdweb-sdk/react/components/connect-wallet/index.tsx index 4ef008ede47..34129df60e9 100644 --- a/apps/dashboard/src/@3rdweb-sdk/react/components/connect-wallet/index.tsx +++ b/apps/dashboard/src/@3rdweb-sdk/react/components/connect-wallet/index.tsx @@ -198,6 +198,7 @@ export const CustomConnectWallet = (props: { open={isNetworkConfigModalOpen} onOpenChange={setIsNetworkConfigModalOpen} editChain={editChain} + client={client} /> ); diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/list-form.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/list-form.tsx index 30640a62728..9796315067b 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/list-form.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/list-form.tsx @@ -559,6 +559,7 @@ export const CreateListingsForm: React.FC = ({ width="140px" height="140px" requireInteraction + client={contract.client} /> diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/listing-drawer.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/listing-drawer.tsx index 3e0a886b3e4..11e821adaca 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/listing-drawer.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/listing-drawer.tsx @@ -51,6 +51,7 @@ export const ListingDrawer: React.FC = ({
= ({ Header: "Media", accessor: (row) => row.asset.metadata, // biome-ignore lint/suspicious/noExplicitAny: FIXME - Cell: (cell: any) => , + Cell: (cell: any) => , }, { Header: "Name", diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/NFTCards.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/NFTCards.tsx index a51904e3a2e..1182984fd9e 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/NFTCards.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/NFTCards.tsx @@ -1,7 +1,7 @@ import { SkeletonContainer } from "@/components/ui/skeleton"; import { TrackedLinkTW } from "@/components/ui/tracked-link"; import { useMemo } from "react"; -import { type NFT, ZERO_ADDRESS } from "thirdweb"; +import { type NFT, type ThirdwebClient, ZERO_ADDRESS } from "thirdweb"; import { NFTMediaWithEmptyState } from "tw-components/nft-media"; import type { ProjectMeta } from "../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types"; import { buildContractPagePath } from "../_utils/contract-page-path"; @@ -32,6 +32,7 @@ interface NFTCardsProps { isPending: boolean; allNfts?: boolean; projectMeta: ProjectMeta | undefined; + client: ThirdwebClient; } export const NFTCards: React.FC = ({ @@ -40,6 +41,7 @@ export const NFTCards: React.FC = ({ isPending, allNfts, projectMeta, + client, }) => { const dummyData = useMemo(() => { return Array.from({ @@ -73,6 +75,7 @@ export const NFTCards: React.FC = ({ requireInteraction width="100%" height="100%" + client={client} /> ); }} diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/index.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/index.tsx index e00607c9f2e..c5e016aeeff 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/index.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/index.tsx @@ -528,6 +528,7 @@ export const ClaimConditionsForm: React.FC = ({ form.setValue(`phases.${index}.snapshot`, snapshot) } isDisabled={!canEditForm} + client={contract.client} /> void; + client: ThirdwebClient; } const csvParser = (items: SnapshotAddressInput[]): SnapshotAddressInput[] => { @@ -49,6 +50,7 @@ const SnapshotViewerSheetContent: React.FC = ({ isDisabled, value, onClose, + client, }) => { const { normalizeQuery, @@ -59,7 +61,11 @@ const SnapshotViewerSheetContent: React.FC = ({ noCsv, reset, removeInvalid, - } = useCsvUpload({ csvParser, defaultRawData: value }); + } = useCsvUpload({ + csvParser, + defaultRawData: value, + client, + }); const paginationPortalRef = useRef(null); const normalizeData = normalizeQuery.data; diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/ConfigureCustomChain.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/ConfigureCustomChain.tsx index 56f8ca2bef7..1b853d5a778 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/ConfigureCustomChain.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/ConfigureCustomChain.tsx @@ -6,9 +6,11 @@ import { ConfigureNetworks } from "components/configure-networks/ConfigureNetwor import { CheckIcon, CircleAlertIcon, RotateCcwIcon } from "lucide-react"; import { useState } from "react"; import { addChainOverrides } from "stores/chainStores"; +import type { ThirdwebClient } from "thirdweb"; export function ConfigureCustomChain(props: { chainSlug: string; + client: ThirdwebClient; }) { const { chainSlug } = props; const isSlugNumber = Number.isInteger(Number(chainSlug)); @@ -61,6 +63,7 @@ export function ConfigureCustomChain(props: { } }} editChain={undefined} + client={props.client} />
diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-metadata.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-metadata.tsx index 3b84562d93c..c1e18c9401c 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-metadata.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-metadata.tsx @@ -43,7 +43,6 @@ export async function getContractMetadataHeaderData( fetchDashboardContractMetadata(contract), fetchPublishedContractsFromDeploy({ contract, - client: contract.client, }), ]); diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/components/nfts-owned.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/components/nfts-owned.tsx index 180be18eb49..117be898bfc 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/components/nfts-owned.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/components/nfts-owned.tsx @@ -27,6 +27,7 @@ export const NftsOwned: React.FC = ({ return nfts.length !== 0 ? ( ({ id: BigInt(nft.id), diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/shared-cross-chain-page.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/shared-cross-chain-page.tsx index 181da3ef249..4cc217dc947 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/shared-cross-chain-page.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/shared-cross-chain-page.tsx @@ -183,7 +183,6 @@ export async function SharedCrossChainPage(props: { coreMetadata = ( await fetchPublishedContractsFromDeploy({ contract: serverContract, - client: serverContract.client, }) ).at(-1) as FetchDeployMetadataResult; } catch {} @@ -256,7 +255,6 @@ export async function SharedCrossChainPage(props: { client: serverContract.client, address: m, }), - client: serverContract.client, }) ).at(-1), ), diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/layout.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/layout.tsx index 665ccc1f1fb..cf1753a6f2a 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/layout.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/layout.tsx @@ -1,4 +1,5 @@ import type { Metadata } from "next"; +import { getAuthToken } from "../../../../api/lib/getAuthToken"; import { SharedContractLayout, generateContractLayoutMetadata, @@ -11,12 +12,13 @@ export default async function Layout(props: { }>; children: React.ReactNode; }) { - const params = await props.params; + const [params, authToken] = await Promise.all([props.params, getAuthToken()]); return ( {props.children} diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/ModuleForm.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/ModuleForm.tsx index ace2f69f5cd..70f99c54f70 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/ModuleForm.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/ModuleForm.tsx @@ -69,9 +69,10 @@ export const InstallModuleForm = (props: InstallModuleFormProps) => { const { contract, account } = props; const { errors } = formState; - const { data, isPending, isFetching } = usePublishedContractsQuery( - watch("publisherAddress"), - ); + const { data, isPending, isFetching } = usePublishedContractsQuery({ + client: contract.client, + address: watch("publisherAddress"), + }); // filter out all the contracts that AREN'T modules const modulesOnly = useMemo(() => { @@ -88,6 +89,7 @@ export const InstallModuleForm = (props: InstallModuleFormProps) => { const allVersions = useAllVersions( watch("publisherAddress"), watch("moduleContract"), + contract.client, ); const installMutation = useMutation({ diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/airdrop-tab.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/airdrop-tab.tsx index 6e45c1dc5e4..0cb64ac9b3d 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/airdrop-tab.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/airdrop-tab.tsx @@ -135,6 +135,7 @@ const AirdropTab: React.FC = ({ setOpen(false)} setAirdrop={(value) => setValue("addresses", value, { shouldDirty: true }) diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/update-metadata-form.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/update-metadata-form.tsx index f610fb41c87..1022a69b8ff 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/update-metadata-form.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/update-metadata-form.tsx @@ -252,6 +252,7 @@ export const UpdateNftMetadata: React.FC = ({
{nft?.metadata && !mediaFileUrl && ( = ({ {/* border */}
{/* media */} - +
diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/table.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/table.tsx index 981e13bfa77..8ac468e2325 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/table.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/table.tsx @@ -75,7 +75,7 @@ export const NFTGetAllTable: React.FC = ({ Header: "Media", accessor: (row) => row.metadata, Cell: (cell: CellProps) => ( - + ), }, { diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/MarketplaceDetails.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/MarketplaceDetails.tsx index 5ea63ec8fa4..33cf982945e 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/MarketplaceDetails.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/MarketplaceDetails.tsx @@ -344,6 +344,7 @@ const ListingCards: React.FC = ({ render={(v) => { return ( ({ ...t, diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/published-by-ui.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/published-by-ui.tsx index 9f119f263c8..3a7aabd4f74 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/published-by-ui.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/published-by-ui.tsx @@ -2,7 +2,7 @@ import { fetchPublishedContractsFromDeploy } from "components/contract-component import { ContractCard } from "components/explore/contract-card"; import { THIRDWEB_DEPLOYER_ADDRESS } from "constants/addresses"; import { resolveEns } from "lib/ens"; -import type { ThirdwebClient, ThirdwebContract } from "thirdweb"; +import type { ThirdwebContract } from "thirdweb"; import { polygon } from "thirdweb/chains"; import { getBytecode, getContract } from "thirdweb/contract"; import { getPublishedUriFromCompilerUri } from "thirdweb/extensions/thirdweb"; @@ -20,13 +20,11 @@ type ModuleMetadataPickedKeys = { export async function getPublishedByCardProps(params: { address: string | null; contract: ThirdwebContract; - client: ThirdwebClient; }) { - const { address, contract, client } = params; + const { address, contract } = params; const publishedContractsFromDeploy = await fetchPublishedContractsFromDeploy({ contract, - client, }); const reversedPublishedContractsFromDeploy = [ @@ -54,7 +52,10 @@ export async function getPublishedByCardProps(params: { let publisherAddressOrEns = publishedContractToShow.publisher; if (!isValidENSName(publishedContractToShow.publisher)) { try { - const res = await resolveEns(publishedContractToShow.publisher, client); + const res = await resolveEns( + publishedContractToShow.publisher, + contract.client, + ); if (res.ensName) { publisherAddressOrEns = res.ensName; } diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/published-by.server.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/published-by.server.tsx index 233238723aa..eea2e7378a9 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/published-by.server.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/published-by.server.tsx @@ -11,7 +11,6 @@ export const PublishedBy: React.FC = async ({ contract }) => { const props = await getPublishedByCardProps({ address, contract, - client: contract.client, }); if (!props) { diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx index e4d69861f94..f3e5619a1fa 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx @@ -1,5 +1,6 @@ import { getProjects } from "@/api/projects"; import { getTeams } from "@/api/team"; +import { getClientThirdwebClient } from "@/constants/thirdweb-client.client"; import type { MinimalTeamsAndProjects } from "components/contract-components/contract-deploy-form/add-to-project-card"; import { resolveFunctionSelectors } from "lib/selectors"; import type { Metadata } from "next"; @@ -27,6 +28,7 @@ export async function SharedContractLayout(props: { chainIdOrSlug: string; projectMeta: ProjectMeta | undefined; children: React.ReactNode; + authToken: string | undefined | null; }) { if (!isAddress(props.contractAddress)) { return notFound(); @@ -43,7 +45,15 @@ export async function SharedContractLayout(props: { ]); if (!info) { - return ; + return ( + + ); } const { clientContract, serverContract, chainMetadata, isLocalhostChain } = diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/airdrop-form.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/airdrop-form.tsx index a6150e5eff2..145b38ad4c3 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/airdrop-form.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/airdrop-form.tsx @@ -97,6 +97,7 @@ export const TokenAirdropForm: React.FC = ({
{airdropFormOpen ? ( setAirdropFormOpen(false)} setAirdrop={(value) => setValue("addresses", value, { shouldDirty: true }) diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/airdrop-upload.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/airdrop-upload.tsx index 9f5c9ea62c3..bb292611fbc 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/airdrop-upload.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/airdrop-upload.tsx @@ -7,7 +7,7 @@ import { useCsvUpload } from "hooks/useCsvUpload"; import { CircleAlertIcon, UploadIcon } from "lucide-react"; import { useMemo, useRef } from "react"; import type { Column } from "react-table"; -import { ZERO_ADDRESS } from "thirdweb"; +import { type ThirdwebClient, ZERO_ADDRESS } from "thirdweb"; import { Button, Heading, Text } from "tw-components"; import { CsvDataTable } from "../../_components/csv-data-table"; @@ -19,6 +19,7 @@ export interface AirdropAddressInput { interface AirdropUploadProps { setAirdrop: (airdrop: AirdropAddressInput[]) => void; onClose: () => void; + client: ThirdwebClient; } const csvParser = (items: AirdropAddressInput[]): AirdropAddressInput[] => { @@ -33,6 +34,7 @@ const csvParser = (items: AirdropAddressInput[]): AirdropAddressInput[] => { export const AirdropUpload: React.FC = ({ setAirdrop, onClose, + client, }) => { const { normalizeQuery, @@ -43,7 +45,7 @@ export const AirdropUpload: React.FC = ({ noCsv, reset, removeInvalid, - } = useCsvUpload({ csvParser }); + } = useCsvUpload({ csvParser, client }); const paginationPortalRef = useRef(null); const normalizeData = normalizeQuery.data; diff --git a/apps/dashboard/src/app/(app)/(dashboard)/contracts/publish/[publish_uri]/page.tsx b/apps/dashboard/src/app/(app)/(dashboard)/contracts/publish/[publish_uri]/page.tsx index 7410746c20b..100a53a15d5 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/contracts/publish/[publish_uri]/page.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/contracts/publish/[publish_uri]/page.tsx @@ -1,10 +1,11 @@ import { ChakraProviderSetup } from "@/components/ChakraProviderSetup"; import { getActiveAccountCookie, getJWTCookie } from "@/constants/cookie"; +import { getClientThirdwebClient } from "@/constants/thirdweb-client.client"; +import { serverThirdwebClient } from "@/constants/thirdweb-client.server"; import { ContractPublishForm } from "components/contract-components/contract-publish-form"; import { revalidatePath } from "next/cache"; import { notFound, redirect } from "next/navigation"; import { fetchDeployMetadata } from "thirdweb/contract"; -import { serverThirdwebClient } from "../../../../../../@/constants/thirdweb-client.server"; import { getLatestPublishedContractsWithPublisherMapping } from "../../../published-contract/[publisher]/[contract_id]/utils/getPublishedContractsWithPublisherMapping"; type DirectDeployPageProps = { @@ -71,7 +72,7 @@ export default async function PublishContractPage(
{ "use server"; @@ -82,6 +83,10 @@ export default async function PublishContractPage( "layout", ); }} + client={getClientThirdwebClient({ + jwt: token, + teamId: undefined, + })} />
diff --git a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/[version]/page.tsx b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/[version]/page.tsx index e6d8a246803..a2a4a2f34a7 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/[version]/page.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/[version]/page.tsx @@ -1,5 +1,6 @@ import { ChakraProviderSetup } from "@/components/ChakraProviderSetup"; import { Separator } from "@/components/ui/separator"; +import { getClientThirdwebClient } from "@/constants/thirdweb-client.client"; import { serverThirdwebClient } from "@/constants/thirdweb-client.server"; import { SimpleGrid } from "@chakra-ui/react"; import { fetchPublishedContractVersions } from "components/contract-components/fetch-contracts-with-versions"; @@ -8,8 +9,10 @@ import { notFound } from "next/navigation"; import { isAddress } from "thirdweb"; import { resolveAddress } from "thirdweb/extensions/ens"; import { getRawAccount } from "../../../../../account/settings/getAccount"; +import { getAuthToken } from "../../../../../api/lib/getAuthToken"; import { PublishedActions } from "../../../components/contract-actions-published.client"; import { DeployContractHeader } from "../../../components/contract-header"; + function mapThirdwebPublisher(publisher: string) { if (publisher === "thirdweb.eth") { return "deployer.thirdweb.eth"; @@ -65,7 +68,10 @@ export default async function PublishedContractPage( return notFound(); } - const account = await getRawAccount(); + const [authToken, account] = await Promise.all([ + getAuthToken(), + getRawAccount(), + ]); return ( <> @@ -86,6 +92,10 @@ export default async function PublishedContractPage( diff --git a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/page.tsx b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/page.tsx index c519afc0f45..ebfc62113fc 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/page.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/[publisher]/[contract_id]/page.tsx @@ -1,9 +1,11 @@ import { ChakraProviderSetup } from "@/components/ChakraProviderSetup"; import { Separator } from "@/components/ui/separator"; +import { getClientThirdwebClient } from "@/constants/thirdweb-client.client"; +import { serverThirdwebClient } from "@/constants/thirdweb-client.server"; import { PublishedContract } from "components/contract-components/published-contract"; import { notFound } from "next/navigation"; -import { serverThirdwebClient } from "../../../../../../@/constants/thirdweb-client.server"; import { getRawAccount } from "../../../../account/settings/getAccount"; +import { getAuthToken } from "../../../../api/lib/getAuthToken"; import { PublishedActions } from "../../components/contract-actions-published.client"; import { DeployContractHeader } from "../../components/contract-header"; import { getPublishedContractsWithPublisherMapping } from "./utils/getPublishedContractsWithPublisherMapping"; @@ -36,7 +38,10 @@ export default async function PublishedContractPage( notFound(); } - const account = await getRawAccount(); + const [account, authToken] = await Promise.all([ + getRawAccount(), + getAuthToken(), + ]); return ( <> @@ -57,6 +62,10 @@ export default async function PublishedContractPage(
diff --git a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/uri-based-deploy.tsx b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/uri-based-deploy.tsx index c32f45f9da9..7d230f777f4 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/uri-based-deploy.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/published-contract/components/uri-based-deploy.tsx @@ -1,6 +1,7 @@ import { getProjects } from "@/api/projects"; import { getTeams } from "@/api/team"; import { ChakraProviderSetup } from "@/components/ChakraProviderSetup"; +import { getClientThirdwebClient } from "@/constants/thirdweb-client.client"; import { CustomContractForm } from "components/contract-components/contract-deploy-form/custom-contract"; import type { FetchDeployMetadataResult } from "thirdweb/contract"; import { getAuthToken } from "../../../api/lib/getAuthToken"; @@ -42,6 +43,11 @@ export async function DeployFormForUri(props: DeployFormForUriProps) { })), ); + const client = getClientThirdwebClient({ + jwt: authToken, + teamId: undefined, + }); + // TODO: remove the `ChakraProviderSetup` wrapper once the form is updated to no longer use chakra return ( @@ -49,8 +55,9 @@ export async function DeployFormForUri(props: DeployFormForUriProps) { metadata={contractMetadata} metadataNoFee={contractMetadataNoFee} modules={modules?.filter((m) => m !== null)} - jwt={authToken} + isLoggedIn={!!authToken} teamsAndProjects={teamsAndProjects} + client={client} /> ); diff --git a/apps/dashboard/src/app/(app)/account/components/AccountHeaderUI.tsx b/apps/dashboard/src/app/(app)/account/components/AccountHeaderUI.tsx index ace060deac8..57dd97a3bf1 100644 --- a/apps/dashboard/src/app/(app)/account/components/AccountHeaderUI.tsx +++ b/apps/dashboard/src/app/(app)/account/components/AccountHeaderUI.tsx @@ -131,6 +131,7 @@ export function AccountHeaderMobileUI(props: AccountHeaderCompProps) { { - const address = req.nextUrl.searchParams.get("address"); - const cookieStore = await cookies(); - - if (!address) { - return NextResponse.json( - { - error: "address is required", - }, - { - status: 400, - }, - ); - } - - const authCookieName = COOKIE_PREFIX_TOKEN + getAddress(address); - - // check if we have a token for the address - const token = cookieStore.get(authCookieName)?.value; - - // no auth token found for the address - if (!token) { - return respond(null); - } - - // check token validity - const accountRes = await fetch( - `${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/account/me`, - { - method: "GET", - headers: { - Authorization: `Bearer ${token}`, - }, - }, - ); - - if (accountRes.status !== 200) { - return respond(null); - } - - return respond(token); -}; diff --git a/apps/dashboard/src/app/(app)/components/Header/SecondaryNav/account-button.client.tsx b/apps/dashboard/src/app/(app)/components/Header/SecondaryNav/account-button.client.tsx index 94ae0df085b..b218937263a 100644 --- a/apps/dashboard/src/app/(app)/components/Header/SecondaryNav/account-button.client.tsx +++ b/apps/dashboard/src/app/(app)/components/Header/SecondaryNav/account-button.client.tsx @@ -24,7 +24,10 @@ export function AccountButton(props: { accountAddress: string; }) { const { setTheme, theme } = useTheme(); - const ensQuery = useEns(props.accountAddress); + const ensQuery = useEns({ + addressOrEnsName: props.accountAddress, + client: props.client, + }); const [isOpen, setIsOpen] = useState(false); return ( diff --git a/apps/dashboard/src/app/(app)/components/MobileBurgerMenuButton.tsx b/apps/dashboard/src/app/(app)/components/MobileBurgerMenuButton.tsx index f7584442db0..b38ae4e5d9b 100644 --- a/apps/dashboard/src/app/(app)/components/MobileBurgerMenuButton.tsx +++ b/apps/dashboard/src/app/(app)/components/MobileBurgerMenuButton.tsx @@ -17,6 +17,7 @@ import { import { useTheme } from "next-themes"; import Link from "next/link"; import { useLayoutEffect, useState } from "react"; +import type { ThirdwebClient } from "thirdweb"; import { ThirdwebMiniLogo } from "./ThirdwebMiniLogo"; export function MobileBurgerMenuButton( @@ -27,16 +28,20 @@ export function MobileBurgerMenuButton( logout: () => void; accountAddress: string; connectButton: React.ReactNode; + client: ThirdwebClient; } | { type: "loggedOut"; + client: ThirdwebClient; }, ) { const [isMenuOpen, setIsMenuOpen] = useState(false); const { setTheme, theme } = useTheme(); - const ensQuery = useEns( - props.type === "loggedIn" ? props.accountAddress : undefined, - ); + const ensQuery = useEns({ + client: props.client, + addressOrEnsName: + props.type === "loggedIn" ? props.accountAddress : undefined, + }); // const [isCMDSearchModalOpen, setIsCMDSearchModalOpen] = useState(false); useLayoutEffect(() => { diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/distribution/token-airdrop.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/distribution/token-airdrop.tsx index 437f63e7b70..61b3a0b2239 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/distribution/token-airdrop.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/distribution/token-airdrop.tsx @@ -36,6 +36,7 @@ import { XIcon, } from "lucide-react"; import { useState } from "react"; +import type { ThirdwebClient } from "thirdweb"; import type { TokenDistributionForm } from "../form"; type AirdropAddressInput = { @@ -47,6 +48,7 @@ type AirdropAddressInput = { export function TokenAirdropSection(props: { form: TokenDistributionForm; + client: ThirdwebClient; }) { const airdropAddresses = props.form.watch("airdropAddresses"); const [showUploadSheet, setShowUploadSheet] = useState(false); @@ -158,6 +160,7 @@ export function TokenAirdropSection(props: { { props.form.setValue("airdropAddresses", addresses); setShowUploadSheet(false); @@ -187,6 +190,7 @@ export function TokenAirdropSection(props: { type AirdropUploadProps = { setAirdrop: (airdrop: AirdropAddressInput[]) => void; onClose: () => void; + client: ThirdwebClient; }; // CSV parser for airdrop data @@ -202,6 +206,7 @@ const csvParser = (items: AirdropAddressInput[]): AirdropAddressInput[] => { const AirdropUpload: React.FC = ({ setAirdrop, onClose, + client, }) => { const { normalizeQuery, @@ -211,7 +216,7 @@ const AirdropUpload: React.FC = ({ noCsv, reset, removeInvalid, - } = useCsvUpload({ csvParser }); + } = useCsvUpload({ csvParser, client }); const normalizeData = normalizeQuery.data; diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/distribution/token-distribution.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/distribution/token-distribution.tsx index de9934af527..fe4c442451b 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/distribution/token-distribution.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/distribution/token-distribution.tsx @@ -60,7 +60,7 @@ export function TokenDistributionFieldset(props: { />
- + @@ -53,6 +59,7 @@ export default async function Page(props: { teamSlug={team.slug} projectSlug={project.slug} authToken={authToken} + clientThirdwebClient={client} />
); @@ -64,6 +71,7 @@ function YourFactoriesSection(props: { authToken: string; teamSlug: string; projectSlug: string; + clientThirdwebClient: ThirdwebClient; }) { return (
@@ -104,6 +112,7 @@ function YourFactoriesSection(props: { authToken={props.authToken} teamSlug={props.teamSlug} projectSlug={props.projectSlug} + clientThirdwebClient={props.clientThirdwebClient} />
@@ -116,6 +125,7 @@ async function AsyncYourFactories(props: { authToken: string; teamSlug: string; projectSlug: string; + clientThirdwebClient: ThirdwebClient; }) { const deployedContracts = await getSortedDeployedContracts({ teamId: props.teamId, @@ -151,6 +161,7 @@ async function AsyncYourFactories(props: { teamSlug={props.teamSlug} projectSlug={props.projectSlug} isFetched={true} + client={props.clientThirdwebClient} /> ); diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/settings/page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/settings/page.tsx index 1409ddb349a..d14459ce40d 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/settings/page.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/in-app-wallets/settings/page.tsx @@ -1,8 +1,11 @@ import { getProject } from "@/api/projects"; import { getSMSCountryTiers } from "@/api/sms"; import { getTeamBySlug } from "@/api/team"; +import { getClientThirdwebClient } from "@/constants/thirdweb-client.client"; import { InAppWalletSettingsPage } from "components/embedded-wallets/Configure"; import { redirect } from "next/navigation"; +import { getAuthToken } from "../../../../../../../api/lib/getAuthToken"; +import { loginRedirect } from "../../../../../../../login/loginRedirect"; import { getValidTeamPlan } from "../../../../../../components/TeamHeader/getValidTeamPlan"; export default async function Page(props: { @@ -10,12 +13,17 @@ export default async function Page(props: { }) { const { team_slug, project_slug } = await props.params; - const [team, project, smsCountryTiers] = await Promise.all([ + const [team, project, smsCountryTiers, authToken] = await Promise.all([ getTeamBySlug(team_slug), getProject(team_slug, project_slug), getSMSCountryTiers(), + getAuthToken(), ]); + if (!authToken) { + loginRedirect(`/team/${team_slug}/connect/in-app-wallets/settings`); + } + if (!team) { redirect("/team"); } @@ -24,6 +32,11 @@ export default async function Page(props: { redirect(`/team/${team_slug}`); } + const client = getClientThirdwebClient({ + jwt: authToken, + teamId: team.id, + }); + return ( ); diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/universal-bridge/settings/page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/universal-bridge/settings/page.tsx index 200657b95fc..7c018619616 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/universal-bridge/settings/page.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/universal-bridge/settings/page.tsx @@ -1,10 +1,12 @@ import { getProject } from "@/api/projects"; import { getTeamBySlug } from "@/api/team"; import { getFees } from "@/api/universal-bridge/developer"; +import { getClientThirdwebClient } from "@/constants/thirdweb-client.client"; import { PayConfig } from "components/pay/PayConfig"; import { RouteDiscovery } from "components/pay/RouteDiscovery"; - import { redirect } from "next/navigation"; +import { getAuthToken } from "../../../../../../../api/lib/getAuthToken"; +import { loginRedirect } from "../../../../../../../login/loginRedirect"; export default async function Page(props: { params: Promise<{ @@ -14,11 +16,18 @@ export default async function Page(props: { }) { const { team_slug, project_slug } = await props.params; - const [project, team] = await Promise.all([ + const [project, team, authToken] = await Promise.all([ getProject(team_slug, project_slug), getTeamBySlug(team_slug), + getAuthToken(), ]); + if (!authToken) { + loginRedirect( + `/team/${team_slug}/${project_slug}/connect/universal-bridge/settings`, + ); + } + if (!team) { redirect("/team"); } @@ -48,6 +57,11 @@ export default async function Page(props: { }; } + const client = getClientThirdwebClient({ + jwt: authToken, + teamId: team.id, + }); + return (
- +
); diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/layout.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/layout.tsx index cb7a14f79e9..578a31f7fe6 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/layout.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/layout.tsx @@ -73,6 +73,7 @@ export default async function ContractLayout(props: {
- +
); diff --git a/apps/dashboard/src/app/(app)/team/components/HeaderLoggedOut/HeaderLoggedOut.tsx b/apps/dashboard/src/app/(app)/team/components/HeaderLoggedOut/HeaderLoggedOut.tsx index ff7dd4873ad..7f2ef61d045 100644 --- a/apps/dashboard/src/app/(app)/team/components/HeaderLoggedOut/HeaderLoggedOut.tsx +++ b/apps/dashboard/src/app/(app)/team/components/HeaderLoggedOut/HeaderLoggedOut.tsx @@ -5,12 +5,14 @@ import { Button } from "@/components/ui/button"; import { cn } from "@/lib/utils"; import Link from "next/link"; import { usePathname } from "next/navigation"; +import type { ThirdwebClient } from "thirdweb"; import { SecondaryNavLinks } from "../../../components/Header/SecondaryNav/SecondaryNav"; import { MobileBurgerMenuButton } from "../../../components/MobileBurgerMenuButton"; import { ThirdwebMiniLogo } from "../../../components/ThirdwebMiniLogo"; function HeaderLoggedOutDesktopUI(props: { className?: string; + client: ThirdwebClient; }) { const pathname = usePathname(); return ( @@ -50,6 +52,7 @@ function HeaderLoggedOutDesktopUI(props: { function HeaderLoggedOutMobileUI(props: { className?: string; + client: ThirdwebClient; }) { const pathname = usePathname(); @@ -72,17 +75,20 @@ function HeaderLoggedOutMobileUI(props: { Connect Wallet - + ); } -export function HeaderLoggedOut() { +export function HeaderLoggedOut(props: { client: ThirdwebClient }) { return (
- - + +
); } diff --git a/apps/dashboard/src/app/(app)/team/components/TeamHeader/TeamHeaderUI.tsx b/apps/dashboard/src/app/(app)/team/components/TeamHeader/TeamHeaderUI.tsx index c132292ac9e..97649a1775d 100644 --- a/apps/dashboard/src/app/(app)/team/components/TeamHeader/TeamHeaderUI.tsx +++ b/apps/dashboard/src/app/(app)/team/components/TeamHeader/TeamHeaderUI.tsx @@ -210,6 +210,7 @@ export function TeamHeaderMobileUI(props: TeamHeaderCompProps) { logout={props.logout} connectButton={props.connectButton} accountAddress={props.accountAddress} + client={props.client} /> diff --git a/apps/dashboard/src/app/(app)/team/components/TeamHeader/team-header.tsx b/apps/dashboard/src/app/(app)/team/components/TeamHeader/team-header.tsx index 5122fe2a6fa..d8d61a02a3e 100644 --- a/apps/dashboard/src/app/(app)/team/components/TeamHeader/team-header.tsx +++ b/apps/dashboard/src/app/(app)/team/components/TeamHeader/team-header.tsx @@ -19,8 +19,13 @@ export async function TeamHeader() { getAuthToken(), ]); + const client = getClientThirdwebClient({ + jwt: authToken, + teamId: undefined, + }); + if (!account || !accountAddress || !teams) { - return ; + return ; } const cookiesObj = await cookies(); @@ -38,17 +43,17 @@ export async function TeamHeader() { const selectedTeam = lastUsedTeam || firstTeam; if (!selectedTeam) { - return ; + return ; } - const client = getClientThirdwebClient({ + const lastUsedTeamClient = getClientThirdwebClient({ jwt: authToken, teamId: lastUsedTeam?.id, }); return ( void; onSubmit: (chain: StoredChain) => void; + client: ThirdwebClient; } const maxAllowedChainOverrides = 10; @@ -55,8 +56,8 @@ export const ConfigureNetworkForm: React.FC = ({ onSubmit, prefillSlug, prefillChainId, + client, }) => { - const client = useThirdwebClient(); const { idToChain, nameToChain } = useAllChainsData(); const chainOverrides = useStore(chainOverridesStore); diff --git a/apps/dashboard/src/components/configure-networks/ConfigureNetworkModal.tsx b/apps/dashboard/src/components/configure-networks/ConfigureNetworkModal.tsx index a1c88099055..2f2305fd167 100644 --- a/apps/dashboard/src/components/configure-networks/ConfigureNetworkModal.tsx +++ b/apps/dashboard/src/components/configure-networks/ConfigureNetworkModal.tsx @@ -1,4 +1,5 @@ import { Dialog, DialogContent } from "@/components/ui/dialog"; +import type { ThirdwebClient } from "thirdweb"; import { type StoredChain, addRecentlyUsedChainId, @@ -10,6 +11,7 @@ export type ConfigureNetworkModalProps = { onOpenChange: (open: boolean) => void; onNetworkAdded?: (chain: StoredChain) => void; editChain: StoredChain | undefined; + client: ThirdwebClient; }; export const ConfigureNetworkModal: React.FC = ( @@ -30,6 +32,7 @@ export const ConfigureNetworkModal: React.FC = ( }} onNetworkConfigured={onModalClose} editChain={props.editChain} + client={props.client} /> diff --git a/apps/dashboard/src/components/configure-networks/ConfigureNetworks.tsx b/apps/dashboard/src/components/configure-networks/ConfigureNetworks.tsx index 0084b0accff..ee07b402710 100644 --- a/apps/dashboard/src/components/configure-networks/ConfigureNetworks.tsx +++ b/apps/dashboard/src/components/configure-networks/ConfigureNetworks.tsx @@ -1,5 +1,6 @@ import { useTrack } from "hooks/analytics/useTrack"; import { toast } from "sonner"; +import type { ThirdwebClient } from "thirdweb"; import { type StoredChain, addChainOverrides, @@ -24,6 +25,7 @@ interface ConfigureNetworksProps { prefillSlug?: string; prefillChainId?: string; editChain: StoredChain | undefined; + client: ThirdwebClient; } export const ConfigureNetworks: React.FC = (props) => { @@ -65,6 +67,7 @@ export const ConfigureNetworks: React.FC = (props) => { )} @@ -74,6 +77,7 @@ export const ConfigureNetworks: React.FC = (props) => { prefillSlug={props.prefillSlug} prefillChainId={props.prefillChainId} onSubmit={handleSubmit} + client={props.client} /> )} diff --git a/apps/dashboard/src/components/contract-components/contract-deploy-form/custom-contract.tsx b/apps/dashboard/src/components/contract-components/contract-deploy-form/custom-contract.tsx index 6c027638b24..2009672442d 100644 --- a/apps/dashboard/src/components/contract-components/contract-deploy-form/custom-contract.tsx +++ b/apps/dashboard/src/components/contract-components/contract-deploy-form/custom-contract.tsx @@ -9,7 +9,6 @@ import { Alert, AlertTitle } from "@/components/ui/alert"; import { Button } from "@/components/ui/button"; import { Checkbox, CheckboxWithLabel } from "@/components/ui/checkbox"; import { ToolTipLabel } from "@/components/ui/tooltip"; -import { useThirdwebClient } from "@/constants/thirdweb.client"; import { Flex, FormControl } from "@chakra-ui/react"; import { useMutation, useQuery } from "@tanstack/react-query"; import { verifyContract } from "app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/sources/ContractSourcesPage"; @@ -34,7 +33,7 @@ import { import Link from "next/link"; import { useCallback, useMemo, useState } from "react"; import { FormProvider, type UseFormReturn, useForm } from "react-hook-form"; -import { ZERO_ADDRESS, getContract } from "thirdweb"; +import { type ThirdwebClient, ZERO_ADDRESS, getContract } from "thirdweb"; import type { FetchDeployMetadataResult } from "thirdweb/contract"; import { deployContractfromDeployMetadata, @@ -82,9 +81,10 @@ import { TrustedForwardersFieldset } from "./trusted-forwarders-fieldset"; interface CustomContractFormProps { metadata: FetchDeployMetadataResult; metadataNoFee: FetchDeployMetadataResult | null; - jwt: string; + isLoggedIn: boolean; modules?: FetchDeployMetadataResult[]; teamsAndProjects: MinimalTeamsAndProjects; + client: ThirdwebClient; } type CustomContractDeploymentFormData = { @@ -155,11 +155,10 @@ export const CustomContractForm: React.FC = ({ metadata, metadataNoFee, modules, - jwt, + isLoggedIn, teamsAndProjects, + client, }) => { - const thirdwebClient = useThirdwebClient(jwt); - const [isImportEnabled, setIsImportEnabled] = useState(true); const [importSelection, setImportSelection] = useState<{ @@ -226,6 +225,7 @@ export const CustomContractForm: React.FC = ({ )[0] || ["", ""]; const customFactoryAbi = useCustomFactoryAbi( + client, customFactoryAddress, customFactoryNetwork ? Number(customFactoryNetwork) : undefined, ); @@ -460,7 +460,7 @@ export const CustomContractForm: React.FC = ({ return ( = ({ deployParams, metadata.constructorParams, shouldHide, - thirdwebClient, + client, ], ); @@ -498,7 +498,7 @@ export const CustomContractForm: React.FC = ({ if (hasContractURI && params.contractMetadata) { // upload the contract metadata _contractURI = await upload({ - client: thirdwebClient, + client, files: [params.contractMetadata], }); } @@ -521,7 +521,7 @@ export const CustomContractForm: React.FC = ({ return await deployMarketplaceContract({ account: activeAccount, chain: walletChain, - client: thirdwebClient, + client, params: { name: params.contractMetadata?.name || "", contractURI: _contractURI, @@ -570,7 +570,7 @@ export const CustomContractForm: React.FC = ({ const coreContractAddress = await deployContractfromDeployMetadata({ account: activeAccount, chain: walletChain, - client: thirdwebClient, + client, deployMetadata: isFeeExempt && metadataNoFee ? metadataNoFee : metadata, initializeParams, implementationConstructorParams, @@ -600,7 +600,7 @@ export const CustomContractForm: React.FC = ({ return await getRequiredTransactions({ chain: walletChain, - client: thirdwebClient, + client, deployMetadata: metadata, modules: modules?.map((m) => ({ deployMetadata: m, @@ -626,7 +626,7 @@ export const CustomContractForm: React.FC = ({ id="custom-contract-form" as="form" onSubmit={form.handleSubmit(async (formData) => { - if (!walletChain?.id || !activeAccount || !jwt) { + if (!walletChain?.id || !activeAccount || !isLoggedIn) { return; } @@ -664,7 +664,7 @@ export const CustomContractForm: React.FC = ({ getContract({ address: contractAddr, chain: walletChain, - client: thirdwebClient, + client, }), ); @@ -735,7 +735,7 @@ export const CustomContractForm: React.FC = ({ form.formState, ).error?.message } - client={thirdwebClient} + client={client} /> )} @@ -754,7 +754,7 @@ export const CustomContractForm: React.FC = ({ form.formState, ).error?.message } - client={thirdwebClient} + client={client} /> )} @@ -788,7 +788,7 @@ export const CustomContractForm: React.FC = ({ form.formState, ).error?.message, }} - client={thirdwebClient} + client={client} /> )} @@ -797,17 +797,14 @@ export const CustomContractForm: React.FC = ({ form={form} isMarketplace={isMarketplace} disabled={!isFeeExempt} - client={thirdwebClient} + client={client} /> )} - {isSplit && } + {isSplit && } {hasTrustedForwarders && ( - + )} {/* for StakeERC721 */} @@ -830,7 +827,7 @@ export const CustomContractForm: React.FC = ({ deployParam={deployParam} extraMetadataParam={extraMetadataParam} isRequired - client={thirdwebClient} + client={client} /> ); })} @@ -858,7 +855,7 @@ export const CustomContractForm: React.FC = ({ deployParam={deployParam} extraMetadataParam={extraMetadataParam} isRequired - client={thirdwebClient} + client={client} /> ); })} @@ -901,7 +898,7 @@ export const CustomContractForm: React.FC = ({ extraMetadataParam={extraMetadataParam} inputClassName="bg-card" isRequired - client={thirdwebClient} + client={client} /> ); })} @@ -911,7 +908,7 @@ export const CustomContractForm: React.FC = ({ form={form} modules={modules} isTWPublisher={isTWPublisher} - client={thirdwebClient} + client={client} /> )} @@ -935,7 +932,7 @@ export const CustomContractForm: React.FC = ({ )} = ({
= ({
diff --git a/apps/dashboard/src/components/contract-components/contract-publish-form/contract-params-fieldset.tsx b/apps/dashboard/src/components/contract-components/contract-publish-form/contract-params-fieldset.tsx index 4d9d78294a4..7cd335610aa 100644 --- a/apps/dashboard/src/components/contract-components/contract-publish-form/contract-params-fieldset.tsx +++ b/apps/dashboard/src/components/contract-components/contract-publish-form/contract-params-fieldset.tsx @@ -236,9 +236,9 @@ export const ContractParamsFieldset: React.FC = ({ /> ) : param.type === "address" || param.type === "address[]" ? ( - + ) : ( - + )} {/* Checkboxes */} diff --git a/apps/dashboard/src/components/contract-components/contract-publish-form/custom-factory.tsx b/apps/dashboard/src/components/contract-components/contract-publish-form/custom-factory.tsx index cb77bad7047..e27872d08d5 100644 --- a/apps/dashboard/src/components/contract-components/contract-publish-form/custom-factory.tsx +++ b/apps/dashboard/src/components/contract-components/contract-publish-form/custom-factory.tsx @@ -29,6 +29,7 @@ export const CustomFactory: React.FC = ({ const form = useFormContext(); const customFactoryAbi = useCustomFactoryAbi( + client, form.watch("customFactoryAddresses[0].value"), form.watch("customFactoryAddresses[0].key"), ); diff --git a/apps/dashboard/src/components/contract-components/contract-publish-form/decoded-bytes-input/decoded-input-array-fieldset.tsx b/apps/dashboard/src/components/contract-components/contract-publish-form/decoded-bytes-input/decoded-input-array-fieldset.tsx index 83bfaaa5456..61ab045d43d 100644 --- a/apps/dashboard/src/components/contract-components/contract-publish-form/decoded-bytes-input/decoded-input-array-fieldset.tsx +++ b/apps/dashboard/src/components/contract-components/contract-publish-form/decoded-bytes-input/decoded-input-array-fieldset.tsx @@ -10,15 +10,17 @@ import { cn } from "@/lib/utils"; import type { AbiParameter } from "abitype"; import { PlusIcon, TrashIcon } from "lucide-react"; import { useFieldArray, useFormContext } from "react-hook-form"; +import type { ThirdwebClient } from "thirdweb"; import { DecodedInputSet } from "./decoded-input-set"; interface DecodedInputArrayFieldsetProps { param: AbiParameter; + client: ThirdwebClient; } export const DecodedInputArrayFieldset: React.FC< DecodedInputArrayFieldsetProps -> = ({ param }) => { +> = ({ param, client }) => { const form = useFormContext(); const { fields, append, remove } = useFieldArray({ @@ -56,7 +58,11 @@ export const DecodedInputArrayFieldset: React.FC<
- +
diff --git a/apps/dashboard/src/components/contract-components/contract-publish-form/decoded-bytes-input/decoded-input-set.tsx b/apps/dashboard/src/components/contract-components/contract-publish-form/decoded-bytes-input/decoded-input-set.tsx index 1472b67856f..434974329d8 100644 --- a/apps/dashboard/src/components/contract-components/contract-publish-form/decoded-bytes-input/decoded-input-set.tsx +++ b/apps/dashboard/src/components/contract-components/contract-publish-form/decoded-bytes-input/decoded-input-set.tsx @@ -9,16 +9,19 @@ import { ToolTipLabel } from "@/components/ui/tooltip"; import type { AbiParameter } from "abitype"; import { PlusIcon, TrashIcon } from "lucide-react"; import { useFieldArray, useFormContext } from "react-hook-form"; +import type { ThirdwebClient } from "thirdweb"; import { DecodedInput } from "./decoded-input"; interface DecodedInputSetProps { param: AbiParameter; setIndex: number; + client: ThirdwebClient; } export const DecodedInputSet: React.FC = ({ param, setIndex, + client, }) => { const form = useFormContext(); @@ -62,6 +65,7 @@ export const DecodedInputSet: React.FC = ({ paramIndex={index} setIndex={setIndex} param={param} + client={client} /> diff --git a/apps/dashboard/src/components/contract-components/contract-publish-form/decoded-bytes-input/decoded-input.tsx b/apps/dashboard/src/components/contract-components/contract-publish-form/decoded-bytes-input/decoded-input.tsx index fd2d67f4e65..eb74bc1ea65 100644 --- a/apps/dashboard/src/components/contract-components/contract-publish-form/decoded-bytes-input/decoded-input.tsx +++ b/apps/dashboard/src/components/contract-components/contract-publish-form/decoded-bytes-input/decoded-input.tsx @@ -11,6 +11,7 @@ import { Switch } from "@/components/ui/switch"; import type { AbiParameter } from "abitype"; import { useState } from "react"; import { useFormContext } from "react-hook-form"; +import type { ThirdwebClient } from "thirdweb"; import { RefBytesInputFieldset } from "./ref-bytes-input-fieldset"; interface DecodedInputProps { @@ -18,6 +19,7 @@ interface DecodedInputProps { paramIndex: number; setIndex: number; className?: string; + client: ThirdwebClient; } export const DecodedInput: React.FC = ({ @@ -25,6 +27,7 @@ export const DecodedInput: React.FC = ({ paramIndex, setIndex, className, + client, }) => { const form = useFormContext(); const [isCustomAddress, setIsCustomAddress] = useState(false); @@ -111,6 +114,7 @@ export const DecodedInput: React.FC = ({ param={param} setIndex={setIndex} paramIndex={paramIndex} + client={client} /> ) : ( = ({ param, setIndex, paramIndex, + client, }) => { const form = useFormContext(); @@ -33,6 +36,7 @@ export const RefBytesInputFieldset: React.FC = ({ paramIndex={paramIndex} setIndex={setIndex} className="border-border border-b pb-6" + client={client} /> ))} diff --git a/apps/dashboard/src/components/contract-components/contract-publish-form/decoded-bytes-input/ref-bytes-input.tsx b/apps/dashboard/src/components/contract-components/contract-publish-form/decoded-bytes-input/ref-bytes-input.tsx index cc7ef249670..12c3bae0ebe 100644 --- a/apps/dashboard/src/components/contract-components/contract-publish-form/decoded-bytes-input/ref-bytes-input.tsx +++ b/apps/dashboard/src/components/contract-components/contract-publish-form/decoded-bytes-input/ref-bytes-input.tsx @@ -13,6 +13,7 @@ import { cn } from "@/lib/utils"; import type { AbiParameter } from "abitype"; import { TrashIcon } from "lucide-react"; import { useFormContext } from "react-hook-form"; +import type { ThirdwebClient } from "thirdweb"; import { useAllVersions, usePublishedContractsQuery } from "../../hooks"; interface RefBytesContractInputProps { @@ -22,6 +23,7 @@ interface RefBytesContractInputProps { setIndex: number; remove: (index: number) => void; className?: string; + client: ThirdwebClient; } export const RefBytesContractInput: React.FC = ({ @@ -31,14 +33,16 @@ export const RefBytesContractInput: React.FC = ({ setIndex, remove, className, + client, }) => { const form = useFormContext(); - const publishedContractsQuery = usePublishedContractsQuery( - form.watch( + const publishedContractsQuery = usePublishedContractsQuery({ + client, + address: form.watch( `constructorParams.${param.name ? param.name : "*"}.dynamicValue.paramsToEncode.${setIndex}.${paramIndex}.dynamicValue.refContracts.${index}.publisherAddress`, ), - ); + }); const allVersions = useAllVersions( form.watch( @@ -47,6 +51,7 @@ export const RefBytesContractInput: React.FC = ({ form.watch( `constructorParams.${param.name ? param.name : "*"}.dynamicValue.paramsToEncode.${setIndex}.${paramIndex}.dynamicValue.refContracts.${index}.contractId`, ), + client, ); return ( diff --git a/apps/dashboard/src/components/contract-components/contract-publish-form/impl-params-fieldset.tsx b/apps/dashboard/src/components/contract-components/contract-publish-form/impl-params-fieldset.tsx index 8cafae8a64d..49f7ac51c0c 100644 --- a/apps/dashboard/src/components/contract-components/contract-publish-form/impl-params-fieldset.tsx +++ b/apps/dashboard/src/components/contract-components/contract-publish-form/impl-params-fieldset.tsx @@ -139,7 +139,7 @@ export const ImplementationParamsFieldset: React.FC< /> ) : ( - + )} {paramTemplateValues.length > 0 && diff --git a/apps/dashboard/src/components/contract-components/contract-publish-form/index.tsx b/apps/dashboard/src/components/contract-components/contract-publish-form/index.tsx index db10baf1298..1e15201bc2b 100644 --- a/apps/dashboard/src/components/contract-components/contract-publish-form/index.tsx +++ b/apps/dashboard/src/components/contract-components/contract-publish-form/index.tsx @@ -13,6 +13,7 @@ import { useTxNotifications } from "hooks/useTxNotifications"; import { ChevronFirstIcon } from "lucide-react"; import { useMemo, useState } from "react"; import { FormProvider, useForm } from "react-hook-form"; +import type { ThirdwebClient } from "thirdweb"; import type { FetchDeployMetadataResult } from "thirdweb/contract"; import { getContractPublisher, @@ -20,7 +21,6 @@ import { } from "thirdweb/extensions/thirdweb"; import { useActiveAccount, useSendAndConfirmTransaction } from "thirdweb/react"; import { Button, Text } from "tw-components"; -import { useThirdwebClient } from "../../../@/constants/thirdweb.client"; import { useEns, useFunctionParamsFromABI } from "../hooks"; import { ContractParamsFieldset } from "./contract-params-fieldset"; import { FactoryFieldset } from "./factory-fieldset"; @@ -31,9 +31,9 @@ import { NetworksFieldset } from "./networks-fieldset"; export function ContractPublishForm(props: { publishMetadata: FetchDeployMetadataResult; onPublishSuccess: () => Promise; - jwt: string; + isLoggedIn: boolean; + client: ThirdwebClient; }) { - const client = useThirdwebClient(props.jwt); const [customFactoryAbi, setCustomFactoryAbi] = useState([]); const [fieldsetToShow, setFieldsetToShow] = useState< "landing" | "factory" | "contractParams" | "implParams" | "networks" @@ -130,7 +130,10 @@ export function ContractPublishForm(props: { !form.watch("displayName") || !!form.getFieldState("version", form.formState).error; - const ensQuery = useEns(account?.address); + const ensQuery = useEns({ + client: props.client, + addressOrEnsName: account?.address, + }); const ensNameOrAddress = useMemo(() => { return ensQuery?.data?.ensName || ensQuery.data?.address; @@ -260,7 +263,7 @@ export function ContractPublishForm(props: { const tx = publishContract({ account, - contract: getContractPublisher(client), + contract: getContractPublisher(props.client), metadata, previousMetadata: props.publishMetadata, }); @@ -328,20 +331,21 @@ export function ContractPublishForm(props: { )} {fieldsetToShow === "contractParams" && ( )} {fieldsetToShow === "implParams" && implDeployParams?.length > 0 && ( )} @@ -350,14 +354,14 @@ export function ContractPublishForm(props: { )} {fieldsetToShow === "networks" && ( - + )} @@ -373,8 +377,8 @@ export function ContractPublishForm(props: { <> ) : fieldsetToShow === "landing" && diff --git a/apps/dashboard/src/components/contract-components/contract-publish-form/landing-fieldset.tsx b/apps/dashboard/src/components/contract-components/contract-publish-form/landing-fieldset.tsx index d3161eaef2a..80ebdc25c01 100644 --- a/apps/dashboard/src/components/contract-components/contract-publish-form/landing-fieldset.tsx +++ b/apps/dashboard/src/components/contract-components/contract-publish-form/landing-fieldset.tsx @@ -18,6 +18,7 @@ import { SelectOption } from "core-ui/batch-upload/lazy-mint-form/select-option" import { useImageFileOrUrl } from "hooks/useImageFileOrUrl"; import { replaceIpfsUrl } from "lib/sdk"; import { useFormContext } from "react-hook-form"; +import type { ThirdwebClient } from "thirdweb"; import type { ExtendedMetadata } from "thirdweb/utils"; import { Card, @@ -28,20 +29,20 @@ import { Link, Text, } from "tw-components"; -import { useThirdwebClient } from "../../../@/constants/thirdweb.client"; import { MarkdownRenderer } from "../published-contract/markdown-renderer"; import { ExternalLinksFieldset } from "./external-links-fieldset"; interface LandingFieldsetProps { latestVersion: string | undefined; placeholderVersion: string; + client: ThirdwebClient; } export const LandingFieldset: React.FC = ({ latestVersion, placeholderVersion, + client, }) => { - const client = useThirdwebClient(); const form = useFormContext(); const logoUrl = useImageFileOrUrl(form.watch("logo")); diff --git a/apps/dashboard/src/components/contract-components/contract-publish-form/ref-contract-impl-input/ref-input-impl-fieldset.tsx b/apps/dashboard/src/components/contract-components/contract-publish-form/ref-contract-impl-input/ref-input-impl-fieldset.tsx index 717f0bdb275..f8b878e1311 100644 --- a/apps/dashboard/src/components/contract-components/contract-publish-form/ref-contract-impl-input/ref-input-impl-fieldset.tsx +++ b/apps/dashboard/src/components/contract-components/contract-publish-form/ref-contract-impl-input/ref-input-impl-fieldset.tsx @@ -2,15 +2,18 @@ import { cn } from "@/lib/utils"; import type { AbiParameter } from "abitype"; import { PlusIcon } from "lucide-react"; import { useFieldArray, useFormContext } from "react-hook-form"; +import type { ThirdwebClient } from "thirdweb"; import { Button } from "tw-components"; import { RefContractImplInput } from "./ref-input-impl"; interface RefInputImplFieldsetProps { param: AbiParameter; + client: ThirdwebClient; } export const RefInputImplFieldset: React.FC = ({ param, + client, }) => { const form = useFormContext(); @@ -30,6 +33,7 @@ export const RefInputImplFieldset: React.FC = ({ index={index} param={param} className={cn(!hideAddButton && "border-border border-b pb-5")} + client={client} /> ))} diff --git a/apps/dashboard/src/components/contract-components/contract-publish-form/ref-contract-impl-input/ref-input-impl.tsx b/apps/dashboard/src/components/contract-components/contract-publish-form/ref-contract-impl-input/ref-input-impl.tsx index a7e26c213b7..65c328c27a6 100644 --- a/apps/dashboard/src/components/contract-components/contract-publish-form/ref-contract-impl-input/ref-input-impl.tsx +++ b/apps/dashboard/src/components/contract-components/contract-publish-form/ref-contract-impl-input/ref-input-impl.tsx @@ -13,6 +13,7 @@ import { cn } from "@/lib/utils"; import type { AbiParameter } from "abitype"; import { TrashIcon } from "lucide-react"; import { useFormContext } from "react-hook-form"; +import type { ThirdwebClient } from "thirdweb"; import { useAllVersions, usePublishedContractsQuery } from "../../hooks"; interface RefContractImplInputProps { @@ -20,21 +21,24 @@ interface RefContractImplInputProps { index: number; remove: (index: number) => void; className?: string; + client: ThirdwebClient; } export const RefContractImplInput: React.FC = ({ param, index, remove, + client, className, }) => { const form = useFormContext(); - const publishedContractsQuery = usePublishedContractsQuery( - form.watch( + const publishedContractsQuery = usePublishedContractsQuery({ + client, + address: form.watch( `implConstructorParams.${param.name ? param.name : "*"}.dynamicValue.refContracts.${index}.publisherAddress`, ), - ); + }); const allVersions = useAllVersions( form.watch( @@ -43,6 +47,7 @@ export const RefContractImplInput: React.FC = ({ form.watch( `implConstructorParams.${param.name ? param.name : "*"}.dynamicValue.refContracts.${index}.contractId`, ), + client, ); return ( diff --git a/apps/dashboard/src/components/contract-components/contract-publish-form/ref-contract-input/ref-input-fieldset.tsx b/apps/dashboard/src/components/contract-components/contract-publish-form/ref-contract-input/ref-input-fieldset.tsx index b6cd4e2539c..56ba6d63460 100644 --- a/apps/dashboard/src/components/contract-components/contract-publish-form/ref-contract-input/ref-input-fieldset.tsx +++ b/apps/dashboard/src/components/contract-components/contract-publish-form/ref-contract-input/ref-input-fieldset.tsx @@ -3,14 +3,17 @@ import { cn } from "@/lib/utils"; import type { AbiParameter } from "abitype"; import { PlusIcon } from "lucide-react"; import { useFieldArray, useFormContext } from "react-hook-form"; +import type { ThirdwebClient } from "thirdweb"; import { RefContractInput } from "./ref-input"; interface RefInputFieldsetProps { param: AbiParameter; + client: ThirdwebClient; } export const RefInputFieldset: React.FC = ({ param, + client, }) => { const form = useFormContext(); @@ -29,6 +32,7 @@ export const RefInputFieldset: React.FC = ({ index={index} param={param} className={cn(!hideAddButton && "border-border border-b pb-5")} + client={client} /> ))} diff --git a/apps/dashboard/src/components/contract-components/contract-publish-form/ref-contract-input/ref-input.tsx b/apps/dashboard/src/components/contract-components/contract-publish-form/ref-contract-input/ref-input.tsx index 548d6521651..d5a593e7a94 100644 --- a/apps/dashboard/src/components/contract-components/contract-publish-form/ref-contract-input/ref-input.tsx +++ b/apps/dashboard/src/components/contract-components/contract-publish-form/ref-contract-input/ref-input.tsx @@ -13,6 +13,7 @@ import { cn } from "@/lib/utils"; import type { AbiParameter } from "abitype"; import { TrashIcon } from "lucide-react"; import { useFormContext } from "react-hook-form"; +import type { ThirdwebClient } from "thirdweb"; import { useAllVersions, usePublishedContractsQuery } from "../../hooks"; interface RefContractInputProps { @@ -20,6 +21,7 @@ interface RefContractInputProps { index: number; remove: (index: number) => void; className?: string; + client: ThirdwebClient; } export const RefContractInput: React.FC = ({ @@ -27,14 +29,16 @@ export const RefContractInput: React.FC = ({ index, remove, className, + client, }) => { const form = useFormContext(); - const publishedContractsQuery = usePublishedContractsQuery( - form.watch( + const publishedContractsQuery = usePublishedContractsQuery({ + client, + address: form.watch( `constructorParams.${param.name ? param.name : "*"}.dynamicValue.refContracts.${index}.publisherAddress`, ), - ); + }); const allVersions = useAllVersions( form.watch( @@ -43,6 +47,7 @@ export const RefContractInput: React.FC = ({ form.watch( `constructorParams.${param.name ? param.name : "*"}.dynamicValue.refContracts.${index}.contractId`, ), + client, ); return ( diff --git a/apps/dashboard/src/components/contract-components/fetchPublishedContractsFromDeploy.ts b/apps/dashboard/src/components/contract-components/fetchPublishedContractsFromDeploy.ts index 1814da9fd7c..df526b13ee4 100644 --- a/apps/dashboard/src/components/contract-components/fetchPublishedContractsFromDeploy.ts +++ b/apps/dashboard/src/components/contract-components/fetchPublishedContractsFromDeploy.ts @@ -1,5 +1,5 @@ import { THIRDWEB_DEPLOYER_ADDRESS } from "constants/addresses"; -import type { ThirdwebClient, ThirdwebContract } from "thirdweb"; +import type { ThirdwebContract } from "thirdweb"; import { fetchPublishedContract } from "thirdweb/contract"; import { getContractPublisher, @@ -19,9 +19,8 @@ type ZkSolcMetadata = { export async function fetchPublishedContractsFromDeploy(options: { contract: ThirdwebContract; - client: ThirdwebClient; }) { - const { contract, client } = options; + const { contract } = options; const { bytecode } = await resolveImplementation(contract); const contractUri = extractIPFSUri(bytecode); if (!contractUri) { @@ -29,7 +28,7 @@ export async function fetchPublishedContractsFromDeploy(options: { } let publishURIs = await getPublishedUriFromCompilerUri({ - contract: getContractPublisher(client), + contract: getContractPublisher(contract.client), compilerMetadataUri: contractUri, }); @@ -39,7 +38,7 @@ export async function fetchPublishedContractsFromDeploy(options: { try { const res = await download({ uri: contractUri, - client, + client: contract.client, }); const deployMetadata = (await res.json()) as ZkSolcMetadata; @@ -50,7 +49,7 @@ export async function fetchPublishedContractsFromDeploy(options: { if (contractId[0]) { const published = await fetchPublishedContract({ - client, + client: contract.client, contractId: contractId[0], publisherAddress: THIRDWEB_DEPLOYER_ADDRESS, }); @@ -60,6 +59,6 @@ export async function fetchPublishedContractsFromDeploy(options: { } return await Promise.all( - publishURIs.map((uri) => fetchDeployMetadata(uri, client)), + publishURIs.map((uri) => fetchDeployMetadata(uri, contract.client)), ); } diff --git a/apps/dashboard/src/components/contract-components/hooks.ts b/apps/dashboard/src/components/contract-components/hooks.ts index 33f808bee20..12121e63353 100644 --- a/apps/dashboard/src/components/contract-components/hooks.ts +++ b/apps/dashboard/src/components/contract-components/hooks.ts @@ -1,6 +1,5 @@ "use client"; -import { useThirdwebClient } from "@/constants/thirdweb.client"; import { queryOptions, useQuery } from "@tanstack/react-query"; import type { Abi } from "abitype"; import { resolveEns } from "lib/ens"; @@ -19,8 +18,8 @@ import { fetchPublishedContractsFromDeploy } from "./fetchPublishedContractsFrom export function useAllVersions( publisherAddress: string | undefined, contractId: string | undefined, + client: ThirdwebClient, ) { - const client = useThirdwebClient(); return useQuery({ queryKey: ["all-releases", publisherAddress, contractId], queryFn: () => { @@ -40,7 +39,6 @@ export function useAllVersions( } export function usePublishedContractsFromDeploy(contract: ThirdwebContract) { - const client = useThirdwebClient(); return useQuery({ queryKey: [ "published-contracts-from-deploy", @@ -50,7 +48,6 @@ export function usePublishedContractsFromDeploy(contract: ThirdwebContract) { queryFn: () => fetchPublishedContractsFromDeploy({ contract, - client, }), enabled: !!contract, retry: false, @@ -108,8 +105,11 @@ export type PublishedContractDetails = Awaited< ReturnType >[number]; -export function usePublishedContractsQuery(address?: string) { - const client = useThirdwebClient(); +export function usePublishedContractsQuery(params: { + client: ThirdwebClient; + address?: string; +}) { + const { client, address } = params; return useQuery({ queryKey: ["published-contracts", address], queryFn: () => fetchPublishedContracts({ address, client }), @@ -176,8 +176,11 @@ function ensQuery(params: { }); } -export function useEns(addressOrEnsName?: string) { - const client = useThirdwebClient(); +export function useEns(params: { + client: ThirdwebClient; + addressOrEnsName?: string; +}) { + const { client, addressOrEnsName } = params; return useQuery(ensQuery({ addressOrEnsName, client })); } @@ -186,11 +189,11 @@ export function useContractEvents(abi: Abi) { } export function useCustomFactoryAbi( + client: ThirdwebClient, contractAddress: string, chainId: number | undefined, ) { const chain = useV5DashboardChain(chainId); - const client = useThirdwebClient(); return useQuery({ queryKey: ["custom-factory-abi", { contractAddress, chainId }], diff --git a/apps/dashboard/src/components/contract-components/published-contract/index.tsx b/apps/dashboard/src/components/contract-components/published-contract/index.tsx index a4d328bc261..c0166e30c44 100644 --- a/apps/dashboard/src/components/contract-components/published-contract/index.tsx +++ b/apps/dashboard/src/components/contract-components/published-contract/index.tsx @@ -1,6 +1,5 @@ "use client"; -import { useThirdwebClient } from "@/constants/thirdweb.client"; import { Divider, Flex, GridItem, List, ListItem } from "@chakra-ui/react"; import { useQuery } from "@tanstack/react-query"; import { ContractFunctionsOverview } from "components/contract-functions/contract-functions"; @@ -46,14 +45,15 @@ interface ExtendedPublishedContract extends PublishedContractWithVersion { interface PublishedContractProps { publishedContract: ExtendedPublishedContract; isLoggedIn: boolean; + client: ThirdwebClient; } export const PublishedContract: React.FC = ({ publishedContract, isLoggedIn, + client, }) => { const address = useActiveAccount()?.address; - const client = useThirdwebClient(); const contractFunctions = usePublishedContractFunctions(publishedContract); const contractEvents = usePublishedContractEvents(publishedContract); @@ -157,7 +157,10 @@ export const PublishedContract: React.FC = ({ {publishedContract.publisher && ( - + )} diff --git a/apps/dashboard/src/components/contract-components/publisher/publisher-header.tsx b/apps/dashboard/src/components/contract-components/publisher/publisher-header.tsx index a05460d7416..442e3a9982d 100644 --- a/apps/dashboard/src/components/contract-components/publisher/publisher-header.tsx +++ b/apps/dashboard/src/components/contract-components/publisher/publisher-header.tsx @@ -2,11 +2,10 @@ import { Button } from "@/components/ui/button"; import { Skeleton } from "@/components/ui/skeleton"; -import { useThirdwebClient } from "@/constants/thirdweb.client"; import { useTrack } from "hooks/analytics/useTrack"; import { replaceDeployerAddress } from "lib/publisher-utils"; import Link from "next/link"; -import { ZERO_ADDRESS } from "thirdweb"; +import { type ThirdwebClient, ZERO_ADDRESS } from "thirdweb"; import { AccountAddress, AccountAvatar, @@ -21,10 +20,16 @@ const TRACKING_CATEGORY = "releaser-header"; interface PublisherHeaderProps { wallet: string; + client: ThirdwebClient; } -export const PublisherHeader: React.FC = ({ wallet }) => { - const ensQuery = useEns(wallet); - const client = useThirdwebClient(); +export const PublisherHeader: React.FC = ({ + wallet, + client, +}) => { + const ensQuery = useEns({ + client, + addressOrEnsName: wallet, + }); const trackEvent = useTrack(); return ( diff --git a/apps/dashboard/src/components/contract-components/tables/cells.tsx b/apps/dashboard/src/components/contract-components/tables/cells.tsx index 98305d8509c..62f2803f048 100644 --- a/apps/dashboard/src/components/contract-components/tables/cells.tsx +++ b/apps/dashboard/src/components/contract-components/tables/cells.tsx @@ -2,14 +2,13 @@ import { Badge } from "@/components/ui/badge"; import { SkeletonContainer } from "@/components/ui/skeleton"; -import { useThirdwebClient } from "@/constants/thirdweb.client"; import { cn } from "@/lib/utils"; import { useDashboardContractMetadata } from "@3rdweb-sdk/react/hooks/useDashboardContractMetadata"; import { useChainSlug } from "hooks/chains/chainSlug"; import { useV5DashboardChain } from "lib/v5-adapter"; import Link from "next/link"; import { memo } from "react"; -import { getContract } from "thirdweb"; +import { type ThirdwebClient, getContract } from "thirdweb"; import { shortenIfAddress } from "utils/usedapp-external"; import { THIRDWEB_DEPLOYER_ADDRESS } from "../../../constants/addresses"; import { usePublishedContractsFromDeploy } from "../hooks"; @@ -20,13 +19,13 @@ export const ContractNameCell = memo(function ContractNameCell(props: { linkOverlay?: boolean; teamSlug: string; projectSlug: string; + client: ThirdwebClient; }) { const chainSlug = useChainSlug(Number(props.chainId)); const chain = useV5DashboardChain(Number(props.chainId)); - const client = useThirdwebClient(); const contract = getContract({ - client, + client: props.client, address: props.contractAddress, chain, }); @@ -60,11 +59,11 @@ export const ContractNameCell = memo(function ContractNameCell(props: { export const ContractTypeCell = memo(function ContractTypeCell(props: { chainId: string; contractAddress: string; + client: ThirdwebClient; }) { - const client = useThirdwebClient(); const chain = useV5DashboardChain(Number(props.chainId)); const contract = getContract({ - client, + client: props.client, address: props.contractAddress, chain, }); diff --git a/apps/dashboard/src/components/contract-components/tables/contract-table.tsx b/apps/dashboard/src/components/contract-components/tables/contract-table.tsx index 5354efba474..5449aa5ac6a 100644 --- a/apps/dashboard/src/components/contract-components/tables/contract-table.tsx +++ b/apps/dashboard/src/components/contract-components/tables/contract-table.tsx @@ -161,6 +161,7 @@ export function ContractTableUI(props: { )} {props.variant === "asset" && Asset Page} + Actions @@ -180,6 +181,7 @@ export function ContractTableUI(props: { linkOverlay teamSlug={props.teamSlug} projectSlug={props.projectSlug} + client={props.client} /> @@ -187,6 +189,7 @@ export function ContractTableUI(props: { diff --git a/apps/dashboard/src/components/contract-pages/table/table-columns/cells/media-cell.tsx b/apps/dashboard/src/components/contract-pages/table/table-columns/cells/media-cell.tsx index aa5f36f3ed9..2216dd06694 100644 --- a/apps/dashboard/src/components/contract-pages/table/table-columns/cells/media-cell.tsx +++ b/apps/dashboard/src/components/contract-pages/table/table-columns/cells/media-cell.tsx @@ -1,3 +1,4 @@ +import type { ThirdwebClient } from "thirdweb"; import type { NFTMetadata } from "thirdweb/utils"; import { NFTMediaWithEmptyState } from "tw-components/nft-media"; @@ -5,13 +6,15 @@ interface MediaCellProps { cell: { value: NFTMetadata; }; + client: ThirdwebClient; } -export const MediaCell: React.FC = ({ cell }) => { +export const MediaCell: React.FC = ({ cell, client }) => { const nftMetadata = cell.value; return ( ); }; @@ -169,6 +171,7 @@ export const InAppWalletSettingsUI: React.FC< ) => void; isUpdating: boolean; embeddedWalletService: ProjectEmbeddedWalletsService; + client: ThirdwebClient; } > = (props) => { const services = props.project.services; @@ -275,6 +278,7 @@ export const InAppWalletSettingsUI: React.FC< @@ -326,6 +330,7 @@ function BrandingFieldset(props: { teamPlan: Team["billingPlan"]; teamSlug: string; requiredPlan: Team["billingPlan"]; + client: ThirdwebClient; }) { return (
@@ -376,6 +381,7 @@ function BrandingFieldset(props: { { props.form.setValue("branding.applicationImageUrl", uri, { @@ -417,18 +423,18 @@ function BrandingFieldset(props: { function AppImageFormControl(props: { uri: string | undefined; setUri: (uri: string) => void; + client: ThirdwebClient; }) { - const client = useThirdwebClient(); const [image, setImage] = useState(); const resolveUrl = resolveSchemeWithErrorHandler({ - client: client, + client: props.client, uri: props.uri || undefined, }); const uploadImage = useMutation({ mutationFn: async (file: File) => { const uri = await upload({ - client: client, + client: props.client, files: [file], }); diff --git a/apps/dashboard/src/components/explore/contract-card/index.tsx b/apps/dashboard/src/components/explore/contract-card/index.tsx index 50dd3a1f2ba..52283bd04be 100644 --- a/apps/dashboard/src/components/explore/contract-card/index.tsx +++ b/apps/dashboard/src/components/explore/contract-card/index.tsx @@ -2,6 +2,7 @@ import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Skeleton } from "@/components/ui/skeleton"; import { TrackedLinkTW } from "@/components/ui/tracked-link"; +import { getClientThirdwebClient } from "@/constants/thirdweb-client.client"; import { serverThirdwebClient } from "@/constants/thirdweb-client.server"; import { resolveSchemeWithErrorHandler } from "@/lib/resolveSchemeWithErrorHandler"; import { cn } from "@/lib/utils"; @@ -202,6 +203,7 @@ export async function ContractCard({ }> )} diff --git a/apps/dashboard/src/components/explore/publisher/index.tsx b/apps/dashboard/src/components/explore/publisher/index.tsx index f486a18e2b1..dc5ea1c02cd 100644 --- a/apps/dashboard/src/components/explore/publisher/index.tsx +++ b/apps/dashboard/src/components/explore/publisher/index.tsx @@ -1,9 +1,9 @@ "use client"; import { Skeleton } from "@/components/ui/skeleton"; -import { useThirdwebClient } from "@/constants/thirdweb.client"; import { replaceDeployerAddress } from "lib/publisher-utils"; import Link from "next/link"; +import type { ThirdwebClient } from "thirdweb"; import { AccountAddress, AccountAvatar, @@ -15,12 +15,13 @@ import { shortenIfAddress } from "utils/usedapp-external"; interface ContractPublisherProps { addressOrEns: string; + client: ThirdwebClient; } export const ContractPublisher: React.FC = ({ addressOrEns, + client, }) => { - const client = useThirdwebClient(); return ( { +export const RouteDiscovery = ({ + project, + client, +}: { + project: ProjectResponse; + client: ThirdwebClient; +}) => { const form = useForm({ resolver: zodResolver(routeDiscoveryValidationSchema), defaultValues: { @@ -133,6 +140,7 @@ export const RouteDiscovery = ({ project }: { project: ProjectResponse }) => { Blockchain { // Update the form field value field.onChange(chain.chainId); diff --git a/apps/dashboard/src/components/selects/NetworkSelectorButton.tsx b/apps/dashboard/src/components/selects/NetworkSelectorButton.tsx index d6f93cf1b0d..6f311afb10d 100644 --- a/apps/dashboard/src/components/selects/NetworkSelectorButton.tsx +++ b/apps/dashboard/src/components/selects/NetworkSelectorButton.tsx @@ -1,7 +1,6 @@ "use client"; import { Button } from "@/components/ui/button"; -import { useThirdwebClient } from "@/constants/thirdweb.client"; import { useStore } from "@/lib/reactive"; import { cn } from "@/lib/utils"; import { popularChains } from "@3rdweb-sdk/react/components/popularChains"; @@ -10,6 +9,7 @@ import { useActiveChainAsDashboardChain } from "lib/v5-adapter"; import { ChevronDownIcon } from "lucide-react"; import { useTheme } from "next-themes"; import { useEffect, useMemo, useRef, useState } from "react"; +import type { ThirdwebClient } from "thirdweb"; import { useActiveWallet } from "thirdweb/react"; import { useNetworkSwitcherModal } from "thirdweb/react"; import { useFavoriteChainIds } from "../../app/(app)/(dashboard)/(chain)/components/client/star-button"; @@ -30,6 +30,7 @@ interface NetworkSelectorButtonProps { isDisabled?: boolean; onSwitchChain?: (chain: StoredChain) => void; className?: string; + client: ThirdwebClient; } export const NetworkSelectorButton: React.FC = ({ @@ -38,8 +39,8 @@ export const NetworkSelectorButton: React.FC = ({ isDisabled, onSwitchChain, className, + client, }) => { - const client = useThirdwebClient(); const { idToChain, allChains } = useAllChainsData(); // recently used chains @@ -214,6 +215,7 @@ export const NetworkSelectorButton: React.FC = ({ open={isNetworkConfigModalOpen} onOpenChange={setIsNetworkConfigModalOpen} editChain={editChain} + client={client} /> ); diff --git a/apps/dashboard/src/components/smart-wallets/AccountFactories/account-cell.tsx b/apps/dashboard/src/components/smart-wallets/AccountFactories/account-cell.tsx index 19f3c36562b..56580974631 100644 --- a/apps/dashboard/src/components/smart-wallets/AccountFactories/account-cell.tsx +++ b/apps/dashboard/src/components/smart-wallets/AccountFactories/account-cell.tsx @@ -1,16 +1,18 @@ "use client"; import { SkeletonContainer } from "@/components/ui/skeleton"; -import { useThirdwebClient } from "@/constants/thirdweb.client"; import { memo } from "react"; -import { getContract } from "thirdweb"; +import { type ThirdwebClient, getContract } from "thirdweb"; import { getAllAccounts } from "thirdweb/extensions/erc4337"; import { useReadContract } from "thirdweb/react"; import { useV5DashboardChain } from "../../../lib/v5-adapter"; -function useAccountCount(address: string, chainId: number) { +function useAccountCount( + address: string, + chainId: number, + client: ThirdwebClient, +) { const chain = useV5DashboardChain(chainId); - const client = useThirdwebClient(); const contract = getContract({ address, chain, @@ -28,10 +30,12 @@ function useAccountCount(address: string, chainId: number) { export const FactoryAccountCell = memo(function FactoryAccountCell(props: { chainId: string; contractAddress: string; + client: ThirdwebClient; }) { const accountsQuery = useAccountCount( props.contractAddress, Number(props.chainId), + props.client, ); return ( = ({ contracts, teamSlug, projectSlug, + client, }) => { return ( @@ -70,6 +73,7 @@ export const FactoryContracts: React.FC = ({ contractAddress={contract.contractAddress} teamSlug={teamSlug} projectSlug={projectSlug} + client={client} /> @@ -87,6 +91,7 @@ export const FactoryContracts: React.FC = ({ diff --git a/apps/dashboard/src/components/wallets/PosthogIdentifier.tsx b/apps/dashboard/src/components/wallets/PosthogIdentifier.tsx index 0f57a4b2299..ce52396e107 100644 --- a/apps/dashboard/src/components/wallets/PosthogIdentifier.tsx +++ b/apps/dashboard/src/components/wallets/PosthogIdentifier.tsx @@ -1,6 +1,6 @@ "use client"; -import { useThirdwebClient } from "@/constants/thirdweb.client"; +import { getClientThirdwebClient } from "@/constants/thirdweb-client.client"; import { usePostHog } from "posthog-js/react"; import { useEffect } from "react"; import { @@ -19,11 +19,12 @@ const walletIdToPHName: Record = { injected: "Injected", }; +const client = getClientThirdwebClient(); + export const PosthogIdentifierClient: React.FC<{ accountId: string | undefined; accountAddress: string | undefined; }> = ({ accountId, accountAddress }) => { - const client = useThirdwebClient(); const account = useActiveAccount(); const chain = useActiveWalletChain(); const balance = useWalletBalance({ diff --git a/apps/dashboard/src/contract-ui/components/solidity-inputs/address-input.tsx b/apps/dashboard/src/contract-ui/components/solidity-inputs/address-input.tsx index 23b2a399097..be523eb7203 100644 --- a/apps/dashboard/src/contract-ui/components/solidity-inputs/address-input.tsx +++ b/apps/dashboard/src/contract-ui/components/solidity-inputs/address-input.tsx @@ -12,6 +12,7 @@ import { validateAddress } from "./helpers"; export const SolidityAddressInput: React.FC = ({ formContext: form, + client, ...inputProps }) => { const { name, ...restOfInputProps } = inputProps; @@ -21,7 +22,10 @@ export const SolidityAddressInput: React.FC = ({ const localInput = _localInput === undefined ? inputNameWatch : _localInput; const address = useActiveAccount()?.address; - const ensQuery = useEns(localInput); + const ensQuery = useEns({ + client, + addressOrEnsName: localInput, + }); const { setValue, clearErrors } = form; diff --git a/apps/dashboard/src/contract-ui/components/solidity-inputs/index.tsx b/apps/dashboard/src/contract-ui/components/solidity-inputs/index.tsx index 2a0e5fdd518..67eca5a5f33 100644 --- a/apps/dashboard/src/contract-ui/components/solidity-inputs/index.tsx +++ b/apps/dashboard/src/contract-ui/components/solidity-inputs/index.tsx @@ -15,6 +15,7 @@ type InputProps = React.ComponentProps; export interface SolidityInputProps extends InputProps { // biome-ignore lint/suspicious/noExplicitAny: FIXME formContext: UseFormReturn; + client: ThirdwebClient; } export interface SolidityInputWithTypeProps extends SolidityInputProps { solidityType: string; diff --git a/apps/dashboard/src/contract-ui/hooks/useContractFunctionComment.ts b/apps/dashboard/src/contract-ui/hooks/useContractFunctionComment.ts index f5bb0777fd1..eb145c3f064 100644 --- a/apps/dashboard/src/contract-ui/hooks/useContractFunctionComment.ts +++ b/apps/dashboard/src/contract-ui/hooks/useContractFunctionComment.ts @@ -1,4 +1,3 @@ -import { useThirdwebClient } from "@/constants/thirdweb.client"; import { useQuery } from "@tanstack/react-query"; import type { ThirdwebContract } from "thirdweb"; import { getCompilerMetadata } from "thirdweb/contract"; @@ -14,7 +13,6 @@ export function useContractFunctionComment( contract: ThirdwebContract, functionName: string, ) { - const client = useThirdwebClient(); return useQuery({ queryKey: [ "contract-function-comment", @@ -80,7 +78,7 @@ export function useContractFunctionComment( const ipfsHash = ipfsLink.split("ipfs/")[1]; const source = await download({ uri: `ipfs://${ipfsHash}`, - client, + client: contract.client, }) .then((r) => r.text()) .catch(() => "Failed to fetch source from IPFS"); diff --git a/apps/dashboard/src/contract-ui/hooks/useContractSources.ts b/apps/dashboard/src/contract-ui/hooks/useContractSources.ts index 5c0fca28920..d2b67c7af72 100644 --- a/apps/dashboard/src/contract-ui/hooks/useContractSources.ts +++ b/apps/dashboard/src/contract-ui/hooks/useContractSources.ts @@ -1,4 +1,3 @@ -import { useThirdwebClient } from "@/constants/thirdweb.client"; import { useQuery } from "@tanstack/react-query"; import type { ThirdwebContract } from "thirdweb"; import { getCompilerMetadata } from "thirdweb/contract"; @@ -8,7 +7,6 @@ import invariant from "tiny-invariant"; // An example for a contract that has IPFS URIs in its metadata: abstract-testnet/0x8A24a7Df38fA5fCCcFD1259e90Fb6996fDdfcADa export function useContractSources(contract?: ThirdwebContract) { - const client = useThirdwebClient(); return useQuery({ queryKey: [ "contract-sources", @@ -37,7 +35,7 @@ export function useContractSources(contract?: ThirdwebContract) { const ipfsHash = ipfsLink.split("ipfs/")[1]; const source = await download({ uri: `ipfs://${ipfsHash}`, - client, + client: contract.client, }) .then((r) => r.text()) .catch(() => "Failed to fetch source from IPFS"); diff --git a/apps/dashboard/src/core-ui/batch-upload/batch-lazy-mint.tsx b/apps/dashboard/src/core-ui/batch-upload/batch-lazy-mint.tsx index a7f7b65b727..9acffd4310b 100644 --- a/apps/dashboard/src/core-ui/batch-upload/batch-lazy-mint.tsx +++ b/apps/dashboard/src/core-ui/batch-upload/batch-lazy-mint.tsx @@ -193,6 +193,7 @@ export const BatchLazyMint: ComponentWithChildren< portalRef={paginationPortalRef} data={nftMetadatas} nextTokenIdToMint={props.nextTokenIdToMint} + client={props.client} />
diff --git a/apps/dashboard/src/core-ui/batch-upload/batch-table.tsx b/apps/dashboard/src/core-ui/batch-upload/batch-table.tsx index 670841e3930..d35a7ed2d85 100644 --- a/apps/dashboard/src/core-ui/batch-upload/batch-table.tsx +++ b/apps/dashboard/src/core-ui/batch-upload/batch-table.tsx @@ -27,11 +27,14 @@ import { } from "lucide-react"; import { useMemo } from "react"; import { type Column, usePagination, useTable } from "react-table"; +import type { ThirdwebClient } from "thirdweb"; import type { NFTInput } from "thirdweb/utils"; -import { useThirdwebClient } from "../../@/constants/thirdweb.client"; -const FileImage: React.FC = ({ src, ...props }) => { - const client = useThirdwebClient(); +const FileImage: React.FC< + ImageProps & { + client: ThirdwebClient; + } +> = ({ src, client, ...props }) => { const img = useImageFileOrUrl( typeof src === "string" && src.startsWith("ipfs://") ? replaceIpfsUrl(src, client) @@ -42,9 +45,11 @@ const FileImage: React.FC = ({ src, ...props }) => { const FileVideo: React.FC< BoxProps & - Omit, "ref" | "src"> & { src: string | File } -> = ({ src, ...props }) => { - const client = useThirdwebClient(); + Omit, "ref" | "src"> & { + src: string | File; + client: ThirdwebClient; + } +> = ({ src, client, ...props }) => { const video = useImageFileOrUrl( typeof src === "string" && src.startsWith("ipfs://") ? replaceIpfsUrl(src, client) @@ -56,12 +61,14 @@ interface BatchTableProps { data: NFTInput[]; portalRef: React.RefObject; nextTokenIdToMint?: bigint; + client: ThirdwebClient; } export const BatchTable: React.FC = ({ data, portalRef, nextTokenIdToMint, + client, }) => { const columns = useMemo(() => { let cols: Column[] = []; @@ -83,6 +90,7 @@ export const BatchTable: React.FC = ({ objectFit="contain" src={value} alt="" + client={client} /> ), }, @@ -99,6 +107,7 @@ export const BatchTable: React.FC = ({ playsInline muted loop + client={client} /> ), }, @@ -130,7 +139,7 @@ export const BatchTable: React.FC = ({ { Header: "Background Color", accessor: (row) => row.background_color }, ]); return cols; - }, [nextTokenIdToMint]); + }, [nextTokenIdToMint, client]); const { getTableProps, diff --git a/apps/dashboard/src/hooks/useCsvUpload.ts b/apps/dashboard/src/hooks/useCsvUpload.ts index 3cb2a9f5ac9..4b6cf4a3337 100644 --- a/apps/dashboard/src/hooks/useCsvUpload.ts +++ b/apps/dashboard/src/hooks/useCsvUpload.ts @@ -1,4 +1,3 @@ -import { useThirdwebClient } from "@/constants/thirdweb.client"; import { useQuery } from "@tanstack/react-query"; import pLimit from "p-limit"; import Papa from "papaparse"; @@ -83,6 +82,7 @@ type Props = { */ csvParser: (items: T[]) => T[]; defaultRawData?: T[] | undefined; + client: ThirdwebClient; }; /** @@ -95,7 +95,6 @@ export function useCsvUpload< // Always gonna need the wallet address T extends { address: string }, >(props: Props) { - const thirdwebClient = useThirdwebClient(); const [rawData, setRawData] = useState< T[] | Array >(props.defaultRawData || []); @@ -141,7 +140,9 @@ export function useCsvUpload< const limit = pLimit(50); const results = await Promise.all( rawData.map((item) => { - return limit(() => checkIsAddress({ item: item, thirdwebClient })); + return limit(() => + checkIsAddress({ item: item, thirdwebClient: props.client }), + ); }), ); return { diff --git a/apps/dashboard/src/tw-components/nft-media.tsx b/apps/dashboard/src/tw-components/nft-media.tsx index d66cd14d187..e6520ee308c 100644 --- a/apps/dashboard/src/tw-components/nft-media.tsx +++ b/apps/dashboard/src/tw-components/nft-media.tsx @@ -1,8 +1,8 @@ "use client"; -import { useThirdwebClient } from "@/constants/thirdweb.client"; import { cn } from "@/lib/utils"; import { ImageIcon } from "lucide-react"; +import type { ThirdwebClient } from "thirdweb"; import { MediaRenderer } from "thirdweb/react"; export const NFTMediaWithEmptyState: React.FC<{ @@ -16,9 +16,8 @@ export const NFTMediaWithEmptyState: React.FC<{ }; requireInteraction?: boolean; controls?: boolean; + client: ThirdwebClient; }> = (props) => { - const client = useThirdwebClient(); - // No media if (!(props.metadata.image || props.metadata.animation_url)) { return ( @@ -51,7 +50,7 @@ export const NFTMediaWithEmptyState: React.FC<{ )} >