diff --git a/lib/webPush.js b/lib/webPush.js index f6313e5c..3b7b41c7 100644 --- a/lib/webPush.js +++ b/lib/webPush.js @@ -318,6 +318,18 @@ export async function notifyDeposit (userId, invoice) { } } +export async function notifyWithdrawal (userId, wdrwl) { + try { + await sendUserNotification(userId, { + title: `${numWithUnits(msatsToSats(wdrwl.payment.mtokens), { abbreviate: false })} were withdrawn from your account`, + tag: 'WITHDRAWAL', + data: { sats: msatsToSats(wdrwl.payment.mtokens) } + }) + } catch (err) { + console.error(err) + } +} + export async function notifyNewStreak (userId, streak) { const index = streak.id % FOUND_BLURBS.length const blurb = FOUND_BLURBS[index] diff --git a/prisma/migrations/20240325114003_withdrawal_notifications/migration.sql b/prisma/migrations/20240325114003_withdrawal_notifications/migration.sql index 838eb1a9..f1903eb8 100644 --- a/prisma/migrations/20240325114003_withdrawal_notifications/migration.sql +++ b/prisma/migrations/20240325114003_withdrawal_notifications/migration.sql @@ -1,2 +1,29 @@ -- AlterTable ALTER TABLE "users" ADD COLUMN "noteWithdrawals" BOOLEAN NOT NULL DEFAULT true; + +CREATE OR REPLACE FUNCTION confirm_withdrawl(wid INTEGER, msats_paid BIGINT, msats_fee_paid BIGINT) +RETURNS INTEGER +LANGUAGE plpgsql +AS $$ +DECLARE + msats_fee_paying BIGINT; + user_id INTEGER; +BEGIN + PERFORM ASSERT_SERIALIZED(); + + IF EXISTS (SELECT 1 FROM "Withdrawl" WHERE id = wid AND status IS NULL) THEN + SELECT "msatsFeePaying", "userId" INTO msats_fee_paying, user_id + FROM "Withdrawl" WHERE id = wid AND status IS NULL; + + UPDATE "Withdrawl" + SET status = 'CONFIRMED', "msatsPaid" = msats_paid, + "msatsFeePaid" = msats_fee_paid, updated_at = now_utc() + WHERE id = wid AND status IS NULL; + + UPDATE users SET msats = msats + (msats_fee_paying - msats_fee_paid) WHERE id = user_id; + RETURN 0; + END IF; + + RETURN 1; +END; +$$; \ No newline at end of file diff --git a/sw/eventListener.js b/sw/eventListener.js index 5cb8b6a7..576b9145 100644 --- a/sw/eventListener.js +++ b/sw/eventListener.js @@ -116,7 +116,7 @@ const mergeAndShowNotification = async (sw, payload, currentNotifications, tag, // tags that need to know the amount of notifications with same tag for merging const AMOUNT_TAGS = ['REPLY', 'MENTION', 'REFERRAL', 'INVITE', 'FOLLOW', 'TERRITORY_POST'] // tags that need to know the sum of sats of notifications with same tag for merging - const SUM_SATS_TAGS = ['DEPOSIT'] + const SUM_SATS_TAGS = ['DEPOSIT', 'WITHDRAWAL'] // this should reflect the amount of notifications that were already merged before let initialAmount = currentNotifications[0]?.data?.amount || 1 if (iOS()) initialAmount = 1 @@ -153,8 +153,11 @@ const mergeAndShowNotification = async (sw, payload, currentNotifications, tag, title = `you have ${amount} new posts in ~${subName}` } } else if (SUM_SATS_TAGS.includes(compareTag)) { - // there is only DEPOSIT in this array - title = `${numWithUnits(sats, { abbreviate: false })} were deposited in your account` + if (compareTag === 'DEPOSIT') { + title = `${numWithUnits(sats, { abbreviate: false })} were deposited in your account` + } else if (compareTag === 'WITHDRAWAL') { + title = `${numWithUnits(sats, { abbreviate: false })} were withdrawn from your account` + } } log(`[sw:push] ${nid} - calculated title: ${title}`) diff --git a/worker/wallet.js b/worker/wallet.js index 8242202b..13179552 100644 --- a/worker/wallet.js +++ b/worker/wallet.js @@ -3,7 +3,7 @@ import { getInvoice, getPayment, cancelHodlInvoice, deletePayment, subscribeToInvoices, subscribeToPayments, subscribeToInvoice } from 'ln-service' -import { notifyDeposit } from '@/lib/webPush' +import { notifyDeposit, notifyWithdrawal } from '@/lib/webPush' import { INVOICE_RETENTION_DAYS } from '@/lib/constants' import { datePivot, sleep } from '@/lib/time.js' import retry from 'async-retry' @@ -228,8 +228,11 @@ async function checkWithdrawal ({ data: { hash }, boss, models, lnd }) { if (wdrwl?.is_confirmed) { const fee = Number(wdrwl.payment.fee_mtokens) const paid = Number(wdrwl.payment.mtokens) - fee - await serialize(models, models.$executeRaw` + const [{ confirm_withdrawl: code }] = await serialize(models, models.$queryRaw` SELECT confirm_withdrawl(${dbWdrwl.id}::INTEGER, ${paid}, ${fee})`) + if (code === 0) { + notifyWithdrawal(dbWdrwl.userId, wdrwl) + } } else if (wdrwl?.is_failed || notFound) { let status = 'UNKNOWN_FAILURE' if (wdrwl?.failed.is_insufficient_balance) {