Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/few-moments-add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"thirdweb": patch
---

Fixed a regression that prompted the user to pay the full amount in the TransactionWidget, rather than the difference from their current balance
15 changes: 11 additions & 4 deletions packages/thirdweb/src/react/core/hooks/useTransactionDetails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,15 @@ export function useTransactionDetails({
encode(transaction).catch(() => "0x"),
]);

const account = wallet?.getAccount();
if (!account) {
throw new Error("No active account");
}

const [tokenInfo, gasCostWei] = await Promise.all([
getToken(
client,
erc20Value ? erc20Value.tokenAddress : NATIVE_TOKEN_ADDRESS,
erc20Value?.tokenAddress || NATIVE_TOKEN_ADDRESS,
transaction.chain.id,
).catch(() => null),
hasSponsoredTransactions
Expand Down Expand Up @@ -151,9 +156,11 @@ export function useTransactionDetails({
chainMetadata.data?.nativeCurrency?.symbol || "ETH";
const tokenSymbol = tokenInfo?.symbol || nativeTokenSymbol;

const totalCostWei = erc20Value
? erc20Value.amountWei
: (value || 0n) + (gasCostWei || 0n);
const totalCostWei =
erc20Value &&
erc20Value.tokenAddress.toLowerCase() !== NATIVE_TOKEN_ADDRESS
? erc20Value.amountWei
: (value || 0n) + (gasCostWei || 0n);
const totalCost = toTokens(totalCostWei, decimal);

const price = tokenInfo?.prices[currency || "USD"] || 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ import type { PayEmbedConnectOptions } from "../PayEmbed.js";
import type { UIOptions } from "./BridgeOrchestrator.js";
import { ChainIcon } from "./common/TokenAndChain.js";
import { WithHeader } from "./common/WithHeader.js";
import { useQuery } from "@tanstack/react-query";
import { getWalletBalance } from "../../../../wallets/utils/getWalletBalance.js";
import { resolvePromisedValue } from "../../../../utils/promise/resolve-promised-value.js";
import { decimals } from "../../../../extensions/erc20/read/decimals.js";
import { getContract } from "../../../../contract/contract.js";
import { NATIVE_TOKEN_ADDRESS } from "../../../../constants/addresses.js";
import { toTokens } from "../../../../utils/units.js";

export interface TransactionPaymentProps {
/**
Expand Down Expand Up @@ -77,6 +84,35 @@ export function TransactionPayment({
wallet,
});

// We can't use useWalletBalance here because erc20Value is a possibly async value
const { data: userBalance } = useQuery({
enabled: !!activeAccount?.address,
queryFn: async (): Promise<string> => {
if (!activeAccount?.address) {
return "0";
}
const erc20Value = await resolvePromisedValue(uiOptions.transaction.erc20Value);
const tokenDecimals = erc20Value?.tokenAddress.toLowerCase() !== NATIVE_TOKEN_ADDRESS && erc20Value
? await decimals({
contract: getContract({
address: erc20Value.tokenAddress,
chain: uiOptions.transaction.chain,
client,
}),
})
: 18;
const walletBalance = await getWalletBalance({
address: activeAccount?.address,
chain: uiOptions.transaction.chain,
tokenAddress: erc20Value?.tokenAddress,
client,
});

return toTokens(walletBalance.value, tokenDecimals);
},
queryKey: ["active-account-address"],
});

const contractName =
transactionDataQuery.data?.contractMetadata?.name || "Unknown Contract";
const functionName =
Expand Down Expand Up @@ -327,7 +363,11 @@ export function TransactionPayment({
onClick={() => {
if (transactionDataQuery.data?.tokenInfo) {
onContinue(
transactionDataQuery.data.totalCost,
Math.max(
0,
Number(transactionDataQuery.data.totalCost) -
Number(userBalance),
).toString(),
transactionDataQuery.data.tokenInfo,
getAddress(activeAccount.address),
);
Expand Down
Loading