private async Task <IList <Coin> > GetUnspentCoins(OperationBitcoinInput input)
        {
            var coins = (await _transactionOutputsService.GetUnspentOutputsAsync(input.Address.ToString(), _confirmationsSettings.MinConfirmationsToDetectOperation)).ToList();

            if (input.Redeem != null)
            {
                coins = coins.Select(o => o.ToScriptCoin(input.Redeem)).Cast <Coin>().ToList();
            }
            return(coins);
        }
        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);
        }
        public async Task <(NeoModules.NEP6.Transactions.Transaction tx, decimal fee)> BuildNeoContractTransactionAsync(string from,
                                                                                                                        string to,
                                                                                                                        decimal amount,
                                                                                                                        bool includeFee)
        {
            var unspentOutputs = (await _transactionOutputsService.GetUnspentOutputsAsync(from)).ToList();

            var tx = new ContractTransaction
            {
                Attributes = new TransactionAttribute[0],
                Inputs     = new CoinReference[0],
                Outputs    = new List <TransferOutput>
                {
                    new TransferOutput
                    {
                        AssetId    = Utils.NeoToken,
                        ScriptHash = to.ToScriptHash(),
                        Value      = BigDecimal.Parse(amount.ToString("F", CultureInfo.InvariantCulture),
                                                      Constants.Assets.Neo.Accuracy)
                    }
                }.Select(p => p.ToTxOutput()).ToArray(),
                Witnesses = new Witness[0]
            };

            var fee = CalculcateFee(tx, unspentOutputs, from.ToScriptHash());

            if (includeFee)
            {
                amount -= fee;
            }

            tx = MakeTransaction(tx,
                                 unspentOutputs,
                                 from.ToScriptHash(),
                                 changeAddress: from.ToScriptHash(),
                                 fee: new Fixed8(fee));

            return(tx, fee);
        }