private async Task <CustomerBalanceResultModel> InternalGetAsync(string customerId) { var value = await GetCachedValue(customerId); if (value != null) { return(value.DeserializeJson <CustomerBalanceResultModel>()); } var walletAddressResult = await _walletsService.GetCustomerWalletAsync(customerId); switch (walletAddressResult.Error) { case CustomerWalletAddressError.CustomerWalletMissing: return(CustomerBalanceResultModel.Failed(CustomerBalanceError.CustomerWalletMissing)); case CustomerWalletAddressError.InvalidCustomerId: return(CustomerBalanceResultModel.Failed(CustomerBalanceError.InvalidCustomerId)); case CustomerWalletAddressError.None: break; default: throw new ArgumentOutOfRangeException(nameof(walletAddressResult.Error)); } var balanceResponse = await _quorumOperationExecutorClient.AddressesApi.GetBalanceForAddressAsync(walletAddressResult.WalletAddress); var transfersInProgress = await _operationsFetcher.GetTransfersInProgressAsync(walletAddressResult.WalletAddress); var transfersInProgressAmount = transfersInProgress .Select(x => JsonConvert.DeserializeObject <TokensTransferContext>(x.ContextJson)) .Sum(x => x.Amount); var seizedAmount = (await _operationsFetcher.GetSeizeOperationsInProgressAsync(customerId)) .Select(x => JsonConvert.DeserializeObject <SeizeToInternalContext>(x.ContextJson)) .Sum(x => x.Amount); var reservedAmount = transfersInProgressAmount + seizedAmount; if (balanceResponse.Balance < reservedAmount) { _log.Warning( $"The reserved amount ({reservedAmount}) is more than actual balance ({balanceResponse.Balance})", context: new { customerId }); } var availableBalance = balanceResponse.Balance - balanceResponse.StakedBalance >= reservedAmount ? balanceResponse.Balance - balanceResponse.StakedBalance - reservedAmount : 0; var result = CustomerBalanceResultModel.Succeeded(availableBalance, balanceResponse.StakedBalance); await SetCacheValueAsync(customerId, result); return(result); }