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()); }
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 waiter = Waiters.GetWaiter(cryptoCode); var rpc = waiter.RPC.PrepareBatch(); var repo = RepositoryProvider.GetRepository(network); var fetchingTransactions = rescanRequest .Transactions .Select(t => FetchTransaction(rpc, waiter.HasTxIndex, 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)) { await repo.SaveTransactions(txs.First().BlockTime, txs.Select(t => t.Transaction).ToArray(), txs.Key); foreach (var tx in txs) { var matches = await repo.GetMatches(tx.Transaction, txs.Key, tx.BlockTime, false); await repo.SaveMatches(matches); _ = AddressPoolService.GenerateAddresses(network, matches); } } return(Ok()); }
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()); }
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(); } }