diff --git a/apps/dashboard/.eslintrc.js b/apps/dashboard/.eslintrc.js index 580ed2f24f9..4bb41fd8667 100644 --- a/apps/dashboard/.eslintrc.js +++ b/apps/dashboard/.eslintrc.js @@ -95,6 +95,30 @@ module.exports = { 'Import "posthog-js" directly only within the analytics helpers ("src/@/analytics/*"). Use the exported helpers from "@/analytics/track" elsewhere.', name: "posthog-js", }, + { + importNames: ["useSendTransaction"], + message: + 'Use `import { useSendAndConfirmTx } from "@/hooks/useSendTx";` instead', + name: "thirdweb/react", + }, + { + importNames: ["useSendAndConfirmTransaction"], + message: + 'Use `import { useSendAndConfirmTx } from "@/hooks/useSendTx";` instead', + name: "thirdweb/react", + }, + { + importNames: ["sendTransaction"], + message: + 'Use `import { useSendAndConfirmTx } from "@/hooks/useSendTx";` instead if used in react component', + name: "thirdweb", + }, + { + importNames: ["sendAndConfirmTransaction"], + message: + 'Use `import { useSendAndConfirmTx } from "@/hooks/useSendTx";` instead if used in react component', + name: "thirdweb", + }, ], patterns: [ { diff --git a/apps/dashboard/src/@/components/contracts/functions/interactive-abi-function.tsx b/apps/dashboard/src/@/components/contracts/functions/interactive-abi-function.tsx index 4b9256fc332..c1f2973ce65 100644 --- a/apps/dashboard/src/@/components/contracts/functions/interactive-abi-function.tsx +++ b/apps/dashboard/src/@/components/contracts/functions/interactive-abi-function.tsx @@ -20,7 +20,7 @@ import { toSerializableTransaction, toWei, } from "thirdweb"; -import { useActiveAccount, useSendAndConfirmTransaction } from "thirdweb/react"; +import { useActiveAccount } from "thirdweb/react"; import { parseAbiParams, stringify, toFunctionSelector } from "thirdweb/utils"; import { FormFieldSetup } from "@/components/blocks/FormFieldSetup"; import { SolidityInput } from "@/components/solidity-inputs"; @@ -34,6 +34,7 @@ import { Input } from "@/components/ui/input"; import { Spinner } from "@/components/ui/Spinner"; import { Skeleton } from "@/components/ui/skeleton"; import { ToolTipLabel } from "@/components/ui/tooltip"; +import { useSendAndConfirmTx } from "@/hooks/useSendTx"; function formatResponseData(data: unknown): { type: "json" | "text"; @@ -264,7 +265,7 @@ export const InteractiveAbiFunction: React.FC = ( data: mutationData, error: mutationError, isPending: mutationLoading, - } = useSendAndConfirmTransaction(); + } = useSendAndConfirmTx(); const { mutate: readFn, diff --git a/apps/dashboard/src/@/components/tx-button/MismatchButton.tsx b/apps/dashboard/src/@/components/tx-button/MismatchButton.tsx index b66580e4ac2..cc5dd52a7a3 100644 --- a/apps/dashboard/src/@/components/tx-button/MismatchButton.tsx +++ b/apps/dashboard/src/@/components/tx-button/MismatchButton.tsx @@ -12,6 +12,7 @@ import { forwardRef, useCallback, useRef, useState } from "react"; import { toast } from "sonner"; import { prepareTransaction, + // eslint-disable-next-line no-restricted-imports sendTransaction, type ThirdwebClient, toWei, diff --git a/apps/dashboard/src/@/hooks/useSendTx.ts b/apps/dashboard/src/@/hooks/useSendTx.ts new file mode 100644 index 00000000000..1d54e925b32 --- /dev/null +++ b/apps/dashboard/src/@/hooks/useSendTx.ts @@ -0,0 +1,19 @@ +import { useTheme } from "next-themes"; +import { + type SendTransactionConfig, + // eslint-disable-next-line no-restricted-imports + useSendAndConfirmTransaction, +} from "thirdweb/react"; +import { getSDKTheme } from "@/utils/sdk-component-theme"; + +export function useSendAndConfirmTx(config?: SendTransactionConfig) { + const { theme } = useTheme(); + const sendAndConfirmTransaction = useSendAndConfirmTransaction({ + payModal: { + theme: getSDKTheme(theme === "light" ? "light" : "dark"), + }, + ...config, + }); + + return sendAndConfirmTransaction; +} diff --git a/apps/dashboard/src/@/hooks/useSplit.ts b/apps/dashboard/src/@/hooks/useSplit.ts index d26d64c72e1..4a190e11145 100644 --- a/apps/dashboard/src/@/hooks/useSplit.ts +++ b/apps/dashboard/src/@/hooks/useSplit.ts @@ -9,7 +9,6 @@ import { type Chain, getAddress, NATIVE_TOKEN_ADDRESS, - sendAndConfirmTransaction, type ThirdwebClient, type ThirdwebContract, } from "thirdweb"; @@ -21,6 +20,7 @@ import { getWalletBalance } from "thirdweb/wallets"; import invariant from "tiny-invariant"; import { parseError } from "../utils/errorParser"; import { tryCatch } from "../utils/try-catch"; +import { useSendAndConfirmTx } from "./useSendTx"; function getTokenBalancesQuery(params: { ownerAddress: string; @@ -79,6 +79,7 @@ export function useOwnedTokenBalances(params: { export function useSplitDistributeFunds(contract: ThirdwebContract) { const account = useActiveAccount(); const queryClient = useQueryClient(); + const sendAndConfirmTx = useSendAndConfirmTx(); const params = { ownerAddress: contract.address, // because we want to fetch the balance of split contract @@ -106,10 +107,7 @@ export function useSplitDistributeFunds(contract: ThirdwebContract) { contract, tokenAddress: currency.tokenAddress, }); - const promise = sendAndConfirmTransaction({ - account, - transaction, - }); + const promise = sendAndConfirmTx.mutateAsync(transaction); toast.promise(promise, { error: (err) => ({ diff --git a/apps/dashboard/src/@/hooks/useVote.ts b/apps/dashboard/src/@/hooks/useVote.ts index c40f732aae6..dd2149ac247 100644 --- a/apps/dashboard/src/@/hooks/useVote.ts +++ b/apps/dashboard/src/@/hooks/useVote.ts @@ -8,9 +8,9 @@ import { } from "thirdweb"; import * as ERC20Ext from "thirdweb/extensions/erc20"; import * as VoteExt from "thirdweb/extensions/vote"; -import { useSendAndConfirmTransaction } from "thirdweb/react"; import type { Account } from "thirdweb/wallets"; import invariant from "tiny-invariant"; +import { useSendAndConfirmTx } from "@/hooks/useSendTx"; export async function tokensDelegated( options: BaseTransactionOptions<{ account: Account | undefined }>, @@ -81,7 +81,7 @@ export async function votingTokenDecimals(options: BaseTransactionOptions) { } export function useDelegateMutation() { - const { mutateAsync } = useSendAndConfirmTransaction(); + const sendAndConfirmTx = useSendAndConfirmTx(); return useMutation({ mutationFn: async (contract: ThirdwebContract) => { @@ -97,7 +97,7 @@ export function useDelegateMutation() { contract: tokenContract, delegatee: contract.address, }); - return await mutateAsync(transaction); + return await sendAndConfirmTx.mutateAsync(transaction); }, }); } diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/FaucetButton.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/FaucetButton.tsx index 3a3e8a14a7b..14942a55f91 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/FaucetButton.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/FaucetButton.tsx @@ -17,7 +17,6 @@ import type { Chain, ChainMetadata } from "thirdweb/chains"; import { useActiveAccount, useActiveWalletChain, - useSendTransaction, useSwitchActiveWalletChain, useWalletBalance, } from "thirdweb/react"; @@ -48,6 +47,7 @@ import { NEXT_PUBLIC_THIRDWEB_ENGINE_FAUCET_WALLET, NEXT_PUBLIC_TURNSTILE_SITE_KEY, } from "@/constants/public-envs"; +import { useSendAndConfirmTx } from "@/hooks/useSendTx"; import { parseError } from "@/utils/errorParser"; import { mapV4ChainToV5Chain } from "@/utils/map-chains"; @@ -310,7 +310,7 @@ function SendFundsToFaucetModalContent(props: { const account = useActiveAccount(); const activeChain = useActiveWalletChain(); const switchActiveWalletChain = useSwitchActiveWalletChain(); - const sendTxMutation = useSendTransaction({ + const sendAndConfirmTx = useSendAndConfirmTx({ payModal: false, }); const switchChainMutation = useMutation({ @@ -334,7 +334,7 @@ function SendFundsToFaucetModalContent(props: { value: toWei(values.amount.toString()), }); - const promise = sendTxMutation.mutateAsync(sendNativeTokenTx); + const promise = sendAndConfirmTx.mutateAsync(sendNativeTokenTx); toast.promise(promise, { error: `Failed to send ${values.amount} ${props.chainMeta.nativeCurrency.symbol} to faucet`, @@ -404,11 +404,11 @@ function SendFundsToFaucetModalContent(props: { {activeChain.id === props.chain.id ? ( ) : ( diff --git a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/cancel-tab.tsx b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/cancel-tab.tsx index f1eefd58a0e..b0ff89ae454 100644 --- a/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/cancel-tab.tsx +++ b/apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/cancel-tab.tsx @@ -2,8 +2,8 @@ import { toast } from "sonner"; import type { ThirdwebContract } from "thirdweb"; import { cancelAuction, cancelListing } from "thirdweb/extensions/marketplace"; -import { useSendAndConfirmTransaction } from "thirdweb/react"; import { TransactionButton } from "@/components/tx-button"; +import { useSendAndConfirmTx } from "@/hooks/useSendTx"; interface CancelTabProps { id: string; @@ -21,15 +21,15 @@ export const CancelTab: React.FC = ({ const transaction = isAuction ? cancelAuction({ auctionId: BigInt(id), contract }) : cancelListing({ contract, listingId: BigInt(id) }); - const cancelQuery = useSendAndConfirmTransaction(); + const sendAndConfirmTx = useSendAndConfirmTx(); return ( { - const promise = cancelQuery.mutateAsync(transaction, { + const promise = sendAndConfirmTx.mutateAsync(transaction, { onError: (error) => { console.error(error); }, 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 2dc7e96d9e3..a9106d4907a 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 @@ -28,7 +28,7 @@ import type { CreateListingParams, } from "thirdweb/extensions/marketplace"; import { createAuction, createListing } from "thirdweb/extensions/marketplace"; -import { useActiveAccount, useSendAndConfirmTransaction } from "thirdweb/react"; +import { useActiveAccount } from "thirdweb/react"; import { shortenAddress } from "thirdweb/utils"; import { CurrencySelector } from "@/components/blocks/CurrencySelector"; import { NFTMediaWithEmptyState } from "@/components/blocks/nft-media"; @@ -54,6 +54,7 @@ import { import { Skeleton } from "@/components/ui/skeleton"; import { ToolTipLabel } from "@/components/ui/tooltip"; import { useDashboardOwnedNFTs } from "@/hooks/useDashboardOwnedNFTs"; +import { useSendAndConfirmTx } from "@/hooks/useSendTx"; import { useTxNotifications } from "@/hooks/useTxNotifications"; import { useOwnedNFTsInsight } from "@/hooks/useWalletNFTs"; import { cn } from "@/lib/utils"; @@ -122,7 +123,7 @@ export const CreateListingsForm: React.FC = ({ chain: contract.chain, }); - const sendAndConfirmTx = useSendAndConfirmTransaction(); + const sendAndConfirmTx = useSendAndConfirmTx(); const listingNotifications = useTxNotifications( "NFT listed Successfully", "Failed to list NFT", 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 42879f44a4e..4da83e4fc96 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 @@ -28,11 +28,7 @@ import { ZERO_ADDRESS, } from "thirdweb"; import { decimals } from "thirdweb/extensions/erc20"; -import { - useActiveAccount, - useReadContract, - useSendAndConfirmTransaction, -} from "thirdweb/react"; +import { useActiveAccount, useReadContract } from "thirdweb/react"; import invariant from "tiny-invariant"; import * as z from "zod"; import { ZodError } from "zod"; @@ -49,6 +45,7 @@ import { Form } from "@/components/ui/form"; import { Spinner } from "@/components/ui/Spinner"; import { ToolTipLabel } from "@/components/ui/tooltip"; import { useIsAdmin } from "@/hooks/useContractRoles"; +import { useSendAndConfirmTx } from "@/hooks/useSendTx"; import { useTxNotifications } from "@/hooks/useTxNotifications"; import { type ClaimConditionInput, @@ -222,7 +219,7 @@ export const ClaimConditionsForm: React.FC = ({ Record >({}); - const sendTx = useSendAndConfirmTransaction(); + const sendAndConfirmTx = useSendAndConfirmTx(); const tokenDecimals = useReadContract(decimals, { contract, @@ -305,7 +302,7 @@ export const ClaimConditionsForm: React.FC = ({ const isFetchingData = claimConditionsQuery.isFetching || - sendTx.isPending || + sendAndConfirmTx.isPending || // Need to make sure the tokenDecimals.data is present when interacting with ERC20 claim conditions (isErc20 && tokenDecimals.isLoading); @@ -428,7 +425,7 @@ export const ClaimConditionsForm: React.FC = ({ }, phasesWithSnapshots, ); - await sendTx.mutateAsync(tx); + await sendAndConfirmTx.mutateAsync(tx); saveClaimPhaseNotification.onSuccess(); } catch (error) { @@ -559,7 +556,7 @@ export const ClaimConditionsForm: React.FC = ({ > { formFields.remove(index); // Clean up snapshot when phase is removed @@ -594,7 +591,8 @@ export const ClaimConditionsForm: React.FC = ({ diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-page.tsx index fb77020273f..be9735e5760 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-page.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/create-nft-page.tsx @@ -1,11 +1,6 @@ "use client"; import { useRef } from "react"; -import { - encode, - getContract, - sendAndConfirmTransaction, - type ThirdwebClient, -} from "thirdweb"; +import { encode, getContract, type ThirdwebClient } from "thirdweb"; import { deployERC721Contract, deployERC1155Contract } from "thirdweb/deploys"; import { multicall } from "thirdweb/extensions/common"; import { @@ -26,6 +21,7 @@ import { reportContractDeployed } from "@/analytics/report"; import type { Team } from "@/api/team/get-team"; import { useGetV5DashboardChain } from "@/hooks/chains/v5-adapter"; import { useAddContractToProject } from "@/hooks/project-contracts"; +import { useSendAndConfirmTx } from "@/hooks/useSendTx"; import type { CreateNFTCollectionAllValues } from "./_common/form"; import { CreateNFTPageUI } from "./create-nft-page-ui"; @@ -42,7 +38,7 @@ export function CreateNFTPage(props: { const addContractToProject = useAddContractToProject(); const contractAddressRef = useRef(undefined); const getChain = useGetV5DashboardChain(); - + const sendAndConfirmTx = useSendAndConfirmTx(); function getAccount(params: { gasless: boolean }) { if (!activeAccount) { throw new Error("Wallet is not connected"); @@ -163,10 +159,10 @@ export function CreateNFTPage(props: { const contract = getDeployedContract({ chain: values.collectionInfo.chain, }); - - const account = getAccount({ - gasless: params.gasless, - }); + // TODO - when gasless is enabled - change how the tx is sent + // const account = getAccount({ + // gasless: params.gasless, + // }); const lazyMintFn = ercType === "erc721" ? lazyMint721 : lazyMint1155; @@ -175,10 +171,7 @@ export function CreateNFTPage(props: { nfts: values.nfts, }); - await sendAndConfirmTransaction({ - account, - transaction, - }); + await sendAndConfirmTx.mutateAsync(transaction); } async function handleSetClaimConditionsERC721(params: { @@ -189,10 +182,10 @@ export function CreateNFTPage(props: { const contract = getDeployedContract({ chain: values.collectionInfo.chain, }); - - const account = getAccount({ - gasless: params.gasless, - }); + // TODO - when gasless is enabled - change how the tx is sent + // const account = getAccount({ + // gasless: params.gasless, + // }); const firstNFT = values.nfts[0]; if (!firstNFT) { @@ -215,10 +208,7 @@ export function CreateNFTPage(props: { ], }); - await sendAndConfirmTransaction({ - account, - transaction, - }); + await sendAndConfirmTx.mutateAsync(transaction); } async function handleSetClaimConditionsERC1155(params: { @@ -234,9 +224,10 @@ export function CreateNFTPage(props: { chain: values.collectionInfo.chain, }); - const account = getAccount({ - gasless: params.gasless, - }); + // TODO - when gasless is enabled - change how the tx is sent + // const account = getAccount({ + // gasless: params.gasless, + // }); const endIndexExclusive = batch.startIndex + batch.count; const nfts = values.nfts.slice(batch.startIndex, endIndexExclusive); @@ -286,10 +277,7 @@ export function CreateNFTPage(props: { data: encodedTransactions, }); - await sendAndConfirmTransaction({ - account, - transaction: tx, - }); + await sendAndConfirmTx.mutateAsync(tx); } async function handleSetAdmins(params: { @@ -331,10 +319,7 @@ export function CreateNFTPage(props: { data: encodedTxs, }); - await sendAndConfirmTransaction({ - account, - transaction: tx, - }); + await sendAndConfirmTx.mutateAsync(tx); } return ( diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page-impl.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page-impl.tsx index 9ec2825510f..43a3e32f09f 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page-impl.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/create-token-page-impl.tsx @@ -4,7 +4,6 @@ import { getAddress, getContract, NATIVE_TOKEN_ADDRESS, - sendAndConfirmTransaction, type ThirdwebClient, toUnits, toWei, @@ -19,9 +18,10 @@ import { } from "thirdweb/extensions/erc20"; import { useActiveAccount } from "thirdweb/react"; import { - createToken, distributeToken, getDeployedEntrypointERC20, + getTokenAddressFromReceipt, + prepareCreateToken, } from "thirdweb/tokens"; import type { ClaimConditionsInput } from "thirdweb/utils"; import { create7702MinimalAccount } from "thirdweb/wallets/smart"; @@ -34,6 +34,7 @@ import { } from "@/constants/addresses"; import { useGetV5DashboardChain } from "@/hooks/chains/v5-adapter"; import { useAddContractToProject } from "@/hooks/project-contracts"; +import { useSendAndConfirmTx } from "@/hooks/useSendTx"; import { pollWithTimeout } from "@/utils/pollWithTimeout"; import { createTokenOnUniversalBridge } from "../_apis/create-token-on-bridge"; import type { CreateAssetFormValues } from "./_common/form"; @@ -53,6 +54,7 @@ export function CreateTokenAssetPage(props: { const addContractToProject = useAddContractToProject(); const contractAddressRef = useRef(undefined); const getChain = useGetV5DashboardChain(); + const sendAndConfirmTx = useSendAndConfirmTx(); function getAccount(gasless: boolean) { if (!activeAccount) { @@ -132,7 +134,7 @@ export function CreateTokenAssetPage(props: { } } - const contractAddress = await createToken({ + const createTokenTx = await prepareCreateToken({ account, chain: chain, client: props.client, @@ -163,6 +165,9 @@ export function CreateTokenAssetPage(props: { developerAddress: "0x1Af20C6B23373350aD464700B5965CE4B0D2aD94", }); + const receipt = await sendAndConfirmTx.mutateAsync(createTokenTx); + const contractAddress = await getTokenAddressFromReceipt(receipt); + // add contract to project in background addContractToProject.mutateAsync({ chainId: params.values.chain, @@ -192,8 +197,7 @@ export function CreateTokenAssetPage(props: { values: CreateAssetFormValues; gasless: boolean; }) { - const { values, gasless } = params; - const account = getAccount(gasless); + const { values } = params; const contract = getDeployedContract({ chain: values.chain }); const airdropTx = await distributeToken({ @@ -206,18 +210,16 @@ export function CreateTokenAssetPage(props: { tokenAddress: contract.address, }); - await sendAndConfirmTransaction({ - account, - transaction: airdropTx, - }); + await sendAndConfirmTx.mutateAsync(airdropTx); } async function ERC20Asset_approveAirdropTokens(params: { values: CreateAssetFormValues; gasless: boolean; }) { - const { values, gasless } = params; - const account = getAccount(gasless); + const { values } = params; + // TODO - when gasless is enabled - change how the tx is sent + // const account = getAccount(params.gasless); const contract = getDeployedContract({ chain: values.chain }); const totalAmountToAirdrop = values.airdropAddresses.reduce( @@ -240,10 +242,7 @@ export function CreateTokenAssetPage(props: { spender: entrypoint.address, }); - await sendAndConfirmTransaction({ - account, - transaction: approvalTx, - }); + await sendAndConfirmTx.mutateAsync(approvalTx); } // DropERC20 ---- @@ -337,10 +336,7 @@ export function CreateTokenAssetPage(props: { contract, }); - await sendAndConfirmTransaction({ - account, - transaction: airdropTx, - }); + await sendAndConfirmTx.mutateAsync(airdropTx); } async function DropERC20_mintTokens(params: { @@ -380,10 +376,7 @@ export function CreateTokenAssetPage(props: { to: account.address, }); - await sendAndConfirmTransaction({ - account, - transaction: claimTx, - }); + await sendAndConfirmTx.mutateAsync(claimTx); } async function DropERC20_setClaimConditions(params: { @@ -439,10 +432,7 @@ export function CreateTokenAssetPage(props: { phases, }); - await sendAndConfirmTransaction({ - account, - transaction: preparedTx, - }); + await sendAndConfirmTx.mutateAsync(preparedTx); } return ( diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/rewards/components/claim-rewards-page.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/rewards/components/claim-rewards-page.tsx index 7cdce2c410b..679dd2a4f87 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/rewards/components/claim-rewards-page.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/rewards/components/claim-rewards-page.tsx @@ -9,11 +9,12 @@ import { type ThirdwebContract, toTokens, } from "thirdweb"; -import { TokenIcon, TokenProvider, useSendTransaction } from "thirdweb/react"; +import { TokenIcon, TokenProvider } from "thirdweb/react"; import { claimRewards } from "thirdweb/tokens"; import { DistributionBarChart } from "@/components/blocks/distribution-chart"; import { WalletAddress } from "@/components/blocks/wallet-address"; import { TransactionButton } from "@/components/tx-button"; +import { useSendAndConfirmTx } from "@/hooks/useSendTx"; import { useDashboardRouter } from "@/lib/DashboardRouter"; import { parseError } from "@/utils/errorParser"; import { tryCatch } from "@/utils/try-catch"; @@ -37,7 +38,7 @@ export function ClaimRewardsPage(props: { }; chainSlug: string; }) { - const sendTx = useSendTransaction(); + const sendAndConfirmTx = useSendAndConfirmTx(); const router = useDashboardRouter(); async function handleClaim() { @@ -47,7 +48,7 @@ export function ClaimRewardsPage(props: { }); const claimRewardsResult = await tryCatch( - sendTx.mutateAsync(claimRewardsTx), + sendAndConfirmTx.mutateAsync(claimRewardsTx), ); if (claimRewardsResult.error) { @@ -66,7 +67,7 @@ export function ClaimRewardsPage(props: { recipient={props.reward.recipient} developer={props.reward.developer} handleClaim={handleClaim} - isClaimPending={sendTx.isPending} + isClaimPending={sendAndConfirmTx.isPending} client={props.assetContractClient.client} chain={props.assetContractClient.chain} chainSlug={props.chainSlug} diff --git a/packages/thirdweb/src/exports/tokens.ts b/packages/thirdweb/src/exports/tokens.ts index df7c63aeacf..a938526a362 100644 --- a/packages/thirdweb/src/exports/tokens.ts +++ b/packages/thirdweb/src/exports/tokens.ts @@ -6,7 +6,10 @@ export { DEFAULT_DEVELOPER_ADDRESS, DEFAULT_DEVELOPER_REWARD_BPS, } from "../tokens/constants.js"; -export { createToken, prepareCreateToken } from "../tokens/create-token.js"; +export { + getTokenAddressFromReceipt, + prepareCreateToken, +} from "../tokens/create-token.js"; export { distributeToken } from "../tokens/distribute-token.js"; export { getDeployedContractFactory, diff --git a/packages/thirdweb/src/tokens/create-token.ts b/packages/thirdweb/src/tokens/create-token.ts index 14b00b209cf..005a74979fc 100644 --- a/packages/thirdweb/src/tokens/create-token.ts +++ b/packages/thirdweb/src/tokens/create-token.ts @@ -3,7 +3,7 @@ import type { Hex } from "viem"; import { parseEventLogs } from "../event/actions/parse-logs.js"; import { createdEvent } from "../extensions/tokens/__generated__/ERC20Entrypoint/events/Created.js"; import { createById } from "../extensions/tokens/__generated__/ERC20Entrypoint/write/createById.js"; -import { sendAndConfirmTransaction } from "../transaction/actions/send-and-confirm-transaction.js"; +import type { TransactionReceipt } from "../transaction/types.js"; import { padHex, toHex } from "../utils/encoding/hex.js"; import { DEFAULT_DEVELOPER_ADDRESS } from "./constants.js"; import { getDeployedEntrypointERC20 } from "./get-entrypoint-erc20.js"; @@ -14,40 +14,7 @@ import { } from "./token-utils.js"; import type { CreateTokenOptions } from "./types.js"; -export async function createToken(options: CreateTokenOptions) { - const { client, account, params, launchConfig } = options; - - const creator = params.owner || account.address; - const encodedInitData = await encodeInitParams({ - client, - creator, - params, - }); - - const salt: Hex = generateSalt(options.salt || bytesToHex(randomBytes(31))); - - const entrypoint = await getDeployedEntrypointERC20(options); - - let hookData: Hex = "0x"; - let contractId = padHex(toHex("ERC20Asset"), { size: 32 }); - if (launchConfig?.kind === "pool") { - hookData = encodePoolConfig(launchConfig.config); - contractId = padHex(toHex("ERC20Asset_Pool"), { size: 32 }); - } - - const transaction = createById({ - contract: entrypoint, - contractId, - params: { - data: encodedInitData, - hookData, - developer: options.developerAddress || DEFAULT_DEVELOPER_ADDRESS, - salt, - }, - creator, - }); - - const receipt = await sendAndConfirmTransaction({ account, transaction }); +export async function getTokenAddressFromReceipt(receipt: TransactionReceipt) { const assetEvent = createdEvent(); const decodedEvent = parseEventLogs({ events: [assetEvent],