Skip to content

Commit ae356ba

Browse files
authored
fix(checkout): Correctly handle adding a new network (#2625)
1 parent 7847ac1 commit ae356ba

3 files changed

Lines changed: 33 additions & 34 deletions

File tree

packages/checkout/sdk/src/network/network.test.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,17 @@ const zkevmNetworkInfo = {
4141
nativeCurrency: ZKEVM_NATIVE_SANDBOX_TOKEN,
4242
};
4343

44+
const unrecognisedChainError = {
45+
error: {
46+
data: {
47+
originalError: {
48+
message: 'Provider error',
49+
code: 4902,
50+
},
51+
},
52+
},
53+
};
54+
4455
jest.mock('../api/http', () => ({
4556
// eslint-disable-next-line @typescript-eslint/naming-convention
4657
HttpClient: jest.fn().mockImplementation(() => ({
@@ -234,10 +245,7 @@ describe('network functions', () => {
234245
(WrappedBrowserProvider as unknown as jest.Mock).mockReturnValue({
235246
send: jest
236247
.fn()
237-
.mockRejectedValue({
238-
message: 'Provider error',
239-
code: 4902,
240-
}),
248+
.mockRejectedValue(unrecognisedChainError),
241249
ethereumProvider: {
242250
isMetaMask: true,
243251
},
@@ -291,7 +299,7 @@ describe('network functions', () => {
291299
.mockReturnValueOnce({
292300
send: jest
293301
.fn()
294-
.mockRejectedValueOnce({ code: 4902 })
302+
.mockRejectedValueOnce(unrecognisedChainError)
295303
.mockResolvedValueOnce({}),
296304
ethereumProvider: {
297305
isMetaMask: true,

packages/checkout/sdk/src/network/network.ts

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* eslint-disable @typescript-eslint/no-explicit-any */
21
import { JsonRpcProvider } from 'ethers';
32
import { CheckoutError, CheckoutErrorType, withCheckoutError } from '../errors';
43
import {
@@ -132,9 +131,16 @@ export async function getNetworkInfo(
132131
);
133132
}
134133

134+
/**
135+
* Errors in ethers v6 are broken - https://github.com/ethers-io/ethers.js/issues/4576
136+
* You get "Error: could not coalesce error....".
137+
* This is a workaround to check if the error is an unrecognised chain error.
138+
* */
139+
const isUnrecognisedChainError = (err: any) => err.error?.data?.originalError?.code === UNRECOGNISED_CHAIN_ERROR_CODE;
140+
135141
export async function switchWalletNetwork(
136142
config: CheckoutConfiguration,
137-
provider: JsonRpcProvider | WrappedBrowserProvider,
143+
provider: WrappedBrowserProvider,
138144
chainId: ChainId,
139145
): Promise<SwitchNetworkResult> {
140146
const { networkMap } = config;
@@ -144,15 +150,15 @@ export async function switchWalletNetwork(
144150
});
145151

146152
if (
147-
!allowedNetworks.networks.some((network) => Number(network.chainId) === chainId)
153+
!allowedNetworks.networks.some((network) => network.chainId === chainId)
148154
) {
149155
throw new CheckoutError(
150156
`Chain:${chainId} is not a supported chain`,
151157
CheckoutErrorType.CHAIN_NOT_SUPPORTED_ERROR,
152158
);
153159
}
154160

155-
if ('ethereumProvider' in provider && provider.ethereumProvider?.isPassport) {
161+
if (provider.ethereumProvider?.isPassport) {
156162
throw new CheckoutError(
157163
'Switching networks with Passport provider is not supported',
158164
CheckoutErrorType.SWITCH_NETWORK_UNSUPPORTED,
@@ -161,29 +167,15 @@ export async function switchWalletNetwork(
161167

162168
// WT-1146 - Refer to the README in this folder for explanation on the switch network flow
163169
try {
164-
if (provider && 'ethereumProvider' in provider) {
165-
await switchNetworkInWallet(networkMap, provider, chainId);
166-
} else {
167-
throw new CheckoutError(
168-
'Incorrect provider type',
169-
CheckoutErrorType.PROVIDER_ERROR,
170-
);
171-
}
172-
} catch (err: any) {
170+
await switchNetworkInWallet(networkMap, provider, chainId);
171+
} catch (err) {
173172
// eslint-disable-next-line no-console
174173
console.error(err);
175-
if (err.code === UNRECOGNISED_CHAIN_ERROR_CODE) {
174+
if (isUnrecognisedChainError(err)) {
176175
try {
177-
if ('ethereumProvider' in provider) {
178-
await addNetworkToWallet(networkMap, provider, chainId);
179-
} else {
180-
throw new CheckoutError(
181-
'Incorrect provider type',
182-
CheckoutErrorType.PROVIDER_ERROR,
183-
);
184-
}
176+
await addNetworkToWallet(networkMap, provider, chainId);
185177
// eslint-disable-next-line @typescript-eslint/no-shadow
186-
} catch (err: any) {
178+
} catch (err) {
187179
throw new CheckoutError(
188180
'User cancelled add network request',
189181
CheckoutErrorType.USER_REJECTED_REQUEST_ERROR,
@@ -209,10 +201,10 @@ export async function switchWalletNetwork(
209201
);
210202
}
211203

212-
const networkInfo: NetworkInfo = await getNetworkInfo(config, newProvider);
204+
const networkInfo = await getNetworkInfo(config, newProvider);
213205

214206
return {
215207
network: networkInfo,
216208
provider: newProvider,
217-
} as SwitchNetworkResult;
209+
};
218210
}

packages/checkout/widgets-lib/src/widgets/connect/views/SwitchNetworkZkEVM.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,8 @@ export function SwitchNetworkZkEVM() {
7575

7676
if (!provider.send) return;
7777

78-
const currentChainId = await provider.send('eth_chainId', []);
79-
// eslint-disable-next-line radix
80-
const parsedChainId = Number(currentChainId.toString());
78+
const currentChainId = await provider.send('eth_chainId', []) as `0x${string}`;
79+
const parsedChainId = Number(currentChainId);
8180

8281
if (parsedChainId === checkout.config.l2ChainId) {
8382
connectDispatch({
@@ -102,7 +101,7 @@ export function SwitchNetworkZkEVM() {
102101
try {
103102
let walletName = '';
104103
if (isWalletConnectProvider(provider)) {
105-
walletName = (provider.provider as any)?.session?.peer?.metadata?.name.toLowerCase();
104+
walletName = (provider.ethereumProvider as any)?.session?.peer?.metadata?.name.toLowerCase();
106105
}
107106
if (walletName.includes('metamask')) {
108107
try {

0 commit comments

Comments
 (0)