public async Task <IActionResult> QrCode(string price, string wallet, string currencyType) { if (decimal.TryParse(price, out decimal result) && !string.IsNullOrWhiteSpace(wallet) && wallet.Length >= 95) { BrokerExchangeParams brokerExchangeParams = new BrokerExchangeParams { SellFiatAmount = result, WalletAddress = wallet, FiatCurrency = "USD", BuyCurrency = "GRFT", SellCurrency = currencyType.ToUpper() }; BrokerExchangeResult exchangeResult = null; try { exchangeResult = await CreateExchange(brokerExchangeParams); } catch (Exception ex) { ViewData["ErrorMessage"] = $"{ex.Message} ({ex.InnerException?.Message})"; return(View("Error")); } ViewData["currencyName"] = currencyType.ToUpper() == "BTC" ? "Bitcoin" : "Ethereum"; return(View(new Tuple <BrokerExchangeResult, string>(exchangeResult, price))); } ViewData["price"] = price; return(View(nameof(SelectGraftWallet))); }
// convert cryptocurrency payment to GRFT public async Task <BrokerExchangeResult> Exchange(BrokerExchangeParams model) { _logger.LogInformation("Exchange: {@params}", model); ValidateExchangeParams(model); if (model.PaymentId == null) { // for Demo payments var calcRes = await CalcExchange(model); model.PaymentId = calcRes.ExchangeId; model.BlockNumber = await _graft.Sale(calcRes.ExchangeId, calcRes.BuyAmount); } Exchange exchange = await GetExchange(model.PaymentId); exchange.OutTxId = model.PaymentId; exchange.OutBlockNumber = model.BlockNumber; var res = await ExchangeStatus(exchange.ExchangeId); _logger.LogInformation("Exchange Result: {@params}", res); return(res); }
void ValidateExchangeParams(BrokerExchangeParams model) { if (!string.IsNullOrWhiteSpace(model.FiatCurrency)) { if (model.BuyFiatAmount <= 0 && model.SellFiatAmount <= 0) { throw new ApiException(ErrorCode.FiatAmountEmpty); } if (model.SellFiatAmount > 0 && model.BuyFiatAmount > 0) { throw new ApiException(ErrorCode.OnlyOneAmountAllowed); } if (model.SellAmount > 0 || model.BuyAmount > 0) { throw new ApiException(ErrorCode.OnlyOneAmountAllowed); } } else { if (model.SellAmount > 0 && model.BuyAmount > 0) { throw new ApiException(ErrorCode.OnlyOneAmountAllowed); } if (model.SellAmount <= 0 && model.BuyAmount <= 0) { throw new ApiException(ErrorCode.InvalidAmount); } } if (string.IsNullOrWhiteSpace(model.SellCurrency)) { throw new ApiException(ErrorCode.SellCurrencyEmpty); } if (!_rateCache.IsSupported(model.SellCurrency)) { throw new ApiException(ErrorCode.SellCurrencyNotSupported, model.SellCurrency); } if (string.IsNullOrWhiteSpace(model.BuyCurrency)) { throw new ApiException(ErrorCode.BuyCurrencyEmpty); } if (!((model.BuyCurrency == "GRFT" && model.SellCurrency == "BTC") || (model.BuyCurrency == "GRFT" && model.SellCurrency == "ETH") || (model.BuyCurrency == "USDT" && model.SellCurrency == "GRFT"))) { throw new ApiException(ErrorCode.CurrencyPairNotSupported, $"{model.SellCurrency}->{model.BuyCurrency}"); } if (string.IsNullOrWhiteSpace(model.WalletAddress)) { throw new ApiException(ErrorCode.WalletEmpty); } }
async Task <Payment> AltcoinSale(GatewaySaleParams model, Terminal terminal) { var brokerParams = new BrokerExchangeParams { FiatCurrency = model.SaleCurrency, SellFiatAmount = model.SaleAmount, SellCurrency = model.PayCurrency, BuyCurrency = "GRFT", WalletAddress = terminal.ServiceProvider.WalletAddress }; var brokerResult = await _broker.Exchange(brokerParams); var payment = new Payment() { Id = brokerResult.ExchangeId, TransactionDate = DateTime.UtcNow, Status = PaymentStatus.New, TerminalId = terminal.Id, StoreId = terminal.StoreId, ServiceProviderId = terminal.ServiceProviderId, SaleAmount = model.SaleAmount, SaleCurrency = model.SaleCurrency, PayToSaleRate = brokerResult.SellToUsdRate, GraftToSaleRate = brokerResult.GraftToUsdRate, PayCurrency = brokerResult.SellCurrency, PayAmount = brokerResult.SellAmount, PayWalletAddress = brokerResult.PayWalletAddress, //ServiceProviderFee = brokerResult.ServiceProviderFee, ExchangeBrokerFee = brokerResult.ExchangeBrokerFeeAmount, //MerchantAmount = brokerResult.MerchantAmount, SaleDetails = model.SaleDetails, }; return(payment); }
public async Task <BrokerExchangeResult> Exchange(BrokerExchangeParams model) { _logger.LogInformation("Exchange: {@params}", model); ValidateExchangeParams(model); Exchange exchange = await ExchangeCalculator.Create(model, _rateCache, _settings); await _cryptoProviderService.CreateAddress(exchange); exchange.Log($"Created new {model.SellCurrency} address: {exchange.PayWalletAddress}"); _cache.Set(exchange.ExchangeId, exchange, DateTimeOffset.Now.AddMinutes(_settings.PaymentTimeoutMinutes)); _db.Exchange.Add(exchange); await _db.SaveChangesAsync(); var res = GetExchangeResult(exchange); _logger.LogInformation("Exchange Result: {@params}", res); return(res); }
public async Task <IActionResult> QrCode(string price, string wallet, string currencyType) { decimal result; if (decimal.TryParse(price, out result) && !string.IsNullOrWhiteSpace(wallet) && wallet.Length >= 95) { BrokerExchangeParams brokerExchangeParams = new BrokerExchangeParams(); brokerExchangeParams.SellFiatAmount = result; brokerExchangeParams.WalletAddress = wallet; brokerExchangeParams.FiatCurrency = "USD"; brokerExchangeParams.BuyCurrency = "GRFT"; brokerExchangeParams.SellCurrency = currencyType.ToUpper(); var exchangeResult = await CreateExchange(brokerExchangeParams); ViewData["currencyName"] = currencyType.ToUpper() == "BTC" ? "Bitcoin" : "Etherium"; return(View(new Tuple <BrokerExchangeResult, string>(exchangeResult, price))); } ViewData["price"] = price; return(View(nameof(SelectGraftWallet))); }
public async Task <GatewaySaleResult> OnlineSale(Payment payment, string currency) { _logger.LogInformation("API Online Sale: {@params}", payment); try { if (payment.Status == PaymentStatus.New) { payment.Status = PaymentStatus.Fail; var terminal = _db.Terminal .Where(t => t.Id == payment.TerminalId) .Include(t => t.ServiceProvider) .Include(t => t.Store).ThenInclude(t => t.Merchant) .FirstOrDefault(); if (terminal == null) { throw new ApiException(ErrorCode.InvalidApiKey); } if (currency == "GRFT") { var graftRate = await _rateCache.GetRateToUsd("GRFT"); payment.PayAmount = payment.SaleAmount / graftRate; payment.PayCurrency = currency; int blockNumber = await _graft.Sale(payment.Id, payment.PayAmount); payment.BlockNumber = blockNumber; payment.PayWalletAddress = _graft.GetQr(payment.Id, payment.PayAmount, blockNumber); } else { // calculate exchange var brokerParams = new BrokerExchangeParams { PaymentId = payment.Id, FiatCurrency = payment.SaleCurrency, SellFiatAmount = payment.SaleAmount, SellCurrency = currency, BuyCurrency = "GRFT", WalletAddress = _settings.GraftWalletAddress //PaymentId = payment.Id, //SaleAmount = payment.SaleAmount, //SaleCurrency = payment.SaleCurrency, //PayCurrency = currency, //ServiceProviderFee = terminal.ServiceProvider.TransactionFee, //ServiceProviderWallet = terminal.ServiceProvider.WalletAddress, //MerchantWallet = terminal.Merchant.WalletAddress }; var calcExchange = await _broker.CalcExchange(brokerParams); payment.PayToSaleRate = calcExchange.SellToUsdRate; payment.GraftToSaleRate = calcExchange.GraftToUsdRate; payment.PayCurrency = calcExchange.SellCurrency; payment.PayAmount = calcExchange.SellAmount; payment.PayWalletAddress = calcExchange.PayWalletAddress; payment.ExchangeBrokerFee = calcExchange.ExchangeBrokerFeeAmount; payment.MerchantAmount = calcExchange.BuyAmount - calcExchange.ExchangeBrokerFeeAmount; // create RTA sale int blockNumber = await _graft.Sale(payment.Id, calcExchange.BuyAmount); payment.BlockNumber = blockNumber; brokerParams.BlockNumber = blockNumber; // initiate exchange var brokerResult = await _broker.Exchange(brokerParams); } payment.Status = PaymentStatus.Waiting; } } catch (Exception ex) { payment.Status = PaymentStatus.Fail; payment.StatusMessage = ex.Message; } if (!_db.Payment.Any(e => e.Id == payment.Id)) { _db.Payment.Add(payment); } else { _db.Payment.Update(payment); } await _db.SaveChangesAsync(); var res = GetSaleResult(payment); return(res); }
internal async Task <BrokerExchangeResult> CreateExchange(BrokerExchangeParams model) { var exchange = await _exchangeService.Exchange(model); return(exchange); }
public async Task <IActionResult> Exchange([FromBody] BrokerExchangeParams model) { var res = await _exchangeService.Exchange(model); return(Ok(res)); }
internal static async Task <Exchange> Create(BrokerExchangeParams model, IRateCache rateCache, PaymentServiceConfiguration settings) { var log = new List <EventItem> { new EventItem($"Started exchange calculation") }; log.Add(new EventItem($"Requesting {model.SellCurrency} rate...")); decimal sellRate = await rateCache.GetRateToUsd(model.SellCurrency); log.Add(new EventItem($"Received {model.SellCurrency} rate: {sellRate} USD")); log.Add(new EventItem($"Requesting GRFT rate...")); decimal graftRate = await rateCache.GetRateToUsd("GRFT"); log.Add(new EventItem($"Received GRFT rate: {graftRate} USD")); decimal sellAmount = 0; decimal graftAmount = 0; decimal buyerAmount = 0; decimal feeAmount = 0; decimal fee = settings.ExchangeBrokerFee; if (!string.IsNullOrWhiteSpace(model.FiatCurrency)) { if (model.SellFiatAmount > 0) { sellAmount = model.SellFiatAmount / sellRate; graftAmount = model.SellFiatAmount / graftRate; feeAmount = graftAmount * fee; buyerAmount = graftAmount - feeAmount; } else { buyerAmount = model.BuyFiatAmount / graftRate; graftAmount = buyerAmount / (1 - fee); feeAmount = graftAmount - buyerAmount; sellAmount = graftAmount * graftRate / sellRate; } } else { if (model.SellAmount > 0) { sellAmount = model.SellAmount; graftAmount = sellAmount * sellRate / graftRate; feeAmount = graftAmount * fee; buyerAmount = graftAmount - feeAmount; } else { buyerAmount = model.BuyAmount; graftAmount = buyerAmount / (1 - fee); feeAmount = graftAmount - buyerAmount; sellAmount = graftAmount * graftRate / sellRate; } } var exchange = new Exchange { ExchangeId = Guid.NewGuid().ToString(), CreatedAt = DateTime.UtcNow, Status = PaymentStatus.Waiting, SellAmount = sellAmount, SellCurrency = model.SellCurrency, BuyAmount = buyerAmount, BuyCurrency = model.BuyCurrency, SellToUsdRate = sellRate, GraftToUsdRate = graftRate, ExchangeBrokerFee = feeAmount, BuyerWallet = model.WalletAddress, BuyerTransactionStatus = GraftTransactionStatus.New }; exchange.ProcessingEvents = log; log.Add(new EventItem($"Created exchange: {exchange.SellAmount} {exchange.SellCurrency} to {exchange.BuyAmount} {exchange.BuyCurrency}")); log.Add(new EventItem($"Exchange Broker fee of {fee*100}% is {exchange.ExchangeBrokerFee} GRFT")); return(exchange); }