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