public static async Task <CornTx> DebitWithdrawTx(string cornaddy, string txId, User user, WalletServer server, decimal amount, BitcornContext dbContext, string platform, int emptyUser) { if (user.UserWallet.Balance >= amount) { var sql = new StringBuilder(); sql.Append(TxUtils.ModifyNumber(nameof(UserWallet), nameof(UserWallet.Balance), amount, '-', nameof(UserWallet.UserId), user.UserId)); sql.Append(TxUtils.ModifyNumber(nameof(WalletServer), nameof(WalletServer.ServerBalance), amount, '-', nameof(WalletServer.Id), server.Id)); await DbOperations.ExecuteSqlRawAsync(dbContext, sql.ToString()); var log = new CornTx(); log.BlockchainTxId = txId; log.Amount = amount; log.Timestamp = DateTime.Now; log.TxType = "$withdraw"; log.TxGroupId = Guid.NewGuid().ToString(); log.Platform = platform; log.ReceiverId = emptyUser; log.SenderId = user.UserId; log.CornAddy = cornaddy; var price = log.UsdtPrice = await ProbitApi.GetCornPriceAsync(dbContext); log.TotalUsdtValue = price * amount; dbContext.CornTx.Add(log); await dbContext.SaveAsync(); return(log); } return(null); }
public async Task <ActionResult <object> > GetPrices() { var prices = await ProbitApi.GetPricesAsync(_dbContext); //(cornBtc, btcUsdt, cornPrice); return(new { cornBtc = prices.Item1, btcUsdt = prices.Item2, cornPrice = prices.Item3, }); }
public async Task <ActionResult <List <AvailableSubscriptionResponse> > > Available([FromRoute] string subscriptionName = null) { try { AvailableSubscriptionInfo[] subscriptions = null; var query = (from subscriptionTier in _dbContext.SubscriptionTier join subscription in _dbContext.Subscription on subscriptionTier.SubscriptionId equals subscription.SubscriptionId select new AvailableSubscriptionInfo { SubscriptionTier = subscriptionTier, Subscription = subscription }); if (string.IsNullOrEmpty(subscriptionName) || subscriptionName == "*") { subscriptions = await query.ToArrayAsync(); } else { subscriptions = await query.Where(s => s.Subscription.Name.ToLower() == subscriptionName.ToLower()).ToArrayAsync(); } var availableSubscriptions = new List <AvailableSubscriptionResponse>(); var cornUsdt = await ProbitApi.GetCornPriceAsync(_dbContext); foreach (var row in subscriptions) { var existingEntry = availableSubscriptions.FirstOrDefault(l => l.Subscription.SubscriptionId == row.Subscription.SubscriptionId); if (existingEntry == null) { existingEntry = new AvailableSubscriptionResponse() { Subscription = row.Subscription, }; availableSubscriptions.Add(existingEntry); } decimal actualCost = 0; if (row.SubscriptionTier.CostUsdt != null && row.SubscriptionTier.CostUsdt > 0) { actualCost = SubscriptionUtils.CalculateUsdtToCornCost(cornUsdt, row.SubscriptionTier); if (row.SubscriptionTier.CostCorn == 0 || row.SubscriptionTier.CostCorn == null) { row.SubscriptionTier.CostCorn = actualCost; } } else if (row.SubscriptionTier.CostCorn != null && row.SubscriptionTier.CostCorn > 0) { actualCost = row.SubscriptionTier.CostCorn.Value; } existingEntry.Tiers.Add(new { tierInfo = row.SubscriptionTier, actualCost }); } return(availableSubscriptions); } catch (Exception e) { await BITCORNLogger.LogError(_dbContext, e, subscriptionName); throw e; } }
public async Task <decimal> cornprice() { return(await ProbitApi.GetCornPriceAsync(_dbContext)); }
public async Task <ActionResult <FullUser> > RegisterNewUser([FromBody] Auth0User auth0User, [FromQuery] string referral = null) { if (this.GetCachedUser() != null) { throw new InvalidOperationException(); } if (auth0User == null) { throw new ArgumentNullException(); } if (!StaticLockCollection.Lock(auth0User.Auth0Id)) { return(StatusCode(UserLockCollection.UserLockedReturnCode)); } var existingUserIdentity = await _dbContext.Auth0Query(auth0User.Auth0Id).Select(u => u.UserIdentity).FirstOrDefaultAsync(); if (existingUserIdentity?.Auth0Id == auth0User.Auth0Id) { var user = _dbContext.User.FirstOrDefault(u => u.UserId == existingUserIdentity.UserId); var userWallet = _dbContext.UserWallet.FirstOrDefault(u => u.UserId == existingUserIdentity.UserId); var userStat = _dbContext.UserStat.FirstOrDefault(u => u.UserId == existingUserIdentity.UserId); StaticLockCollection.Release(auth0User.Auth0Id); return(BitcornUtils.GetFullUser(user, existingUserIdentity, userWallet, userStat)); } int referralId; try { referralId = Convert.ToInt32(referral); } catch (Exception e) { referralId = 0; } try { var user = CreateUser(auth0User, referralId); _dbContext.User.Add(user); if (referral != null && referralId != 0) { var referrer = await _dbContext.Referrer.FirstOrDefaultAsync(r => r.ReferralId == referralId); if (ReferralUtils.IsValidReferrer(referrer)) { var referrerUser = await _dbContext.User.FirstOrDefaultAsync(u => u.UserId == referrer.UserId); if (referrerUser != null && !referrerUser.IsBanned) { var referralPayoutTotal = await ReferralUtils.TotalReward(_dbContext, referrer); var referrerRegistrationReward = await TxUtils.SendFromBitcornhub(referrerUser, referralPayoutTotal, "BITCORNFarms", "Registrations reward", _dbContext); var userRegistrationReward = await TxUtils.SendFromBitcornhub(user, referrer.Amount, "BITCORNFarms", "Recruit registrations reward", _dbContext); if (referrerRegistrationReward && userRegistrationReward) { await ReferralUtils.UpdateYtdTotal(_dbContext, referrer, referralPayoutTotal); await ReferralUtils.LogReferralTx(_dbContext, referrer.UserId, referralPayoutTotal, "Registration reward"); await ReferralUtils.LogReferralTx(_dbContext, user.UserId, referrer.Amount, "Recruit registration reward"); var referrerStat = await _dbContext.UserStat.FirstOrDefaultAsync(s => s.UserId == referrer.UserId); if (referrerStat != null) { if (referrerStat.TotalReferrals == null) { referrerStat.TotalReferrals = 0; } referrerStat.TotalReferrals++; if (referrerStat.TotalReferralRewardsCorn == null) { referrerStat.TotalReferralRewardsCorn = 0; } referrerStat.TotalReferralRewardsCorn += referralPayoutTotal; if (referrerStat.TotalReferralRewardsUsdt == null) { referrerStat.TotalReferralRewardsUsdt = 0; } referrerStat.TotalReferralRewardsUsdt += (referralPayoutTotal * (await ProbitApi.GetCornPriceAsync(_dbContext))); } user.UserReferral.SignupReward = DateTime.Now; } } } } await _dbContext.SaveAsync(); return(BitcornUtils.GetFullUser(user, user.UserIdentity, user.UserWallet, user.UserStat)); } catch (Exception e) { await BITCORNLogger.LogError(_dbContext, e, JsonConvert.SerializeObject(auth0User)); throw e; } finally { StaticLockCollection.Release(auth0User.Auth0Id); } }
/// <summary> /// reads stored order by id /// </summary> public async Task <ActionResult <object> > ReadOrder([FromBody] ReadOrderRequest orderRequest) { try { var user = (this.GetCachedUser()); if (this.GetUserMode() != null && this.GetUserMode() == 1) { throw new NotImplementedException(); } if (user != null && user.IsBanned) { return(StatusCode((int)HttpStatusCode.Forbidden)); } var checkOrder = await GetOrder(orderRequest.OrderId); if (checkOrder == null) { return(StatusCode((int)HttpStatusCode.NotFound)); } var(order, client) = checkOrder.Value; if (client.ClientId != orderRequest.ClientId) { return(StatusCode(400)); } if (order.OrderState != 0) { return(StatusCode((int)HttpStatusCode.Gone)); } if (order.ReadBy != user.UserId) { order.ReadBy = user.UserId; await _dbContext.SaveAsync(); } var orderItems = await _dbContext.OrderItem.Where(e => e.OrderId == order.OrderId).ToArrayAsync(); if (orderItems.Length > client.OrderMaxSize) { return(StatusCode((int)HttpStatusCode.NotAcceptable)); } if (orderItems.Sum(e => e.CornAmount) > client.OrderMaxCost) { return(StatusCode((int)HttpStatusCode.NotAcceptable)); } var cornPrice = await ProbitApi.GetCornPriceAsync(_dbContext); var cornOrderSum = orderItems.Select(e => e.CornAmount).Sum(); var cornCurrentSum = orderItems.Select(e => e.UsdAmount / cornPrice).Sum(); var costDiff = Math.Abs(cornCurrentSum - cornOrderSum); if (costDiff > client.AcceptedCostDiff) { foreach (var orderItem in orderItems) { orderItem.CornAmount = orderItem.UsdAmount / cornPrice; } await _dbContext.SaveAsync(); /*var cornAmount = usdAmount / cornPrice; * orderItem.CornAmount = cornAmount;*/ } var username = user.Username; if (string.IsNullOrEmpty(username)) { username = user.UserIdentity.Auth0Nickname; } return(new { orderInfo = new OrderOutput(order, client, orderItems), cornPrice, totalCornPrice = orderItems.Select(e => e.CornAmount).Sum(), totalUsdPrice = orderItems.Select(e => e.UsdAmount).Sum(), userName = username, balance = user.UserWallet.Balance }); } catch (Exception e) { Console.WriteLine(e); throw e; } }
/// <summary> /// called from client server to create an order tht the user will authorize /// </summary> public async Task <ActionResult <object> > AuthorizeOrder([FromBody] AuthorizeOrderRequest orderRequest) { try { var user = (this.GetCachedUser()); if (this.GetUserMode() != null && this.GetUserMode() == 1) { throw new NotImplementedException(); } if (user != null) { if (user.IsBanned) { return(StatusCode(403)); } var checkOrder = await GetOrder(orderRequest.OrderId); if (checkOrder == null) { return(StatusCode(404)); } var(order, client) = checkOrder.Value; if (order.OrderState != 0) { return(StatusCode((int)HttpStatusCode.Gone)); } if (order.ClientId != orderRequest.ClientId) { return(StatusCode((int)HttpStatusCode.BadRequest)); } var orderItems = await _dbContext.OrderItem.Where(e => e.OrderId == order.OrderId).ToArrayAsync(); if (orderItems.Length > client.OrderMaxSize) { return(StatusCode((int)HttpStatusCode.NotAcceptable)); } if (orderItems.Sum(e => e.CornAmount) > client.OrderMaxCost) { return(StatusCode((int)HttpStatusCode.NotAcceptable)); } var recipientUser = await _dbContext.JoinUserModels() .FirstOrDefaultAsync((u) => u.UserId == client.RecipientUser); var cornPrice = await ProbitApi.GetCornPriceAsync(_dbContext); var cornOrderSum = orderItems.Select(e => e.CornAmount).Sum(); var cornCurrentSum = orderItems.Select(e => e.UsdAmount / cornPrice).Sum(); var costDiff = Math.Abs(cornCurrentSum - cornOrderSum); if (costDiff <= client.AcceptedCostDiff) { if (recipientUser != null) { var processInfo = await TxUtils.PrepareTransaction(user, recipientUser, cornOrderSum, client.ClientId, "app:order", _dbContext); var paymentSuccess = await processInfo.ExecuteTransaction(_dbContext); if (paymentSuccess) { var jwt = CreateJwt(client, order, orderItems, cornOrderSum, processInfo.Transactions[0].TxId.Value); order.TxId = processInfo.Transactions[0].TxId; order.OrderState = 1; order.CompletedAt = DateTime.Now; await _dbContext.SaveAsync(); if (string.IsNullOrEmpty(client.Capture)) { return(new { jwt, txId = order.TxId.Value, amount = cornOrderSum }); } else { var restClient = new RestClient(); var url = $"{client.Domain}/{client.Capture}"; var redirectUrl = $"{client.Domain}/{client.Redirect}"; var restRequest = new RestRequest(url, Method.POST); if (client.PostFormat == "application/x-www-form-urlencoded") { restRequest.AddHeader("Content-Type", "application/x-www-form-urlencoded"); restRequest.AddObject(new { jwt }); } else { restRequest.AddJsonBody(new { jwt }); } var restResponse = restClient.Execute(restRequest); await BITCORNLogger.LogError(_dbContext, new Exception("Order hook callback"), restResponse.Content); return(new { redirect = redirectUrl, txId = order.TxId.Value, amount = cornOrderSum }); } } else { return(new { txId = -1 }); } } } else { return(StatusCode((int)HttpStatusCode.PaymentRequired)); } } return(StatusCode((int)HttpStatusCode.BadRequest)); } catch (Exception e) { await BITCORNLogger.LogError(_dbContext, e, JsonConvert.SerializeObject(orderRequest)); return(StatusCode(500)); } }
/// <summary> /// called from client server to create an order tht the user will authorize /// </summary> public async Task <ActionResult <OrderOutput> > CreateOrder([FromBody] CreateOrderRequest orderRequest) { try { var appId = this.GetAppId(_configuration); if (string.IsNullOrEmpty(appId)) { return(StatusCode((int)HttpStatusCode.BadRequest)); } if (appId != orderRequest.ClientId) { await BITCORNLogger.LogError(_dbContext, new Exception("Unauthorized app request " + appId + " - " + orderRequest.ClientId), JsonConvert.SerializeObject(orderRequest)); return(StatusCode(401)); } var client = await _dbContext.ThirdPartyClient.FirstOrDefaultAsync((e) => e.ClientId == appId); //await BITCORNLogger.LogError(_dbContext,new Exception(""),JsonConvert.SerializeObject(orderRequest)); if (client != null) { if (client.OrderMaxSize != null) { if (client.OrderMaxSize.Value > orderRequest.Items.Length) { return(StatusCode((int)HttpStatusCode.NotAcceptable)); } } var cornPrice = await ProbitApi.GetCornPriceAsync(_dbContext); if (client.OrderMaxCost != null) { var totalSum = orderRequest.Items.Select(i => i.AmountUsd / cornPrice).Sum(); if (totalSum > client.OrderMaxCost.Value) { return(StatusCode((int)HttpStatusCode.NotAcceptable)); } } var order = new Order(); order.ClientId = client.ClientId; order.OrderId = Guid.NewGuid().ToString(); order.ClientOrderId = orderRequest.ClientOrderId.ToString(); OrderItem[] items = new OrderItem[orderRequest.Items.Length]; for (int i = 0; i < orderRequest.Items.Length; i++) { var orderItem = new OrderItem(); orderItem.Name = orderRequest.Items[i].Name; orderItem.OrderId = order.OrderId; orderItem.ClientItemId = orderRequest.Items[i].ItemId; orderItem.Quantity = orderRequest.Items[i].Quantity; if (orderItem.Quantity < 1) { orderItem.Quantity = 1; } var usdAmount = orderRequest.Items[i].AmountUsd; var cornAmount = usdAmount / cornPrice; orderItem.CornAmount = cornAmount; orderItem.UsdAmount = orderRequest.Items[i].AmountUsd; items[i] = orderItem; _dbContext.OrderItem.Add(orderItem); } order.OrderState = 0; order.CreatedAt = DateTime.Now; _dbContext.Order.Add(order); await _dbContext.SaveAsync(); return(new OrderOutput(order, client, items)); } return(StatusCode(400)); } catch (Exception e) { await BITCORNLogger.LogError(_dbContext, e, JsonConvert.SerializeObject(orderRequest)); return(StatusCode(500)); } }
/// <summary> /// method to prepare a transaction, calling this method will not move fund immediately /// </summary> /// <param name="req">transaction request</param> /// <returns>transaction tracker output</returns> public static async Task <TxProcessInfo> ProcessRequest(ITxRequest req, BitcornContext dbContext) { if (req.Amount <= 0) { throw new ArgumentException("Amount"); } //create tx process info that will be tracking this transaction var info = new TxProcessInfo(); //create hashset of receivers var platformIds = new HashSet <PlatformId>(); //set sender user info.From = req.FromUser; //array of recipient ids var toArray = req.To.ToArray(); //calculate total amount of corn being sent var totalAmountRequired = toArray.Length * req.Amount; bool canExecuteAll = false; //check if sender has enough corn to execute all transactions if (info.From != null && info.From.UserWallet.Balance >= totalAmountRequired) { if (info.From.UserWallet.IsLocked != null && info.From.UserWallet.IsLocked == true) { canExecuteAll = false; } else { if (!(await ShouldLockWallet(dbContext, info.From, totalAmountRequired))) { canExecuteAll = true; } } } //get platform ids of recipients foreach (var to in toArray) { var toPlatformId = BitcornUtils.GetPlatformId(to); if (!platformIds.Contains(toPlatformId)) { platformIds.Add(toPlatformId); } } var platformIdArray = platformIds.ToArray(); //get recipients query var userQuery = BitcornUtils.GetUsersForPlatform(platformIdArray, dbContext).AsNoTracking(); //convert into dictionary mapped by their platformid var users = await BitcornUtils.ToPlatformDictionary(platformIdArray, userQuery, dbContext); //create list for receipts var output = new List <TxReceipt>(); //create group transaction id var txid = Guid.NewGuid().ToString(); var sql = new StringBuilder(); //get corn usdt price at this time var cornUsdtPrice = (await ProbitApi.GetCornPriceAsync(dbContext)); foreach (var to in platformIdArray) { var receipt = new TxReceipt(); //if sender is registered, assign it to the receipt if (info.From != null) { receipt.From = new SelectableUser(info.From); } //if recipient is registered, assign it to the receipt if (users.TryGetValue(to.Id, out User user)) { receipt.To = new SelectableUser(user); //if all transactions can be executed, attempt to validate this transaction if (canExecuteAll) { //verifytx returns corntx if this transaction will be made receipt.Tx = VerifyTx(info.From, user, cornUsdtPrice, req.Amount, req.Platform, req.TxType, txid); } //if this transaction will be made, log it into corntx table if (receipt.Tx != null) { dbContext.CornTx.Add(receipt.Tx); } } //add receipt to the output output.Add(receipt); } //set receipts to the transaction tracker info.Transactions = output.ToArray(); return(info); }
public static async Task <CornTx[]> Deposit(BitcornContext dbContext, WalletDepositRequest request, IConfiguration configuration) { var receipts = new List <CornTx>(); try { var server = dbContext.WalletServer.FirstOrDefault((s) => s.Index == request.Index); int newDeposits = 0; var sql = new StringBuilder(); foreach (var payment in request.Payments) { decimal amount = payment.Amount; string address = payment.Address; string txid = payment.TxId; bool isLogged = await dbContext.IsDepositRegistered(txid); if (!isLogged) { var wallet = await dbContext.WalletByAddress(address); if (wallet != null) { newDeposits++; var cornTx = new CornTx(); cornTx.Amount = amount; cornTx.BlockchainTxId = txid; cornTx.CornAddy = address; cornTx.ReceiverId = wallet.UserId; cornTx.SenderId = int.Parse(configuration["Config:EmptyUserId"]); cornTx.CornAddy = address; cornTx.Timestamp = DateTime.Now; cornTx.TxType = TransactionType.receive.ToString(); cornTx.Platform = "wallet-server"; cornTx.TxGroupId = Guid.NewGuid().ToString(); var price = cornTx.UsdtPrice = await ProbitApi.GetCornPriceAsync(dbContext); cornTx.TotalUsdtValue = price * amount; var deposit = new CornDeposit(); deposit.TxId = txid; deposit.UserId = wallet.UserId; sql.Append(TxUtils.ModifyNumber(nameof(UserWallet), nameof(UserWallet.Balance), amount, '+', nameof(UserWallet.UserId), wallet.UserId)); sql.Append(TxUtils.ModifyNumber(nameof(WalletServer), nameof(WalletServer.ServerBalance), amount, '+', nameof(WalletServer.Id), server.Id)); dbContext.CornTx.Add(cornTx); dbContext.CornDeposit.Add(deposit); receipts.Add(cornTx); } } } if (newDeposits > 0) { server.LastBalanceUpdateBlock = request.Block; int count = await DbOperations.ExecuteSqlRawAsync(dbContext, sql.ToString()); await dbContext.SaveAsync(); } } catch (Exception e) { await BITCORNLogger.LogError(dbContext, e, JsonConvert.SerializeObject(request)); } return(receipts.ToArray()); }
public async Task <UserWallet> Wallet([FromRoute] string id) { var platformId = BitcornUtils.GetPlatformId(id); var user = await BitcornUtils.GetUserForPlatform(platformId, _dbContext).FirstOrDefaultAsync(); if (user != null) { var userWallet = user.UserWallet; if (!UserLockCollection.Lock(userWallet.UserId)) { return(userWallet); } try { var referralId = _dbContext.UserReferral.FirstOrDefault(r => r.UserId == userWallet.UserId)?.ReferralId; if (referralId != 0 && referralId != null) { var userReferral = await _dbContext.UserReferral.FirstOrDefaultAsync(r => r.UserId == userWallet.UserId); var referrer = await _dbContext.Referrer.FirstOrDefaultAsync(r => r.ReferralId == userReferral.ReferralId); var referrerUser = await _dbContext.JoinUserModels().FirstOrDefaultAsync(w => w.UserId == referrer.UserId); var referrerStat = await _dbContext.UserStat.FirstOrDefaultAsync(s => s.UserId == referrer.UserId); await ReferralUtils.BonusPayout(_dbContext, userReferral, referrer, user, referrerUser, referrerStat); if (referrer != null && userReferral != null && userReferral.MinimumBalanceDate == null && userWallet.Balance >= MIN_BALANCE_QUEST_AMOUNT) { if (referrer.YtdTotal < 600 || (referrer.ETag != null && referrer.Key != null)) { var referralPayoutTotal = await ReferralUtils.TotalReward(_dbContext, referrer); var miniumBalanceRewardUser = await TxUtils.SendFromBitcornhub(user, referrer.Amount, "BITCORNFarms", "Minium balance reward", _dbContext); var miniumBalanceReward = await TxUtils.SendFromBitcornhub(referrerUser, referralPayoutTotal, "BITCORNFarms", "Minium balance reward", _dbContext); if (miniumBalanceReward && miniumBalanceRewardUser) { referrerStat.TotalReferralRewardsCorn += referralPayoutTotal; referrerStat.TotalReferralRewardsUsdt += (referralPayoutTotal * (await ProbitApi.GetCornPriceAsync(_dbContext))); userReferral.MinimumBalanceDate = DateTime.Now; await ReferralUtils.UpdateYtdTotal(_dbContext, referrer, referralPayoutTotal); await ReferralUtils.LogReferralTx(_dbContext, user.UserId, referrer.Amount, "Recruit minimum balance Reward"); await ReferralUtils.LogReferralTx(_dbContext, referrerUser.UserId, referralPayoutTotal, "Minimum balance Reward"); await ReferralUtils.BonusPayout(_dbContext, userReferral, referrer, user, referrerUser, referrerStat); } } } await _dbContext.SaveAsync(); } } catch (Exception e) { await BITCORNLogger.LogError(_dbContext, e, id); } finally { UserLockCollection.Release(userWallet.UserId); } return(user.UserWallet); } else { return(null); } }