diff --git a/src/providers/useWalletConnectProvider.ts b/src/providers/useWalletConnectProvider.ts index cef0dd63..86d56228 100644 --- a/src/providers/useWalletConnectProvider.ts +++ b/src/providers/useWalletConnectProvider.ts @@ -6,7 +6,25 @@ interface Result { connected: boolean } +class ProviderEventTarget extends EventTarget { + constructor(provider: WalletConnectEthereumProvider) { + super() + + // @ts-expect-error signer is a private property, but we didn't find another way + provider.signer.on('connect', () => { + this.dispatchEvent(new Event('connect')) + }) + + provider.on('disconnect', () => { + this.dispatchEvent(new Event('disconnect')) + }) + } +} + +// Global states for providers and event targets const providers: Record = {} +// We need the indirection via an extra EventTarget to workaround MaxListenersExceededWarning emitted from WalletConnectEthereumProvider +const providerEventTargets: Record = {} const useWalletConnectProvider = (connectionId: string): Result => { if (!providers[connectionId]) { @@ -17,30 +35,33 @@ const useWalletConnectProvider = (connectionId: string): Result => { 100: 'https://rpc.gnosischain.com/', }, }) + providerEventTargets[connectionId] = new ProviderEventTarget( + providers[connectionId] + ) } + const provider = providers[connectionId] const [connected, setConnected] = useState(provider.connected) + const providerEventTarget = providerEventTargets[connectionId] useEffect(() => { const handleConnection = () => { console.log(`WalletConnect connected: ${connectionId}`) setConnected(true) } - // @ts-expect-error signer is a private property, but we didn't find another way - provider.signer.on('connect', handleConnection) + providerEventTarget.addEventListener('connect', handleConnection) const handleDisconnection = () => { console.log(`WalletConnect disconnected: ${connectionId}`) setConnected(false) } - provider.on('disconnect', handleDisconnection) + providerEventTarget.addEventListener('disconnect', handleDisconnection) return () => { - // @ts-expect-error signer is a private property, but we didn't find another way - provider.signer.off('connect', handleConnection) - provider.off('disconnect', handleDisconnection) + providerEventTarget.removeEventListener('connect', handleConnection) + providerEventTarget.removeEventListener('disconnect', handleDisconnection) } - }, [provider, connectionId]) + }, [providerEventTarget, connectionId]) return { provider, connected } } diff --git a/src/settings/Connection/ConnectButton/index.tsx b/src/settings/Connection/ConnectButton/index.tsx index db3bd073..17b343a6 100644 --- a/src/settings/Connection/ConnectButton/index.tsx +++ b/src/settings/Connection/ConnectButton/index.tsx @@ -6,8 +6,8 @@ import { useConnection } from '../../connectionHooks' import classes from './style.module.css' import walletConnectLogoUrl from './wallet-connect-logo.png' -const ConnectButton: React.FC = () => { - const { provider, connected } = useConnection() +const ConnectButton: React.FC<{ id: string }> = ({ id }) => { + const { provider, connected } = useConnection(id) return ( <> {connected ? ( diff --git a/src/settings/Connection/Edit.tsx b/src/settings/Connection/Edit.tsx index ecb0acc8..10254142 100644 --- a/src/settings/Connection/Edit.tsx +++ b/src/settings/Connection/Edit.tsx @@ -27,8 +27,10 @@ const EditConnection: React.FC = ({ id, onLaunch }) => { const { connection, connected } = useConnection(id) const { label, avatarAddress, moduleAddress, roleId } = connection - const { loading, isValidSafe, enabledModules } = - useSafeModuleInfo(avatarAddress) + const { loading, isValidSafe, enabledModules } = useSafeModuleInfo( + avatarAddress, + id + ) const pushSettingsRoute = usePushSettingsRoute() @@ -86,7 +88,7 @@ const EditConnection: React.FC = ({ id, onLaunch }) => { /> - + { const [loading, setLoading] = useState(true) const [isValidSafe, setIsValidSafe] = useState(false) const [enabledModules, setEnabledModules] = useState([]) - const { provider, connected } = useConnection() - + const { provider, connected } = useConnection(connectionId) useEffect(() => { if (!connected) return diff --git a/src/settings/useConnectionDryRun.tsx b/src/settings/useConnectionDryRun.tsx index a2a78648..9b5fb25a 100644 --- a/src/settings/useConnectionDryRun.tsx +++ b/src/settings/useConnectionDryRun.tsx @@ -3,6 +3,7 @@ import WalletConnectEthereumProvider from '@walletconnect/ethereum-provider' import { useEffect, useState } from 'react' import { wrapRequest } from '../providers/WrappingProvider' +import { Connection } from '../types' import { decodeRolesError } from '../utils' import { @@ -12,16 +13,13 @@ import { import { useConnection } from './connectionHooks' const useConnectionDryRun = ({ + id, moduleAddress, avatarAddress, roleId, -}: { - moduleAddress: string - avatarAddress: string - roleId: string -}) => { +}: Connection) => { const [error, setError] = useState(null) - const { provider, connected } = useConnection() + const { provider, connected } = useConnection(id) useEffect(() => { if (connected && avatarAddress && moduleAddress && roleId) {