diff --git a/package.json b/package.json index 49cda9fb..88412119 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,6 @@ "lint": "prettier --check src && eslint src", "format": "git diff head --name-only --diff-filter d | grep -E '(js|ts|svelte|css)$' | xargs -r prettier --write", "format:all": "prettier --write src", - "test": "vitest run", "prepare": "husky" }, "devDependencies": { @@ -26,7 +25,6 @@ "eslint-config-prettier": "^9.1.2", "eslint-plugin-svelte": "^2.46.1", "globals": "^15.15.0", - "jsdom": "^24.0.0", "postcss": "^8.5.6", "prettier": "^3.8.1", "prettier-plugin-svelte": "^3.4.1", @@ -35,8 +33,7 @@ "tailwindcss": "^3.4.19", "typescript": "^5.9.3", "typescript-eslint": "^8.53.1", - "vite": "^5.4.21", - "vitest": "^1.6.0" + "vite": "^5.4.21" }, "type": "module", "dependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5f53968c..eafcf4c4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3491,14 +3491,6 @@ packages: peerDependencies: '@capacitor/core': ^7.0.0 - nostr-tools@2.15.0: - resolution: {integrity: sha512-Jj/+UFbu3JbTAWP4ipPFNuyD4W5eVRBNAP+kmnoRCYp3bLmTrlQ0Qhs5O1xSQJTFpjdZqoS0zZOUKdxUdjc+pw==} - peerDependencies: - typescript: '>=5.0.0' - peerDependenciesMeta: - typescript: - optional: true - nostr-tools@2.20.0: resolution: {integrity: sha512-Kq/2lMyeOdGvpDsYH2an8HP4H0aFCqwKythhTzxfgZTVv4L3NOgrJw2SxH8jkWlH8xPhWxGfN6lFtC+EAa2qYQ==} peerDependencies: @@ -8421,18 +8413,6 @@ snapshots: dependencies: '@capacitor/core': 8.0.1 - nostr-tools@2.15.0(typescript@5.9.3): - dependencies: - '@noble/ciphers': 0.5.3 - '@noble/curves': 1.2.0 - '@noble/hashes': 1.3.1 - '@scure/base': 1.1.1 - '@scure/bip32': 1.3.1 - '@scure/bip39': 1.2.1 - nostr-wasm: 0.1.0 - optionalDependencies: - typescript: 5.9.3 - nostr-tools@2.20.0(typescript@5.9.3): dependencies: '@noble/ciphers': 0.5.3 diff --git a/src/lib/lightning/bolt11/Invoice.test.ts b/src/lib/lightning/bolt11/Invoice.test.ts deleted file mode 100644 index 6a1a2f46..00000000 --- a/src/lib/lightning/bolt11/Invoice.test.ts +++ /dev/null @@ -1,36 +0,0 @@ -import {describe, expect, it} from "vitest" -import {mockDateNow} from "../test/helpers" -import {Invoice} from "./Invoice" - -describe("Invoice", () => { - const invoiceString = - "lnbc20u1p3y0x3hpp5743k2g0fsqqxj7n8qzuhns5gmkk4djeejk3wkp64ppevgekvc0jsdqcve5kzar2v9nr5gpqd4hkuetesp5ez2g297jduwc20t6lmqlsg3man0vf2jfd8ar9fh8fhn2g8yttfkqxqy9gcqcqzys9qrsgqrzjqtx3k77yrrav9hye7zar2rtqlfkytl094dsp0ms5majzth6gt7ca6uhdkxl983uywgqqqqlgqqqvx5qqjqrzjqd98kxkpyw0l9tyy8r8q57k7zpy9zjmh6sez752wj6gcumqnj3yxzhdsmg6qq56utgqqqqqqqqqqqeqqjq7jd56882gtxhrjm03c93aacyfy306m4fq0tskf83c0nmet8zc2lxyyg3saz8x6vwcp26xnrlagf9semau3qm2glysp7sv95693fphvsp54l567" - - it("parses invoice data", () => { - const invoice = new Invoice({pr: invoiceString}) - - expect(invoice.satoshi).toBe(2000) - expect(invoice.description).toBe("fiatjaf: money") - expect(invoice.paymentHash).toBe( - "f5636521e98000697a6700b979c288ddad56cb3995a2eb07550872c466ccc3e5", - ) - }) - - it("tracks expiry", () => { - const invoice = new Invoice({pr: invoiceString}) - - const restoreBefore = mockDateNow(invoice.timestamp * 1000) - expect(invoice.hasExpired()).toBe(false) - restoreBefore() - - const restoreAfter = mockDateNow((invoice.timestamp + (invoice.expiry ?? 0) + 1) * 1000) - expect(invoice.hasExpired()).toBe(true) - restoreAfter() - }) - - it("validates preimages", () => { - const invoice = new Invoice({pr: invoiceString}) - expect(invoice.validatePreimage("00")).toBe(false) - expect(invoice.validatePreimage("not-hex")).toBe(false) - }) -}) diff --git a/src/lib/lightning/bolt11/amount.test.ts b/src/lib/lightning/bolt11/amount.test.ts deleted file mode 100644 index 5dd8e3f9..00000000 --- a/src/lib/lightning/bolt11/amount.test.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {describe, expect, it} from "vitest" -import {hrpToMillisats, parseHrpAmount} from "./amount" - -describe("bolt11 amount parsing", () => { - it("parses hrp amounts", () => { - expect(hrpToMillisats("20u")).toBe(2_000_000n) - expect(hrpToMillisats("1m")).toBe(100_000_000n) - }) - - it("parses bolt11 hrp", () => { - const parsed = parseHrpAmount("lnbc20u") - expect(parsed?.millisats).toBe(2_000_000n) - expect(parsed?.satoshi).toBe(2000) - expect(parseHrpAmount("lnbc")).toBeUndefined() - }) -}) diff --git a/src/lib/lightning/bolt11/bech32.test.ts b/src/lib/lightning/bolt11/bech32.test.ts deleted file mode 100644 index 5ff38ed7..00000000 --- a/src/lib/lightning/bolt11/bech32.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {describe, expect, it} from "vitest" -import {bech32Decode, convertBits} from "./bech32" - -describe("bech32", () => { - it("decodes bolt11 invoices", () => { - const invoice = - "lnbc20u1p3y0x3hpp5743k2g0fsqqxj7n8qzuhns5gmkk4djeejk3wkp64ppevgekvc0jsdqcve5kzar2v9nr5gpqd4hkuetesp5ez2g297jduwc20t6lmqlsg3man0vf2jfd8ar9fh8fhn2g8yttfkqxqy9gcqcqzys9qrsgqrzjqtx3k77yrrav9hye7zar2rtqlfkytl094dsp0ms5majzth6gt7ca6uhdkxl983uywgqqqqlgqqqvx5qqjqrzjqd98kxkpyw0l9tyy8r8q57k7zpy9zjmh6sez752wj6gcumqnj3yxzhdsmg6qq56utgqqqqqqqqqqqeqqjq7jd56882gtxhrjm03c93aacyfy306m4fq0tskf83c0nmet8zc2lxyyg3saz8x6vwcp26xnrlagf9semau3qm2glysp7sv95693fphvsp54l567" - - const decoded = bech32Decode(invoice) - - expect(decoded.hrp).toBe("lnbc20u") - expect(decoded.words.length).toBeGreaterThan(0) - }) - - it("converts bit groups", () => { - const data = new Uint8Array([1, 2, 3]) - const words = convertBits(data, 8, 5, true) - const restored = convertBits(words, 5, 8, false) - - expect(restored).toEqual([1, 2, 3]) - }) -}) diff --git a/src/lib/lightning/bolt11/decoder.test.ts b/src/lib/lightning/bolt11/decoder.test.ts deleted file mode 100644 index 61743da8..00000000 --- a/src/lib/lightning/bolt11/decoder.test.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {describe, expect, it} from "vitest" -import {decodeInvoice} from "./decoder" - -describe("bolt11 decoder", () => { - it("decodes required fields", () => { - const invoice = - "lnbc20u1p3y0x3hpp5743k2g0fsqqxj7n8qzuhns5gmkk4djeejk3wkp64ppevgekvc0jsdqcve5kzar2v9nr5gpqd4hkuetesp5ez2g297jduwc20t6lmqlsg3man0vf2jfd8ar9fh8fhn2g8yttfkqxqy9gcqcqzys9qrsgqrzjqtx3k77yrrav9hye7zar2rtqlfkytl094dsp0ms5majzth6gt7ca6uhdkxl983uywgqqqqlgqqqvx5qqjqrzjqd98kxkpyw0l9tyy8r8q57k7zpy9zjmh6sez752wj6gcumqnj3yxzhdsmg6qq56utgqqqqqqqqqqqeqqjq7jd56882gtxhrjm03c93aacyfy306m4fq0tskf83c0nmet8zc2lxyyg3saz8x6vwcp26xnrlagf9semau3qm2glysp7sv95693fphvsp54l567" - - const decoded = decodeInvoice(invoice) - - expect(decoded?.paymentHash).toBe( - "f5636521e98000697a6700b979c288ddad56cb3995a2eb07550872c466ccc3e5", - ) - expect(decoded?.satoshi).toBe(2000) - expect(decoded?.timestamp).toBe(1648859703) - expect(decoded?.expiry).toBe(172800) - expect(decoded?.description).toBe("fiatjaf: money") - }) -}) diff --git a/src/lib/lightning/nwc/NWCClient.test.ts b/src/lib/lightning/nwc/NWCClient.test.ts deleted file mode 100644 index c5710e20..00000000 --- a/src/lib/lightning/nwc/NWCClient.test.ts +++ /dev/null @@ -1,67 +0,0 @@ -import {describe, expect, it} from "vitest" -import {getPubkey, makeSecret, normalizeRelayUrl} from "@welshman/util" -import {NWCClient} from "./NWCClient" - -describe("NWCClient", () => { - it("builds and accepts wallet connect urls", () => { - const secret = makeSecret() - const walletSecret = makeSecret() - const walletPubkey = getPubkey(walletSecret) - const relayUrls = ["wss://relay.one", "wss://relay.two"] - - const client = new NWCClient({ - relayUrls, - walletPubkey, - secret, - lud16: "user@example.com", - }) - - const url = client.options.nostrWalletConnectUrl - - expect(url).toContain(`nostr+walletconnect://${walletPubkey}?`) - expect(url).toContain(`relay=${relayUrls[0]}`) - expect(url).toContain(`relay=${relayUrls[1]}`) - expect(url).toContain(`pubkey=${getPubkey(secret)}`) - expect(url).toContain(`secret=${secret}`) - - const parsedClient = new NWCClient({nostrWalletConnectUrl: url}) - - expect(parsedClient.walletPubkey).toBe(walletPubkey) - expect(parsedClient.relayUrls).toEqual(relayUrls.map(normalizeRelayUrl)) - expect(parsedClient.options.secret).toBe(secret) - }) - - it("accepts a single relay url", () => { - const secret = makeSecret() - const walletSecret = makeSecret() - const walletPubkey = getPubkey(walletSecret) - - const client = new NWCClient({ - relayUrl: "wss://relay.single", - walletPubkey, - secret, - }) - - expect(client.relayUrls).toEqual([normalizeRelayUrl("wss://relay.single")]) - }) - - it("requires hex keys", () => { - expect( - () => - new NWCClient({ - relayUrl: "wss://relay.single", - walletPubkey: "npub1nothex", - secret: makeSecret(), - }), - ).toThrow("Invalid wallet pubkey") - - expect( - () => - new NWCClient({ - relayUrl: "wss://relay.single", - walletPubkey: getPubkey(makeSecret()), - secret: "nsec1nothex", - }), - ).toThrow("Invalid secret key") - }) -}) diff --git a/src/lib/lightning/test/helpers.ts b/src/lib/lightning/test/helpers.ts deleted file mode 100644 index 1db41363..00000000 --- a/src/lib/lightning/test/helpers.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {vi} from "vitest" - -export const stubFetch = ( - impl: (input: RequestInfo | URL, init?: RequestInit) => Promise = () => - Promise.reject(new Error("fetch not mocked")), -) => { - const original = globalThis.fetch - const mock = vi.fn(impl) as unknown as typeof fetch - globalThis.fetch = mock - - return { - mock, - restore: () => { - globalThis.fetch = original - }, - } -} - -export const mockDateNow = (timestampMs: number) => { - const spy = vi.spyOn(Date, "now").mockReturnValue(timestampMs) - return () => spy.mockRestore() -} diff --git a/src/lib/lightning/test/setup.ts b/src/lib/lightning/test/setup.ts deleted file mode 100644 index 3e72557c..00000000 --- a/src/lib/lightning/test/setup.ts +++ /dev/null @@ -1,11 +0,0 @@ -import {afterEach, vi} from "vitest" - -const originalFetch: typeof fetch | undefined = globalThis.fetch - -afterEach(() => { - if (globalThis.fetch !== originalFetch) { - globalThis.fetch = originalFetch as typeof fetch - } - - vi.restoreAllMocks() -}) diff --git a/src/lib/lightning/test/smoke.test.ts b/src/lib/lightning/test/smoke.test.ts deleted file mode 100644 index 4b1e0e68..00000000 --- a/src/lib/lightning/test/smoke.test.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {describe, expect, it} from "vitest" -import {mockDateNow, stubFetch} from "./helpers" - -describe("lightning test harness", () => { - it("supports time and fetch helpers", async () => { - const restoreDate = mockDateNow(1717171717171) - expect(Date.now()).toBe(1717171717171) - restoreDate() - - const {mock, restore} = stubFetch(async () => ({ok: true}) as Response) - - const response = await fetch("https://example.com") - expect(response.ok).toBe(true) - expect(mock).toHaveBeenCalledTimes(1) - - restore() - }) -}) diff --git a/src/lib/lightning/wallet/WebLNWallet.test.ts b/src/lib/lightning/wallet/WebLNWallet.test.ts deleted file mode 100644 index 33f6b19f..00000000 --- a/src/lib/lightning/wallet/WebLNWallet.test.ts +++ /dev/null @@ -1,35 +0,0 @@ -import {describe, expect, it, vi} from "vitest" -import {WebLNWallet, type WebLNProvider} from "./WebLNWallet" - -const makeProvider = (): WebLNProvider => ({ - enable: vi.fn().mockResolvedValue(undefined), - getBalance: vi.fn().mockResolvedValue({balance: 123}), - sendPayment: vi.fn().mockResolvedValue({preimage: "00"}), - makeInvoice: vi.fn().mockResolvedValue({paymentRequest: "lnbc123"}), -}) - -describe("WebLNWallet", () => { - it("returns balance in sats", async () => { - const provider = makeProvider() - const wallet = new WebLNWallet(provider) - - await expect(wallet.getBalanceSats()).resolves.toBe(123) - expect(provider.enable).toHaveBeenCalledTimes(1) - }) - - it("rejects msat amount overrides", async () => { - const wallet = new WebLNWallet(makeProvider()) - - await expect(wallet.payInvoice({invoice: "lnbc123", msats: 1000})).rejects.toThrow( - "Unable to pay zero invoices with webln", - ) - }) - - it("normalizes invoice responses", async () => { - const provider = makeProvider() - provider.makeInvoice = vi.fn().mockResolvedValue("lnbc456") - const wallet = new WebLNWallet(provider) - - await expect(wallet.createInvoice({sats: 10})).resolves.toBe("lnbc456") - }) -}) diff --git a/src/lib/lightning/wallet/factory.test.ts b/src/lib/lightning/wallet/factory.test.ts deleted file mode 100644 index bc3fc339..00000000 --- a/src/lib/lightning/wallet/factory.test.ts +++ /dev/null @@ -1,44 +0,0 @@ -import {describe, expect, it, vi} from "vitest" -import {WalletType, getPubkey, makeSecret} from "@welshman/util" -import {createWalletAdapter} from "./factory" -import {NWCWallet} from "./NWCWallet" -import {WebLNWallet, type WebLNProvider} from "./WebLNWallet" - -describe("wallet factory", () => { - it("creates NWC adapters", () => { - const secret = makeSecret() - const walletPubkey = getPubkey(makeSecret()) - const adapter = createWalletAdapter({ - type: WalletType.NWC, - info: { - lud16: "wallet@example.com", - secret, - relayUrl: "wss://relay.example.com", - walletPubkey, - nostrWalletConnectUrl: `nostr+walletconnect://${walletPubkey}?relay=wss://relay.example.com&secret=${secret}`, - }, - }) - - expect(adapter).toBeInstanceOf(NWCWallet) - }) - - it("creates WebLN adapters", () => { - const provider: WebLNProvider = { - enable: vi.fn().mockResolvedValue(undefined), - getBalance: vi.fn().mockResolvedValue({balance: 1}), - sendPayment: vi.fn().mockResolvedValue({}), - makeInvoice: vi.fn().mockResolvedValue("lnbc1"), - } - const browserWindow = window as Window & {webln?: WebLNProvider} - browserWindow.webln = provider - - const adapter = createWalletAdapter({ - type: WalletType.WebLN, - info: {supports: ["lightning"]}, - }) - - expect(adapter).toBeInstanceOf(WebLNWallet) - - delete browserWindow.webln - }) -}) diff --git a/vitest.config.ts b/vitest.config.ts deleted file mode 100644 index bf7d3fb7..00000000 --- a/vitest.config.ts +++ /dev/null @@ -1,10 +0,0 @@ -import {defineConfig} from "vitest/config" - -export default defineConfig({ - test: { - environment: "jsdom", - include: ["src/lib/lightning/**/*.test.ts"], - restoreMocks: true, - setupFiles: ["src/lib/lightning/test/setup.ts"], - }, -})