From b618cd5e11e7f6bf98370b3c20c9fa80c7903c33 Mon Sep 17 00:00:00 2001 From: artemkolodko Date: Tue, 3 Oct 2023 14:05:46 +0100 Subject: [PATCH 1/4] Add ES payment stats --- src/bot.ts | 12 +++++++++++- src/database/chat.service.ts | 26 ++++++++++++++++++++++++-- src/es/index.ts | 3 +++ src/modules/payment/index.ts | 11 ++++++++--- src/modules/types.ts | 6 ++++++ 5 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/bot.ts b/src/bot.ts index 099a53e6..65fe3ceb 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -112,6 +112,11 @@ bot.use(async (ctx: BotContext, next: NextFunction): Promise => { firstResponseTime: 0n, actualResponseTime: 0n, sessionState: RequestState.Initial + }, + payments: { + freeCreditsAmount: 0n, + oneCreditsAmount: 0n, + fiatCreditsAmount: 0n, } } const transaction = Sentry.startTransaction({ name: 'bot-command' }) @@ -139,6 +144,7 @@ bot.use(async (ctx: BotContext, next: NextFunction): Promise => { } await next() transaction.finish() + if (ctx.transient.analytics.module) { const userId = Number(ctx.message?.from?.id ?? '0') const username = ctx.message?.from?.username ?? '' @@ -151,6 +157,7 @@ bot.use(async (ctx: BotContext, next: NextFunction): Promise => { const totalProcessingTime = (now() - startTime).toString() const firstResponseTime = (ctx.transient.analytics.firstResponseTime - startTime).toString() const actualResponseTime = (ctx.transient.analytics.actualResponseTime - startTime).toString() + const { freeCreditsAmount, oneCreditsAmount, fiatCreditsAmount } = ctx.transient.payments ES.add({ command, text: ctx.message?.text ?? '', @@ -161,7 +168,10 @@ bot.use(async (ctx: BotContext, next: NextFunction): Promise => { actualResponseTime, refunded: ctx.transient.refunded, sessionState: ctx.transient.analytics.sessionState, - totalProcessingTime + totalProcessingTime, + freeCreditsAmount: freeCreditsAmount.toString(), + oneCreditsAmount: oneCreditsAmount.toString(), + fiatCreditsAmount: fiatCreditsAmount.toString(), }).catch((ex: any) => { logger.error({ errorMsg: ex.message }, 'Failed to add data to ES') }) diff --git a/src/database/chat.service.ts b/src/database/chat.service.ts index 5170bb67..06a4868e 100644 --- a/src/database/chat.service.ts +++ b/src/database/chat.service.ts @@ -21,6 +21,12 @@ interface UserCredits { totalCreditsAmount: bn } +interface CreditsPayment { + freeCredits: string + oneCredits: string + fiatCredits: string +} + export class ChatService { creditsAssignedCache = new LRUCache({ max: 1000, ttl: 24 * 60 * 60 * 1000 }) @@ -109,7 +115,13 @@ export class ChatService { } } - public async withdrawCredits (accountId: number, payAmount: bn): Promise { + public async withdrawCredits ( + accountId: number, + payAmount: bn + ): Promise<{ + userPayment: CreditsPayment + userCredits: UserCredits + }> { const { totalCreditsAmount, creditAmount, @@ -139,7 +151,17 @@ export class ChatService { oneCreditAmount: oneCreditsNext.toFixed(), fiatCreditAmount: fiatCreditNext.toFixed() }) - return await this.getUserCredits(accountId) + + const userCredits = await this.getUserCredits(accountId) + + return { + userPayment: { + freeCredits: creditsPayAmount.toFixed(), + oneCredits: oneCreditsPay.toFixed(), + fiatCredits: fiatCreditPay.toFixed() + }, + userCredits + } } public async initChat ({ tgUserId, accountId, tgUsername = '' }: { tgUserId: number, accountId: number, tgUsername?: string }): Promise { diff --git a/src/es/index.ts b/src/es/index.ts index 90ebd1bf..fa1f3209 100644 --- a/src/es/index.ts +++ b/src/es/index.ts @@ -23,6 +23,9 @@ export interface BotLogData { actualResponseTime: string // converted from bigint refunded: boolean sessionState: string + freeCreditsAmount: string // converted from bigint + oneCreditsAmount: string // converted from bigint + fiatCreditsAmount: string // converted from bigint } const Index = config.es.index ?? 'bot-logs' diff --git a/src/modules/payment/index.ts b/src/modules/payment/index.ts index 41027d9a..c3b42b69 100644 --- a/src/modules/payment/index.ts +++ b/src/modules/payment/index.ts @@ -397,13 +397,18 @@ export class BotPayments { ) if (totalBalanceDelta.gte(0)) { - const balanceAfter = await chatService.withdrawCredits(accountId, totalPayAmount) + const { userPayment, userCredits: userCreditsAfter} = await chatService.withdrawCredits(accountId, totalPayAmount) this.logger.info(`[${from.id} @${ from.username - }] successfully paid from credits, credits balance after: ${balanceAfter.totalCreditsAmount}`) + }] successfully paid from credits, credits balance after: ${userCreditsAfter.totalCreditsAmount}`) - freeCreditsFeeCounter.inc(this.convertBigNumber(totalPayAmount)) await this.writePaymentLog(ctx, totalPayAmount) + + ctx.transient.payments.freeCreditsAmount = BigInt(userPayment.freeCredits) + ctx.transient.payments.fiatCreditsAmount = BigInt(userPayment.fiatCredits) + ctx.transient.payments.oneCreditsAmount = BigInt(userPayment.oneCredits) + + freeCreditsFeeCounter.inc(this.convertBigNumber(totalPayAmount)) return true } else { const oneBalance = await this.getAddressBalance(userAccount.address) diff --git a/src/modules/types.ts b/src/modules/types.ts index 2ee8a626..948da602 100644 --- a/src/modules/types.ts +++ b/src/modules/types.ts @@ -108,7 +108,12 @@ export interface Analytics { actualResponseTime: bigint sessionState: RequestState module: string +} +export interface PaymentAnalytics { + freeCreditsAmount: bigint + oneCreditsAmount: bigint + fiatCreditsAmount: bigint } export interface BotSessionData { @@ -123,6 +128,7 @@ export interface TransientStateContext { transient: { analytics: Analytics refunded: boolean + payments: PaymentAnalytics } } From f5915e3d1de3f5c230e09347ea0724e869a5f22e Mon Sep 17 00:00:00 2001 From: artemkolodko Date: Tue, 3 Oct 2023 14:06:53 +0100 Subject: [PATCH 2/4] Lint fixes --- src/bot.ts | 4 ++-- src/database/chat.service.ts | 6 +++--- src/modules/payment/index.ts | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/bot.ts b/src/bot.ts index 65fe3ceb..3e19be7d 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -116,7 +116,7 @@ bot.use(async (ctx: BotContext, next: NextFunction): Promise => { payments: { freeCreditsAmount: 0n, oneCreditsAmount: 0n, - fiatCreditsAmount: 0n, + fiatCreditsAmount: 0n } } const transaction = Sentry.startTransaction({ name: 'bot-command' }) @@ -171,7 +171,7 @@ bot.use(async (ctx: BotContext, next: NextFunction): Promise => { totalProcessingTime, freeCreditsAmount: freeCreditsAmount.toString(), oneCreditsAmount: oneCreditsAmount.toString(), - fiatCreditsAmount: fiatCreditsAmount.toString(), + fiatCreditsAmount: fiatCreditsAmount.toString() }).catch((ex: any) => { logger.error({ errorMsg: ex.message }, 'Failed to add data to ES') }) diff --git a/src/database/chat.service.ts b/src/database/chat.service.ts index 06a4868e..5634902e 100644 --- a/src/database/chat.service.ts +++ b/src/database/chat.service.ts @@ -119,9 +119,9 @@ export class ChatService { accountId: number, payAmount: bn ): Promise<{ - userPayment: CreditsPayment - userCredits: UserCredits - }> { + userPayment: CreditsPayment + userCredits: UserCredits + }> { const { totalCreditsAmount, creditAmount, diff --git a/src/modules/payment/index.ts b/src/modules/payment/index.ts index c3b42b69..24d3ae43 100644 --- a/src/modules/payment/index.ts +++ b/src/modules/payment/index.ts @@ -397,7 +397,7 @@ export class BotPayments { ) if (totalBalanceDelta.gte(0)) { - const { userPayment, userCredits: userCreditsAfter} = await chatService.withdrawCredits(accountId, totalPayAmount) + const { userPayment, userCredits: userCreditsAfter } = await chatService.withdrawCredits(accountId, totalPayAmount) this.logger.info(`[${from.id} @${ from.username }] successfully paid from credits, credits balance after: ${userCreditsAfter.totalCreditsAmount}`) From 137b07ddfdd1450a9e2f4c2996ed188f8e2110b1 Mon Sep 17 00:00:00 2001 From: artemkolodko Date: Tue, 3 Oct 2023 17:17:56 +0100 Subject: [PATCH 3/4] Add totalCredits field --- src/bot.ts | 16 +++++++++------- src/database/chat.service.ts | 2 ++ src/es/index.ts | 7 ++++--- src/modules/payment/index.ts | 7 ++++--- src/modules/types.ts | 7 ++++--- 5 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/bot.ts b/src/bot.ts index 3e19be7d..68eed92e 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -114,9 +114,10 @@ bot.use(async (ctx: BotContext, next: NextFunction): Promise => { sessionState: RequestState.Initial }, payments: { - freeCreditsAmount: 0n, - oneCreditsAmount: 0n, - fiatCreditsAmount: 0n + totalCredits: 0n, + freeCredits: 0n, + oneCredits: 0n, + fiatCredits: 0n } } const transaction = Sentry.startTransaction({ name: 'bot-command' }) @@ -157,7 +158,7 @@ bot.use(async (ctx: BotContext, next: NextFunction): Promise => { const totalProcessingTime = (now() - startTime).toString() const firstResponseTime = (ctx.transient.analytics.firstResponseTime - startTime).toString() const actualResponseTime = (ctx.transient.analytics.actualResponseTime - startTime).toString() - const { freeCreditsAmount, oneCreditsAmount, fiatCreditsAmount } = ctx.transient.payments + const { totalCredits, freeCredits, oneCredits, fiatCredits } = ctx.transient.payments ES.add({ command, text: ctx.message?.text ?? '', @@ -169,9 +170,10 @@ bot.use(async (ctx: BotContext, next: NextFunction): Promise => { refunded: ctx.transient.refunded, sessionState: ctx.transient.analytics.sessionState, totalProcessingTime, - freeCreditsAmount: freeCreditsAmount.toString(), - oneCreditsAmount: oneCreditsAmount.toString(), - fiatCreditsAmount: fiatCreditsAmount.toString() + totalCredits: totalCredits.toString(), + freeCredits: freeCredits.toString(), + oneCredits: oneCredits.toString(), + fiatCredits: fiatCredits.toString() }).catch((ex: any) => { logger.error({ errorMsg: ex.message }, 'Failed to add data to ES') }) diff --git a/src/database/chat.service.ts b/src/database/chat.service.ts index 5634902e..dccc1543 100644 --- a/src/database/chat.service.ts +++ b/src/database/chat.service.ts @@ -22,6 +22,7 @@ interface UserCredits { } interface CreditsPayment { + totalCredits: string freeCredits: string oneCredits: string fiatCredits: string @@ -156,6 +157,7 @@ export class ChatService { return { userPayment: { + totalCredits: totalCreditsAmount.toFixed(), freeCredits: creditsPayAmount.toFixed(), oneCredits: oneCreditsPay.toFixed(), fiatCredits: fiatCreditPay.toFixed() diff --git a/src/es/index.ts b/src/es/index.ts index fa1f3209..eac11138 100644 --- a/src/es/index.ts +++ b/src/es/index.ts @@ -23,9 +23,10 @@ export interface BotLogData { actualResponseTime: string // converted from bigint refunded: boolean sessionState: string - freeCreditsAmount: string // converted from bigint - oneCreditsAmount: string // converted from bigint - fiatCreditsAmount: string // converted from bigint + totalCredits: string // converted from bigint + freeCredits: string // converted from bigint + oneCredits: string // converted from bigint + fiatCredits: string // converted from bigint } const Index = config.es.index ?? 'bot-logs' diff --git a/src/modules/payment/index.ts b/src/modules/payment/index.ts index 24d3ae43..05d3a5b4 100644 --- a/src/modules/payment/index.ts +++ b/src/modules/payment/index.ts @@ -404,9 +404,10 @@ export class BotPayments { await this.writePaymentLog(ctx, totalPayAmount) - ctx.transient.payments.freeCreditsAmount = BigInt(userPayment.freeCredits) - ctx.transient.payments.fiatCreditsAmount = BigInt(userPayment.fiatCredits) - ctx.transient.payments.oneCreditsAmount = BigInt(userPayment.oneCredits) + ctx.transient.payments.totalCredits = BigInt(userPayment.totalCredits) + ctx.transient.payments.freeCredits = BigInt(userPayment.freeCredits) + ctx.transient.payments.oneCredits = BigInt(userPayment.oneCredits) + ctx.transient.payments.fiatCredits = BigInt(userPayment.fiatCredits) freeCreditsFeeCounter.inc(this.convertBigNumber(totalPayAmount)) return true diff --git a/src/modules/types.ts b/src/modules/types.ts index 948da602..7f85f93f 100644 --- a/src/modules/types.ts +++ b/src/modules/types.ts @@ -111,9 +111,10 @@ export interface Analytics { } export interface PaymentAnalytics { - freeCreditsAmount: bigint - oneCreditsAmount: bigint - fiatCreditsAmount: bigint + totalCredits: bigint + freeCredits: bigint + oneCredits: bigint + fiatCredits: bigint } export interface BotSessionData { From 2c954cc7b6afb18bd3ea1ef73cfe4c6d0996e326 Mon Sep 17 00:00:00 2001 From: artemkolodko Date: Wed, 4 Oct 2023 18:09:42 +0100 Subject: [PATCH 4/4] Refactor ES payments stats: use USD float number instead of ONE credits wei --- src/bot.ts | 22 ++++++++++++---------- src/database/chat.service.ts | 2 +- src/es/index.ts | 8 ++++---- src/modules/payment/index.ts | 14 ++++++++++---- src/modules/types.ts | 10 +++++----- 5 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/bot.ts b/src/bot.ts index 68eed92e..1676391a 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -113,11 +113,11 @@ bot.use(async (ctx: BotContext, next: NextFunction): Promise => { actualResponseTime: 0n, sessionState: RequestState.Initial }, - payments: { - totalCredits: 0n, - freeCredits: 0n, - oneCredits: 0n, - fiatCredits: 0n + payment: { + paymentTotal: 0, + paymentFreeCredits: 0, + paymentOneCredits: 0, + paymentFiatCredits: 0 } } const transaction = Sentry.startTransaction({ name: 'bot-command' }) @@ -158,7 +158,9 @@ bot.use(async (ctx: BotContext, next: NextFunction): Promise => { const totalProcessingTime = (now() - startTime).toString() const firstResponseTime = (ctx.transient.analytics.firstResponseTime - startTime).toString() const actualResponseTime = (ctx.transient.analytics.actualResponseTime - startTime).toString() - const { totalCredits, freeCredits, oneCredits, fiatCredits } = ctx.transient.payments + + const { paymentTotal, paymentFreeCredits, paymentOneCredits, paymentFiatCredits } = ctx.transient.payment + ES.add({ command, text: ctx.message?.text ?? '', @@ -170,10 +172,10 @@ bot.use(async (ctx: BotContext, next: NextFunction): Promise => { refunded: ctx.transient.refunded, sessionState: ctx.transient.analytics.sessionState, totalProcessingTime, - totalCredits: totalCredits.toString(), - freeCredits: freeCredits.toString(), - oneCredits: oneCredits.toString(), - fiatCredits: fiatCredits.toString() + paymentTotal, + paymentFreeCredits, + paymentOneCredits, + paymentFiatCredits }).catch((ex: any) => { logger.error({ errorMsg: ex.message }, 'Failed to add data to ES') }) diff --git a/src/database/chat.service.ts b/src/database/chat.service.ts index dccc1543..355d8381 100644 --- a/src/database/chat.service.ts +++ b/src/database/chat.service.ts @@ -157,7 +157,7 @@ export class ChatService { return { userPayment: { - totalCredits: totalCreditsAmount.toFixed(), + totalCredits: payAmount.toFixed(), freeCredits: creditsPayAmount.toFixed(), oneCredits: oneCreditsPay.toFixed(), fiatCredits: fiatCreditPay.toFixed() diff --git a/src/es/index.ts b/src/es/index.ts index eac11138..209611ff 100644 --- a/src/es/index.ts +++ b/src/es/index.ts @@ -23,10 +23,10 @@ export interface BotLogData { actualResponseTime: string // converted from bigint refunded: boolean sessionState: string - totalCredits: string // converted from bigint - freeCredits: string // converted from bigint - oneCredits: string // converted from bigint - fiatCredits: string // converted from bigint + paymentTotal: number // float + paymentFreeCredits: number // float + paymentOneCredits: number // float + paymentFiatCredits: number // float } const Index = config.es.index ?? 'bot-logs' diff --git a/src/modules/payment/index.ts b/src/modules/payment/index.ts index 05d3a5b4..61f1cf51 100644 --- a/src/modules/payment/index.ts +++ b/src/modules/payment/index.ts @@ -183,6 +183,12 @@ export class BotPayments { return +value } + public async fromONEToUSD (amountWei: string, fractionalDigits = 4): Promise { + const currentRate = await this.getOneRate() + const amountONE = this.web3.utils.fromWei(amountWei, 'ether') + return +(currentRate * +amountONE).toFixed(fractionalDigits) + } + public async getAddressBalance (address: string): Promise { const balance = await this.web3.eth.getBalance(address) return bn(balance.toString()) @@ -404,10 +410,10 @@ export class BotPayments { await this.writePaymentLog(ctx, totalPayAmount) - ctx.transient.payments.totalCredits = BigInt(userPayment.totalCredits) - ctx.transient.payments.freeCredits = BigInt(userPayment.freeCredits) - ctx.transient.payments.oneCredits = BigInt(userPayment.oneCredits) - ctx.transient.payments.fiatCredits = BigInt(userPayment.fiatCredits) + ctx.transient.payment.paymentTotal = await this.fromONEToUSD(userPayment.totalCredits) + ctx.transient.payment.paymentFreeCredits = await this.fromONEToUSD(userPayment.freeCredits) + ctx.transient.payment.paymentOneCredits = await this.fromONEToUSD(userPayment.oneCredits) + ctx.transient.payment.paymentFiatCredits = await this.fromONEToUSD(userPayment.fiatCredits) freeCreditsFeeCounter.inc(this.convertBigNumber(totalPayAmount)) return true diff --git a/src/modules/types.ts b/src/modules/types.ts index 7f85f93f..1cf56bc8 100644 --- a/src/modules/types.ts +++ b/src/modules/types.ts @@ -111,10 +111,10 @@ export interface Analytics { } export interface PaymentAnalytics { - totalCredits: bigint - freeCredits: bigint - oneCredits: bigint - fiatCredits: bigint + paymentTotal: number + paymentFreeCredits: number + paymentOneCredits: number + paymentFiatCredits: number } export interface BotSessionData { @@ -129,7 +129,7 @@ export interface TransientStateContext { transient: { analytics: Analytics refunded: boolean - payments: PaymentAnalytics + payment: PaymentAnalytics } }