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
            });
        }
Exemplo n.º 2
0
        public async Task <PaymentResult> PrePayAsync(PaymentCommand cmd)
        {
            IPaymentRequest paymentRequest = await _paymentRequestRepository.GetAsync(cmd.MerchantId, cmd.PaymentRequestId);

            if (paymentRequest == null)
            {
                throw new PaymentRequestNotFoundException(cmd.MerchantId, cmd.PaymentRequestId);
            }

            string payerWalletAddress = (await _merchantWalletService.GetDefaultAsync(
                                             cmd.PayerMerchantId,
                                             paymentRequest.PaymentAssetId,
                                             PaymentDirection.Outgoing)).WalletAddress;

            await _walletBalanceValidator.ValidateTransfer(payerWalletAddress, paymentRequest.PaymentAssetId, cmd.Amount);

            return(new PaymentResult
            {
                Amount = cmd.Amount,
                AssetId = paymentRequest.PaymentAssetId,
                PaymentRequestId = paymentRequest.Id,
                PaymentRequestWalletAddress = paymentRequest.WalletAddress
            });
        }
Exemplo n.º 3
0
        public async Task <CashoutResult> ExecuteAsync(CashoutCommand cmd)
        {
            BlockchainType network = await _assetSettingsService.GetNetworkAsync(cmd.SourceAssetId);

            string hotwallet = _bcnSettingsResolver.GetCashoutHotWallet(network);

            if (string.IsNullOrEmpty(hotwallet))
            {
                throw new CashoutHotwalletNotDefinedException(network);
            }

            string sourceAddress = await GetSourceAddressAsync(cmd);

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

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

            foreach (var transferTransactionResult in toHotWallet.Transactions)
            {
                string historyId = await _walletHistoryService.PublishCashoutAsync(new WalletHistoryCashoutCommand
                {
                    Blockchain      = toHotWallet.Blockchain,
                    AssetId         = transferTransactionResult.AssetId,
                    Amount          = transferTransactionResult.Amount,
                    DesiredAsset    = cmd.DesiredAsset,
                    EmployeeEmail   = cmd.EmployeeEmail,
                    TransactionHash = transferTransactionResult.Hash,
                    WalletAddress   = string.Join(Constants.Separator, transferTransactionResult.Sources)
                });

                await _transactionsService.CreateTransactionAsync(new CreateTransactionCommand
                {
                    Amount                = transferTransactionResult.Amount,
                    Blockchain            = toHotWallet.Blockchain,
                    AssetId               = transferTransactionResult.AssetId,
                    Confirmations         = 0,
                    Hash                  = transferTransactionResult.Hash,
                    IdentityType          = transferTransactionResult.IdentityType,
                    Identity              = transferTransactionResult.Identity,
                    TransferId            = toHotWallet.Id,
                    Type                  = TransactionType.CashOut,
                    SourceWalletAddresses = transferTransactionResult.Sources.ToArray(),
                    ContextData           = new CashoutTransactionContext
                    {
                        DesiredAsset       = cmd.DesiredAsset,
                        EmployeeEmail      = cmd.EmployeeEmail,
                        HistoryOperationId = historyId
                    }.ToJson()
                });
            }

            return(new CashoutResult
            {
                Amount = cmd.SourceAmount,
                AssetId = cmd.SourceAssetId,
                SourceWalletAddress = sourceAddress,
                DestWalletAddress = hotwallet
            });
        }