public bool WriteTransactionOutput(StringBuilder sql) { if (From == null) { return(false); } decimal totalAmount = 0; decimal singleTx = 0; List <int> recipients = new List <int>(); for (int i = 0; i < Transactions.Length; i++) { if (Transactions[i].Tx != null) { totalAmount += Transactions[i].Tx.Amount.Value; recipients.Add(Transactions[i].To.UserId); singleTx = Transactions[i].Tx.Amount.Value; } } TotalAmount = totalAmount; ValidRecipients = recipients.ToArray(); if (ValidRecipients.Length > 0) { sql.Append(TxUtils.ModifyNumber(nameof(UserWallet), nameof(UserWallet.Balance), singleTx, '+', nameof(UserWallet.UserId), ValidRecipients)); sql.Append(TxUtils.ModifyNumber(nameof(UserWallet), nameof(UserWallet.Balance), totalAmount, '-', nameof(UserWallet.UserId), From.UserId)); return(true); } return(false); }
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 <int> Payout([FromBody] HashSet <string> chatters) { try { var grouping = (await _dbContext.JoinUserModels().Where(u => chatters.Contains(u.UserIdentity.TwitchId)) .AsNoTracking() .ToArrayAsync()).GroupBy(u => u.SubTier).ToArray(); decimal total = 0; int changedRows = 0; StringBuilder sql = new StringBuilder(); var pk = nameof(UserWallet.UserId); foreach (var group in grouping) { decimal payout = 0; var level = group.Key; if (level == 0) { continue; } var ids = group.Select(u => u.UserId).ToArray(); if (level == 1) { payout = 0.25m; } else if (level == 2) { payout = .5m; } else { payout = 1; } sql.Append(TxUtils.ModifyNumber(nameof(UserWallet), nameof(UserWallet.Balance), payout, '+', pk, ids)); sql.Append(TxUtils.ModifyNumber(nameof(UserStat), nameof(UserStat.EarnedIdle), payout, '+', pk, ids)); int count = await _dbContext.Database.ExecuteSqlRawAsync(sql.ToString()); total += payout * count; changedRows += count; } if (changedRows > 0) { await _dbContext.Database.ExecuteSqlRawAsync(TxUtils.ModifyNumber(nameof(UserWallet), nameof(UserWallet.Balance), total, '-', pk, BitcornHubPK)); } //this endpoint is called frequently so can use this to check if there are tx's that need to be refunded await TxUtils.RefundUnclaimed(_dbContext); return(changedRows / 2); } catch (Exception e) { await BITCORNLogger.LogError(_dbContext, e); throw e; } }
public static async Task BonusPayout(BitcornContext dbContext, UserReferral userReferral, Referrer referrer, User user, User referrerUser, UserStat referrerStat) { if (userReferral != null && userReferral.SignupReward != null && userReferral.MinimumBalanceDate != null && userReferral.WalletDownloadDate != null && userReferral.SyncDate != null && userReferral.Bonus == null && userReferral.ReferrerBonus == null && userReferral.UserSubscriptionId == null && referrer != null && !user.IsBanned && !referrerUser.IsBanned) { var subQuery = SubscriptionUtils.GetActiveSubscription(dbContext, user, "BITCORNFarms", 1); if (subQuery == null) { return; } var userSubInfo = await subQuery.FirstOrDefaultAsync(); if (userSubInfo == null) { return; } userReferral.UserSubscriptionId = userSubInfo.UserSubcriptionTierInfo.UserSubscription.UserSubscriptionId; var amount = BONUS_PAYOUT; var bonusReward = await TxUtils.SendFromBitcornhub(user, amount, "BITCORNFarms", "Referral bonus reward", dbContext); if (IsValidReferrer(referrer)) { if (bonusReward) { userReferral.Bonus = DateTime.Now; await LogReferralTx(dbContext, user.UserId, amount, "Recruit bonus reward"); var referrerBonusReward = await TxUtils.SendFromBitcornhub(referrerUser, amount, "BITCORNFarms", "Referral bonus reward", dbContext); if (referrerBonusReward) { await UpdateYtdTotal(dbContext, referrer, amount); await LogReferralTx(dbContext, referrerUser.UserId, amount, "Referral bonus reward"); referrerStat.TotalReferralRewardsCorn += amount; referrerStat.TotalReferralRewardsUsdt += (amount * await ProbitApi.GetCornPriceAsync(dbContext)); userReferral.ReferrerBonus = DateTime.Now; } } } } }
static async Task <bool> ShareSubscriptionPaymentWithReferrer(BitcornContext dbContext, Subscription subInfo, decimal cost, SubTx subTx, Referrer referrer, User referrerUser, User subscriptionPaymentRecipient) { if (referrer.EnableSubscriptionRewards) { //get referrer user info if (!subInfo.RestrictReferralRewards || (subInfo.RestrictReferralRewards && (referrerUser.Level == "BEST" || referrerUser.Level == "BAIT" || referrerUser.IsAdmin() || referrer.Tier >= 3))) { //calculate amount that will be sent to the referrer var referralShare = cost * subInfo.ReferrerPercentage.Value; //prepare transaction to the referrer var referralShareTx = await TxUtils.PrepareTransaction(subscriptionPaymentRecipient, referrerUser, referralShare, "BITCORNFarms", "$sub referral share", dbContext); //make sure stat tracking values have been initialized if (referrerUser.UserStat.TotalReferralRewardsCorn == null) { referrerUser.UserStat.TotalReferralRewardsCorn = 0; } //make sure stat tracking values have been initialized if (referrerUser.UserStat.TotalReferralRewardsUsdt == null) { referrerUser.UserStat.TotalReferralRewardsUsdt = 0; } //increment total received corn rewards referrerUser.UserStat.TotalReferralRewardsCorn += referralShare; //inceremnt total received usdt rewards referrerUser.UserStat.TotalReferralRewardsUsdt += ((referralShare) * (await ProbitApi.GetCornPriceAsync(dbContext))); //execute transaction if (await TxUtils.ExecuteTransaction(referralShareTx, dbContext)) { //if transaction was made, log & update ytd total await ReferralUtils.UpdateYtdTotal(dbContext, referrer, referralShare); var referralTx = await ReferralUtils.LogReferralTx(dbContext, referrerUser.UserId, referralShare, "$sub referral share"); subTx.ReferralTxId = referralTx.ReferralTxId; await dbContext.SaveAsync(); return(true); } } } return(false); }
public static async Task ReferralRewards(BitcornContext dbContext, WalletDownload walletDownload, UserReferral userReferral, User referrerUser, User user, string type) { if (user.IsBanned || referrerUser.IsBanned) { return; } var referrer = await dbContext.Referrer .FirstOrDefaultAsync(w => w.UserId == walletDownload.ReferralUserId); userReferral.WalletDownloadDate = DateTime.Now; if (IsValidReferrer(referrer)) { var referralPayoutTotal = await ReferralUtils.TotalReward(dbContext, referrer) + await ReferralUtils.WalletBonusReward(dbContext, referrer, 10);; var referrerReward = await TxUtils.SendFromBitcornhub(referrerUser, referralPayoutTotal, "BITCORNFarms", type, dbContext); var referreeReward = await TxUtils.SendFromBitcornhub(user, referrer.Amount + 10, "BITCORNFarms", type, dbContext); if (referrerReward && referreeReward) { await ReferralUtils.LogReferralTx(dbContext, referrerUser.UserId, referralPayoutTotal, type); await ReferralUtils.LogReferralTx(dbContext, user.UserId, referrer.Amount + 10, $"Recruit {type}"); await ReferralUtils.UpdateYtdTotal(dbContext, referrer, referralPayoutTotal); if (referrerUser.UserStat.TotalReferralRewardsCorn == null) { referrerUser.UserStat.TotalReferralRewardsCorn = 0; } if (referrerUser.UserStat.TotalReferralRewardsUsdt == null) { referrerUser.UserStat.TotalReferralRewardsUsdt = 0; } referrerUser.UserStat.TotalReferralRewardsCorn += referralPayoutTotal; referrerUser.UserStat.TotalReferralRewardsUsdt += ((referralPayoutTotal) * (await ProbitApi.GetCornPriceAsync(dbContext))); userReferral.WalletDownloadDate = DateTime.Now; await ReferralUtils.BonusPayout(dbContext, userReferral, referrer, user, referrerUser, referrerUser.UserStat); } } }
public async Task <ActionResult <object> > GetSold24() { decimal sold24 = 0; try { sold24 = await TxUtils.GetSoldCorn24h(_dbContext); } catch { } return(new { sold24, available = Math.Abs(TxController.SELL_CORN_CAP_24H - sold24) }); }
public virtual async Task OnSyncSuccess(DateTime?socialAccountCreationDate, PlatformId platformId) { await TxUtils.TryClaimTx(platformId, null, _dbContext); var key = $"{platformId.Platform}|{platformId.Id}"; if (!(await _dbContext.SocialIdentity.AnyAsync(s => s.PlatformId == key))) { if (socialAccountCreationDate != null && DateTime.Now > socialAccountCreationDate.Value.AddDays(7)) { await ReferralUtils.UpdateReferralSync(_dbContext, platformId); } _dbContext.SocialIdentity.Add(new SocialIdentity() { PlatformId = key, Timestamp = DateTime.Now }); await _dbContext.SaveAsync(); } }
public static async Task <CornTx> DebitWithdrawTx(string txId, User user, WalletServer server, decimal amount, BitcornContext dbContext, string platform) { 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 dbContext.Database.ExecuteSqlRawAsync(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 = user.UserId; dbContext.CornTx.Add(log); await dbContext.SaveAsync(); return(log); } return(null); }
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); } }
public static async Task <BitcornResponse> Withdraw(BitcornContext dbContext, IConfiguration configuration, User user, string cornAddy, decimal amount, string platform) { var cornResponse = new BitcornResponse(); cornResponse.WalletAvailable = true; try { if (user.IsBanned) { return(cornResponse); } if (user.UserWallet.Balance < amount) { return(cornResponse); } if (user.UserWallet.IsLocked != null && user.UserWallet.IsLocked.Value) { return(cornResponse); } if ((await TxUtils.ShouldLockWallet(dbContext, user, amount))) { return(cornResponse); } var server = await dbContext.GetWalletServer(user.UserWallet); if (!server.Enabled || !server.WithdrawEnabled) { cornResponse.WalletAvailable = false; return(cornResponse); } string accessToken = await GetWalletServerAccessToken(configuration); //failed to fetch access token if (!CheckAccessTokenExists(accessToken)) { throw new UnauthorizedAccessException("Failed to fetch wallet server access token"); } using (var client = new WalletClient(server.Endpoint, accessToken)) { var response = await client.SendToAddressAsync(cornAddy, amount); if (!response.IsError) { string txId = response.GetParsedContent(); await DebitWithdrawTx(cornAddy, txId, user, server, amount, dbContext, platform, int.Parse(configuration["Config:EmptyUserId"])); cornResponse.WalletObject = txId; } //we got an error, fetch the internal wallet error code and figure out what to do else { //get wallet error response var error = response.GetError(); cornResponse.ErrorCode = error.Code; cornResponse.DepositAddress = server.DepositAddress; //invalid withdrawal address if (error.Code == WalletErrorCodes.RPC_INVALID_ADDRESS_OR_KEY) { cornResponse.UserError = true; } //too much immature corn to complete this transaction at this time else if (error.Code == WalletErrorCodes.RPC_WALLET_INSUFFICIENT_FUNDS) { cornResponse.WalletAvailable = false; } //wallet server was not reached else if (error.Code == WalletErrorCodes.HTTP_ERROR) { cornResponse.WalletAvailable = false; } try { await BITCORNLogger.LogError(dbContext, new Exception("wallet withdraw failed"), JsonConvert.SerializeObject(new { error = error, amount, cornAddy })); } catch (Exception ex) { } } } } catch (Exception e) { throw e; } return(cornResponse); }
public static async Task UpdateReferralSync(BitcornContext dbContext, PlatformId platformId) { var user = BitcornUtils.GetUserForPlatform(platformId, dbContext).FirstOrDefault(); try { if (user != null && user.UserId != 0) { if (user.IsBanned) { return; } if (!UserLockCollection.Lock(user.UserId)) { throw new Exception("User is locked"); } var userReferral = await dbContext.UserReferral.FirstOrDefaultAsync(u => u.UserId == user.UserId); if (userReferral != null && userReferral.SyncDate == null) { var referrer = await dbContext.Referrer.FirstOrDefaultAsync(r => r.ReferralId == userReferral.ReferralId); if (referrer != null && (referrer.YtdTotal < 600 || (referrer.ETag != null && referrer.Key != null))) { var referralPayoutTotal = await ReferralUtils.TotalReward(dbContext, referrer); var referrerUser = await dbContext.User.FirstOrDefaultAsync(u => u.UserId == referrer.UserId); if (referrerUser.IsBanned) { if (user != null) { UserLockCollection.Release(user.UserId); } return; } var referreeReward = await TxUtils.SendFromBitcornhub(user, referrer.Amount, "BITCORNfarms", "Recruit social sync", dbContext); var referrerReward = await TxUtils.SendFromBitcornhub(referrerUser, referralPayoutTotal, "BITCORNfarms", "Social sync", dbContext); if (referrerReward && referreeReward) { userReferral.SyncDate = DateTime.Now; await UpdateYtdTotal(dbContext, referrer, referralPayoutTotal); await LogReferralTx(dbContext, referrer.UserId, referralPayoutTotal, "Social Sync"); await LogReferralTx(dbContext, user.UserId, referralPayoutTotal, "Recruit social Sync"); var userStat = await dbContext.UserStat.FirstOrDefaultAsync(s => s.UserId == referrer.UserId); userStat.TotalReferralRewardsCorn += referralPayoutTotal; userStat.TotalReferralRewardsUsdt += (referralPayoutTotal * (await ProbitApi.GetCornPriceAsync(dbContext))); await ReferralUtils.BonusPayout(dbContext, userReferral, referrer, user, referrerUser, userStat); } } } await dbContext.SaveAsync(); } } catch (Exception e) { await BITCORNLogger.LogError(dbContext, e, null); throw; } finally { if (user != null) { UserLockCollection.Release(user.UserId); } } }
public async Task <FullUser> Register([FromBody] RegistrationData registrationData) { if (registrationData == null) { throw new ArgumentNullException("registrationData"); } if (registrationData.Auth0Id == null) { throw new ArgumentNullException("registrationData.Auth0Id"); } if (registrationData.PlatformId == null) { throw new ArgumentNullException("registrationData.PlatformId"); } try { string auth0Id = registrationData.Auth0Id; var auth0DbUser = await _dbContext.Auth0Query(auth0Id).FirstOrDefaultAsync(); var platformId = BitcornUtils.GetPlatformId(registrationData.PlatformId); switch (platformId.Platform) { case "twitch": var twitchUser = await TwitchKraken.GetTwitchUser(platformId.Id); var twitchDbUser = await _dbContext.TwitchQuery(platformId.Id).FirstOrDefaultAsync(); if (twitchDbUser != null && twitchDbUser.UserIdentity.Auth0Id == null) { // _dbContext.UserIdentity.Remove(auth0DbUser); auth0DbUser.UserIdentity.TwitchId = twitchDbUser.UserIdentity.TwitchId; CopyIdentity(auth0DbUser.UserIdentity, twitchDbUser.UserIdentity); twitchDbUser.UserIdentity.TwitchUsername = twitchUser.name; twitchDbUser.UserIdentity.Auth0Id = auth0Id; twitchDbUser.UserIdentity.Auth0Nickname = auth0DbUser.UserIdentity.Auth0Nickname; await MigrateUser(auth0DbUser, twitchDbUser); await TxUtils.TryClaimTx(platformId, null, _dbContext); return(GetFullUser(twitchDbUser)); } else if (twitchDbUser == null && auth0DbUser != null) { auth0DbUser.UserIdentity.TwitchId = platformId.Id; auth0DbUser.UserIdentity.TwitchUsername = twitchUser.name; await _dbContext.SaveAsync(); await TxUtils.TryClaimTx(platformId, null, _dbContext); return(GetFullUser(auth0DbUser)); } else if (twitchDbUser != null) { var e = new Exception($"A login id already exists for this twitch id {platformId.Id}"); await BITCORNLogger.LogError(_dbContext, e); throw e; } else { var e = new Exception( $"Failed to register twitch {platformId.Id} {auth0Id}"); await BITCORNLogger.LogError(_dbContext, e); throw e; } case "discord": try { var discordToken = DiscordApi.GetDiscordBotToken(_configuration); var discordUser = await DiscordApi.GetDiscordUser(discordToken, platformId.Id); var discordDbUser = await _dbContext.DiscordQuery(platformId.Id).FirstOrDefaultAsync(); if (discordDbUser != null && discordDbUser.UserIdentity.Auth0Id == null) { //_dbContext.UserIdentity.Remove(auth0DbUser); //await _dbContext.SaveAsync(); auth0DbUser.UserIdentity.DiscordId = discordDbUser.UserIdentity.DiscordId; CopyIdentity(auth0DbUser.UserIdentity, discordDbUser.UserIdentity); discordDbUser.UserIdentity.DiscordUsername = DiscordApi.GetUsernameString(discordUser); discordDbUser.UserIdentity.Auth0Id = auth0Id; discordDbUser.UserIdentity.Auth0Nickname = auth0DbUser.UserIdentity.Auth0Nickname; await MigrateUser(auth0DbUser, discordDbUser); await TxUtils.TryClaimTx(platformId, null, _dbContext); return(GetFullUser(discordDbUser)); } else if (discordDbUser == null && auth0DbUser != null) { auth0DbUser.UserIdentity.DiscordId = platformId.Id; auth0DbUser.UserIdentity.DiscordUsername = DiscordApi.GetUsernameString(discordUser); await _dbContext.SaveAsync(); await TxUtils.TryClaimTx(platformId, null, _dbContext); return(GetFullUser(auth0DbUser)); } else if (discordDbUser?.UserIdentity.Auth0Id != null) { var e = new Exception($"A login id already exists for this discord id"); await BITCORNLogger.LogError(_dbContext, e, $"Auth0Id already exists for user {platformId.Id}"); throw e; } else { var e = new Exception($"Failed to register discord"); await BITCORNLogger.LogError(_dbContext, e, $"Failed to register discord id for user {platformId.Id} {auth0Id}"); throw e; } } catch (Exception e) { await BITCORNLogger.LogError(_dbContext, e); throw new Exception($"Failed to add user's discord"); } throw new Exception($"HOW THE F**K DID YOU GET HERE"); case "twitter": try { var twitterUser = await TwitterApi.GetTwitterUser(_configuration, platformId.Id); var twitterDbUser = await _dbContext.TwitterQuery(platformId.Id).FirstOrDefaultAsync(); if (twitterDbUser != null && twitterDbUser.UserIdentity.Auth0Id == null) { auth0DbUser.UserIdentity.TwitterId = twitterDbUser.UserIdentity.TwitterId; //_dbContext.UserIdentity.Remove(auth0DbUser); CopyIdentity(auth0DbUser.UserIdentity, twitterDbUser.UserIdentity); twitterDbUser.UserIdentity.Auth0Id = auth0Id; twitterDbUser.UserIdentity.TwitterUsername = twitterUser.Name; twitterDbUser.UserIdentity.Auth0Nickname = auth0DbUser.UserIdentity.Auth0Nickname; await MigrateUser(auth0DbUser, twitterDbUser); await TxUtils.TryClaimTx(platformId, null, _dbContext); return(GetFullUser(twitterDbUser)); } if (twitterDbUser == null && auth0DbUser != null) { auth0DbUser.UserIdentity.TwitterId = platformId.Id; auth0DbUser.UserIdentity.TwitterUsername = twitterUser.Name; await _dbContext.SaveAsync(); await TxUtils.TryClaimTx(platformId, null, _dbContext); return(GetFullUser(auth0DbUser)); } if (twitterDbUser?.UserIdentity.Auth0Id != null) { var e = new Exception($"Auth0Id already exists for user {platformId.Id}"); await BITCORNLogger.LogError(_dbContext, e); throw e; } var ex = new Exception($"Failed to register twitter id for user {platformId.Id} {auth0Id}"); await BITCORNLogger.LogError(_dbContext, ex); throw ex; } catch (Exception e) { await BITCORNLogger.LogError(_dbContext, e); throw e; } throw new Exception($"HOW THE F**K DID YOU GET HERE"); case "reddit": try { var redditDbUser = await _dbContext.RedditQuery(platformId.Id).FirstOrDefaultAsync(); if (redditDbUser != null && redditDbUser.UserIdentity.Auth0Id == null) { auth0DbUser.UserIdentity.RedditId = redditDbUser.UserIdentity.RedditId; CopyIdentity(auth0DbUser.UserIdentity, redditDbUser.UserIdentity); //_dbContext.UserIdentity.Remove(auth0DbUser); redditDbUser.UserIdentity.Auth0Id = auth0Id; redditDbUser.UserIdentity.Auth0Nickname = auth0DbUser.UserIdentity.Auth0Nickname; await MigrateUser(auth0DbUser, redditDbUser); await TxUtils.TryClaimTx(platformId, null, _dbContext); return(GetFullUser(redditDbUser)); } else if (redditDbUser == null && auth0DbUser != null) { auth0DbUser.UserIdentity.RedditId = platformId.Id; await _dbContext.SaveAsync(); await TxUtils.TryClaimTx(platformId, null, _dbContext); return(GetFullUser(auth0DbUser)); } else if (redditDbUser?.UserIdentity.Auth0Id != null) { var e = new Exception($"Auth0Id already exists for user {platformId.Id}"); await BITCORNLogger.LogError(_dbContext, e); throw e; } else { var e = new Exception($"Failed to register reddit id for user {platformId.Id} {platformId.Id}"); await BITCORNLogger.LogError(_dbContext, e); throw e; } } catch (Exception e) { await BITCORNLogger.LogError(_dbContext, e); throw e; } throw new Exception($"HOW THE F**K DID YOU GET HERE"); default: throw new Exception("Invalid platform provided in the Id"); } } catch (Exception e) { throw new Exception($"registration failed for {registrationData}"); } throw new Exception("HOW THE F**K DID YOU GET HERE"); }
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); } }
public static async Task <CornTx[]> Deposit(BitcornContext dbContext, WalletDepositRequest request) { 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) { newDeposits++; var wallet = await dbContext.WalletByAddress(address); if (wallet != null) { var cornTx = new CornTx(); cornTx.Amount = amount; cornTx.BlockchainTxId = txid; cornTx.ReceiverId = wallet.UserId; cornTx.SenderId = null; cornTx.Timestamp = DateTime.Now; cornTx.TxType = TransactionType.receive.ToString(); cornTx.Platform = "wallet-server"; cornTx.TxGroupId = Guid.NewGuid().ToString(); 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 dbContext.Database.ExecuteSqlRawAsync(sql.ToString()); await dbContext.SaveAsync(); } } catch (Exception e) { await BITCORNLogger.LogError(dbContext, e); } return(receipts.ToArray()); }
/// <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)); } }
private static async Task <SubscriptionResponse> ProcessSubscription(BitcornContext dbContext, SubscriptionResponse output, SubRequest subRequest, Subscription subInfo, SubscriptionTier requestedTierInfo, User user) { decimal cost = 0; //if tier usdt cost has been initialized, the corn cost has to be calculated if (requestedTierInfo.CostUsdt != null && requestedTierInfo.CostUsdt > 0) { cost = await CalculateUsdtToCornCost(dbContext, requestedTierInfo); } // check if cost is initialized properly else if (requestedTierInfo.CostCorn != null && requestedTierInfo.CostCorn > 0) { cost = requestedTierInfo.CostCorn.Value; } else { throw new ArgumentException($"Invalid cost setting on subscription tier id:{requestedTierInfo.SubscriptionId}"); } //set the amount that will be removed from subscriber to the response object output.Cost = cost; //initialize array of existing subscriptions UserSubcriptionTierInfo[] existingSubscriptions = new UserSubcriptionTierInfo[0]; if (user != null) { //set data to existing subscriptions array existingSubscriptions = await GetUserSubscriptions(dbContext, user) .Where(t => t.SubscriptionTier.SubscriptionId == subInfo.SubscriptionId).ToArrayAsync(); } //initialize reference to existing subtierinfo UserSubcriptionTierInfo existingSubscription = null; //initialize current substate var subState = SubscriptionState.None; //if any subscriptions were found if (existingSubscriptions.Any()) { //set existing subtierinfo existingSubscription = existingSubscriptions[0]; //if sub has expired, set substate to expired if (subInfo.HasExpired(existingSubscription.UserSubscription)) { subState = SubscriptionState.Expired; } //if existing sub has not expired, but the tier is below, set subState to TierDown else if (existingSubscription.SubscriptionTier.Tier < requestedTierInfo.Tier) { subState = SubscriptionState.TierDown; } //else, the user is subscribed else { subState = SubscriptionState.Subscribed; } } //initialize reference to usersubscription & tx request UserSubscription sub = null; TxRequest txRequest = null; //if current user sub state is not subscribed & the client confirmed the cost to be equal to the cost amount, attempt to subscribe var costDiff = Math.Abs(subRequest.Amount - cost); if (subState != SubscriptionState.Subscribed && costDiff <= 100000)//subRequest.Amount == cost) { //initialize recipient of the transaction string[] to = new string[1]; //default to bitcornhub if no subscription owner has been set int recipientId = TxUtils.BitcornHubPK; //if subscription owner is set, overwrite bitcornhub if (subInfo.OwnerUserId != null && subInfo.OwnerUserId > 0) { recipientId = subInfo.OwnerUserId.Value; } to[0] = $"userid|{recipientId}"; //initialize tx request txRequest = new TxRequest(user, cost, subRequest.Platform, "$sub", to); //prepare transaction for saving var processInfo = await TxUtils.ProcessRequest(txRequest, dbContext); var transactions = processInfo.Transactions; if (transactions != null && transactions.Length > 0) { StringBuilder sql = new StringBuilder(); //check if transaction can be executed if (processInfo.WriteTransactionOutput(sql)) { //transaction is ready to be saved switch (subState) { case SubscriptionState.None: //user was previously not subscribed, create instance of usersubscription and point it to the user sub = new UserSubscription(); sub.SubscriptionId = subInfo.SubscriptionId; sub.SubscriptionTierId = requestedTierInfo.SubscriptionTierId; sub.UserId = user.UserId; sub.FirstSubDate = DateTime.Now; sub.SubCount = 1; dbContext.UserSubscription.Add(sub); break; case SubscriptionState.TierDown: case SubscriptionState.Expired: //previous subscription was found, update subscription tier existingSubscription.UserSubscription.SubscriptionTierId = requestedTierInfo.SubscriptionTierId; existingSubscription.UserSubscription.SubCount += 1; sub = existingSubscription.UserSubscription; break; default: break; } //set subscription date to now sub.LastSubDate = DateTime.Now; await DbOperations.ExecuteSqlRawAsync(dbContext, sql.ToString()); await dbContext.SaveAsync(IsolationLevel.RepeatableRead); //create subtx that will link user, corntx and usersubscription together var subTx = new SubTx(); subTx.UserId = user.UserId; subTx.SubTxId = transactions[0].TxId.Value; subTx.UserSubscriptionId = sub.UserSubscriptionId; dbContext.SubTx.Add(subTx); //if user was not subscribed before, attempt to share the payment with a referrer if (!await TrySharePaymentWithReferrer(dbContext, output, subRequest, subInfo, requestedTierInfo, user, recipientId, cost, subState, subTx)) { await dbContext.SaveAsync(); } subState = SubscriptionState.Subscribed; } //append receipt object with what client requested await TxUtils.AppendTxs(transactions, dbContext, subRequest.Columns); var tx = transactions[0]; output.TxId = tx.TxId; output.User = tx.From; } } //couldn't process transaction if (txRequest == null) { //fill out response object await PopuplateUserResponse(dbContext, subRequest, output, user); if (existingSubscription != null) { sub = existingSubscription.UserSubscription; } } if (subState == SubscriptionState.Subscribed && sub != null) { var end = output.SubscriptionEndTime = sub.LastSubDate.Value.AddDays(subInfo.Duration); //calculate days left output.DaysLeft = Math.Ceiling((end.Value - DateTime.Now).TotalDays); //setup sub info output.UserSubscriptionInfo = await GetUserSubscriptions(dbContext, user) .Where(t => t.SubscriptionTier.SubscriptionId == subInfo.SubscriptionId).FirstOrDefaultAsync(); } return(output); }
public async Task TestTipCornToUnregistered() { var dbContext = TestUtils.CreateDatabase(); try { var startFromUser = dbContext.TwitchQuery(_configuration["Config:TestFromUserId"]).FirstOrDefault().UserWallet.Balance; var txController = new TxController(dbContext); var request = new TipRequest(); request.Columns = new string[] { }; string toTwitchId = "123123"; request.To = "twitch|" + toTwitchId; request.From = "twitch|" + _configuration["Config:TestFromUserId"]; request.Platform = "twitch"; request.Amount = 100; var toUser = await dbContext.TwitchAsync(toTwitchId); dbContext.RemoveRange(dbContext.UnclaimedTx); TestUtils.RemoveUserIfExists(dbContext, toUser); var response = await txController.Tipcorn(request); var receipt = response.Value[0]; Assert.Null(receipt.Tx); Assert.NotNull(receipt.From); Assert.Null(receipt.To); using (var dbContext2 = TestUtils.CreateDatabase()) { var endFromUser = dbContext2.TwitchQuery(_configuration["Config:TestFromUserId"]).FirstOrDefault().UserWallet.Balance; Assert.Equal(startFromUser - request.Amount, endFromUser); dbContext2.AddUser(new UserIdentity() { Auth0Id = "temp", Auth0Nickname = "temp", TwitchId = toTwitchId }, new UserWallet()); var to = await dbContext2.TwitchAsync(toTwitchId); await TxUtils.TryClaimTx(new PlatformId() { Platform = "twitch", Id = toTwitchId }, to, dbContext2); } using (var dbContext2 = TestUtils.CreateDatabase()) { var to = await dbContext2.TwitchAsync(toTwitchId); Assert.Equal(request.Amount, to.UserWallet.Balance); var claim2 = await TxUtils.TryClaimTx(new PlatformId() { Platform = "twitch", Id = toTwitchId }, to, dbContext2);; Assert.Equal(0, claim2); } } finally { dbContext.Dispose(); } }
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; } }
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; } }