public async Task <PaginatedList <SamuraiOperation> > GetOperationsHistoryAsync(string address, string continuation) { var continuationToken = continuation != null ? JsonConvert.DeserializeObject <SamuraiContinuationToken>(continuation) : new SamuraiContinuationToken { Start = 0 }; var response = await _url .AppendPathSegments("api", "AddressHistory", address) .SetQueryParams(new { Count = 1000, Start = continuationToken.Start }) .GetJsonAsync <SamuraiOperationsHistoryResponse>(); var nextStart = response.History.Length + continuationToken.Start; var resultContinuationToken = response.History.Length < 1000 ? null : new SamuraiContinuationToken { Start = nextStart }; return(PaginatedList.From(resultContinuationToken, response.History)); }
public async Task <PaginatedList <Transaction> > GetHistoryAsync(string continuation) { var operationExecutions = await GetOperationExecutionsAsync(); var continuationToken = continuation != null ? JsonConvert.DeserializeObject <TableContinuationToken>(continuation) : null; var query = new TableQuery <CashoutBatchEntity> { TakeCount = 1000 }; var response = await _cashoutBatchesTable.ExecuteQuerySegmentedAsync(query, continuationToken); var transactions = response.Results .Where(cashoutsBatch => cashoutsBatch.State == CashoutsBatchState.Finished) .SelectMany(cashoutsBatch => { var blockchain = _blockchainsProvider.GetByBilIdOrDefault(cashoutsBatch.BlockchainType); if (blockchain == null) { return(Enumerable.Empty <Transaction>()); } if (!operationExecutions.TryGetValue(cashoutsBatch.BatchId, out var operationExecution)) { _log.Warning($"Operation execution for cashouts batch {cashoutsBatch.BatchId} not found, skipping"); return(Enumerable.Empty <Transaction>()); } if (operationExecution.Result != OperationExecutionResult.Completed && operationExecution.Result != OperationExecutionResult.Success) { return(Enumerable.Empty <Transaction>()); } if (string.IsNullOrWhiteSpace(operationExecution.TransactionHash)) { _log.Warning($"Transaction hash for cashouts batch {cashoutsBatch.BatchId} is empty, skipping"); return(Enumerable.Empty <Transaction>()); } var cashouts = JsonConvert.DeserializeObject <BatchedCashout[]>(cashoutsBatch.Cashouts); return(cashouts.Select(cashout => new Transaction ( blockchain.CryptoCurrency, operationExecution.TransactionHash, cashout.ClientId, cashout.DestinationAddress, TransactionType.Withdrawal ))); }) .ToArray(); return(PaginatedList.From(response.ContinuationToken, transactions)); }
public async Task <PaginatedList <SamuraiErc20Operation> > GetErc20OperationsHistory(string address, string continuation) { var continuationToken = continuation != null ? JsonConvert.DeserializeObject <SamuraiContinuationToken>(continuation) : new SamuraiContinuationToken { Start = 0 }; var response = await _url .AppendPathSegments("api", "Erc20TransferHistory", "getErc20Transfers", "v2") .SetQueryParams(new { count = 1000, start = continuationToken.Start }) .PostJsonAsync(new { assetHolder = address }); var responseContent = await response.Content.ReadAsStringAsync(); var operations = JsonConvert.DeserializeObject <SamuraiErc20Operation[]>(responseContent); var nextStart = operations.Length + continuationToken.Start; var resultContinuationToken = operations.Length < 1000 ? null : new SamuraiContinuationToken { Start = nextStart }; return(PaginatedList.From(resultContinuationToken, operations)); }
public async Task <PaginatedList <DepositWallet> > GetWalletsAsync(string continuation) { var continuationToken = continuation != null ? JsonConvert.DeserializeObject <TableContinuationToken>(continuation) : null; var query = new TableQuery <BlockchainWalletEntity> { TakeCount = 1000 }; var response = await _table.ExecuteQuerySegmentedAsync(query, continuationToken); var transactions = response.Results .Select(wallet => { var blockchain = _blockchainsProvider.GetByBilIdOrDefault(wallet.IntegrationLayerId); if (blockchain == null) { return(null); } return(new DepositWallet ( wallet.ClientId, wallet.Address, blockchain.CryptoCurrency )); }) .Where(x => x != null) .ToArray(); return(PaginatedList.From(response.ContinuationToken, transactions)); }
public async Task <PaginatedList <Transaction> > GetHistoryAsync(DepositWallet depositWallet, string continuation) { if (!CanProvideHistoryFor(depositWallet)) { return(PaginatedList.From(Array.Empty <Transaction>())); } var continuationToken = continuation != null ? JsonConvert.DeserializeObject <ContinuationToken>(continuation) : new ContinuationToken { Page = 0 }; InsightApiTransactionsResponse response = null; try { response = await _insightApi.GetAddressTransactions(depositWallet.Address, continuationToken.Page); } catch (FlurlHttpException ex) when(ex.Call.HttpStatus == HttpStatusCode.BadRequest) { var responseMessage = await ex.GetResponseStringAsync(); if (responseMessage == "Invalid address. Code:-5") { _log.Warning ( "Insight API treated address as invalid. Skipping", context: new { Address = depositWallet.Address } ); } else { throw; } } if (response == null) { return(PaginatedList.From(Array.Empty <Transaction>())); } var depositOperations = response.Transactions.Where(tx => IsDeposit(tx, depositWallet.Address)); var depositTransactions = Map(depositOperations, depositWallet); var nextPage = continuationToken.Page + 1; var resultContinuation = nextPage < response.PagesTotal ? new ContinuationToken { Page = nextPage } : null; return(PaginatedList.From(resultContinuation, depositTransactions)); }
public async Task <PaginatedList <DepositWallet> > GetWalletsAsync(string continuation) { var continuationToken = continuation != null ? JsonConvert.DeserializeObject <TableContinuationToken>(continuation) : null; var query = new TableQuery <BcnCredentialsRecordEntity> { TakeCount = 1000 }; var response = await _table.ExecuteQuerySegmentedAsync(query, continuationToken); var transactions = response.Results .SelectMany(wallet => { var assetReference = wallet.AssetId.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault(); var blockchain = _blockchainsProvider.GuessBlockchainOrDefault(assetReference); if (blockchain == null) { return(Enumerable.Empty <DepositWallet>()); } var clientId = Guid.Parse(wallet.ClientId); var wallets = new List <DepositWallet>(); if (!string.IsNullOrWhiteSpace(wallet.Address)) { wallets.Add(new DepositWallet ( clientId, wallet.Address, blockchain.CryptoCurrency )); } if (!string.IsNullOrWhiteSpace(wallet.AssetAddress)) { wallets.Add(new DepositWallet ( clientId, wallet.AssetAddress, blockchain.CryptoCurrency )); } return(wallets); }) .ToArray(); return(PaginatedList.From(response.ContinuationToken, transactions)); }
public async Task <PaginatedList <Transaction> > GetHistoryAsync(DepositWallet depositWallet, string continuation) { if (!CanProvideHistoryFor(depositWallet)) { return(PaginatedList.From(Array.Empty <Transaction>())); } var response = await _client.GetBalance(depositWallet.Address, false, continuation); var depositOperations = response.Operations.Where(IsDeposit); var depositTransactions = Map(depositOperations, depositWallet.Address, depositWallet.UserId); return(PaginatedList.From(response.Continuation, depositTransactions.ToArray())); }
public async Task <PaginatedList <DepositWallet> > GetWalletsAsync(string continuation) { var continuationToken = continuation != null ? JsonConvert.DeserializeObject <TableContinuationToken>(continuation) : null; var query = new TableQuery <WalletCredentialsEntity> { TakeCount = 1000 }; var response = await _table.ExecuteQuerySegmentedAsync(query, continuationToken); var transactions = response.Results .SelectMany(wallet => { var userId = Guid.Parse(wallet.ClientId); var wallets = new List <DepositWallet>(); var bitcoin = _blockchainsProvider.GetBitcoin(); if (!string.IsNullOrEmpty(wallet.MultiSig)) { wallets.Add(new DepositWallet ( userId, wallet.MultiSig, bitcoin.CryptoCurrency )); } if (!string.IsNullOrEmpty(wallet.ColoredMultiSig)) { wallets.Add(new DepositWallet ( userId, wallet.ColoredMultiSig, bitcoin.CryptoCurrency )); } return(wallets); }) .ToArray(); return(PaginatedList.From(response.ContinuationToken, transactions)); }
public async Task <PaginatedList <DepositWallet> > GetWalletsAsync(string continuation) { if (_collection == null) { throw new InvalidOperationException("MongoStorage not configured"); } var continuationToken = continuation != null ? JsonConvert.DeserializeObject <MongoContinuationToken>(continuation) : new MongoContinuationToken { Skip = 0 }; var entities = await _collection.AsQueryable() .Skip(continuationToken.Skip) .Take(1000) .ToListAsync(); var wallets = entities .Select(wallet => { var blockchain = _blockchainsProvider.GetByBilIdOrDefault(wallet.BlockchainType); if (blockchain == null) { return(null); } return(new DepositWallet(wallet.ClientId, wallet.Address, blockchain.CryptoCurrency)); }) .Where(wallet => wallet != null) .ToArray(); var resultContinuationToken = entities.Count < 1000 ? null : new MongoContinuationToken { Skip = continuationToken.Skip + entities.Count }; return(PaginatedList.From(resultContinuationToken, wallets)); }
public async Task <PaginatedList <Transaction> > GetHistoryAsync(string continuation) { var continuationToken = continuation != null ? JsonConvert.DeserializeObject <TableContinuationToken>(continuation) : null; var query = new TableQuery <CashOperationEntity> { TakeCount = 1000 }; var response = await _table.ExecuteQuerySegmentedAsync(query, continuationToken); var transactions = response.Results .Where(operation => operation.Amount < 0 && !string.IsNullOrWhiteSpace(operation.AddressTo) && !string.IsNullOrWhiteSpace(operation.BlockChainHash) && operation.AddressTo != operation.AddressFrom && !string.IsNullOrWhiteSpace(operation.AssetId) && !string.IsNullOrWhiteSpace(operation.ClientId)) .Select(operation => { var blockchain = _blockchainsProvider.GetByAssetIdOrDefault(operation.AssetId); if (blockchain == null) { return(null); } return(new Transaction ( blockchain.CryptoCurrency, operation.BlockChainHash, new Guid(operation.ClientId), operation.AddressTo, TransactionType.Withdrawal )); }) .Where(x => x != null) .ToArray(); return(PaginatedList.From(response.ContinuationToken, transactions)); }
public async Task <PaginatedList <Transaction> > GetHistoryAsync(DepositWallet depositWallet, string continuation) { if (!CanProvideHistoryFor(depositWallet)) { return(PaginatedList.From(Array.Empty <Transaction>())); } if (continuation != null) { throw new NotSupportedException("Continuation is not supported"); } var operations = await ReadTransactionsAsync(depositWallet); var internalOperations = await ReadInternalTransactionsAsync(depositWallet); var internalOperationHashes = internalOperations.Select(x => x.TransactionHash).ToHashSet(); var transactions = operations .Where(x => !internalOperationHashes.Contains(x.TransactionHash) && IsDeposit(depositWallet.Address, x.To)) .Select(x => new Transaction ( _ethereum.CryptoCurrency, x.TransactionHash.ToLower(), depositWallet.UserId, depositWallet.Address, TransactionType.Deposit )); var internalTransactions = internalOperations .Where(x => IsDeposit(depositWallet.Address, x.To)) .Select(x => new Transaction ( _ethereum.CryptoCurrency, x.TransactionHash.ToLower(), depositWallet.UserId, depositWallet.Address, TransactionType.Deposit )); var allTransactions = transactions.Concat(internalTransactions).ToArray(); return(PaginatedList.From(allTransactions)); }
public async Task <PaginatedList <Transaction> > GetHistoryAsync(DepositWallet depositWallet, string continuation) { if (!CanProvideHistoryFor(depositWallet)) { return(PaginatedList.From(Array.Empty <Transaction>())); } if (continuation != null) { throw new NotSupportedException("Continuation is not supported"); } var addressParts = depositWallet.Address.Split('+', StringSplitOptions.RemoveEmptyEntries); var address = addressParts[0]; var tag = addressParts.Length > 1 ? addressParts[1] : null; List <RippleTransaction> txs; if (!_memoryCache.TryGetValue <List <RippleTransaction> >(address, out txs)) { lock (_mutex.GetOrAdd(address, new object())) { if (!_memoryCache.TryGetValue <List <RippleTransaction> >(address, out txs)) { txs = GetRippleTransactions(address).Result; _memoryCache.Set(address, txs, _settings.CacheExpirationPeriod); } } } return(PaginatedList.From( GetDeposits(txs, depositWallet, address, tag) )); }
public async Task <PaginatedList <Transaction> > GetHistoryAsync(string continuation) { var continuationToken = continuation != null ? JsonConvert.DeserializeObject <TableContinuationToken>(continuation) : null; var query = new TableQuery <CashoutEntity> { TakeCount = 1000 }; var response = await _table.ExecuteQuerySegmentedAsync(query, continuationToken); var transactions = response.Results .Where(cashout => cashout.Result == CashoutResult.Success && !string.IsNullOrWhiteSpace(cashout.TransactionHash)) .Select(cashout => { var blockchain = _blockchainsProvider.GetByBilIdOrDefault(cashout.BlockchainType); if (blockchain == null) { return(null); } return(new Transaction ( blockchain.CryptoCurrency, cashout.TransactionHash, cashout.ClientId, cashout.ToAddress, TransactionType.Withdrawal )); }) .Where(x => x != null) .ToArray(); return(PaginatedList.From(response.ContinuationToken, transactions)); }