From eaa1ea95620ad1f1ca1610c1041416476d72d11f Mon Sep 17 00:00:00 2001 From: im-adithya Date: Wed, 4 Dec 2024 18:11:00 +0530 Subject: [PATCH 1/5] chore: remove explicit type --- src/lnurlp.ts | 8 ++++---- src/main.ts | 6 +++--- src/users.ts | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/lnurlp.ts b/src/lnurlp.ts index 3fe1ce3..306d215 100644 --- a/src/lnurlp.ts +++ b/src/lnurlp.ts @@ -1,4 +1,4 @@ -import { Context, Hono } from "hono"; +import { Hono } from "hono"; import { nwc } from "npm:@getalby/sdk"; import { logger } from "../src/logger.ts"; import { BASE_URL, DOMAIN } from "./constants.ts"; @@ -8,7 +8,7 @@ import "./nwc/nwcPool.ts"; export function createLnurlWellKnownApp(db: DB) { const hono = new Hono(); - hono.get("/:username", async (c: Context) => { + hono.get("/:username", async (c) => { try { const username = c.req.param("username"); @@ -38,7 +38,7 @@ export function createLnurlWellKnownApp(db: DB) { export function createLnurlApp(db: DB) { const hono = new Hono(); - hono.get("/:username/callback", async (c: Context) => { + hono.get("/:username/callback", async (c) => { try { const username = c.req.param("username"); const amount = c.req.query("amount"); @@ -72,7 +72,7 @@ export function createLnurlApp(db: DB) { } }); - hono.get("/:username/verify/:payment_hash", async (c: Context) => { + hono.get("/:username/verify/:payment_hash", async (c) => { try { const username = c.req.param("username"); const paymentHash = c.req.param("payment_hash"); diff --git a/src/main.ts b/src/main.ts index 8cb87b3..55f14de 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,4 @@ -import { Context, Hono } from "hono"; +import { Hono } from "hono"; import { serveStatic } from "hono/deno"; import { secureHeaders } from "hono/secure-headers"; //import { sentry } from "npm:@hono/sentry"; @@ -30,13 +30,13 @@ hono.route("/.well-known/lnurlp", createLnurlWellKnownApp(db)); hono.route("/lnurlp", createLnurlApp(db)); hono.route("/users", createUsersApp(db, nwcPool)); -hono.get("/ping", (c: Context) => { +hono.get("/ping", (c) => { return c.body("OK"); }); hono.use("/favicon.ico", serveStatic({ path: "./favicon.ico" })); -hono.get("/robots.txt", (c: Context) => { +hono.get("/robots.txt", (c) => { return c.body("User-agent: *\nDisallow: /", 200); }); diff --git a/src/users.ts b/src/users.ts index 80372c2..0b9f3e9 100644 --- a/src/users.ts +++ b/src/users.ts @@ -1,4 +1,4 @@ -import { Context, Hono } from "hono"; +import { Hono } from "hono"; import { DOMAIN } from "./constants.ts"; import { DB } from "./db/db.ts"; import { logger } from "./logger.ts"; @@ -7,7 +7,7 @@ import { NWCPool } from "./nwc/nwcPool.ts"; export function createUsersApp(db: DB, nwcPool: NWCPool) { const hono = new Hono(); - hono.post("/", async (c: Context) => { + hono.post("/", async (c) => { logger.debug("create user", {}); const createUserRequest: { connectionSecret: string; username?: string } = From 143311669c78e59c80772c2e9b9619dd744c8861 Mon Sep 17 00:00:00 2001 From: im-adithya Date: Thu, 5 Dec 2024 15:00:36 +0530 Subject: [PATCH 2/5] chore: further changes --- deno.lock | 4 ++ ...k_tom.sql => 0001_ancient_katie_power.sql} | 7 +-- drizzle/meta/0001_snapshot.json | 58 +------------------ drizzle/meta/_journal.json | 4 +- src/constants.ts | 2 + src/db/db.ts | 10 ++-- src/db/schema.ts | 10 +--- src/lnurlp.ts | 14 ++--- src/nwc/nwcPool.ts | 2 +- 9 files changed, 28 insertions(+), 83 deletions(-) rename drizzle/{0001_fluffy_black_tom.sql => 0001_ancient_katie_power.sql} (67%) diff --git a/deno.lock b/deno.lock index ffb510c..22c71d0 100644 --- a/deno.lock +++ b/deno.lock @@ -4,6 +4,7 @@ "jsr:@hono/hono@^4.5.5": "4.5.5", "jsr:@nostr/tools@^2.10.3": "2.10.3", "jsr:@std/assert@^1.0.6": "1.0.6", + "jsr:@std/dotenv@*": "0.225.2", "jsr:@std/expect@*": "1.0.4", "jsr:@std/internal@^1.0.4": "1.0.4", "npm:@getalby/sdk@*": "3.7.1", @@ -39,6 +40,9 @@ "jsr:@std/internal" ] }, + "@std/dotenv@0.225.2": { + "integrity": "e2025dce4de6c7bca21dece8baddd4262b09d5187217e231b033e088e0c4dd23" + }, "@std/expect@1.0.4": { "integrity": "97f68a445a9de0d9670200d2b7a19a7505a01b2cb390a983ba8d97d90ce30c4f", "dependencies": [ diff --git a/drizzle/0001_fluffy_black_tom.sql b/drizzle/0001_ancient_katie_power.sql similarity index 67% rename from drizzle/0001_fluffy_black_tom.sql rename to drizzle/0001_ancient_katie_power.sql index d205d7e..3fad9cb 100644 --- a/drizzle/0001_fluffy_black_tom.sql +++ b/drizzle/0001_ancient_katie_power.sql @@ -1,7 +1,7 @@ CREATE TABLE IF NOT EXISTS "invoices" ( "id" serial PRIMARY KEY NOT NULL, "user_id" integer NOT NULL, - "amount" integer NOT NULL, + "amount" bigint NOT NULL, "description" text, "description_hash" text, "payment_request" text NOT NULL, @@ -20,7 +20,4 @@ EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint -CREATE INDEX IF NOT EXISTS "user_id_idx" ON "invoices" USING btree ("user_id");--> statement-breakpoint -CREATE INDEX IF NOT EXISTS "payment_hash_idx" ON "invoices" USING btree ("payment_hash");--> statement-breakpoint -CREATE INDEX IF NOT EXISTS "user_payment_hash_idx" ON "invoices" USING btree ("user_id","payment_hash");--> statement-breakpoint -CREATE INDEX IF NOT EXISTS "username_idx" ON "users" USING btree ("username"); \ No newline at end of file +CREATE INDEX IF NOT EXISTS "user_id_idx" ON "invoices" USING btree ("user_id"); \ No newline at end of file diff --git a/drizzle/meta/0001_snapshot.json b/drizzle/meta/0001_snapshot.json index 72495e3..d547cfb 100644 --- a/drizzle/meta/0001_snapshot.json +++ b/drizzle/meta/0001_snapshot.json @@ -1,5 +1,5 @@ { - "id": "a90a8c91-5f2c-48da-9109-ae0a37820ceb", + "id": "87dd9fe6-7a48-463d-bfce-15767f26fee9", "prevId": "e292703e-d08b-4f8b-a9eb-3937fe872be7", "version": "7", "dialect": "postgresql", @@ -22,7 +22,7 @@ }, "amount": { "name": "amount", - "type": "integer", + "type": "bigint", "primaryKey": false, "notNull": true }, @@ -91,42 +91,6 @@ "concurrently": false, "method": "btree", "with": {} - }, - "payment_hash_idx": { - "name": "payment_hash_idx", - "columns": [ - { - "expression": "payment_hash", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "user_payment_hash_idx": { - "name": "user_payment_hash_idx", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "payment_hash", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} } }, "foreignKeys": { @@ -192,23 +156,7 @@ "default": "now()" } }, - "indexes": { - "username_idx": { - "name": "username_idx", - "columns": [ - { - "expression": "username", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, + "indexes": {}, "foreignKeys": {}, "compositePrimaryKeys": {}, "uniqueConstraints": { diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json index 6980b63..280a250 100644 --- a/drizzle/meta/_journal.json +++ b/drizzle/meta/_journal.json @@ -12,8 +12,8 @@ { "idx": 1, "version": "7", - "when": 1732639452062, - "tag": "0001_fluffy_black_tom", + "when": 1733390179465, + "tag": "0001_ancient_katie_power", "breakpoints": true } ] diff --git a/src/constants.ts b/src/constants.ts index bd49fb9..13686fa 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,3 +1,5 @@ +import "jsr:@std/dotenv/load"; + export const PORT = parseInt(Deno.env.get("PORT") || "8080"); export const BASE_URL = Deno.env.get("BASE_URL"); if (!BASE_URL) { diff --git a/src/db/db.ts b/src/db/db.ts index 92a4962..bdc3c76 100644 --- a/src/db/db.ts +++ b/src/db/db.ts @@ -69,7 +69,7 @@ export class DB { async createInvoice( userId: number, transaction: nwc.Nip47Transaction - ): Promise<{ identifier: string }> { + ) { await this._db.insert(invoices).values({ userId, amount: transaction.amount, @@ -80,12 +80,12 @@ export class DB { metadata: transaction.metadata, }); - return { identifier: transaction.payment_hash }; + return; } - async findInvoice(identifier: string) { + async findInvoice(paymentHash: string) { const result = await this._db.query.invoices.findFirst({ - where: eq(invoices.paymentHash, identifier), + where: eq(invoices.paymentHash, paymentHash), }); if (!result) { throw new Error("invoice not found"); @@ -93,7 +93,7 @@ export class DB { return result; } - async updateInvoice( + async markInvoiceSettled( userId: number, transaction: nwc.Nip47Transaction ): Promise { diff --git a/src/db/schema.ts b/src/db/schema.ts index 6fff944..4a98210 100644 --- a/src/db/schema.ts +++ b/src/db/schema.ts @@ -1,20 +1,16 @@ -import { index, integer, jsonb, pgTable, serial, text, timestamp } from "drizzle-orm/pg-core"; +import { bigint, index, integer, jsonb, pgTable, serial, text, timestamp } from "drizzle-orm/pg-core"; export const users = pgTable("users", { id: serial("id").primaryKey(), encryptedConnectionSecret: text("connection_secret").notNull(), username: text("username").unique().notNull(), createdAt: timestamp("created_at").notNull().defaultNow(), -}, (table) => { - return { - usernameIdx: index("username_idx").on(table.username), - }; }); export const invoices = pgTable("invoices", { id: serial("id").primaryKey(), userId: integer("user_id").references(() => users.id, { onDelete: "cascade" }).notNull(), - amount: integer("amount").notNull(), + amount: bigint("amount", { mode: "number" }).notNull(), description: text("description"), descriptionHash: text("description_hash"), paymentRequest: text("payment_request").unique().notNull(), @@ -26,7 +22,5 @@ export const invoices = pgTable("invoices", { }, (table) => { return { userIdIdx: index("user_id_idx").on(table.userId), - paymentHashIdx: index("payment_hash_idx").on(table.paymentHash), - userPaymentHashIdx: index("user_payment_hash_idx").on(table.userId, table.paymentHash), }; }); diff --git a/src/lnurlp.ts b/src/lnurlp.ts index 540e958..27b176e 100644 --- a/src/lnurlp.ts +++ b/src/lnurlp.ts @@ -79,7 +79,7 @@ export function createLnurlApp(db: DB) { const description = zapRequest ? zapRequest.content : comment; - const content = zapRequest ? JSON.stringify(nostr) : getLnurlMetadata(username); + const content = zapRequest ? (nostr || "") : getLnurlMetadata(username); const descriptionHash = await computeDescriptionHash(content); const user = await db.findUser(username); @@ -100,10 +100,10 @@ export function createLnurlApp(db: DB) { description_hash: descriptionHash, }); - const invoice = await db.createInvoice(user.id, transaction); + await db.createInvoice(user.id, transaction); return c.json({ - verify: `${BASE_URL}/lnurlp/${username}/verify/${invoice.identifier}`, + verify: `${BASE_URL}/lnurlp/${username}/verify/${transaction.payment_hash}`, routes: [], pr: transaction.invoice, }); @@ -112,14 +112,14 @@ export function createLnurlApp(db: DB) { } }); - hono.get("/:username/verify/:identifier", async (c) => { + hono.get("/:username/verify/:payment_hash", async (c) => { try { const username = c.req.param("username"); - const identifier = c.req.param("identifier"); + const paymentHash = c.req.param("payment_hash"); - logger.debug("LNURLp verify", { username, identifier }); + logger.debug("LNURLp verify", { username, paymentHash }); - const invoice = await db.findInvoice(identifier); + const invoice = await db.findInvoice(paymentHash); return c.json({ settled: !!invoice.settledAt, diff --git a/src/nwc/nwcPool.ts b/src/nwc/nwcPool.ts index fd6d0c9..1030693 100644 --- a/src/nwc/nwcPool.ts +++ b/src/nwc/nwcPool.ts @@ -27,7 +27,7 @@ export class NWCPool { (notification) => { logger.debug("received notification", { userId, notification }); if (notification.notification_type === "payment_received") { - this._db.updateInvoice(userId, notification.notification) + this._db.markInvoiceSettled(userId, notification.notification) } }, ["payment_received"] From f8e8c222b815b32abc8fb454ee34a9ed129c312b Mon Sep 17 00:00:00 2001 From: im-adithya Date: Mon, 9 Dec 2024 16:13:08 +0530 Subject: [PATCH 3/5] chore: remove description hash --- ...t_katie_power.sql => 0001_fixed_vertigo.sql} | 1 - drizzle/meta/0001_snapshot.json | 8 +------- drizzle/meta/_journal.json | 4 ++-- src/constants.ts | 2 -- src/db/db.ts | 9 ++++----- src/db/schema.ts | 1 - src/lnurlp.ts | 17 +++-------------- src/users.ts | 2 +- 8 files changed, 11 insertions(+), 33 deletions(-) rename drizzle/{0001_ancient_katie_power.sql => 0001_fixed_vertigo.sql} (96%) diff --git a/drizzle/0001_ancient_katie_power.sql b/drizzle/0001_fixed_vertigo.sql similarity index 96% rename from drizzle/0001_ancient_katie_power.sql rename to drizzle/0001_fixed_vertigo.sql index 3fad9cb..0d2b03b 100644 --- a/drizzle/0001_ancient_katie_power.sql +++ b/drizzle/0001_fixed_vertigo.sql @@ -3,7 +3,6 @@ CREATE TABLE IF NOT EXISTS "invoices" ( "user_id" integer NOT NULL, "amount" bigint NOT NULL, "description" text, - "description_hash" text, "payment_request" text NOT NULL, "payment_hash" text NOT NULL, "preimage" text, diff --git a/drizzle/meta/0001_snapshot.json b/drizzle/meta/0001_snapshot.json index d547cfb..657ef27 100644 --- a/drizzle/meta/0001_snapshot.json +++ b/drizzle/meta/0001_snapshot.json @@ -1,5 +1,5 @@ { - "id": "87dd9fe6-7a48-463d-bfce-15767f26fee9", + "id": "2088fd9b-1767-4f38-b32a-a68bbde5f684", "prevId": "e292703e-d08b-4f8b-a9eb-3937fe872be7", "version": "7", "dialect": "postgresql", @@ -32,12 +32,6 @@ "primaryKey": false, "notNull": false }, - "description_hash": { - "name": "description_hash", - "type": "text", - "primaryKey": false, - "notNull": false - }, "payment_request": { "name": "payment_request", "type": "text", diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json index 280a250..e08e9e1 100644 --- a/drizzle/meta/_journal.json +++ b/drizzle/meta/_journal.json @@ -12,8 +12,8 @@ { "idx": 1, "version": "7", - "when": 1733390179465, - "tag": "0001_ancient_katie_power", + "when": 1733740354508, + "tag": "0001_fixed_vertigo", "breakpoints": true } ] diff --git a/src/constants.ts b/src/constants.ts index 13686fa..bd49fb9 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,5 +1,3 @@ -import "jsr:@std/dotenv/load"; - export const PORT = parseInt(Deno.env.get("PORT") || "8080"); export const BASE_URL = Deno.env.get("BASE_URL"); if (!BASE_URL) { diff --git a/src/db/db.ts b/src/db/db.ts index bdc3c76..520e6fd 100644 --- a/src/db/db.ts +++ b/src/db/db.ts @@ -29,7 +29,7 @@ export class DB { async createUser( connectionSecret: string, username?: string - ): Promise<{ username: string }> { + ) { const parsed = nwc.NWCClient.parseWalletConnectUrl(connectionSecret); if (!parsed.secret) { throw new Error("no secret found in connection secret"); @@ -40,12 +40,12 @@ export class DB { const encryptedConnectionSecret = await encrypt(connectionSecret); - await this._db.insert(users).values({ + const [newUser] = await this._db.insert(users).values({ encryptedConnectionSecret, username, - }); + }).returning({ id: users.id, username: users.username }); - return { username }; + return newUser; } getAllUsers() { @@ -74,7 +74,6 @@ export class DB { userId, amount: transaction.amount, description: transaction.description, - descriptionHash: transaction.description_hash, paymentRequest: transaction.invoice, paymentHash: transaction.payment_hash, metadata: transaction.metadata, diff --git a/src/db/schema.ts b/src/db/schema.ts index 4a98210..ce27c33 100644 --- a/src/db/schema.ts +++ b/src/db/schema.ts @@ -12,7 +12,6 @@ export const invoices = pgTable("invoices", { userId: integer("user_id").references(() => users.id, { onDelete: "cascade" }).notNull(), amount: bigint("amount", { mode: "number" }).notNull(), description: text("description"), - descriptionHash: text("description_hash"), paymentRequest: text("payment_request").unique().notNull(), paymentHash: text("payment_hash").unique().notNull(), preimage: text("preimage"), diff --git a/src/lnurlp.ts b/src/lnurlp.ts index 27b176e..e901114 100644 --- a/src/lnurlp.ts +++ b/src/lnurlp.ts @@ -14,13 +14,6 @@ function getLnurlMetadata(username: string): string { ]) } -async function computeDescriptionHash(content: string): Promise { - const hashBuffer = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(content)); - return Array.from(new Uint8Array(hashBuffer)) - .map((b) => b.toString(16).padStart(2, "0")) - .join(""); -} - export function createLnurlWellKnownApp(db: DB) { const hono = new Hono(); @@ -62,7 +55,7 @@ export function createLnurlApp(db: DB) { const payerData = c.req.query("payerdata") ? JSON.parse(c.req.query("payerdata") || "") : null; const nostr = c.req.query("nostr") ? decodeURIComponent(c.req.query("nostr") || "") : null; - logger.debug("LNURLp callback", { username, amount, comment, payerData, nostr }); + logger.debug("LNURLp callback", { username, amount, comment, payer_data: payerData, nostr }); if (!amount) { throw new Error("No amount provided"); @@ -79,9 +72,6 @@ export function createLnurlApp(db: DB) { const description = zapRequest ? zapRequest.content : comment; - const content = zapRequest ? (nostr || "") : getLnurlMetadata(username); - const descriptionHash = await computeDescriptionHash(content); - const user = await db.findUser(username); const nwcClient = new nwc.NWCClient({ @@ -96,8 +86,7 @@ export function createLnurlApp(db: DB) { // TODO: payer_data can be improved using nostr worker payer_data: payerData || undefined, nostr: zapRequest || undefined, - }, - description_hash: descriptionHash, + } }); await db.createInvoice(user.id, transaction); @@ -117,7 +106,7 @@ export function createLnurlApp(db: DB) { const username = c.req.param("username"); const paymentHash = c.req.param("payment_hash"); - logger.debug("LNURLp verify", { username, paymentHash }); + logger.debug("LNURLp verify", { username, payment_hash: paymentHash }); const invoice = await db.findInvoice(paymentHash); diff --git a/src/users.ts b/src/users.ts index 0b9f3e9..34e6ea1 100644 --- a/src/users.ts +++ b/src/users.ts @@ -24,7 +24,7 @@ export function createUsersApp(db: DB, nwcPool: NWCPool) { const lightningAddress = user.username + "@" + DOMAIN; - nwcPool.subscribeUser(createUserRequest.connectionSecret, user.username); + nwcPool.subscribeUser(createUserRequest.connectionSecret, user.id); return c.json({ lightningAddress, From c09a41b3a6ff1f02de816719441267f3f627417b Mon Sep 17 00:00:00 2001 From: Roland Bewick Date: Mon, 9 Dec 2024 20:12:18 +0700 Subject: [PATCH 4/5] doc: remove old command from readme --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 3fda3b1..72ca6ec 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ A minimal Lightning address server powered by [NWC](https://nwc.dev) ```json { - "connectionSecret": "nostr+walletconnect://..." + "connectionSecret": "nostr+walletconnect://..." } ``` @@ -26,7 +26,6 @@ A minimal Lightning address server powered by [NWC](https://nwc.dev) - [Install Deno](https://docs.deno.com/runtime/manual/getting_started/installation/) - Copy `.env.example` to `.env` -- Setup DB: `deno task db:migrate` - Run in dev mode: `deno task dev` ### Creating a new migration From eb97e4715066b9dabe9925a7e2d301781ff4f8a9 Mon Sep 17 00:00:00 2001 From: im-adithya Date: Tue, 10 Dec 2024 12:19:51 +0530 Subject: [PATCH 5/5] chore: add user id payment hash idx --- ...fixed_vertigo.sql => 0001_white_prism.sql} | 3 ++- drizzle/meta/0001_snapshot.json | 23 ++++++++++++++++++- drizzle/meta/_journal.json | 4 ++-- src/db/schema.ts | 1 + 4 files changed, 27 insertions(+), 4 deletions(-) rename drizzle/{0001_fixed_vertigo.sql => 0001_white_prism.sql} (84%) diff --git a/drizzle/0001_fixed_vertigo.sql b/drizzle/0001_white_prism.sql similarity index 84% rename from drizzle/0001_fixed_vertigo.sql rename to drizzle/0001_white_prism.sql index 0d2b03b..a2cc79f 100644 --- a/drizzle/0001_fixed_vertigo.sql +++ b/drizzle/0001_white_prism.sql @@ -19,4 +19,5 @@ EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint -CREATE INDEX IF NOT EXISTS "user_id_idx" ON "invoices" USING btree ("user_id"); \ No newline at end of file +CREATE INDEX IF NOT EXISTS "user_id_idx" ON "invoices" USING btree ("user_id");--> statement-breakpoint +CREATE INDEX IF NOT EXISTS "user_payment_hash_idx" ON "invoices" USING btree ("user_id","payment_hash"); \ No newline at end of file diff --git a/drizzle/meta/0001_snapshot.json b/drizzle/meta/0001_snapshot.json index 657ef27..d0f04a0 100644 --- a/drizzle/meta/0001_snapshot.json +++ b/drizzle/meta/0001_snapshot.json @@ -1,5 +1,5 @@ { - "id": "2088fd9b-1767-4f38-b32a-a68bbde5f684", + "id": "52607bd8-7a1a-4a34-ad27-91b78733e85c", "prevId": "e292703e-d08b-4f8b-a9eb-3937fe872be7", "version": "7", "dialect": "postgresql", @@ -85,6 +85,27 @@ "concurrently": false, "method": "btree", "with": {} + }, + "user_payment_hash_idx": { + "name": "user_payment_hash_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "payment_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} } }, "foreignKeys": { diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json index e08e9e1..8c625fe 100644 --- a/drizzle/meta/_journal.json +++ b/drizzle/meta/_journal.json @@ -12,8 +12,8 @@ { "idx": 1, "version": "7", - "when": 1733740354508, - "tag": "0001_fixed_vertigo", + "when": 1733813329314, + "tag": "0001_white_prism", "breakpoints": true } ] diff --git a/src/db/schema.ts b/src/db/schema.ts index ce27c33..cea1949 100644 --- a/src/db/schema.ts +++ b/src/db/schema.ts @@ -21,5 +21,6 @@ export const invoices = pgTable("invoices", { }, (table) => { return { userIdIdx: index("user_id_idx").on(table.userId), + userPaymentHashIdx: index("user_payment_hash_idx").on(table.userId, table.paymentHash), }; });