@wagmi/connectors 5.7.3 → 5.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- export const version = '5.7.3';
1
+ export const version = '5.7.5';
2
2
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"metaMask.d.ts","sourceRoot":"","sources":["../../src/metaMask.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,kBAAkB,EAElB,WAAW,EACZ,MAAM,eAAe,CAAA;AAStB,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,KAAK,EAEL,YAAY,EACb,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAIL,KAAK,mBAAmB,EAUzB,MAAM,MAAM,CAAA;AAEb,MAAM,MAAM,kBAAkB,GAAG,YAAY,CAC3C,uBAAuB,GACrB,KAAK,CACD;IAEE,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACpC,GACD;IAGE,WAAW,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,EAAE,CAAA;KAAE,GAAG,SAAS,CAAA;CAChE,CACJ,CACJ,CAAA;AAED,KAAK,uBAAuB,GAAG,OAAO,CACpC,YAAY,CACV,IAAI,CACF,kBAAkB,EAChB,SAAS,GACT,qBAAqB,GACrB,qBAAqB,GACrB,gBAAgB,GAChB,aAAa,GACb,gBAAgB,CACnB,CACF,GAAG;IACF,kBAAkB;IAClB,mBAAmB,CAAC,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAA;IAC/D,kBAAkB;IAClB,mBAAmB,CAAC,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAA;IAC/D,kBAAkB;IAClB,cAAc,CAAC,EAAE,kBAAkB,CAAC,gBAAgB,CAAC,CAAA;IACrD,kBAAkB;IAClB,WAAW,CAAC,EAAE,kBAAkB,CAAC,aAAa,CAAC,CAAA;CAChD,CACF,CAAA;AAGD,wBAAgB,QAAQ,CAAC,UAAU,GAAE,kBAAuB;2BAGjC,mBAAmB,GAAG,IAAI;sBAC/B,MAAM,GAAG,IAAI;4BAgalC;yBApae,QAAQ"}
1
+ {"version":3,"file":"metaMask.d.ts","sourceRoot":"","sources":["../../src/metaMask.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,kBAAkB,EAElB,WAAW,EACZ,MAAM,eAAe,CAAA;AAQtB,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,KAAK,EAEL,YAAY,EACb,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAIL,KAAK,mBAAmB,EAWzB,MAAM,MAAM,CAAA;AAEb,MAAM,MAAM,kBAAkB,GAAG,YAAY,CAC3C,uBAAuB,GACrB,KAAK,CACD;IAEE,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACpC,GACD;IAGE,WAAW,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,EAAE,CAAA;KAAE,GAAG,SAAS,CAAA;CAChE,CACJ,CACJ,CAAA;AAED,KAAK,uBAAuB,GAAG,OAAO,CACpC,YAAY,CACV,IAAI,CACF,kBAAkB,EAChB,SAAS,GACT,qBAAqB,GACrB,qBAAqB,GACrB,gBAAgB,GAChB,aAAa,GACb,gBAAgB,CACnB,CACF,GAAG;IACF,kBAAkB;IAClB,mBAAmB,CAAC,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAA;IAC/D,kBAAkB;IAClB,mBAAmB,CAAC,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAA;IAC/D,kBAAkB;IAClB,cAAc,CAAC,EAAE,kBAAkB,CAAC,gBAAgB,CAAC,CAAA;IACrD,kBAAkB;IAClB,WAAW,CAAC,EAAE,kBAAkB,CAAC,aAAa,CAAC,CAAA;CAChD,CACF,CAAA;AAGD,wBAAgB,QAAQ,CAAC,UAAU,GAAE,kBAAuB;2BAGjC,mBAAmB,GAAG,IAAI;sBAC/B,MAAM,GAAG,IAAI;4BAwalC;yBA5ae,QAAQ"}
@@ -1,2 +1,2 @@
1
- export declare const version = "5.7.3";
1
+ export declare const version = "5.7.5";
2
2
  //# sourceMappingURL=version.d.ts.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@wagmi/connectors",
3
3
  "description": "Collection of connectors for Wagmi",
4
- "version": "5.7.3",
4
+ "version": "5.7.5",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "dependencies": {
41
41
  "@coinbase/wallet-sdk": "4.2.3",
42
- "@metamask/sdk": "0.31.4",
42
+ "@metamask/sdk": "0.31.5",
43
43
  "@safe-global/safe-apps-provider": "0.18.5",
44
44
  "@safe-global/safe-apps-sdk": "9.1.0",
45
45
  "@walletconnect/ethereum-provider": "2.17.0",
package/src/metaMask.ts CHANGED
@@ -11,7 +11,6 @@ import {
11
11
  createConnector,
12
12
  extractRpcUrls,
13
13
  } from '@wagmi/core'
14
- import type { linea, lineaSepolia, mainnet, sepolia } from '@wagmi/core/chains'
15
14
  import type {
16
15
  Compute,
17
16
  ExactPartial,
@@ -24,6 +23,7 @@ import {
24
23
  type Address,
25
24
  type Hex,
26
25
  type ProviderConnectInfo,
26
+ type ProviderRpcError,
27
27
  ResourceUnavailableRpcError,
28
28
  type RpcError,
29
29
  SwitchChainError,
@@ -315,57 +315,11 @@ export function metaMask(parameters: MetaMaskParameters = {}) {
315
315
  const chain = config.chains.find((x) => x.id === chainId)
316
316
  if (!chain) throw new SwitchChainError(new ChainNotConfiguredError())
317
317
 
318
- // Default chains cannot be added or removed
319
- const isDefaultChain = (() => {
320
- const metaMaskDefaultChains = [
321
- 1, 11_155_111, 59_144, 59_141,
322
- ] satisfies [
323
- typeof mainnet.id,
324
- typeof sepolia.id,
325
- typeof linea.id,
326
- typeof lineaSepolia.id,
327
- ]
328
- return metaMaskDefaultChains.find((x) => x === chainId)
329
- })()
330
-
331
- // Avoid back and forth on mobile by using `'wallet_addEthereumChain'` for non-default chains
332
318
  try {
333
- if (!isDefaultChain)
334
- await provider.request({
335
- method: 'wallet_addEthereumChain',
336
- params: [
337
- {
338
- blockExplorerUrls: (() => {
339
- const { default: blockExplorer, ...blockExplorers } =
340
- chain.blockExplorers ?? {}
341
- if (addEthereumChainParameter?.blockExplorerUrls)
342
- return addEthereumChainParameter.blockExplorerUrls
343
- if (blockExplorer)
344
- return [
345
- blockExplorer.url,
346
- ...Object.values(blockExplorers).map((x) => x.url),
347
- ]
348
- return
349
- })(),
350
- chainId: numberToHex(chainId),
351
- chainName: addEthereumChainParameter?.chainName ?? chain.name,
352
- iconUrls: addEthereumChainParameter?.iconUrls,
353
- nativeCurrency:
354
- addEthereumChainParameter?.nativeCurrency ??
355
- chain.nativeCurrency,
356
- rpcUrls: (() => {
357
- if (addEthereumChainParameter?.rpcUrls?.length)
358
- return addEthereumChainParameter.rpcUrls
359
- return [chain.rpcUrls.default?.http[0] ?? '']
360
- })(),
361
- } satisfies AddEthereumChainParameter,
362
- ],
363
- })
364
- else
365
- await provider.request({
366
- method: 'wallet_switchEthereumChain',
367
- params: [{ chainId: numberToHex(chainId) }],
368
- })
319
+ await provider.request({
320
+ method: 'wallet_switchEthereumChain',
321
+ params: [{ chainId: numberToHex(chainId) }],
322
+ })
369
323
 
370
324
  // During `'wallet_switchEthereumChain'`, MetaMask makes a `'net_version'` RPC call to the target chain.
371
325
  // If this request fails, MetaMask does not emit the `'chainChanged'` event, but will still switch the chain.
@@ -375,47 +329,101 @@ export function metaMask(parameters: MetaMaskParameters = {}) {
375
329
  await waitForChainIdToSync()
376
330
  await sendAndWaitForChangeEvent(chainId)
377
331
 
378
- async function waitForChainIdToSync() {
379
- // On mobile, there is a race condition between the result of `'wallet_addEthereumChain'` and `'eth_chainId'`.
380
- // To avoid this, we wait for `'eth_chainId'` to return the expected chain ID with a retry loop.
381
- await withRetry(
382
- async () => {
383
- const value = hexToNumber(
384
- // `'eth_chainId'` is cached by the MetaMask SDK side to avoid unnecessary deeplinks
385
- (await provider.request({ method: 'eth_chainId' })) as Hex,
386
- )
387
- // `value` doesn't match expected `chainId`, throw to trigger retry
388
- if (value !== chainId)
389
- throw new Error('User rejected switch after adding network.')
390
- return value
391
- },
392
- {
393
- delay: 50,
394
- retryCount: 20, // android device encryption is slower
395
- },
396
- )
397
- }
398
-
399
- async function sendAndWaitForChangeEvent(chainId: number) {
400
- await new Promise<void>((resolve) => {
401
- const listener = ((data) => {
402
- if ('chainId' in data && data.chainId === chainId) {
403
- config.emitter.off('change', listener)
404
- resolve()
405
- }
406
- }) satisfies Parameters<typeof config.emitter.on>[1]
407
- config.emitter.on('change', listener)
408
- config.emitter.emit('change', { chainId })
409
- })
410
- }
411
-
412
332
  return chain
413
333
  } catch (err) {
414
334
  const error = err as RpcError
335
+
415
336
  if (error.code === UserRejectedRequestError.code)
416
337
  throw new UserRejectedRequestError(error)
338
+
339
+ // Indicates chain is not added to provider
340
+ if (
341
+ error.code === 4902 ||
342
+ // Unwrapping for MetaMask Mobile
343
+ // https://github.com/MetaMask/metamask-mobile/issues/2944#issuecomment-976988719
344
+ (error as ProviderRpcError<{ originalError?: { code: number } }>)
345
+ ?.data?.originalError?.code === 4902
346
+ ) {
347
+ try {
348
+ await provider.request({
349
+ method: 'wallet_addEthereumChain',
350
+ params: [
351
+ {
352
+ blockExplorerUrls: (() => {
353
+ const { default: blockExplorer, ...blockExplorers } =
354
+ chain.blockExplorers ?? {}
355
+ if (addEthereumChainParameter?.blockExplorerUrls)
356
+ return addEthereumChainParameter.blockExplorerUrls
357
+ if (blockExplorer)
358
+ return [
359
+ blockExplorer.url,
360
+ ...Object.values(blockExplorers).map((x) => x.url),
361
+ ]
362
+ return
363
+ })(),
364
+ chainId: numberToHex(chainId),
365
+ chainName: addEthereumChainParameter?.chainName ?? chain.name,
366
+ iconUrls: addEthereumChainParameter?.iconUrls,
367
+ nativeCurrency:
368
+ addEthereumChainParameter?.nativeCurrency ??
369
+ chain.nativeCurrency,
370
+ rpcUrls: (() => {
371
+ if (addEthereumChainParameter?.rpcUrls?.length)
372
+ return addEthereumChainParameter.rpcUrls
373
+ return [chain.rpcUrls.default?.http[0] ?? '']
374
+ })(),
375
+ } satisfies AddEthereumChainParameter,
376
+ ],
377
+ })
378
+
379
+ await waitForChainIdToSync()
380
+ await sendAndWaitForChangeEvent(chainId)
381
+
382
+ return chain
383
+ } catch (err) {
384
+ const error = err as RpcError
385
+ if (error.code === UserRejectedRequestError.code)
386
+ throw new UserRejectedRequestError(error)
387
+ throw new SwitchChainError(error)
388
+ }
389
+ }
390
+
417
391
  throw new SwitchChainError(error)
418
392
  }
393
+
394
+ async function waitForChainIdToSync() {
395
+ // On mobile, there is a race condition between the result of `'wallet_addEthereumChain'` and `'eth_chainId'`.
396
+ // To avoid this, we wait for `'eth_chainId'` to return the expected chain ID with a retry loop.
397
+ await withRetry(
398
+ async () => {
399
+ const value = hexToNumber(
400
+ // `'eth_chainId'` is cached by the MetaMask SDK side to avoid unnecessary deeplinks
401
+ (await provider.request({ method: 'eth_chainId' })) as Hex,
402
+ )
403
+ // `value` doesn't match expected `chainId`, throw to trigger retry
404
+ if (value !== chainId)
405
+ throw new Error('User rejected switch after adding network.')
406
+ return value
407
+ },
408
+ {
409
+ delay: 50,
410
+ retryCount: 20, // android device encryption is slower
411
+ },
412
+ )
413
+ }
414
+
415
+ async function sendAndWaitForChangeEvent(chainId: number) {
416
+ await new Promise<void>((resolve) => {
417
+ const listener = ((data) => {
418
+ if ('chainId' in data && data.chainId === chainId) {
419
+ config.emitter.off('change', listener)
420
+ resolve()
421
+ }
422
+ }) satisfies Parameters<typeof config.emitter.on>[1]
423
+ config.emitter.on('change', listener)
424
+ config.emitter.emit('change', { chainId })
425
+ })
426
+ }
419
427
  },
420
428
  async onAccountsChanged(accounts) {
421
429
  // Disconnect if there are no accounts
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = '5.7.3'
1
+ export const version = '5.7.5'