public async Task <CommandHandlingResult> Handle(BuildTransactionCommand command,
                                                         IEventPublisher publisher)
        {
            var alreadyPublishedEvt = await _commandHandlerEventRepository.TryGetEventAsync(command.TransactionId,
                                                                                            CommandHandlerId);

            if (alreadyPublishedEvt != null)
            {
                publisher.PublishEvent(alreadyPublishedEvt);

                return(CommandHandlingResult.Ok());
            }
            try
            {
                var res = await _claimBuilderClient.BuildClaimTransacionAsync(command.TransactionId, command.Address);

                publisher.PublishEvent(await _commandHandlerEventRepository.InsertEventAsync(command.TransactionId,
                                                                                             CommandHandlerId,
                                                                                             new TransactionBuiltEvent
                {
                    TransactionId = command.TransactionId,
                    AllGas        = res.allGas,
                    ClaimedGas    = res.claimedGas,
                    UnsignedTransactionContext = res.transactionContext
                }));
            }
            catch (NeoClaimTransactionException e)
            {
                switch (e.ErrorType)
                {
                case NeoClaimTransactionException.ErrorCode.ClaimableGasNotAvailiable:
                    _log.Info($"Api said that claimable gas not available",
                              context: new { txId = command.TransactionId });

                    publisher.PublishEvent(await _commandHandlerEventRepository.InsertEventAsync(command.TransactionId,
                                                                                                 CommandHandlerId,
                                                                                                 new ClaimbaleGasNotAvailiableEvent
                    {
                        TransactionId = command.TransactionId
                    }));

                    break;

                case NeoClaimTransactionException.ErrorCode.TransactionAlreadyBroadcased:
                    _log.Info($"Api said that claim transaction is already broadcasted - do nothing",
                              context: new { txId = command.TransactionId });
                    break;

                default:
                    throw new ArgumentException($"Unknown switch {e.ErrorType}", nameof(e.ErrorType), e);
                }
            }

            _chaosKitty.Meow(command.TransactionId);

            return(CommandHandlingResult.Ok());
        }
        public async Task <CommandHandlingResult> Handle(SignTransactionCommand command, IEventPublisher publisher)
        {
            var alreadyPublishedEvt = await _commandHandlerEventRepository.TryGetEventAsync(command.TransactionId, CommandHandlerId);

            if (alreadyPublishedEvt != null)
            {
                publisher.PublishEvent(alreadyPublishedEvt);

                return(CommandHandlingResult.Ok());
            }

            var transactionSigningResult = await _signFacadeClient.SignTransactionAsync
                                           (
                blockchainType : command.BlockchainType,
                request : new SignTransactionRequest
            {
                PublicAddresses    = new[] { command.SignerAddress },
                TransactionContext = command.TransactionContext
            }
                                           );

            _chaosKitty.Meow(command.TransactionId);

            if (string.IsNullOrWhiteSpace(transactionSigningResult?.SignedTransaction))
            {
                throw new InvalidOperationException("Sign service returned the empty transaction");
            }

            publisher.PublishEvent(await _commandHandlerEventRepository.InsertEventAsync(command.TransactionId,
                                                                                         CommandHandlerId,
                                                                                         new TransactionSignedEvent
            {
                OperationId       = command.OperationId,
                TransactionId     = command.TransactionId,
                SignedTransaction = transactionSigningResult.SignedTransaction
            }));

            return(CommandHandlingResult.Ok());
        }