@@ -20,6 +20,7 @@ import {
2020 Address ,
2121 ProtocolType ,
2222 addBufferToGasLimit ,
23+ assert ,
2324 pick ,
2425 rootLogger ,
2526 timeout ,
@@ -171,8 +172,20 @@ export class MultiProvider<MetaExt = {}> extends ChainMetadataManager<MetaExt> {
171172 const chainName = this . getChainName ( chainNameOrId ) ;
172173 this . providers [ chainName ] = provider ;
173174 const signer = this . signers [ chainName ] ;
174- if ( signer && signer . provider ) {
175- this . setSigner ( chainName , signer . connect ( provider ) ) ;
175+ if ( signer && signer . provider && ! this . useSharedSigner ) {
176+ try {
177+ this . setSigner ( chainName , signer . connect ( provider ) ) ;
178+ } catch ( e : unknown ) {
179+ // JsonRpcSigner throws UNSUPPORTED_OPERATION for .connect();
180+ // use a type guard instead of `as` cast to safely access .code
181+ const code =
182+ typeof e === 'object' && e !== null && 'code' in e
183+ ? String ( ( e as Record < string , unknown > ) . code )
184+ : undefined ;
185+ if ( code !== 'UNSUPPORTED_OPERATION' ) {
186+ throw e ;
187+ }
188+ }
176189 }
177190 return provider ;
178191 }
@@ -183,8 +196,7 @@ export class MultiProvider<MetaExt = {}> extends ChainMetadataManager<MetaExt> {
183196 */
184197 setProviders ( providers : ChainMap < Provider > ) : void {
185198 for ( const chain of Object . keys ( providers ) ) {
186- const chainName = this . getChainName ( chain ) ;
187- this . providers [ chainName ] = providers [ chain ] ;
199+ this . setProvider ( chain , providers [ chain ] ) ;
188200 }
189201 }
190202
@@ -201,7 +213,15 @@ export class MultiProvider<MetaExt = {}> extends ChainMetadataManager<MetaExt> {
201213 // Auto-connect the signer for convenience
202214 const provider = this . tryGetProvider ( chainName ) ;
203215 if ( ! provider ) return signer ;
204- return signer . connect ( provider ) ;
216+ const connected = signer . connect ( provider ) ;
217+ // Only cache when not using a shared signer. In shared-signer mode,
218+ // caching pins the signer to this provider; setProvider() skips
219+ // reconnection when useSharedSigner is true, so the cached signer
220+ // would go stale after a provider swap.
221+ if ( ! this . useSharedSigner ) {
222+ this . signers [ chainName ] = connected ;
223+ }
224+ return connected ;
205225 }
206226
207227 /**
@@ -336,6 +356,7 @@ export class MultiProvider<MetaExt = {}> extends ChainMetadataManager<MetaExt> {
336356 rangeSize = this . getMaxBlockRange ( chainNameOrId ) ,
337357 ) : Promise < { fromBlock : number ; toBlock : number } > {
338358 const toBlock = await this . getProvider ( chainNameOrId ) . getBlock ( 'latest' ) ;
359+ assert ( toBlock , `Unable to fetch latest block for ${ chainNameOrId } ` ) ;
339360 const fromBlock = Math . max ( toBlock . number - rangeSize , 0 ) ;
340361 return { fromBlock, toBlock : toBlock . number } ;
341362 }
@@ -395,6 +416,7 @@ export class MultiProvider<MetaExt = {}> extends ChainMetadataManager<MetaExt> {
395416 ...overrides ,
396417 } ) ;
397418 // manually wait for deploy tx to be confirmed
419+ assert ( contract . deployTransaction , 'Deploy transaction missing' ) ;
398420 await this . handleTx ( chainNameOrId , contract . deployTransaction ) ;
399421 }
400422
@@ -489,11 +511,13 @@ export class MultiProvider<MetaExt = {}> extends ChainMetadataManager<MetaExt> {
489511 this . logger . info (
490512 `Pending ${ txUrl || response . hash } (wait(0) returned pending, waiting for initial inclusion)` ,
491513 ) ;
492- return timeout (
514+ const inclusionReceipt = await timeout (
493515 response . wait ( 1 ) ,
494516 timeoutMs ,
495517 `Timeout (${ timeoutMs } ms) waiting for initial inclusion for tx ${ response . hash } ` ,
496518 ) ;
519+ assert ( inclusionReceipt , `Transaction ${ response . hash } was not included` ) ;
520+ return inclusionReceipt ;
497521 }
498522
499523 /**
@@ -511,6 +535,11 @@ export class MultiProvider<MetaExt = {}> extends ChainMetadataManager<MetaExt> {
511535 ) : Promise < ContractReceipt > {
512536 const provider = this . getProvider ( chainNameOrId ) ;
513537 const receipt = await response . wait ( 1 ) ; // Wait for initial inclusion
538+ assert ( receipt , `Transaction ${ response . hash } was not included` ) ;
539+ assert (
540+ typeof receipt . blockNumber === 'number' ,
541+ `Receipt missing block number for tx ${ response . hash } ` ,
542+ ) ;
514543 const txBlock = receipt . blockNumber ;
515544
516545 // Check if block tag is supported on first call
0 commit comments