From 56f2482508f2ba71bd6b0295c70c6abca7101e57 Mon Sep 17 00:00:00 2001 From: Dmitry Blues Date: Fri, 27 Sep 2024 20:00:19 +0200 Subject: [PATCH] Fix race condition in injected.ts (#4207) * Fix race condition in injected.ts It can hangs if "once" catches an event with unexpected chainId * chore: tweaks --------- Co-authored-by: Tom Meagher --- .changeset/hungry-colts-flow.md | 6 ++++++ packages/connectors/src/metaMask.ts | 14 +++++++++----- packages/core/src/connectors/injected.ts | 14 +++++++++----- 3 files changed, 24 insertions(+), 10 deletions(-) create mode 100644 .changeset/hungry-colts-flow.md diff --git a/.changeset/hungry-colts-flow.md b/.changeset/hungry-colts-flow.md new file mode 100644 index 0000000000..fd49674a1c --- /dev/null +++ b/.changeset/hungry-colts-flow.md @@ -0,0 +1,6 @@ +--- +"@wagmi/connectors": patch +"@wagmi/core": patch +--- + +Updated chain switch listener for `injected` and `metaMask` to be more robust. diff --git a/packages/connectors/src/metaMask.ts b/packages/connectors/src/metaMask.ts index 2331621f9b..e3b4f908cd 100644 --- a/packages/connectors/src/metaMask.ts +++ b/packages/connectors/src/metaMask.ts @@ -239,11 +239,15 @@ export function metaMask(parameters: MetaMaskParameters = {}) { if (currentChainId === chainId) config.emitter.emit('change', { chainId }) }), - new Promise((resolve) => - config.emitter.once('change', ({ chainId: currentChainId }) => { - if (currentChainId === chainId) resolve() - }), - ), + new Promise((resolve) => { + const listener = ((data) => { + if ('chainId' in data && data.chainId === chainId) { + config.emitter.off('change', listener) + resolve() + } + }) satisfies Parameters[1] + config.emitter.on('change', listener) + }), ]) return chain } catch (err) { diff --git a/packages/core/src/connectors/injected.ts b/packages/core/src/connectors/injected.ts index 84fdc06e8e..c242094d58 100644 --- a/packages/core/src/connectors/injected.ts +++ b/packages/core/src/connectors/injected.ts @@ -428,11 +428,15 @@ export function injected(parameters: InjectedParameters = {}) { if (currentChainId === chainId) config.emitter.emit('change', { chainId }) }), - new Promise((resolve) => - config.emitter.once('change', ({ chainId: currentChainId }) => { - if (currentChainId === chainId) resolve() - }), - ), + new Promise((resolve) => { + const listener = ((data) => { + if ('chainId' in data && data.chainId === chainId) { + config.emitter.off('change', listener) + resolve() + } + }) satisfies Parameters[1] + config.emitter.on('change', listener) + }), ]) return chain } catch (err) {