Skip to content

Commit 0682f26

Browse files
committed
[TOOL-3047] Dashboard: Fix TransactionButton opening "No funds" Modal when quickly clicking it after switching chain (#5941)
1 parent 0e2b3df commit 0682f26

File tree

2 files changed

+37
-23
lines changed

2 files changed

+37
-23
lines changed

apps/dashboard/src/components/buttons/MismatchButton.tsx

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -63,41 +63,42 @@ const GAS_FREE_CHAINS = [
6363
247253, // Saakuru Testnet
6464
];
6565

66-
function useNetworkMismatchAdapter(desiredChainId: number) {
66+
function useIsNetworkMismatch(txChainId: number) {
6767
const walletChainId = useActiveWalletChain()?.id;
6868
if (!walletChainId) {
6969
// simply not ready yet, assume false
7070
return false;
7171
}
7272
// otherwise, compare the chain ids
73-
return walletChainId !== desiredChainId;
73+
return walletChainId !== txChainId;
7474
}
7575

7676
type MistmatchButtonProps = React.ComponentProps<typeof Button> & {
77-
desiredChainId: number;
77+
txChainId: number;
7878
twAccount: Account | undefined;
7979
};
8080

8181
export const MismatchButton = forwardRef<
8282
HTMLButtonElement,
8383
MistmatchButtonProps
8484
>((props, ref) => {
85-
const { desiredChainId, twAccount, ...buttonProps } = props;
85+
const { txChainId, twAccount, ...buttonProps } = props;
8686
const account = useActiveAccount();
8787
const wallet = useActiveWallet();
8888
const activeWalletChain = useActiveWalletChain();
8989
const [dialog, setDialog] = useState<undefined | "no-funds" | "pay">();
9090
const { theme } = useTheme();
9191
const client = useThirdwebClient();
9292
const pathname = usePathname();
93+
const txChain = useV5DashboardChain(txChainId);
9394

94-
const evmBalance = useWalletBalance({
95+
const txChainBalance = useWalletBalance({
9596
address: account?.address,
96-
chain: activeWalletChain,
97+
chain: txChain,
9798
client,
9899
});
99100

100-
const networksMismatch = useNetworkMismatchAdapter(desiredChainId);
101+
const networksMismatch = useIsNetworkMismatch(txChainId);
101102
const [isMismatchPopoverOpen, setIsMismatchPopoverOpen] = useState(false);
102103
const trackEvent = useTrack();
103104

@@ -130,8 +131,15 @@ export const MismatchButton = forwardRef<
130131
);
131132
}
132133

134+
const isBalanceRequired = !GAS_FREE_CHAINS.includes(txChainId);
135+
133136
const notEnoughBalance =
134-
(evmBalance.data?.value || 0n) === 0n && !GAS_FREE_CHAINS.includes(chainId);
137+
(txChainBalance.data?.value || 0n) === 0n && isBalanceRequired;
138+
139+
const disabled =
140+
buttonProps.disabled ||
141+
// if user is about to trigger a transaction on txChain, but txChainBalance is not yet loaded and is required before proceeding
142+
(!networksMismatch && txChainBalance.isPending && isBalanceRequired);
135143

136144
return (
137145
<>
@@ -150,6 +158,7 @@ export const MismatchButton = forwardRef<
150158
<PopoverTrigger asChild>
151159
<Button
152160
{...buttonProps}
161+
disabled={disabled}
153162
type={
154163
networksMismatch || notEnoughBalance ? "button" : buttonProps.type
155164
}
@@ -182,7 +191,7 @@ export const MismatchButton = forwardRef<
182191
</PopoverTrigger>
183192
<PopoverContent className="min-w-[350px]" side="top" sideOffset={10}>
184193
<MismatchNotice
185-
desiredChainId={desiredChainId}
194+
txChainId={txChainId}
186195
onClose={(hasSwitched) => {
187196
if (hasSwitched) {
188197
setIsMismatchPopoverOpen(false);
@@ -416,8 +425,8 @@ function GetFundsFromFaucet(props: {
416425

417426
const MismatchNotice: React.FC<{
418427
onClose: (hasSwitched: boolean) => void;
419-
desiredChainId: number;
420-
}> = ({ onClose, desiredChainId }) => {
428+
txChainId: number;
429+
}> = ({ onClose, txChainId }) => {
421430
const connectedChainId = useActiveWalletChain()?.id;
422431
const switchNetwork = useSwitchActiveWalletChain();
423432
const activeWallet = useActiveWallet();
@@ -427,14 +436,15 @@ const MismatchNotice: React.FC<{
427436
const walletConnectedNetworkInfo = connectedChainId
428437
? idToChain.get(connectedChainId)
429438
: undefined;
430-
const chain = desiredChainId ? idToChain.get(desiredChainId) : undefined;
431-
const chainV5 = useV5DashboardChain(desiredChainId);
439+
440+
const txChain = txChainId ? idToChain.get(txChainId) : undefined;
441+
const chainV5 = useV5DashboardChain(txChainId);
432442
const switchNetworkMutation = useMutation({
433443
mutationFn: switchNetwork,
434444
});
435445

436446
const onSwitchWallet = useCallback(async () => {
437-
if (actuallyCanAttemptSwitch && desiredChainId && chainV5) {
447+
if (actuallyCanAttemptSwitch && txChainId && chainV5) {
438448
try {
439449
await switchNetworkMutation.mutateAsync(chainV5);
440450
onClose(true);
@@ -446,7 +456,7 @@ const MismatchNotice: React.FC<{
446456
}, [
447457
chainV5,
448458
actuallyCanAttemptSwitch,
449-
desiredChainId,
459+
txChainId,
450460
onClose,
451461
switchNetworkMutation,
452462
]);
@@ -458,15 +468,19 @@ const MismatchNotice: React.FC<{
458468
Network Mismatch
459469
</h3>
460470

461-
<p className="text-muted-foreground">
471+
<p className="mb-1 text-muted-foreground">
462472
Your wallet is connected to the{" "}
463-
<span className="font-medium capitalize">
473+
<span className="font-semibold capitalize">
464474
{walletConnectedNetworkInfo?.name ||
465475
`Chain ID #${connectedChainId}`}
466476
</span>{" "}
467-
network but this action requires you to connect to the{" "}
468-
<span className="font-medium capitalize">
469-
{chain?.name || `Chain ID #${desiredChainId}`}
477+
network
478+
</p>
479+
480+
<p className="text-muted-foreground">
481+
This action requires you to connect to the{" "}
482+
<span className="font-semibold capitalize">
483+
{txChain?.name || `Chain ID #${txChainId}`}
470484
</span>{" "}
471485
network.
472486
</p>
@@ -485,7 +499,7 @@ const MismatchNotice: React.FC<{
485499
<UnplugIcon className="size-4 shrink-0" />
486500
)}
487501
<span className="line-clamp-1 block truncate">
488-
Switch {chain ? `to ${chain.name}` : "chain"}
502+
Switch {txChain ? `to ${txChain.name}` : "chain"}
489503
</span>
490504
</Button>
491505

apps/dashboard/src/components/buttons/TransactionButton.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export const TransactionButton: React.FC<TransactionButtonProps> = ({
7171
<PopoverTrigger asChild>
7272
<ButtonComponent
7373
variant={variant || "primary"}
74-
desiredChainId={txChainID}
74+
txChainId={txChainID}
7575
twAccount={twAccount}
7676
{...restButtonProps}
7777
disabled={disabled}
@@ -189,7 +189,7 @@ const ExternalApprovalNotice: React.FC<ExternalApprovalNoticeProps> = ({
189189
<h4 className="text-foreground">Approve Transaction</h4>
190190

191191
<p className="text-muted-foreground text-sm">
192-
You will need to approve this transaction in your connected wallet.
192+
Your connected wallet will prompt you to approve this transaction
193193
</p>
194194

195195
{showHint && (

0 commit comments

Comments
 (0)