diff --git a/api/resolvers/wallet.js b/api/resolvers/wallet.js index c71749ac0..b32a5ef83 100644 --- a/api/resolvers/wallet.js +++ b/api/resolvers/wallet.js @@ -5,7 +5,7 @@ import { import crypto, { timingSafeEqual } from 'crypto' import { decodeCursor, LIMIT, nextCursorEncoded } from '@/lib/cursor' import { SELECT, itemQueryWithMeta } from './item' -import { formatMsats, msatsToSats, msatsToSatsDecimal, satsToMsats } from '@/lib/format' +import { msatsToSats, msatsToSatsDecimal, satsToMsats } from '@/lib/format' import { USER_ID, INVOICE_RETENTION_DAYS, PAID_ACTION_PAYMENT_METHODS, @@ -745,30 +745,17 @@ export const walletLogger = ({ wallet, models }) => { // server implementation of wallet logger interface on client const log = (level) => async (message, context = {}) => { + const { invoiceForwardId, status, ...rest } = context try { - if (context?.bolt11) { - // automatically populate context from bolt11 to avoid duplicating this code - const decoded = await parsePaymentRequest({ request: context.bolt11 }) - context = { - ...context, - amount: formatMsats(decoded.mtokens), - payment_hash: decoded.id, - created_at: decoded.created_at, - expires_at: decoded.expires_at, - description: decoded.description, - // payments should affect wallet status - status: true - } - } - context.recv = true - await models.walletLog.create({ data: { userId: wallet.userId, wallet: wallet.type, level, message, - context + status: invoiceForwardId ? true : status, + invoiceForwardId, + context: rest } }) } catch (err) { diff --git a/prisma/migrations/20250118192921_normalized_wallet_logs/migration.sql b/prisma/migrations/20250118192921_normalized_wallet_logs/migration.sql new file mode 100644 index 000000000..fc8929c6a --- /dev/null +++ b/prisma/migrations/20250118192921_normalized_wallet_logs/migration.sql @@ -0,0 +1,6 @@ +-- AlterTable +ALTER TABLE "WalletLog" ADD COLUMN "invoiceForwardId" INTEGER; +ALTER TABLE "WalletLog" ADD COLUMN "status" BOOLEAN NOT NULL DEFAULT false; + +-- AddForeignKey +ALTER TABLE "WalletLog" ADD CONSTRAINT "WalletLog_invoiceForwardId_fkey" FOREIGN KEY ("invoiceForwardId") REFERENCES "InvoiceForward"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index dcdb3b938..db96c07ab 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -247,14 +247,17 @@ model VaultEntry { } model WalletLog { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) @map("created_at") - userId Int - user User @relation(fields: [userId], references: [id], onDelete: Cascade) - wallet WalletType - level LogLevel - message String - context Json? @db.JsonB + id Int @id @default(autoincrement()) + createdAt DateTime @default(now()) @map("created_at") + userId Int + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + wallet WalletType + level LogLevel + message String + invoiceForwardId Int? + invoiceForward InvoiceForward? @relation(fields: [invoiceForwardId], references: [id]) + status Boolean @default(false) + context Json? @db.JsonB @@index([userId, createdAt]) } @@ -995,9 +998,10 @@ model InvoiceForward { invoiceId Int @unique withdrawlId Int? @unique - invoice Invoice @relation(fields: [invoiceId], references: [id], onDelete: Cascade) - wallet Wallet @relation(fields: [walletId], references: [id], onDelete: Cascade) - withdrawl Withdrawl? @relation(fields: [withdrawlId], references: [id], onDelete: SetNull) + invoice Invoice @relation(fields: [invoiceId], references: [id], onDelete: Cascade) + wallet Wallet @relation(fields: [walletId], references: [id], onDelete: Cascade) + withdrawl Withdrawl? @relation(fields: [withdrawlId], references: [id], onDelete: SetNull) + WalletLog WalletLog[] @@index([invoiceId]) @@index([walletId]) diff --git a/wallets/server.js b/wallets/server.js index f14e9fb36..7aa1e4bb8 100644 --- a/wallets/server.js +++ b/wallets/server.js @@ -34,11 +34,9 @@ export async function createInvoice (userId, { msats, description, descriptionHa const logger = walletLogger({ wallet, models }) try { - logger.info( - `↙ incoming payment: ${formatSats(msatsToSats(msats))}`, - { - amount: formatMsats(msats) - }) + logger.info(`↙ incoming payment: ${formatSats(msatsToSats(msats))}`, { + amount: formatMsats(msats) + }) let invoice try { diff --git a/worker/paidAction.js b/worker/paidAction.js index 9b3ecb5a6..df191751e 100644 --- a/worker/paidAction.js +++ b/worker/paidAction.js @@ -2,7 +2,7 @@ import { getPaymentFailureStatus, hodlInvoiceCltvDetails, getPaymentOrNotSent } import { paidActions } from '@/api/paidAction' import { walletLogger } from '@/api/resolvers/wallet' import { LND_PATHFINDING_TIME_PREF_PPM, LND_PATHFINDING_TIMEOUT_MS, PAID_ACTION_TERMINAL_STATES } from '@/lib/constants' -import { formatMsats, formatSats, msatsToSats, toPositiveNumber } from '@/lib/format' +import { formatSats, msatsToSats, toPositiveNumber } from '@/lib/format' import { datePivot } from '@/lib/time' import { Prisma } from '@prisma/client' import { @@ -317,18 +317,12 @@ export async function paidActionForwarded ({ data: { invoiceId, withdrawal, ...a }, { models, lnd, boss }) if (transitionedInvoice) { - const { bolt11, msatsPaid } = transitionedInvoice.invoiceForward.withdrawl + const { msatsPaid } = transitionedInvoice.invoiceForward.withdrawl const logger = walletLogger({ wallet: transitionedInvoice.invoiceForward.wallet, models }) - logger.ok( - `↙ payment received: ${formatSats(msatsToSats(Number(msatsPaid)))}`, - { - bolt11, - preimage: transitionedInvoice.preimage - // we could show the outgoing fee that we paid from the incoming amount to the receiver - // but we don't since it might look like the receiver paid the fee but that's not the case. - // fee: formatMsats(msatsFeePaid) - }) + logger.ok(`↙ payment received: ${formatSats(msatsToSats(Number(msatsPaid)))}`, { + invoiceForwardId: transitionedInvoice.invoiceForward.id + }) } return transitionedInvoice @@ -376,13 +370,10 @@ export async function paidActionFailedForward ({ data: { invoiceId, withdrawal: }, { models, lnd, boss }) if (transitionedInvoice) { - const { bolt11, msatsFeePaying } = transitionedInvoice.invoiceForward.withdrawl const logger = walletLogger({ wallet: transitionedInvoice.invoiceForward.wallet, models }) - logger.warn( - `incoming payment failed: ${message}`, { - bolt11, - max_fee: formatMsats(msatsFeePaying) - }) + logger.warn(`incoming payment failed: ${message}`, { + invoiceForwardId: transitionedInvoice.invoiceForward.id + }) } return transitionedInvoice @@ -446,7 +437,9 @@ export async function paidActionCanceling ({ data: { invoiceId, ...args }, model const { wallet, bolt11 } = transitionedInvoice.invoiceForward const logger = walletLogger({ wallet, models }) const decoded = await parsePaymentRequest({ request: bolt11 }) - logger.info(`invoice for ${formatSats(msatsToSats(decoded.mtokens))} canceled by payer`, { bolt11 }) + logger.info(`invoice for ${formatSats(msatsToSats(decoded.mtokens))} canceled by payer`, { + invoiceForwardId: transitionedInvoice.invoiceForward.id + }) } } diff --git a/worker/payingAction.js b/worker/payingAction.js index a2c945d60..cf4135d80 100644 --- a/worker/payingAction.js +++ b/worker/payingAction.js @@ -1,6 +1,6 @@ import { getPaymentFailureStatus, getPaymentOrNotSent } from '@/api/lnd' import { walletLogger } from '@/api/resolvers/wallet' -import { formatMsats, formatSats, msatsToSats, toPositiveBigInt } from '@/lib/format' +import { formatSats, msatsToSats, toPositiveBigInt } from '@/lib/format' import { datePivot } from '@/lib/time' import { notifyWithdrawal } from '@/lib/webPush' import { Prisma } from '@prisma/client' @@ -124,13 +124,9 @@ export async function payingActionConfirmed ({ data: args, models, lnd, boss }) await notifyWithdrawal(transitionedWithdrawal) const logger = walletLogger({ models, wallet: transitionedWithdrawal.wallet }) - logger?.ok( - `↙ payment received: ${formatSats(msatsToSats(transitionedWithdrawal.msatsPaid))}`, - { - bolt11: transitionedWithdrawal.bolt11, - preimage: transitionedWithdrawal.preimage, - fee: formatMsats(transitionedWithdrawal.msatsFeePaid) - }) + logger?.ok(`↙ payment received: ${formatSats(msatsToSats(transitionedWithdrawal.msatsPaid))}`, { + invoiceForwardId: transitionedWithdrawal.invoiceForward.id + }) } } @@ -166,11 +162,8 @@ export async function payingActionFailed ({ data: args, models, lnd, boss }) { if (transitionedWithdrawal) { const logger = walletLogger({ models, wallet: transitionedWithdrawal.wallet }) - logger?.error( - `incoming payment failed: ${message}`, - { - bolt11: transitionedWithdrawal.bolt11, - max_fee: formatMsats(transitionedWithdrawal.msatsFeePaying) - }) + logger?.error(`incoming payment failed: ${message}`, { + invoiceForwardId: transitionedWithdrawal.invoiceForward.id + }) } }