public async Task <IWalletBalance> UpdateBalance(string address) { var wallet = await _observableWalletRepository.Get(address); if (wallet != null) { return(await UpdateBalance(wallet)); } return(null); }
public async Task <decimal?> UpdateBalance(string address) { if (await _observableWalletRepository.Get(address) != null) { var lastBlock = await _blockchainProvider.GetHeightAsync(); var unspentOutputs = (await _transactionOutputsService.GetUnspentOutputsAsync(address)) .ToList(); var blockHeightFromTxHash = new ConcurrentDictionary <UInt256, (string txHash, int blockHeight, string blockHash)>(); await unspentOutputs.Select(p => p.Reference.PrevHash).Distinct() .ForEachAsyncSemaphore(8, async txHash => { var tx = await _blockchainProvider.GetTransactionOrDefaultAsync(txHash.ToString().Substring(2)); if (tx == null) { throw new InvalidOperationException($"Unable to find transaction with hash {txHash}"); } blockHeightFromTxHash.TryAdd(txHash, tx.Value); }); var validatedUnspentOutputs = unspentOutputs .Where(p => { var tx = blockHeightFromTxHash[p.Reference.PrevHash]; if (tx.blockHash == null) // unconfirmed tx { return(false); } return(tx.blockHeight <= lastBlock); }).ToList(); var neoBalance = (decimal)validatedUnspentOutputs .Where(p => p.Output.AssetId == Utils.NeoToken) .Sum(p => p.Output.Value); var gasBalance = (decimal)validatedUnspentOutputs .Where(p => p.Output.AssetId == Utils.GasToken) .Sum(p => p.Output.Value); await Task.WhenAll(UpdateBalanceInRepo(lastBlock, address, neoBalance, Constants.Assets.Neo.AssetId), UpdateBalanceInRepo(lastBlock, address, gasBalance, Constants.Assets.Gas.AssetId));; } return(null); }