Esempio n. 1
0
        public Medium.Response CreatePost(Repository repo, Cycle prevCycle, Cycle currentCycle)
        {
            StringBuilder post = new StringBuilder();

            post.AppendLine($"<h1>Tezos Blockchain cycle {prevCycle.index} stats</h1>");

            post.AppendLine("<p><i>This post was generated fully automatically by the <a href='https://tzsnt.fr/'>TezosNotifierBot</a>.</i></p>");
            post.AppendLine("<p><img src='https://tzsnt.fr/img/tezos-notifier-horizontal.png' /></p>");
            post.AppendLine("<h1>General cycle stats</h1>");
            post.AppendLine($"<p>Cycle {prevCycle.index} is completed in {prevCycle.Length.Days} days, {prevCycle.Length.Hours} hours, {prevCycle.Length.Minutes} minutes!</p>");
            post.AppendLine($"<p>Next {currentCycle.index} cycle will end on {currentCycle.endTime.ToString("MMMMM d a\\t HH:mm", CultureInfo.GetCultureInfo("en"))} UTC.</p>");
            post.AppendLine("<h1>Transaction stats</h1>");
            post.AppendLine($"<p>In the {prevCycle.index} cycle were made {_tzKtClient.GetTransactionsCount(prevCycle.firstLevel, prevCycle.lastLevel).ToString("###,###,###,###")} transactions.</p>");

            Tezos.MarketData md = FillRates(post, prevCycle, currentCycle);

            post.AppendLine("<h1>Whale transactions</h1>");

            var whaleTransactions = _tzKtClient.GetTransactions($"level.ge={prevCycle.firstLevel}&level.le={prevCycle.lastLevel}&status=applied&amount.ge=500000000000");

            if (whaleTransactions.Count == 0)
            {
                post.AppendLine("<p>Not a single whale transaction was made.</p>");
            }
            else if (whaleTransactions.Count == 0)
            {
                post.AppendLine("<p>There was 1 whale transaction with amount &gt; 500 000 XTZ:</p>");
            }
            else
            {
                post.AppendLine($"<p>There were {whaleTransactions.Count} whale transactions with amount &gt; 500 000 XTZ:</p>");
            }
            post.AppendLine("<ul>");
            foreach (var wt in whaleTransactions)
            {
                var sender = repo.GetUserTezosAddress(0, wt.Sender.address);
                var target = repo.GetUserTezosAddress(0, wt.Target.address);
                post.AppendLine($"<li><a target='_blank' href='https://tzkt.io/{wt.Hash}?utm_source=tezosnotifierbot'>transaction</a> of {(wt.Amount / 1000000M).TezToString()} ({(wt.Amount / 1000000M).TezToUsd(md)} USD) from <a href='https://tzkt.io/{wt.Sender.address}?utm_source=tezosnotifierbot'>{sender.DisplayName()}</a> to <a href='https://tzkt.io/{wt.Target.address}?utm_source=tezosnotifierbot'>{target.DisplayName()}</a></li>");
            }
            post.AppendLine("</ul>");
            post.AppendLine($"<p>So more then {whaleTransactions.Sum(o => o.Amount / 1000000M).TezToString()} was transferred by whales!</p>");
            FillGovernance(post, prevCycle, currentCycle);
            post.AppendLine("<p><hr /></p>");
            FillLinks(post);

            var result = Publish($"Tezos Blockchain cycle {prevCycle.index} stats", post.ToString());

            return(result);
        }
Esempio n. 2
0
        async Task Run(CancellationToken stoppingToken)
        {
            using var scope = _provider.CreateScope();
            var provider = scope.ServiceProvider;

            using var db = scope.ServiceProvider.GetRequiredService <TezosDataContext>();
            var bot = scope.ServiceProvider.GetRequiredService <TezosBot>();

            var block = db.LastBlock.Single();

            if (block.Level > lastBlock)
            {
                var tzKt      = provider.GetService <ITzKtClient>();
                var tzKtBlock = tzKt.GetBlock(block.Level);
                var repo      = provider.GetRequiredService <Repository>();
                var wtlist    = repo.GetWhaleTransactions();
                var allUsers  = repo.GetUsers();
                if (DateTime.Now.Subtract(mdReceived).TotalMinutes > 5)
                {
                    try
                    {
                        md = _provider.GetRequiredService <TezosNotifyBot.CryptoCompare.IMarketDataProvider>().GetMarketData();
                    }
                    catch
                    {
                    }

                    mdReceived = DateTime.Now;
                }

                foreach (var address in wtlist.GroupBy(o => o.FromAddress).Where(o => o.Sum(o1 => o1.Amount) >= 250000))
                {
                    var minLevel = address.Min(a => a.Level);
                    var maxLevel = address.Max(a => a.Level);
                    if (maxLevel < block.Level)
                    {
                        continue;
                    }
                    var timeStamp  = address.Min(a => a.Timestamp);
                    var from_start = tzKt.GetBalance(address.Key, minLevel - 1);
                    var from_end   = tzKt.GetBalance(address.Key, block.Level);
                    var amount     = (from_start - from_end);
                    foreach (var u in allUsers.Where(o =>
                                                     !o.Inactive && o.WhaleThreshold > 0 && o.WhaleThreshold <= amount && o.SmartWhaleAlerts))
                    {
                        var ua_from      = repo.GetUserTezosAddress(u.Id, address.Key);
                        var listFiltered = address.Where(o => !o.Notifications.Any(n => n.UserId == u.Id) && o.Amount < u.WhaleThreshold);

                        if (listFiltered.Count() <= 1 || listFiltered.Sum(o => o.Amount) < u.WhaleThreshold)
                        {
                            continue;
                        }

                        string result = resMgr.Get(Res.WhaleOutflow,
                                                   new ContextObject
                        {
                            u      = u,
                            Amount = from_start - from_end,
                            md     = md,
                            ua     = ua_from,
                            Period = (int)Math.Ceiling(tzKtBlock.Timestamp.Subtract(timeStamp).TotalDays)
                        });
                        string tags = "";
                        foreach (var op in listFiltered.OrderByDescending(o => o.Amount).Take(10).OrderBy(o => o.Level))
                        {
                            var ua_to = repo.GetUserTezosAddress(u.Id, op.ToAddress);
                            result += "\n" + resMgr.Get(Res.WhaleOutflowItem,
                                                        new ContextObject
                            {
                                u      = u,
                                Amount = op.Amount,
                                md     = md,
                                ua     = ua_to,
                                Block  = op.Level,
                                OpHash = op.OpHash
                            });
                            repo.AddWhaleTransactionNotify(op.Id, u.Id);
                            tags += ua_to.HashTag();
                        }
                        if (u.Type == 0)
                        {
                            result += "\n" + resMgr.Get(Res.TurnOff, u) + ": /outflow_off";
                        }
                        if (!u.HideHashTags)
                        {
                            result += "\n\n#whale" + ua_from.HashTag() + tags;
                        }

                        bot.SendTextMessage(u.Id, result, ReplyKeyboards.MainMenu(resMgr, u));
                    }
                }

                var minDate = tzKtBlock.Timestamp.AddDays(-_config.WhaleSeriesLength);
                repo.CleanWhaleTransactions(minDate);

                lastBlock = block.Level;
            }

            await Task.Delay(1000, stoppingToken);
        }