Beispiel #1
0
        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));
        }
Beispiel #3
0
        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));
        }
Beispiel #4
0
        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));
        }
Beispiel #6
0
        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));
        }
Beispiel #7
0
        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));
        }
Beispiel #10
0
        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));
        }
Beispiel #12
0
        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));
        }