/// <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 <TxProcessInfo> ProcessRequest(ITxRequest req, BitcornContext dbContext) { if (req.Amount <= 0) { throw new ArgumentException("Amount"); } var info = new TxProcessInfo(); var platformIds = new HashSet <PlatformId>(); var fromPlatformId = BitcornUtils.GetPlatformId(req.From); var fromUser = await BitcornUtils.GetUserForPlatform(fromPlatformId, dbContext).AsNoTracking().FirstOrDefaultAsync(); info.From = fromUser; var toArray = req.To.ToArray(); var totalAmountRequired = toArray.Length * req.Amount; bool canExecuteAll = false; if (fromUser != null && fromUser.UserWallet.Balance >= totalAmountRequired) { canExecuteAll = true; } foreach (var to in toArray) { var toPlatformId = BitcornUtils.GetPlatformId(to); if (!platformIds.Contains(toPlatformId)) { platformIds.Add(toPlatformId); } } var platformIdArray = platformIds.ToArray(); var userQuery = BitcornUtils.GetUsersForPlatform(platformIdArray, dbContext).AsNoTracking(); var users = await BitcornUtils.ToPlatformDictionary(platformIdArray, userQuery, dbContext); var output = new List <TxReceipt>(); var txid = Guid.NewGuid().ToString(); var sql = new StringBuilder(); foreach (var to in platformIdArray) { var receipt = new TxReceipt(); if (fromUser != null) { receipt.From = new SelectableUser(fromUser); } if (users.TryGetValue(to.Id, out User user)) { receipt.To = new SelectableUser(user); if (canExecuteAll) { receipt.Tx = VerifyTx(fromUser, user, req.Amount, req.Platform, req.TxType, txid); } if (receipt.Tx != null) { dbContext.CornTx.Add(receipt.Tx); } } output.Add(receipt); } info.Transactions = output.ToArray(); return(info); }