File tree Expand file tree Collapse file tree
ion_connect/providers/relays Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -59,6 +59,12 @@ class RelayAuth extends _$RelayAuth {
5959 ref.read (relaysReplicaDelayProvider.notifier).setDelay ();
6060 return true ;
6161 }
62+ // If relay is already authenticated with a different public key (user switch/logout race condition),
63+ // close the relay connection. RelayClosedMixin will automatically invalidate the relay provider,
64+ // causing the next request to get a fresh connection with correct credentials.
65+ if (RelayAuthService .isAlreadyAuthenticatedWithDifferentKeyError (error)) {
66+ relay.close ();
67+ }
6268 return false ;
6369 },
6470 );
@@ -188,4 +194,13 @@ class RelayAuthService {
188194 static bool isRelayAuthoritativeError (Object ? error) {
189195 return error is SendEventException && error.code.startsWith ('relay-is-authoritative' );
190196 }
197+
198+ /// Detects if the error indicates the relay is already authenticated with a different public key.
199+ /// This can happen during user switch/logout when a relay connection is reused before being invalidated.
200+ static bool isAlreadyAuthenticatedWithDifferentKeyError (Object ? error) {
201+ if (error is ! SendEventException ) return false ;
202+ final errorMessage = error.code.toLowerCase ();
203+ return errorMessage.contains ('already authenticated' ) &&
204+ errorMessage.contains ('different public key' );
205+ }
191206}
Original file line number Diff line number Diff line change @@ -110,11 +110,16 @@ class Count extends _$Count {
110110 },
111111 );
112112
113- await ref.read (ionConnectNotifierProvider.notifier).sendEvent (
114- requestEvent,
115- actionSource: ActionSourceRelayUrl (relay.keys.first.url),
116- cache: false ,
117- );
113+ try {
114+ await ref.read (ionConnectNotifierProvider.notifier).sendEvent (
115+ requestEvent,
116+ actionSource: ActionSourceRelayUrl (relay.keys.first.url),
117+ cache: false ,
118+ );
119+ } catch (sendError) {
120+ relay.keys.first.unsubscribe (subscription.id);
121+ rethrow ;
122+ }
118123
119124 final responseEntity = await messagesFuture;
120125
Original file line number Diff line number Diff line change @@ -28,16 +28,20 @@ class FollowersCount extends _$FollowersCount {
2828 ),
2929 ];
3030
31- return await ref.watch (
32- countProvider (
33- actionSource: ActionSourceUser (pubkey),
34- requestData: EventCountRequestData (filters: filters),
35- key: pubkey,
36- type: EventCountResultType .followers,
37- cache: cache,
38- network: network,
39- ).future,
40- ) as FutureOr <int ?>;
31+ try {
32+ return await ref.watch (
33+ countProvider (
34+ actionSource: ActionSourceUser (pubkey),
35+ requestData: EventCountRequestData (filters: filters),
36+ key: pubkey,
37+ type: EventCountResultType .followers,
38+ cache: cache,
39+ network: network,
40+ ).future,
41+ ) as FutureOr <int ?>;
42+ } catch (error) {
43+ return null ;
44+ }
4145 }
4246
4347 void addOne () {
You can’t perform that action at this time.
0 commit comments