public async Task ProcessMessage(CashInOutQueueMessage message)
        {
            _log.Info(message: "Processing message", message.ToJson());

            ChaosKitty.Meow();

            var transaction = await _transactionsRepository.FindByTransactionIdAsync(message.Id);

            if (transaction == null)
            {
                if (_cashOperationsRepositoryClient.GetAsync(message.ClientId, message.Id) == null)
                {
                    _log.Warning($"{nameof(CashInOutQueue)}:{nameof(CashInOutQueueMessage)}", "unknown transaction", context: message.ToJson());
                    return;
                }

                await ProcessExternalCashin(message);
            }
            else
            {
                switch (transaction.CommandType)
                {
                case BitCoinCommands.CashIn:
                case BitCoinCommands.Issue:
                    await ProcessIssue(message);

                    break;

                case BitCoinCommands.CashOut:
                    await ProcessCashOut(message);

                    break;

                case BitCoinCommands.ManualUpdate:
                    ProcessManualUpdate(message);
                    break;

                default:
                    _log.Warning($"{nameof(CashInOutQueue)}:{nameof(CashInOutQueueMessage)}", $"Unknown command type (value = [{transaction.CommandType}])", context: message.ToJson());
                    break;
                }
            }
        }
        public async Task <bool> ProcessMessage(CashInOutQueueMessage queueMessage)
        {
            var transaction = await _bitcoinTransactionsRepository.FindByTransactionIdAsync(queueMessage.Id);

            if (transaction == null)
            {
                // external cashin
                if (_cashOperationsRepository.GetAsync(queueMessage.ClientId, queueMessage.Id) != null)
                {
                    return(await ProcessExternalCashin(queueMessage));
                }

                await _log.WriteWarningAsync(nameof(CashInOutQueue), nameof(ProcessMessage), queueMessage.ToJson(), "unkown transaction");

                return(false);
            }

            try
            {
                switch (transaction.CommandType)
                {
                case BitCoinCommands.Issue:
                    return(await ProcessIssue(transaction, queueMessage));

                case BitCoinCommands.CashOut:
                    return(await ProcessCashOut(transaction, queueMessage));

                case BitCoinCommands.Destroy:
                    return(await ProcessDestroy(transaction, queueMessage));

                case BitCoinCommands.ManualUpdate:
                    return(await ProcessManualOperation(transaction, queueMessage));

                default:
                    await _log.WriteWarningAsync(nameof(CashInOutQueue), nameof(ProcessMessage), queueMessage.ToJson(), $"Unknown command type (value = [{transaction.CommandType}])");

                    return(false);
                }
            }
            catch (Exception ex)
            {
                await _log.WriteErrorAsync(nameof(CashInOutQueue), nameof(ProcessMessage), queueMessage.ToJson(), ex);

                return(false);
            }
        }
        private async Task ProcessIssue(CashInOutQueueMessage message)
        {
            var isClientTrusted = await _clientAccountClient.IsTrustedAsync(message.ClientId);

            var asset = await _assetsServiceWithCache.TryGetAssetAsync(message.AssetId);

            if (!isClientTrusted.Value && !asset.IsTrusted)
            {
                _log.Warning($"{nameof(CashInOutMessageProcessor)}:{nameof(ProcessIssue)}", "Client and asset are not trusted.", context: message.ToJson());
                return;
            }

            var walletCredentials = await _walletCredentialsRepository.GetAsync(message.ClientId);

            var amount        = message.Amount.ParseAnyDecimal();
            var transactionId = message.Id;
            var context       = await _transactionService.GetTransactionContext <IssueContextData>(transactionId);

            context.CashOperationId = transactionId;
            _cqrsEngine.SendCommand(new SaveIssueOperationStateCommand
            {
                Command = new IssueCommand
                {
                    TransactionId = Guid.Parse(transactionId),
                    Context       = context.ToJson(),
                    Amount        = Math.Abs(amount),
                    AssetId       = message.AssetId,
                    Multisig      = walletCredentials?.MultiSig
                },
                Context = context,
                Message = message
            }, BoundedContexts.TxHandler, BoundedContexts.Operations);
        }