Skip to content

Commit

Permalink
[TOOL-3047] Dashboard: Fix TransactionButton opening "No funds" Modal…
Browse files Browse the repository at this point in the history
… when quickly clicking it after switching chain (#5941)
  • Loading branch information
MananTank committed Jan 13, 2025
1 parent 0e2b3df commit 0682f26
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 23 deletions.
56 changes: 35 additions & 21 deletions apps/dashboard/src/components/buttons/MismatchButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,41 +63,42 @@ const GAS_FREE_CHAINS = [
247253, // Saakuru Testnet
];

function useNetworkMismatchAdapter(desiredChainId: number) {
function useIsNetworkMismatch(txChainId: number) {
const walletChainId = useActiveWalletChain()?.id;
if (!walletChainId) {
// simply not ready yet, assume false
return false;
}
// otherwise, compare the chain ids
return walletChainId !== desiredChainId;
return walletChainId !== txChainId;
}

type MistmatchButtonProps = React.ComponentProps<typeof Button> & {
desiredChainId: number;
txChainId: number;
twAccount: Account | undefined;
};

export const MismatchButton = forwardRef<
HTMLButtonElement,
MistmatchButtonProps
>((props, ref) => {
const { desiredChainId, twAccount, ...buttonProps } = props;
const { txChainId, twAccount, ...buttonProps } = props;
const account = useActiveAccount();
const wallet = useActiveWallet();
const activeWalletChain = useActiveWalletChain();
const [dialog, setDialog] = useState<undefined | "no-funds" | "pay">();
const { theme } = useTheme();
const client = useThirdwebClient();
const pathname = usePathname();
const txChain = useV5DashboardChain(txChainId);

const evmBalance = useWalletBalance({
const txChainBalance = useWalletBalance({
address: account?.address,
chain: activeWalletChain,
chain: txChain,
client,
});

const networksMismatch = useNetworkMismatchAdapter(desiredChainId);
const networksMismatch = useIsNetworkMismatch(txChainId);
const [isMismatchPopoverOpen, setIsMismatchPopoverOpen] = useState(false);
const trackEvent = useTrack();

Expand Down Expand Up @@ -130,8 +131,15 @@ export const MismatchButton = forwardRef<
);
}

const isBalanceRequired = !GAS_FREE_CHAINS.includes(txChainId);

const notEnoughBalance =
(evmBalance.data?.value || 0n) === 0n && !GAS_FREE_CHAINS.includes(chainId);
(txChainBalance.data?.value || 0n) === 0n && isBalanceRequired;

const disabled =
buttonProps.disabled ||
// if user is about to trigger a transaction on txChain, but txChainBalance is not yet loaded and is required before proceeding
(!networksMismatch && txChainBalance.isPending && isBalanceRequired);

return (
<>
Expand All @@ -150,6 +158,7 @@ export const MismatchButton = forwardRef<
<PopoverTrigger asChild>
<Button
{...buttonProps}
disabled={disabled}
type={
networksMismatch || notEnoughBalance ? "button" : buttonProps.type
}
Expand Down Expand Up @@ -182,7 +191,7 @@ export const MismatchButton = forwardRef<
</PopoverTrigger>
<PopoverContent className="min-w-[350px]" side="top" sideOffset={10}>
<MismatchNotice
desiredChainId={desiredChainId}
txChainId={txChainId}
onClose={(hasSwitched) => {
if (hasSwitched) {
setIsMismatchPopoverOpen(false);
Expand Down Expand Up @@ -416,8 +425,8 @@ function GetFundsFromFaucet(props: {

const MismatchNotice: React.FC<{
onClose: (hasSwitched: boolean) => void;
desiredChainId: number;
}> = ({ onClose, desiredChainId }) => {
txChainId: number;
}> = ({ onClose, txChainId }) => {
const connectedChainId = useActiveWalletChain()?.id;
const switchNetwork = useSwitchActiveWalletChain();
const activeWallet = useActiveWallet();
Expand All @@ -427,14 +436,15 @@ const MismatchNotice: React.FC<{
const walletConnectedNetworkInfo = connectedChainId
? idToChain.get(connectedChainId)
: undefined;
const chain = desiredChainId ? idToChain.get(desiredChainId) : undefined;
const chainV5 = useV5DashboardChain(desiredChainId);

const txChain = txChainId ? idToChain.get(txChainId) : undefined;
const chainV5 = useV5DashboardChain(txChainId);
const switchNetworkMutation = useMutation({
mutationFn: switchNetwork,
});

const onSwitchWallet = useCallback(async () => {
if (actuallyCanAttemptSwitch && desiredChainId && chainV5) {
if (actuallyCanAttemptSwitch && txChainId && chainV5) {
try {
await switchNetworkMutation.mutateAsync(chainV5);
onClose(true);
Expand All @@ -446,7 +456,7 @@ const MismatchNotice: React.FC<{
}, [
chainV5,
actuallyCanAttemptSwitch,
desiredChainId,
txChainId,
onClose,
switchNetworkMutation,
]);
Expand All @@ -458,15 +468,19 @@ const MismatchNotice: React.FC<{
Network Mismatch
</h3>

<p className="text-muted-foreground">
<p className="mb-1 text-muted-foreground">
Your wallet is connected to the{" "}
<span className="font-medium capitalize">
<span className="font-semibold capitalize">
{walletConnectedNetworkInfo?.name ||
`Chain ID #${connectedChainId}`}
</span>{" "}
network but this action requires you to connect to the{" "}
<span className="font-medium capitalize">
{chain?.name || `Chain ID #${desiredChainId}`}
network
</p>

<p className="text-muted-foreground">
This action requires you to connect to the{" "}
<span className="font-semibold capitalize">
{txChain?.name || `Chain ID #${txChainId}`}
</span>{" "}
network.
</p>
Expand All @@ -485,7 +499,7 @@ const MismatchNotice: React.FC<{
<UnplugIcon className="size-4 shrink-0" />
)}
<span className="line-clamp-1 block truncate">
Switch {chain ? `to ${chain.name}` : "chain"}
Switch {txChain ? `to ${txChain.name}` : "chain"}
</span>
</Button>

Expand Down
4 changes: 2 additions & 2 deletions apps/dashboard/src/components/buttons/TransactionButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export const TransactionButton: React.FC<TransactionButtonProps> = ({
<PopoverTrigger asChild>
<ButtonComponent
variant={variant || "primary"}
desiredChainId={txChainID}
txChainId={txChainID}
twAccount={twAccount}
{...restButtonProps}
disabled={disabled}
Expand Down Expand Up @@ -189,7 +189,7 @@ const ExternalApprovalNotice: React.FC<ExternalApprovalNoticeProps> = ({
<h4 className="text-foreground">Approve Transaction</h4>

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

{showHint && (
Expand Down

0 comments on commit 0682f26

Please sign in to comment.