Skip to content

WalletConnect switchChain leaks a change listener on failure #5032

@Zelys-DFKH

Description

@Zelys-DFKH

When switchChain fails (user rejection, network error, RPC timeout), the change event listener registered on the connector's emitter is never removed.

What's happening

In packages/connectors/src/walletConnect.ts, the implementation registers a listener to wait for the chain-changed confirmation:

```typescript
config.emitter.on('change', listener)
```

This runs concurrently with the wallet_switchEthereumChain request inside Promise.all. When the request rejects, Promise.all propagates the rejection to the catch block, but the listener stays attached. There's no cleanup on the error path.

Why it matters

Every failed switch attempt adds one orphaned listener to the connector's emitter. With mobile wallets via WalletConnect, rejections are common: user dismisses the prompt, wallet is backgrounded, connection drops. These pile up.

Reproduction

```typescript
// WalletConnect connector, any chain that prompts a switch

for (let i = 0; i < 5; i++) {
await connector.switchChain({ chainId: 1 }).catch(() => {})
}

console.log(connector.emitter.listenerCount('change')) // 5, not 0
```

Environment

  • @wagmi/connectors: 8.x
  • WalletConnect v2, mobile wallet (iOS/Android)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions