예제 #1
0
        public async Task <IAsset> FindAssetByBlockchainAssetIdAsync(string blockchainAssetId)
        {
            if (blockchainAssetId == null)
            {
                return(await _assetsService.TryGetAssetAsync(LykkeConstants.BitcoinAssetId));
            }

            var assets = await _assetsService.GetAllAssetsAsync();

            return(assets.FirstOrDefault(itm => itm.BlockChainAssetId == blockchainAssetId || itm.Id == blockchainAssetId));
        }
예제 #2
0
        public async Task <bool> ProcessMessage(TradeQueueItem queueMessage)
        {
            await _marketOrdersRepository.CreateAsync(queueMessage.Order);

            if (!queueMessage.Order.Status.Equals("matched", StringComparison.OrdinalIgnoreCase))
            {
                await _log.WriteInfoAsync(nameof(TradeQueue), nameof(ProcessMessage), queueMessage.Order.ToJson(), "Message processing being aborted, due to order status is not matched. Order was saved");

                return(true);
            }

            var walletCredsMarket = await _walletCredentialsRepository.GetAsync(queueMessage.Trades[0].MarketClientId);

            var walletCredsLimit = await _walletCredentialsRepository.GetAsync(queueMessage.Trades[0].LimitClientId);

            var clientTrades = queueMessage.ToDomainOffchain(walletCredsMarket, walletCredsLimit, await _assetsService.GetAllAssetsAsync());

            var notify = new HashSet <string>();

            try
            {
                // for trusted clients only write history (finally block)
                if (await _clientAccountsRepository.IsTrusted(queueMessage.Order.ClientId))
                {
                    return(true);
                }

                // get operations only by market order user (limit user will be processed in limit trade queue)
                var operations = AggregateSwaps(queueMessage.Trades).Where(x => x.ClientId == queueMessage.Order.ClientId).ToList();

                await CreateTransaction(queueMessage.Order.ExternalId, operations, clientTrades);

                var ethereumTxRequest = await _ethereumTransactionRequestRepository.GetByOrderAsync(queueMessage.Order.ExternalId);

                if (ethereumTxRequest != null)
                {
                    var wasTransferOk = await ProcessEthGuaranteeTransfer(ethereumTxRequest, operations, clientTrades);

                    if (!wasTransferOk)
                    {
                        return(true);
                    }
                }

                var sellOperations = operations.Where(x => x.Amount < 0);
                var buyOperations  = operations.Where(x => x.Amount > 0);

                foreach (var operation in sellOperations)
                {
                    var asset = await _assetsService.TryGetAssetAsync(operation.AssetId);

                    if (asset.Blockchain == Blockchain.Ethereum)
                    {
                        continue;   //guarantee transfer already sent for eth
                    }
                    // return change in offchain
                    var offchainOrder = await _offchainOrdersRepository.GetOrder(queueMessage.Order.ExternalId);

                    var change = offchainOrder.ReservedVolume - Math.Abs(operation.Amount);

                    if (change < 0)
                    {
                        await _log.WriteWarningAsync(nameof(TradeQueue), nameof(ProcessMessage),
                                                     $"Order: [{offchainOrder.OrderId}], data: [{operation.ToJson()}]",
                                                     "Diff is less than ZERO !");
                    }

                    if (change > 0)
                    {
                        await _offchainRequestService.CreateOffchainRequestAndNotify(operation.TransferId, operation.ClientId,
                                                                                     operation.AssetId, change, offchainOrder.OrderId, OffchainTransferType.FromHub);

                        notify.Add(operation.ClientId);
                    }
                }

                foreach (var operation in buyOperations)
                {
                    var asset = await _assetsService.TryGetAssetAsync(operation.AssetId);

                    if (asset.Blockchain == Blockchain.Ethereum)
                    {
                        await ProcessEthBuy(operation, asset, clientTrades, queueMessage.Order.ExternalId);

                        continue;
                    }

                    await _offchainRequestService.CreateOffchainRequestAndNotify(operation.TransferId, operation.ClientId,
                                                                                 operation.AssetId, operation.Amount, queueMessage.Order.ExternalId, OffchainTransferType.FromHub);

                    notify.Add(operation.ClientId);
                }
            }
            finally
            {
                await _clientTradesRepository.SaveAsync(clientTrades);

                foreach (var item in notify)
                {
                    await _offchainRequestService.NotifyUser(item);
                }
            }

            return(true);
        }