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);
        }