Skip to content

Commit 55fb360

Browse files
committed
fix: allow any wallet to auto-switch chain, not just injected
1 parent 51e42a4 commit 55fb360

File tree

15 files changed

+68
-27
lines changed

15 files changed

+68
-27
lines changed

app/[locale]/learn/wallets/add-network/[slug]/AddNetworkButton.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@ const AddNetworkButton = ({ chainId, label }: Props) => {
1717
const { isConnected } = useAccount();
1818
const isMounted = useMounted();
1919

20-
return isConnected && isMounted ? (
21-
<Button style="primary" size="md" onClick={() => switchChain(chainId)}>
22-
{label}
23-
</Button>
24-
) : (
25-
<ConnectButton style="primary" size="md" />
26-
);
20+
if (isConnected && isMounted) {
21+
return (
22+
<Button style="primary" size="md" onClick={() => switchChain(chainId)}>
23+
{label}
24+
</Button>
25+
);
26+
}
27+
28+
return <ConnectButton style="primary" size="md" />;
2729
};
2830

2931
export default AddNetworkButton;

components/allowances/controls/ControlsWrapper.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,28 @@ interface Props {
1414
children: (disabled: boolean) => ReactElement;
1515
overrideDisabled?: boolean;
1616
disabledReason?: string;
17+
skipSwitchChain?: boolean;
1718
}
1819

19-
const ControlsWrapper = ({ chainId, address, switchChainSize, children, overrideDisabled, disabledReason }: Props) => {
20+
const ControlsWrapper = ({
21+
chainId,
22+
address,
23+
switchChainSize,
24+
children,
25+
overrideDisabled,
26+
disabledReason,
27+
skipSwitchChain,
28+
}: Props) => {
2029
const t = useTranslations();
21-
const { address: account, connector, chain } = useAccount();
30+
const { address: account, chain } = useAccount();
2231

2332
const chainName = getChainName(chainId);
2433

2534
const isConnected = !isNullish(account);
2635
const isConnectedAddress = isConnected && address === account;
27-
const needsToSwitchChain = isConnected && chainId !== chain?.id;
28-
const canSwitchChain = connector?.type === 'injected';
36+
const needsToSwitchChain = isConnected && chainId !== chain?.id && !skipSwitchChain;
2937
const isChainSwitchEnabled = !isNullish(switchChainSize);
30-
const shouldRenderSwitchChainButton = needsToSwitchChain && canSwitchChain && isChainSwitchEnabled;
38+
const shouldRenderSwitchChainButton = needsToSwitchChain && isChainSwitchEnabled;
3139
const disabled =
3240
!isConnectedAddress || (needsToSwitchChain && !shouldRenderSwitchChainButton) || Boolean(overrideDisabled);
3341

components/allowances/controls/SwitchChainButton.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ interface Props {
1010

1111
const SwitchChainButton = ({ chainId, size }: Props) => {
1212
const t = useTranslations();
13-
const { switchChainAsync, canSwitchChain } = useSwitchChain();
13+
const { switchChainAsync } = useSwitchChain();
1414

1515
const { execute, loading } = useAsyncCallback(() => switchChainAsync(chainId));
1616

1717
const button = (
18-
<Button style="secondary" size={size} disabled={!canSwitchChain} loading={loading} onClick={execute}>
18+
<Button style="secondary" size={size} loading={loading} onClick={execute}>
1919
{loading ? t('common.buttons.switching') : t('common.buttons.switch_chain')}
2020
</Button>
2121
);

components/allowances/controls/batch-revoke/BatchRevokeControls.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const BatchRevokeControls = ({ feeDollarAmount, isRevoking, isAllConfirmed, setO
3030
return (
3131
<div className="flex flex-col items-center justify-center gap-8">
3232
<FeeNotice chainId={selectedChainId} feeDollarAmount={feeDollarAmount} />
33-
<ControlsWrapper chainId={selectedChainId} address={address}>
33+
<ControlsWrapper chainId={selectedChainId} address={address} switchChainSize="md">
3434
{(disabled) => (
3535
<div>
3636
<Button

components/allowances/controls/batch-revoke/BatchRevokeModalWithButton.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,12 @@ const BatchRevokeModalWithButton = ({ table }: Props) => {
4444

4545
return (
4646
<>
47-
<ControlsWrapper chainId={selectedChainId} address={address} overrideDisabled={!isSomeRowsSelected}>
47+
<ControlsWrapper
48+
chainId={selectedChainId}
49+
address={address}
50+
overrideDisabled={!isSomeRowsSelected}
51+
skipSwitchChain
52+
>
4853
{(disabled) => (
4954
<div className="w-fit">
5055
<Button style="primary" size="sm" disabled={disabled} onClick={() => setOpen(true)}>

components/allowances/dashboard/cells/AllowanceCell.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ const AllowanceCell = ({ allowance, onUpdate }: Props) => {
6161
) : null}
6262
</div>
6363
{isErc20Allowance(allowance.payload) && (
64-
<ControlsWrapper chainId={allowance.chainId} address={allowance.owner} switchChainSize={undefined}>
64+
<ControlsWrapper chainId={allowance.chainId} address={allowance.owner}>
6565
{(disabled) => (
6666
<div>
6767
<Button

components/allowances/dashboard/cells/GlobalSelectCell.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@ const GlobalSelectCell = ({ table }: Props) => {
1717
const indeterminate = table.getSelectedRowModel().flatRows.length > 0;
1818

1919
return (
20-
<ControlsWrapper chainId={selectedChainId} address={address} overrideDisabled={selectableCount === 0}>
20+
<ControlsWrapper
21+
chainId={selectedChainId}
22+
address={address}
23+
overrideDisabled={selectableCount === 0}
24+
skipSwitchChain
25+
>
2126
{(disabled) => (
2227
<div className="w-fit">
2328
<Checkbox

components/allowances/dashboard/cells/SelectCell.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const SelectCell = ({ row }: Props) => {
2727
address={address}
2828
overrideDisabled={Boolean(tooltip)}
2929
disabledReason={tooltip}
30+
skipSwitchChain
3031
>
3132
{(disabled) => (
3233
<div className="w-fit">

lib/hooks/ethereum/useSwitchChain.tsx

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,42 @@
11
import { getChainAddEthereumChainParameter } from 'lib/utils/chains';
2+
import { useTranslations } from 'next-intl';
23
import { useCallback } from 'react';
4+
import { toast } from 'react-toastify';
35
import { useAccount, useSwitchChain as useSwitchChainInternal } from 'wagmi';
46

57
export const useSwitchChain = () => {
8+
const t = useTranslations();
9+
610
const { switchChain: switchChainInternal, switchChainAsync: switchChainAsyncInternal } = useSwitchChainInternal();
711
const { connector } = useAccount();
812
const canSwitchChain = connector?.type === 'injected';
913

1014
const switchChain = useCallback(
1115
(chainId: number) => {
12-
const addEthereumChainParameter = getChainAddEthereumChainParameter(chainId);
13-
return switchChainInternal({ chainId, addEthereumChainParameter });
16+
try {
17+
const addEthereumChainParameter = getChainAddEthereumChainParameter(chainId);
18+
return switchChainInternal({ chainId, addEthereumChainParameter });
19+
} catch (error) {
20+
console.error(error);
21+
toast.error(t('common.toasts.switch_chain_failed'));
22+
throw error;
23+
}
1424
},
15-
[switchChainInternal],
25+
[switchChainInternal, t],
1626
);
1727

1828
const switchChainAsync = useCallback(
19-
(chainId: number) => {
20-
const addEthereumChainParameter = getChainAddEthereumChainParameter(chainId);
21-
return switchChainAsyncInternal({ chainId, addEthereumChainParameter });
29+
async (chainId: number) => {
30+
try {
31+
const addEthereumChainParameter = getChainAddEthereumChainParameter(chainId);
32+
return await switchChainAsyncInternal({ chainId, addEthereumChainParameter });
33+
} catch (error) {
34+
console.error(error);
35+
toast.error(t('common.toasts.switch_chain_failed'));
36+
throw error;
37+
}
2238
},
23-
[switchChainAsyncInternal],
39+
[switchChainAsyncInternal, t],
2440
);
2541

2642
return { switchChain, switchChainAsync, canSwitchChain };

lib/utils/errors.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ export const isNetworkError = (error?: string | any): boolean => {
127127
if (lowercaseMessage?.includes('request timed out')) return true;
128128
if (lowercaseMessage?.includes('request took too long to respond')) return true;
129129
if (lowercaseMessage?.includes('failed to fetch')) return true;
130+
if (lowercaseMessage?.includes('service temporarily unavailable')) return true;
130131
return false;
131132
};
132133

0 commit comments

Comments
 (0)