diff --git a/src/services/lnd/lnd.ts b/src/services/lnd/lnd.ts index f6c72459..7ba9758a 100644 --- a/src/services/lnd/lnd.ts +++ b/src/services/lnd/lnd.ts @@ -388,20 +388,28 @@ export default class { async DecodeInvoice(paymentRequest: string): Promise { if (this.liquidProvider.getSettings().useOnlyLiquidityProvider) { // Use light-bolt11-decoder when LND is bypassed - const decoded = decodeBolt11(paymentRequest) - let numSatoshis = 0 - let paymentHash = '' - - for (const section of decoded.sections) { - if (section.name === 'amount') { - // Amount is in millisatoshis - numSatoshis = Math.floor(Number(section.value) / 1000) - } else if (section.name === 'payment_hash') { - paymentHash = section.value as string + try { + const decoded = decodeBolt11(paymentRequest) + let numSatoshis = 0 + let paymentHash = '' + + for (const section of decoded.sections) { + if (section.name === 'amount') { + // Amount is in millisatoshis + numSatoshis = Math.floor(Number(section.value) / 1000) + } else if (section.name === 'payment_hash') { + paymentHash = section.value as string + } } + + if (!paymentHash) { + throw new Error("Payment hash not found in invoice") + } + + return { numSatoshis, paymentHash } + } catch (err: any) { + throw new Error(`Failed to decode invoice: ${err.message}`) } - - return { numSatoshis, paymentHash } } // console.log("Decoding invoice") const res = await this.lightning.decodePayReq({ payReq: paymentRequest }, DeadLineMetadata()) diff --git a/src/services/main/index.ts b/src/services/main/index.ts index 601ff291..fcbb3cf8 100644 --- a/src/services/main/index.ts +++ b/src/services/main/index.ts @@ -298,7 +298,7 @@ export default class { // Send CLINK receipt if this invoice was from a noffer request try { if (userInvoice.clink_requester_pub && userInvoice.clink_requester_event_id) { - this.createClinkReceipt(log, userInvoice) + await this.createClinkReceipt(log, userInvoice) } } catch (err: any) { log(ERROR, "cannot create clink receipt", err.message || "") diff --git a/src/services/storage/entity/UserReceivingInvoice.ts b/src/services/storage/entity/UserReceivingInvoice.ts index 186c91b4..f0b69530 100644 --- a/src/services/storage/entity/UserReceivingInvoice.ts +++ b/src/services/storage/entity/UserReceivingInvoice.ts @@ -8,7 +8,6 @@ export type ZapInfo = { relays: string[] description: string } - @Entity() @Index("recv_invoice_paid_serial", ["user.serial_id", "paid_at_unix", "serial_id"], { where: "paid_at_unix > 0" }) export class UserReceivingInvoice { diff --git a/src/services/storage/migrations/1765354000000-clink_requester.ts b/src/services/storage/migrations/1765354000000-clink_requester.ts deleted file mode 100644 index 3028dce9..00000000 --- a/src/services/storage/migrations/1765354000000-clink_requester.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; - -export class ClinkRequester1765354000000 implements MigrationInterface { - name = 'ClinkRequester1765354000000' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_receiving_invoice" ADD COLUMN "clink_requester_pub" varchar`); - await queryRunner.query(`ALTER TABLE "user_receiving_invoice" ADD COLUMN "clink_requester_event_id" varchar`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_receiving_invoice" DROP COLUMN "clink_requester_pub"`); - await queryRunner.query(`ALTER TABLE "user_receiving_invoice" DROP COLUMN "clink_requester_event_id"`); - } - -} diff --git a/src/services/storage/migrations/1765497600000-clink_requester.ts b/src/services/storage/migrations/1765497600000-clink_requester.ts new file mode 100644 index 00000000..5568d4e3 --- /dev/null +++ b/src/services/storage/migrations/1765497600000-clink_requester.ts @@ -0,0 +1,25 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class ClinkRequester1765497600000 implements MigrationInterface { + name = 'ClinkRequester1765497600000' + + public async up(queryRunner: QueryRunner): Promise { + // Check if columns already exist (idempotent migration for existing databases) + const tableInfo = await queryRunner.query(`PRAGMA table_info("user_receiving_invoice")`); + const hasPubColumn = tableInfo.some((col: any) => col.name === 'clink_requester_pub'); + const hasEventIdColumn = tableInfo.some((col: any) => col.name === 'clink_requester_event_id'); + + if (!hasPubColumn) { + await queryRunner.query(`ALTER TABLE "user_receiving_invoice" ADD COLUMN "clink_requester_pub" varchar(64)`); + } + if (!hasEventIdColumn) { + await queryRunner.query(`ALTER TABLE "user_receiving_invoice" ADD COLUMN "clink_requester_event_id" varchar(64)`); + } + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user_receiving_invoice" DROP COLUMN "clink_requester_pub"`); + await queryRunner.query(`ALTER TABLE "user_receiving_invoice" DROP COLUMN "clink_requester_event_id"`); + } + +} diff --git a/src/services/storage/migrations/runner.ts b/src/services/storage/migrations/runner.ts index d7a99ec7..c87adf78 100644 --- a/src/services/storage/migrations/runner.ts +++ b/src/services/storage/migrations/runner.ts @@ -27,14 +27,14 @@ import { UserAccess1759426050669 } from './1759426050669-user_access.js' import { AddBlindToUserOffer1760000000000 } from './1760000000000-add_blind_to_user_offer.js' import { ApplicationAvatarUrl1761000001000 } from './1761000001000-application_avatar_url.js' import { AdminSettings1761683639419 } from './1761683639419-admin_settings.js' -import { ClinkRequester1765354000000 } from './1765354000000-clink_requester.js' +import { ClinkRequester1765497600000 } from './1765497600000-clink_requester.js' export const allMigrations = [Initial1703170309875, LspOrder1718387847693, LiquidityProvider1719335699480, LndNodeInfo1720187506189, TrackedProvider1720814323679, CreateInviteTokenTable1721751414878, PaymentIndex1721760297610, DebitAccess1726496225078, DebitAccessFixes1726685229264, DebitToPub1727105758354, UserCbUrl1727112281043, UserOffer1733502626042, ManagementGrant1751307732346, ManagementGrantBanned1751989251513, InvoiceCallbackUrls1752425992291, OldSomethingLeftover1753106599604, UserReceivingInvoiceIdx1753109184611, AppUserDevice1753285173175, - UserAccess1759426050669, AddBlindToUserOffer1760000000000, ApplicationAvatarUrl1761000001000, AdminSettings1761683639419, ClinkRequester1765354000000] + UserAccess1759426050669, AddBlindToUserOffer1760000000000, ApplicationAvatarUrl1761000001000, AdminSettings1761683639419, ClinkRequester1765497600000] export const allMetricsMigrations = [LndMetrics1703170330183, ChannelRouting1709316653538, HtlcCount1724266887195, BalanceEvents1724860966825, RootOps1732566440447, RootOpsTime1745428134124, ChannelEvents1750777346411] /* export const TypeOrmMigrationRunner = async (log: PubLogger, storageManager: Storage, settings: DbSettings, arg: string | undefined): Promise => {