From 808b7900ab4c57b3e8554cafebf2e90b3466445f Mon Sep 17 00:00:00 2001 From: Vandana Date: Tue, 30 Jun 2026 17:30:26 -0700 Subject: [PATCH] fix(notifications): format USDT pushes as USD --- .../ibex/webhook-server/routes/on-receive.ts | 4 +++ .../create-push-notification-content.ts | 33 +++++++++++++++---- .../create-push-notification-content.spec.ts | 21 ++++++++++++ 3 files changed, 51 insertions(+), 7 deletions(-) create mode 100644 test/flash/unit/services/notifications/create-push-notification-content.spec.ts diff --git a/src/services/ibex/webhook-server/routes/on-receive.ts b/src/services/ibex/webhook-server/routes/on-receive.ts index 06f44595e..29d2c277a 100644 --- a/src/services/ibex/webhook-server/routes/on-receive.ts +++ b/src/services/ibex/webhook-server/routes/on-receive.ts @@ -22,6 +22,8 @@ import { ibexWebhookPaths } from "@services/ibex/webhook-config" import { authenticate, logRequest, validateIbexIp } from "../middleware" +const USDT_MICROS_PER_MAJOR_UNIT = 1_000_000 + interface PaymentContext { receiverWallet: Wallet recipientAccount: Account @@ -255,6 +257,8 @@ const parsePaymentHash = (hash: unknown) => const toPaymentAmount = (currency: WalletCurrency) => (dollarAmount: number) => { let amount: PaymentAmount["amount"] | undefined if (currency === WalletCurrency.Usd) amount = BigInt(Math.round(dollarAmount * 100)) + if (currency === WalletCurrency.Usdt) + amount = BigInt(Math.round(dollarAmount * USDT_MICROS_PER_MAJOR_UNIT)) return { amount: amount as PaymentAmount["amount"], currency } } diff --git a/src/services/notifications/create-push-notification-content.ts b/src/services/notifications/create-push-notification-content.ts index 205af4796..f54fcde01 100644 --- a/src/services/notifications/create-push-notification-content.ts +++ b/src/services/notifications/create-push-notification-content.ts @@ -5,6 +5,7 @@ import { WalletCurrency } from "@domain/shared" import { getLanguageOrDefault } from "@domain/locale" const i18n = getI18nInstance() +const USDT_MICROS_PER_MAJOR_UNIT = 1_000_000 const customToLocaleString = ( number: number, @@ -36,20 +37,38 @@ export const createPushNotificationContent = ({ } => { const locale = getLanguageOrDefault(userLanguage) const baseCurrency = amount.currency + const walletCurrencyLabel = baseCurrency === WalletCurrency.Usdt ? "USD" : baseCurrency const notificationType = type === "balance" ? type : `transaction.${type}` const title = i18n.__( { phrase: `notification.${notificationType}.title`, locale }, - { walletCurrency: baseCurrency }, + { walletCurrency: walletCurrencyLabel }, ) - const baseCurrencyName = baseCurrency === WalletCurrency.Btc ? "sats" : "" - const displayedBaseAmount = - baseCurrency === WalletCurrency.Usd ? Number(amount.amount) / 100 : amount.amount + let baseCurrencyName = "" + let displayedBaseAmount: number | bigint = amount.amount + let numberFormatOptions: Intl.NumberFormatOptions = { style: "decimal" } + + if (baseCurrency === WalletCurrency.Btc) { + baseCurrencyName = "sats" + } + + if (baseCurrency === WalletCurrency.Usd) { + displayedBaseAmount = Number(amount.amount) / 100 + numberFormatOptions = { + currency: baseCurrency, + style: "currency", + currencyDisplay: "narrowSymbol", + } + } + + if (baseCurrency === WalletCurrency.Usdt) { + baseCurrencyName = "USD" + displayedBaseAmount = Number(amount.amount) / USDT_MICROS_PER_MAJOR_UNIT + } + const baseCurrencyAmount = customToLocaleString(Number(displayedBaseAmount), locale, { minimumFractionDigits: 0, maximumFractionDigits: MajorExponent.STANDARD, - currency: baseCurrency, - style: baseCurrency === WalletCurrency.Btc ? "decimal" : "currency", - currencyDisplay: "narrowSymbol", + ...numberFormatOptions, }) let body = i18n.__( diff --git a/test/flash/unit/services/notifications/create-push-notification-content.spec.ts b/test/flash/unit/services/notifications/create-push-notification-content.spec.ts new file mode 100644 index 000000000..04d6618c1 --- /dev/null +++ b/test/flash/unit/services/notifications/create-push-notification-content.spec.ts @@ -0,0 +1,21 @@ +import { NotificationType } from "@domain/notifications" +import { WalletCurrency } from "@domain/shared" +import { createPushNotificationContent } from "@services/notifications/create-push-notification-content" + +describe("createPushNotificationContent", () => { + it("formats USDT invoice-paid notifications with USD-facing copy", () => { + const content = createPushNotificationContent({ + type: NotificationType.LnInvoicePaid, + userLanguage: "en" as UserLanguageOrEmpty, + amount: { + amount: 20_000n, + currency: WalletCurrency.Usdt, + } as PaymentAmount, + }) + + expect(content).toEqual({ + title: "USD Transaction", + body: "+0.02 USD", + }) + }) +})