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)); }
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); }