public async Task <ExchangeResult> ExecuteAsync(ExchangeCommand cmd)
        {
            BlockchainType network = await _assetSettingsService.GetNetworkAsync(cmd.SourceAssetId);

            if (await _assetSettingsService.GetNetworkAsync(cmd.DestAssetId) != network)
            {
                throw new ExchangeOperationNotSupportedException("Assets are being served by different blockchains");
            }

            IAssetPairRate rate = await _assetRatesService.GetCurrentRateAsync(cmd.SourceAssetId, cmd.DestAssetId);

            if (cmd.ExpectedRate != null && rate.BidPrice != cmd.ExpectedRate)
            {
                throw new ExchangeRateChangedException(rate.BidPrice);
            }

            string hotwallet = _bcnSettingsResolver.GetExchangeHotWallet(network);

            string sourceAddress = await GetSourceAddressAsync(cmd);

            decimal exchangeAmount = cmd.SourceAmount * rate.BidPrice;

            await _walletBalanceValidator.ValidateTransfer(sourceAddress, cmd.SourceAssetId, cmd.SourceAmount);

            await _walletBalanceValidator.ValidateTransfer(hotwallet, cmd.DestAssetId, exchangeAmount);

            TransferResult toHotWallet = await _retryPolicy
                                         .ExecuteAsync(() => _transferService.ExchangeThrowFail(
                                                           cmd.SourceAssetId,
                                                           sourceAddress,
                                                           hotwallet,
                                                           cmd.SourceAmount));

            await RegisterTransferTxsAsync(toHotWallet);

            string destAddress = await GetDestAddressAsync(cmd);

            TransferResult fromHotWallet = await _retryPolicy
                                           .ExecuteAsync(() => _transferService.ExchangeThrowFail(
                                                             cmd.DestAssetId,
                                                             hotwallet,
                                                             destAddress,
                                                             exchangeAmount));

            await RegisterTransferTxsAsync(fromHotWallet, false);

            return(new ExchangeResult
            {
                SourceAssetId = cmd.SourceAssetId,
                SourceAmount = cmd.SourceAmount,
                DestAssetId = cmd.DestAssetId,
                DestAmount = exchangeAmount,
                Rate = rate.BidPrice
            });
        }