Skip to content

Commit

Permalink
fix: metamask chain switch with missing net_version (#3859)
Browse files Browse the repository at this point in the history
* fix: metamask chain switch with missing net_version

* chore: up comment

* chore: changeset

---------

Co-authored-by: Tom Meagher <tom@meagher.co>
  • Loading branch information
holic and tmm committed Apr 26, 2024
1 parent d4274c0 commit 400c960
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 14 deletions.
5 changes: 5 additions & 0 deletions .changeset/tough-steaks-rush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@wagmi/core": patch
---

Added workaround to injected connector for MetaMask bug, where chain switching does not work if target chain RPC `'net_version'` request fails.
34 changes: 20 additions & 14 deletions packages/core/src/connectors/injected.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {
type AddEthereumChainParameter,
type Address,
type EIP1193EventMap,
type EIP1193Provider,
type ProviderConnectInfo,
ProviderRpcError,
Expand Down Expand Up @@ -384,19 +383,26 @@ export function injected(parameters: InjectedParameters = {}) {

try {
await Promise.all([
provider.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: numberToHex(chainId) }],
}),
new Promise<void>((resolve) => {
const listener: EIP1193EventMap['chainChanged'] = (data) => {
if (Number(data) === chainId) {
provider.removeListener('chainChanged', listener)
resolve()
}
}
provider.on('chainChanged', listener)
}),
provider
.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: numberToHex(chainId) }],
})
// During `'wallet_switchEthereumChain'`, MetaMask makes a `'net_version'` RPC call to the target chain.
// If this request fails, MetaMask does not emit the `'chainChanged'` event, but will still switch the chain.
// To counter this behavior, we request and emit the current chain ID to confirm the chain switch either via
// this callback or an externally emitted `'chainChanged'` event.
// https://github.com/MetaMask/metamask-extension/issues/24247
.then(async () => {
const currentChainId = await this.getChainId()
if (currentChainId === chainId)
config.emitter.emit('change', { chainId })
}),
new Promise<void>((resolve) =>
config.emitter.once('change', ({ chainId: currentChainId }) => {
if (currentChainId === chainId) resolve()
}),
),
])
return chain
} catch (err) {
Expand Down

0 comments on commit 400c960

Please sign in to comment.