コード例 #1
0
        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)));
        }
コード例 #2
0
        // 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);
        }
コード例 #3
0
        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);
            }
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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)));
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        internal async Task <BrokerExchangeResult> CreateExchange(BrokerExchangeParams model)
        {
            var exchange = await _exchangeService.Exchange(model);

            return(exchange);
        }
コード例 #9
0
        public async Task <IActionResult> Exchange([FromBody] BrokerExchangeParams model)
        {
            var res = await _exchangeService.Exchange(model);

            return(Ok(res));
        }
コード例 #10
0
        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);
        }