diff --git a/backend/mpc-system/services/service-party-android/app/src/main/java/com/durian/tssparty/presentation/viewmodel/MainViewModel.kt b/backend/mpc-system/services/service-party-android/app/src/main/java/com/durian/tssparty/presentation/viewmodel/MainViewModel.kt index 0afbf2d8..ff96c47f 100644 --- a/backend/mpc-system/services/service-party-android/app/src/main/java/com/durian/tssparty/presentation/viewmodel/MainViewModel.kt +++ b/backend/mpc-system/services/service-party-android/app/src/main/java/com/durian/tssparty/presentation/viewmodel/MainViewModel.kt @@ -395,7 +395,7 @@ class MainViewModel @Inject constructor( val currentSessionId = _currentSessionId.value if (currentSessionId != null && event.sessionId == currentSessionId) { android.util.Log.d("MainViewModel", "Session started event for keygen initiator, triggering keygen") - viewModelScope.launch { + safeLaunch { startKeygenAsInitiator( sessionId = currentSessionId, thresholdT = event.thresholdT, @@ -717,7 +717,7 @@ class MainViewModel @Inject constructor( private fun startKeygenAsJoiner() { val joinInfo = pendingJoinKeygenInfo ?: return - viewModelScope.launch { + safeLaunch { _uiState.update { it.copy(isLoading = true, error = null) } android.util.Log.d("MainViewModel", "Starting keygen as joiner: sessionId=${joinInfo.sessionId}, partyIndex=${joinInfo.partyIndex}") @@ -795,7 +795,7 @@ class MainViewModel @Inject constructor( * Matches Electron's cosign:validateInviteCode - returns sessionInfo + joinToken + parties */ fun validateSignInviteCode(inviteCode: String) { - viewModelScope.launch { + safeLaunch { _uiState.update { it.copy(isLoading = true, error = null) } pendingCoSignInviteCode = inviteCode @@ -905,7 +905,7 @@ class MainViewModel @Inject constructor( private fun startSignAsJoiner() { val signInfo = pendingJoinSignInfo ?: return - viewModelScope.launch { + safeLaunch { _uiState.update { it.copy(isLoading = true, error = null) } android.util.Log.d("MainViewModel", "Starting sign as joiner: sessionId=${signInfo.sessionId}, partyIndex=${signInfo.partyIndex}") @@ -969,7 +969,7 @@ class MainViewModel @Inject constructor( * Delete a share */ fun deleteShare(id: Long) { - viewModelScope.launch { + safeLaunch { repository.deleteShare(id) // Update wallet count _appState.update { state -> @@ -997,7 +997,7 @@ class MainViewModel @Inject constructor( * 加载钱包的交易记录 */ fun loadTransactionRecords(shareId: Long) { - viewModelScope.launch { + safeLaunch { repository.getTransactionRecords(shareId).collect { records -> _transactionRecords.value = records } @@ -1009,7 +1009,7 @@ class MainViewModel @Inject constructor( * 首次导入钱包时调用 */ fun syncTransactionHistory(shareId: Long, address: String) { - viewModelScope.launch { + safeLaunch { _isSyncingHistory.value = true android.util.Log.d("MainViewModel", "[SYNC] Starting transaction history sync for $address") @@ -1040,7 +1040,7 @@ class MainViewModel @Inject constructor( * 应用启动时调用 */ fun confirmPendingTransactions() { - viewModelScope.launch { + safeLaunch { val rpcUrl = _settings.value.kavaRpcUrl val pendingRecords = repository.getPendingTransactions() android.util.Log.d("MainViewModel", "[TX-CONFIRM] Found ${pendingRecords.size} pending transactions") @@ -1181,7 +1181,7 @@ class MainViewModel @Inject constructor( * Test Message Router connection */ fun testMessageRouter(serverUrl: String) { - viewModelScope.launch { + safeLaunch { _messageRouterTestResult.value = null val result = repository.testMessageRouter(serverUrl) result.fold( @@ -1206,7 +1206,7 @@ class MainViewModel @Inject constructor( * Test Account Service connection */ fun testAccountService(serviceUrl: String) { - viewModelScope.launch { + safeLaunch { _accountServiceTestResult.value = null val result = repository.testAccountService(serviceUrl) result.fold( @@ -1231,7 +1231,7 @@ class MainViewModel @Inject constructor( * Test Kava API connection */ fun testKavaApi(rpcUrl: String) { - viewModelScope.launch { + safeLaunch { _kavaApiTestResult.value = null val result = repository.testKavaApi(rpcUrl) result.fold( @@ -1286,7 +1286,7 @@ class MainViewModel @Inject constructor( * Now fetches both KAVA and Green Points (绿积分) balances */ fun fetchBalanceForShare(share: ShareRecord) { - viewModelScope.launch { + safeLaunch { val rpcUrl = _settings.value.kavaRpcUrl // Ensure we use EVM address format for RPC calls val evmAddress = AddressUtils.getEvmAddress(share.address, share.publicKey) @@ -1306,7 +1306,7 @@ class MainViewModel @Inject constructor( * Fetch balance for a wallet address (for already-EVM addresses) */ fun fetchBalance(address: String) { - viewModelScope.launch { + safeLaunch { val rpcUrl = _settings.value.kavaRpcUrl val result = repository.getWalletBalance(address, rpcUrl) result.onSuccess { walletBalance -> @@ -1320,7 +1320,7 @@ class MainViewModel @Inject constructor( * Fetch balances for all wallets */ fun fetchAllBalances() { - viewModelScope.launch { + safeLaunch { shares.value.forEach { share -> fetchBalanceForShare(share) }