public async Task <ActionResult <TxReceipt[]> > Rain([FromBody] RainRequest rainRequest)
        {
            try
            {
                if (rainRequest == null)
                {
                    throw new ArgumentNullException();
                }
                if (rainRequest.From == null)
                {
                    throw new ArgumentNullException();
                }
                if (rainRequest.To == null)
                {
                    throw new ArgumentNullException();
                }
                if (rainRequest.Amount <= 0)
                {
                    return(StatusCode((int)HttpStatusCode.BadRequest));
                }

                var processInfo = await TxUtils.ProcessRequest(rainRequest, _dbContext);

                var transactions = processInfo.Transactions;
                if (transactions != null && transactions.Length > 0)
                {
                    StringBuilder sql = new StringBuilder();
                    if (processInfo.WriteTransactionOutput(sql))
                    {
                        string pk         = nameof(UserStat.UserId);
                        string table      = nameof(UserStat);
                        var    recipients = processInfo.ValidRecipients;
                        var    fromId     = transactions[0].From.UserId;

                        var recipientStats = new List <ColumnValuePair>();
                        recipientStats.Add(new ColumnValuePair(nameof(UserStat.RainedOn), 1));
                        recipientStats.Add(new ColumnValuePair(nameof(UserStat.RainedOnTotal), rainRequest.Amount));

                        sql.Append(TxUtils.ModifyNumbers(table, recipientStats, '+', pk, recipients));
                        sql.Append(TxUtils.UpdateNumberIfTop(table, nameof(UserStat.TopRainedOn), rainRequest.Amount, pk, recipients));

                        var senderStats = new List <ColumnValuePair>();
                        senderStats.Add(new ColumnValuePair(nameof(UserStat.Rained), 1));
                        senderStats.Add(new ColumnValuePair(nameof(UserStat.RainTotal), processInfo.TotalAmount));

                        sql.Append(TxUtils.ModifyNumbers(table, senderStats, '+', pk, fromId));
                        sql.Append(TxUtils.UpdateNumberIfTop(table, nameof(UserStat.TopRain), processInfo.TotalAmount, pk, fromId));

                        await _dbContext.Database.ExecuteSqlRawAsync(sql.ToString());

                        await _dbContext.SaveAsync(IsolationLevel.RepeatableRead);
                    }
                    await TxUtils.AppendTxs(transactions, _dbContext, rainRequest.Columns);
                }
                return(processInfo.Transactions);
            }
            catch (Exception e)
            {
                await BITCORNLogger.LogError(_dbContext, e);

                throw e;
            }
        }
        public async Task <ActionResult <TxReceipt[]> > Tipcorn([FromBody] TipRequest tipRequest)
        {
            if (tipRequest == null)
            {
                throw new ArgumentNullException();
            }
            if (tipRequest.From == null)
            {
                throw new ArgumentNullException();
            }
            if (tipRequest.To == null)
            {
                throw new ArgumentNullException();
            }
            if (tipRequest.To == tipRequest.From)
            {
                return(StatusCode((int)HttpStatusCode.BadRequest));
            }
            if (tipRequest.Amount <= 0)
            {
                return(StatusCode((int)HttpStatusCode.BadRequest));
            }

            try
            {
                var processInfo = await TxUtils.ProcessRequest(tipRequest, _dbContext);

                var transactions = processInfo.Transactions;
                if (transactions != null && transactions.Length > 0)
                {
                    StringBuilder sql = new StringBuilder();
                    if (processInfo.WriteTransactionOutput(sql))
                    {
                        var receipt = transactions[0];
                        if (receipt.Tx != null)
                        {
                            var    to        = receipt.To.User.UserStat;
                            var    from      = receipt.From.User.UserStat;
                            var    amount    = tipRequest.Amount;
                            string table     = nameof(UserStat);
                            var    pk        = nameof(UserStat.UserId);
                            var    fromStats = new List <ColumnValuePair>();

                            fromStats.Add(new ColumnValuePair(nameof(UserStat.Tip), 1));
                            fromStats.Add(new ColumnValuePair(nameof(UserStat.TipTotal), amount));

                            sql.Append(TxUtils.ModifyNumbers(table, fromStats, '+', pk, from.UserId));

                            var toStats = new List <ColumnValuePair>();
                            toStats.Add(new ColumnValuePair(nameof(UserStat.Tipped), 1));
                            toStats.Add(new ColumnValuePair(nameof(UserStat.TippedTotal), amount));

                            sql.Append(TxUtils.ModifyNumbers(table, toStats, '+', pk, to.UserId));

                            sql.Append(TxUtils.UpdateNumberIfTop(table, nameof(UserStat.TopTip), amount, pk, from.UserId));
                            sql.Append(TxUtils.UpdateNumberIfTop(table, nameof(UserStat.TopTipped), amount, pk, to.UserId));

                            await _dbContext.Database.ExecuteSqlRawAsync(sql.ToString());

                            await _dbContext.SaveAsync(IsolationLevel.RepeatableRead);
                        }
                    }
                    else
                    {
                        if (processInfo.From != null && !processInfo.From.IsBanned && processInfo.Transactions[0].To == null)
                        {
                            if (processInfo.From.UserWallet.Balance >= tipRequest.Amount)
                            {
                                var unclaimed = new UnclaimedTx();
                                unclaimed.TxType             = ((ITxRequest)tipRequest).TxType;
                                unclaimed.Platform           = tipRequest.Platform;
                                unclaimed.ReceiverPlatformId = BitcornUtils.GetPlatformId(tipRequest.To).Id;
                                unclaimed.Amount             = tipRequest.Amount;
                                unclaimed.Timestamp          = DateTime.Now;
                                unclaimed.SenderUserId       = processInfo.From.UserId;
                                unclaimed.Expiration         = DateTime.Now.AddMinutes(TimeToClaimTipMinutes);
                                unclaimed.Claimed            = false;
                                unclaimed.Refunded           = false;

                                _dbContext.UnclaimedTx.Add(unclaimed);
                                await _dbContext.Database.ExecuteSqlRawAsync(TxUtils.ModifyNumber(nameof(UserWallet), nameof(UserWallet.Balance), tipRequest.Amount, '-', nameof(UserWallet.UserId), processInfo.From.UserId));

                                await _dbContext.SaveAsync();
                            }
                        }
                    }
                    await TxUtils.AppendTxs(transactions, _dbContext, tipRequest.Columns);
                }
                return(transactions);
            }
            catch (Exception e)
            {
                await BITCORNLogger.LogError(_dbContext, e);

                throw e;
            }
        }