diff --git a/src/models/StratumV1Client.ts b/src/models/StratumV1Client.ts index bd2efc95..83818bff 100644 --- a/src/models/StratumV1Client.ts +++ b/src/models/StratumV1Client.ts @@ -541,10 +541,14 @@ export class StratumV1Client { } if (submissionDifficulty > this.entity.bestDifficulty) { + + + await this.clientService.updateBestDifficulty(this.extraNonceAndSessionId, submissionDifficulty); this.entity.bestDifficulty = submissionDifficulty; if (submissionDifficulty > (await this.addressSettingsService.getSettings(this.clientAuthorization.address, true)).bestDifficulty) { await this.addressSettingsService.updateBestDifficulty(this.clientAuthorization.address, submissionDifficulty, this.entity.userAgent); + await this.notificationService.notifySubscribersBestDiff(this.clientAuthorization.address, submissionDifficulty); } } diff --git a/src/services/discord.service.ts b/src/services/discord.service.ts index 999076a9..d8a41f73 100644 --- a/src/services/discord.service.ts +++ b/src/services/discord.service.ts @@ -2,6 +2,7 @@ import { Injectable, OnModuleInit } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { Block } from 'bitcoinjs-lib'; import { Client, Collection, Events, GatewayIntentBits, REST, Routes, SlashCommandBuilder, TextChannel } from 'discord.js'; +import { NumberSuffix } from '../utils/NumberSuffix'; interface IDiscordCommand { data: SlashCommandBuilder; @@ -28,6 +29,8 @@ export class DiscordService implements OnModuleInit { private clientId: string; private guildId: string; private channelId: string; + private diffNotifications: boolean; + private numberSuffix: NumberSuffix; private bot: Client; private commandCollection: Collection; @@ -56,6 +59,9 @@ export class DiscordService implements OnModuleInit { }); this.bot = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages] }); this.bot.login(this.token); + + this.numberSuffix = new NumberSuffix(); + this.diffNotifications = (this.configService.get('DISCORD_DIFF_NOTIFICATIONS').toLowerCase() == 'true') || false; } } @@ -135,4 +141,18 @@ export class DiscordService implements OnModuleInit { channel.send(`Block Found! Result: ${message}, Height: ${height}`); } } + + public async notifySubscribersBestDiff(submissionDifficulty: number) { + + if (process.env.NODE_APP_INSTANCE == null || process.env.NODE_APP_INSTANCE == '0') { + if (this.bot == null || this.diffNotifications == false) { + return; + } + + const guild = await this.bot.guilds.fetch(this.guildId); + const channel = await guild.channels.fetch(this.channelId) as TextChannel; + channel.send(`New Best Diff! Result: ${this.numberSuffix.to(submissionDifficulty)}`); + } + + } } \ No newline at end of file diff --git a/src/services/notification.service.ts b/src/services/notification.service.ts index f643426b..a48eeafe 100644 --- a/src/services/notification.service.ts +++ b/src/services/notification.service.ts @@ -21,4 +21,9 @@ export class NotificationService implements OnModuleInit { await this.discordService.notifySubscribersBlockFound(height, block, message); await this.telegramService.notifySubscribersBlockFound(address, height, block, message); } + + public async notifySubscribersBestDiff(address: string, submissionDifficulty: number) { + await this.discordService.notifySubscribersBestDiff(submissionDifficulty); + await this.telegramService.notifySubscribersBestDiff(address, submissionDifficulty); + } } \ No newline at end of file diff --git a/src/services/telegram.service.ts b/src/services/telegram.service.ts index ba3e5d00..19e1281a 100644 --- a/src/services/telegram.service.ts +++ b/src/services/telegram.service.ts @@ -3,6 +3,7 @@ import { ConfigService } from '@nestjs/config'; import { validate } from 'bitcoin-address-validation'; import { Block } from 'bitcoinjs-lib'; import * as TelegramBot from 'node-telegram-bot-api'; +import { NumberSuffix } from '../utils/NumberSuffix'; import { TelegramSubscriptionsService } from '../ORM/telegram-subscriptions/telegram-subscriptions.service'; @@ -11,19 +12,25 @@ import { TelegramSubscriptionsService } from '../ORM/telegram-subscriptions/tele export class TelegramService implements OnModuleInit { private bot: TelegramBot; + private diffNotifications: boolean; + private numberSuffix: NumberSuffix; constructor( private readonly configService: ConfigService, private readonly telegramSubscriptionsService: TelegramSubscriptionsService ) { const token: string | null = this.configService.get('TELEGRAM_BOT_TOKEN'); + if (token == null || token.length < 1) { return; } this.bot = new TelegramBot(token, { polling: true }); + console.log('Telegram bot init'); + this.numberSuffix = new NumberSuffix(); + this.diffNotifications = (this.configService.get('TELEGRAM_DIFF_NOTIFICATIONS').toLowerCase() == 'true') || false; } async onModuleInit(): Promise { @@ -38,8 +45,15 @@ export class TelegramService implements OnModuleInit { this.bot.sendMessage(msg.chat.id, "Invalid address."); return; } - await this.telegramSubscriptionsService.saveSubscription(msg.chat.id, address); - this.bot.sendMessage(msg.chat.id, "Subscribed!"); + + const subscribers = await this.telegramSubscriptionsService.getSubscriptions(address); + if (subscribers.length == 0) { + await this.telegramSubscriptionsService.saveSubscription(msg.chat.id, address); + this.bot.sendMessage(msg.chat.id, "Subscribed!"); + } + else { + this.bot.sendMessage(msg.chat.id, "Already Subscribed!"); + } }); this.bot.onText(/\/start/, (msg) => { @@ -57,8 +71,25 @@ export class TelegramService implements OnModuleInit { } const subscribers = await this.telegramSubscriptionsService.getSubscriptions(address); - subscribers.forEach(subscriber => { - this.bot.sendMessage(subscriber.telegramChatId, `Block Found! Result: ${message}, Height: ${height}`); + + const subscriberMessages = subscribers.map(subscriber =>{ + return this.bot.sendMessage(subscriber.telegramChatId, `Block Found! Result: ${message}, Height: ${height}`); + }); + + Promise.all(subscriberMessages).then(); + } + + public async notifySubscribersBestDiff(address: string, submissionDifficulty: number) { + if (this.bot == null || this.diffNotifications == false) { + return; + } + + const subscribers = await this.telegramSubscriptionsService.getSubscriptions(address); + const subscriberMessages = subscribers.map(subscriber => { + return this.bot.sendMessage(subscriber.telegramChatId, `New Best Diff! Result: ${this.numberSuffix.to(submissionDifficulty)}`); }); + + Promise.all(subscriberMessages).then(); } + } \ No newline at end of file diff --git a/src/utils/NumberSuffix.ts b/src/utils/NumberSuffix.ts new file mode 100644 index 00000000..78fd4405 --- /dev/null +++ b/src/utils/NumberSuffix.ts @@ -0,0 +1,21 @@ + +export class NumberSuffix { + + to(value: number): string { + + const suffixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y', 'R', 'Q']; + + if (value == null || value < 0) { + return '0'; + } + + let power = Math.floor(Math.log10(value) / 3); + if (power < 0) { + power = 0; + } + const scaledValue = value / Math.pow(1000, power); + const suffix = suffixes[power]; + + return scaledValue.toFixed(2) + suffix; + } +} \ No newline at end of file