@@ -117,16 +117,31 @@ export abstract class BaseProvider<C extends BaseProviderConfig, S extends BaseP
117117 ( this . _providerEngineProxy as any ) . setTarget ( provider ) ;
118118
119119 // we want events to propagate from Ethereum provider -> wrapper provider (e.g. CommonJRPC provider) -> SDK -> dapp
120- // when a listener is added to the wrapper provider, listen to the same event from the Ethereum provider and re-emit it
121- this . once ( "newListener" , ( event , _listener ) => {
120+ // ensure that only one handler is added for each event
121+ const reEmitHandler = ( event : string ) => {
122+ // listen to the event from the Ethereum provider
122123 provider . on ( event as keyof ProviderEvents , ( ...args ) => {
123124 // handle chainChanged event: update chainId state
124125 if ( event === EIP1193_EVENTS . CHAIN_CHANGED ) {
125126 const chainId = args [ 0 ] as string ;
126127 this . update ( { chainId } as Partial < S > ) ;
127128 }
128- this . emit ( event as keyof BaseProviderEvents < S > , ...( args as never ) ) ;
129+
130+ // re-emit the event
131+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
132+ this . emit ( event as keyof BaseProviderEvents < S > , ...( args as any ) ) ;
129133 } ) ;
134+ } ;
135+
136+ // handle existing events
137+ this . eventNames ( ) . forEach ( ( event ) => {
138+ reEmitHandler ( event as string ) ;
139+ } ) ;
140+ // handle when a new listener is added
141+ this . on ( "newListener" , ( event : string ) => {
142+ // skip if the event already exists
143+ if ( this . listenerCount ( event as keyof BaseProviderEvents < S > ) > 0 ) return ;
144+ reEmitHandler ( event ) ;
130145 } ) ;
131146 } else {
132147 this . _providerEngineProxy = createEventEmitterProxy < SafeEventEmitterProvider > ( provider ) ;
0 commit comments