diff --git a/backend/mpc-system/services/service-party-android/app/src/main/java/com/durian/tssparty/data/repository/TssRepository.kt b/backend/mpc-system/services/service-party-android/app/src/main/java/com/durian/tssparty/data/repository/TssRepository.kt index af74fce7..c0ecff0c 100644 --- a/backend/mpc-system/services/service-party-android/app/src/main/java/com/durian/tssparty/data/repository/TssRepository.kt +++ b/backend/mpc-system/services/service-party-android/app/src/main/java/com/durian/tssparty/data/repository/TssRepository.kt @@ -276,6 +276,27 @@ class TssRepository @Inject constructor( } } + /** + * Ensure session event subscription is active + * Called before critical operations (like joining sign session) to ensure + * the event stream hasn't silently disconnected + */ + private fun ensureSessionEventSubscriptionActive() { + // Check if the session event job is still active + val isActive = sessionEventJob?.isActive == true + android.util.Log.d("TssRepository", "Checking session event subscription: isActive=$isActive") + + if (!isActive) { + android.util.Log.w("TssRepository", "Session event subscription is not active, restarting...") + startSessionEventSubscription() + } else { + // Even if the job is "active", the gRPC stream may have silently disconnected + // Force a restart to ensure we have a fresh connection + android.util.Log.d("TssRepository", "Refreshing session event subscription to ensure fresh connection") + startSessionEventSubscription() + } + } + /** * Set session event callback (called by ViewModel) */ @@ -1143,6 +1164,10 @@ class TssRepository @Inject constructor( // Start message subscription (matching Electron's prepareForSign) startMessageRouting(sessionId, myPartyIndex) + // CRITICAL: Ensure session event subscription is active + // The event stream may have silently disconnected, so refresh it + ensureSessionEventSubscriptionActive() + android.util.Log.d("TssRepository", "Sign session state set, waiting for session_started event or in_progress status") Result.success(JoinSignViaGrpcResult( @@ -2049,6 +2074,10 @@ class TssRepository @Inject constructor( // Step 5: Start message routing (prepareForSign) BEFORE sign starts startMessageRouting(sessionId, myPartyIndex) + // CRITICAL: Ensure session event subscription is active for sign initiator + // The event stream may have silently disconnected + ensureSessionEventSubscriptionActive() + // Step 6: Check if session already in_progress if (joinData.sessionStatus == "in_progress") { android.util.Log.d("TssRepository", "[CO-SIGN] Session already in_progress, will trigger sign immediately")