public async Task <APIResponse> AssetEth([FromBody] AssetEthModel model) { // validate if (BaseValidableModel.IsInvalid(model, out var errFields)) { return(APIResponse.BadRequest(errFields)); } // try parse amount if (!BigInteger.TryParse(model.Amount, out var inputAmount) || inputAmount < 1) { return(APIResponse.BadRequest(nameof(model.Amount), "Invalid amount")); } // try parse fiat currency var exchangeCurrency = FiatCurrency.Usd; if (Enum.TryParse(model.Currency, true, out FiatCurrency fc)) { exchangeCurrency = fc; } // --- var rcfg = RuntimeConfigHolder.Clone(); var user = await GetUserFromDb(); var userTier = CoreLogic.User.GetTier(user); var agent = GetUserAgentInfo(); if (userTier < UserTier.Tier2) { return(APIResponse.BadRequest(APIErrorCode.AccountNotVerified)); } // --- if (!rcfg.Gold.AllowTradingEth) { return(APIResponse.BadRequest(APIErrorCode.TradingNotAllowed)); } var limits = WithdrawalLimits(rcfg, TradableCurrency.Eth); var estimation = await Estimation(rcfg, inputAmount, TradableCurrency.Eth, exchangeCurrency, model.EthAddress, model.Reversed, limits.Min, limits.Max); if (!estimation.TradingAllowed || estimation.ResultCurrencyAmount < 1) { return(APIResponse.BadRequest(APIErrorCode.TradingNotAllowed)); } if (estimation.IsLimitExceeded) { return(APIResponse.BadRequest(APIErrorCode.TradingExchangeLimit, estimation.View.Limits)); } // limit gold amount to max available if (estimation.ResultGoldAmount.FromSumus() > user.UserSumusWallet.BalanceGold) { estimation = await Estimation(rcfg, user.UserSumusWallet.BalanceGold.ToSumus(), TradableCurrency.Eth, exchangeCurrency, model.EthAddress, false, limits.Min, limits.Max); if (!estimation.TradingAllowed || estimation.ResultCurrencyAmount < 1) { return(APIResponse.BadRequest(APIErrorCode.TradingNotAllowed)); } if (estimation.IsLimitExceeded) { return(APIResponse.BadRequest(APIErrorCode.TradingExchangeLimit, estimation.View.Limits)); } } var timeNow = DateTime.UtcNow; // history var finHistory = new DAL.Models.UserFinHistory() { Status = UserFinHistoryStatus.Unconfirmed, Type = UserFinHistoryType.GoldSell, Source = "GOLD", SourceAmount = TextFormatter.FormatTokenAmountFixed(estimation.ResultGoldAmount, TokensPrecision.Sumus), Destination = "ETH", DestinationAmount = TextFormatter.FormatTokenAmountFixed(estimation.ResultCurrencyAmount, TokensPrecision.Ethereum), Comment = "", TimeCreated = timeNow, UserId = user.Id, }; DbContext.UserFinHistory.Add(finHistory); await DbContext.SaveChangesAsync(); // request var request = new DAL.Models.SellGoldEth() { Status = BuySellGoldRequestStatus.Unconfirmed, GoldAmount = estimation.ResultGoldAmount.FromSumus(), Destination = model.EthAddress, EthAmount = estimation.ResultCurrencyAmount.FromSumus(), ExchangeCurrency = exchangeCurrency, GoldRateCents = estimation.CentsPerGoldRate, EthRateCents = estimation.CentsPerAssetRate, TimeCreated = timeNow, RelFinHistoryId = finHistory.Id, UserId = user.Id, }; // add and save DbContext.SellGoldEth.Add(request); await DbContext.SaveChangesAsync(); var assetPerGold = CoreLogic.Finance.Estimation.AssetPerGold(TradableCurrency.Eth, estimation.CentsPerAssetRate, estimation.CentsPerGoldRate); return(APIResponse.Success( new AssetEthView() { RequestId = request.Id, EthRate = estimation.CentsPerAssetRate / 100d, GoldRate = estimation.CentsPerGoldRate / 100d, Currency = exchangeCurrency.ToString().ToUpper(), EthPerGoldRate = assetPerGold.ToString(), Estimation = estimation.View, } )); }
public async Task <APIResponse> AssetEth([FromBody] AssetEthModel model) { // validate if (BaseValidableModel.IsInvalid(model, out var errFields)) { return(APIResponse.BadRequest(errFields)); } // try parse amount if (!BigInteger.TryParse(model.Amount, out var inputAmount) || inputAmount < 1) { return(APIResponse.BadRequest(nameof(model.Amount), "Invalid amount")); } // try parse fiat currency var exchangeCurrency = FiatCurrency.Usd; if (Enum.TryParse(model.Currency, true, out FiatCurrency fc)) { exchangeCurrency = fc; } // --- var rcfg = RuntimeConfigHolder.Clone(); var user = await GetUserFromDb(); // --- if (!rcfg.Gold.AllowTradingEth) { return(APIResponse.BadRequest(APIErrorCode.TradingNotAllowed)); } var limits = DepositLimits(rcfg, TradableCurrency.Eth); // estimation var estimation = await Estimation(rcfg, inputAmount, TradableCurrency.Eth, exchangeCurrency, model.Reversed, 0d, limits.Min, limits.Max); if (!estimation.TradingAllowed || estimation.ResultCurrencyAmount < 1) { return(APIResponse.BadRequest(APIErrorCode.TradingNotAllowed)); } if (estimation.IsLimitExceeded) { return(APIResponse.BadRequest(APIErrorCode.TradingExchangeLimit, estimation.View.Limits)); } var timeNow = DateTime.UtcNow; // request var request = new DAL.Models.BuyGoldEth() { Status = BuySellGoldRequestStatus.Unconfirmed, ExchangeCurrency = exchangeCurrency, GoldRateCents = estimation.CentsPerGoldRate, EthRateCents = estimation.CentsPerAssetRate, TimeCreated = timeNow, UserId = user.Id, }; DbContext.BuyGoldEth.Add(request); await DbContext.SaveChangesAsync(); // get a token from eth2gold service var contractToken = ""; { try { var reply = await Bus.Request( Eth2Gold.Subject.Request.OrderCreate, new Eth2Gold.Request.OrderCreate() { ExternalID = (ulong)request.Id, }, Eth2Gold.Request.OrderCreateReply.Parser ); if (reply.ResultCase == Eth2Gold.Request.OrderCreateReply.ResultOneofCase.Token) { if (reply.Token.ToByteArray().Length != 32) { throw new Exception($"token is length of {reply.Token.ToByteArray().Length}"); } contractToken = BitConverter.ToString(reply.Token.ToByteArray()).Replace("-", string.Empty); } else { throw new Exception(reply.Error); } } catch (Exception e) { Logger.Error(e, "Failed to get token from eth2gold service"); return(APIResponse.Failure(APIErrorCode.InternalServerError)); } } var assetPerGold = CoreLogic.Finance.Estimation.AssetPerGold(TradableCurrency.Eth, estimation.CentsPerAssetRate, estimation.CentsPerGoldRate); return(APIResponse.Success( new AssetEthView() { RequestId = request.Id, EthRate = estimation.CentsPerAssetRate / 100d, GoldRate = estimation.CentsPerGoldRate / 100d, EthPerGoldRate = assetPerGold.ToString(), Currency = exchangeCurrency.ToString().ToUpper(), Expires = ((DateTimeOffset)timeNow.AddHours(1)).ToUnixTimeSeconds(), Estimation = estimation.View, ContractToken = contractToken, } )); }