Beispiel #1
0
        public async Task <IActionResult> TrackWallet(
            string cryptoCode,
            [ModelBinder(BinderType = typeof(DerivationStrategyModelBinder))]
            DerivationStrategyBase derivationScheme,
            [ModelBinder(BinderType = typeof(BitcoinAddressModelBinder))]
            BitcoinAddress address)
        {
            TrackedSource trackedSource = GetTrackedSource(derivationScheme, address);

            if (trackedSource == null)
            {
                return(NotFound());
            }
            var network = GetNetwork(cryptoCode, false);

            if (trackedSource is DerivationSchemeTrackedSource dts)
            {
                foreach (var feature in Enum.GetValues(typeof(DerivationFeature)).Cast <DerivationFeature>())
                {
                    await RepositoryProvider.GetRepository(network).GenerateAddresses(dts.DerivationStrategy, feature, new GenerateAddressQuery(minAddresses: 3, null));
                }
                foreach (var feature in Enum.GetValues(typeof(DerivationFeature)).Cast <DerivationFeature>())
                {
                    _ = AddressPoolService.GenerateAddresses(network, dts.DerivationStrategy, feature);
                }
            }
            else if (trackedSource is IDestination ats)
            {
                await RepositoryProvider.GetRepository(network).Track(ats);
            }
            return(Ok());
        }
Beispiel #2
0
        public async Task <IActionResult> Rescan(string cryptoCode, [FromBody] RescanRequest rescanRequest)
        {
            if (rescanRequest == null)
            {
                throw new ArgumentNullException(nameof(rescanRequest));
            }
            if (rescanRequest?.Transactions == null)
            {
                throw new NBXplorerException(new NBXplorerError(400, "transactions-missing", "You must specify 'transactions'"));
            }

            bool willFetchTransactions = rescanRequest.Transactions.Any(t => t.Transaction == null);
            bool needTxIndex           = rescanRequest.Transactions.Any(t => t.Transaction == null && t.BlockId == null);
            var  network = GetNetwork(cryptoCode, willFetchTransactions);

            var rpc  = Waiters.GetWaiter(cryptoCode).RPC.PrepareBatch();
            var repo = RepositoryProvider.GetRepository(network);

            var fetchingTransactions = rescanRequest
                                       .Transactions
                                       .Select(t => FetchTransaction(rpc, t))
                                       .ToArray();

            await rpc.SendBatchAsync();

            await Task.WhenAll(fetchingTransactions);

            var transactions = fetchingTransactions.Select(t => t.GetAwaiter().GetResult())
                               .Where(tx => tx.Transaction != null)
                               .ToArray();

            foreach (var txs in transactions.GroupBy(t => t.BlockId, t => (t.Transaction, t.BlockTime))
                     .OrderBy(t => t.First().BlockTime))
            {
                repo.SaveTransactions(txs.First().BlockTime, txs.Select(t => t.Transaction).ToArray(), txs.Key);
                foreach (var tx in txs)
                {
                    var matches = repo.GetMatches(tx.Transaction).Select(m => new MatchedTransaction()
                    {
                        BlockId = txs.Key, Match = m
                    }).ToArray();
                    repo.SaveMatches(tx.BlockTime, matches);
                    AddressPoolService.RefillAddressPoolIfNeeded(network, matches);
                }
            }

            return(Ok());
        }
Beispiel #3
0
        public async Task <IActionResult> TrackWallet(
            string cryptoCode,
            [ModelBinder(BinderType = typeof(DerivationStrategyModelBinder))]
            DerivationStrategyBase derivationScheme,
            [ModelBinder(BinderType = typeof(BitcoinAddressModelBinder))]
            BitcoinAddress address, [FromBody] TrackWalletRequest request = null)
        {
            request = request ?? new TrackWalletRequest();
            TrackedSource trackedSource = GetTrackedSource(derivationScheme, address);

            if (trackedSource == null)
            {
                return(NotFound());
            }
            var network = GetNetwork(cryptoCode, false);

            if (trackedSource is DerivationSchemeTrackedSource dts)
            {
                if (request.Wait)
                {
                    foreach (var feature in keyPathTemplates.GetSupportedDerivationFeatures())
                    {
                        await RepositoryProvider.GetRepository(network).GenerateAddresses(dts.DerivationStrategy, feature, GenerateAddressQuery(request, feature));
                    }
                }
                else
                {
                    foreach (var feature in keyPathTemplates.GetSupportedDerivationFeatures())
                    {
                        await RepositoryProvider.GetRepository(network).GenerateAddresses(dts.DerivationStrategy, feature, new GenerateAddressQuery(minAddresses: 3, null));
                    }
                    foreach (var feature in keyPathTemplates.GetSupportedDerivationFeatures())
                    {
                        _ = AddressPoolService.GenerateAddresses(network, dts.DerivationStrategy, feature, GenerateAddressQuery(request, feature));
                    }
                }
            }
            else if (trackedSource is IDestination ats)
            {
                await RepositoryProvider.GetRepository(network).Track(ats);
            }
            return(Ok());
        }
Beispiel #4
0
        public async Task <IActionResult> TrackWallet(
            string cryptoCode,
            [ModelBinder(BinderType = typeof(DestinationModelBinder))]
            DerivationStrategyBase derivationStrategy)
        {
            if (derivationStrategy == null)
            {
                return(NotFound());
            }
            var network = GetNetwork(cryptoCode, false);

            foreach (var feature in Enum.GetValues(typeof(DerivationFeature)).Cast <DerivationFeature>())
            {
                await RepositoryProvider.GetRepository(network).RefillAddressPoolIfNeeded(derivationStrategy, feature, 1);

                AddressPoolService.RefillAddressPoolIfNeeded(network, derivationStrategy, feature);
            }
            return(Ok());
        }
Beispiel #5
0
        public async Task <KeyPathInformation> GetUnusedAddress(
            string cryptoCode,
            [ModelBinder(BinderType = typeof(DerivationStrategyModelBinder))]
            DerivationStrategyBase strategy, DerivationFeature feature = DerivationFeature.Deposit, int skip = 0, bool reserve = false)
        {
            if (strategy == null)
            {
                throw new ArgumentNullException(nameof(strategy));
            }
            var network    = GetNetwork(cryptoCode, false);
            var repository = RepositoryProvider.GetRepository(network);

            if (skip >= repository.MinPoolSize)
            {
                throw new NBXplorerError(404, "strategy-not-found", $"This strategy is not tracked, or you tried to skip too much unused addresses").AsException();
            }
            try
            {
                var result = await repository.GetUnused(strategy, feature, skip, reserve);

                if (reserve)
                {
                    while (result == null)
                    {
                        await AddressPoolService.GenerateAddresses(network, strategy, feature, 1);

                        result = await repository.GetUnused(strategy, feature, skip, reserve);
                    }
                    _ = AddressPoolService.GenerateAddresses(network, strategy, feature);
                }
                return(result);
            }
            catch (NotSupportedException)
            {
                throw new NBXplorerError(400, "derivation-not-supported", $"The derivation scheme {feature} is not supported").AsException();
            }
        }