From f444677872d1e4d0d7ba6f2be787a1dfd3390d6e Mon Sep 17 00:00:00 2001 From: Padreug Date: Tue, 22 Sep 2026 23:09:34 +0200 Subject: [PATCH] fix(wallet): narrow the bolt11 amount section so the build passes `dev` does not build. This is fallout from #162: `vue-tsc -b` rejects `section.value` with error TS2339: Property 'value' does not exist on type 'Section'. Property 'value' does not exist on type '{ name: "checksum"; letters: string; }'. `Section` is a discriminated union and its "checksum" member carries only `letters`. The predicate was written as `(s: any) => ...`, which is not a type guard, so `find` returned the whole union and `.value` could not resolve against every member. Replaced with a real type predicate narrowing to the `amount` member. My fault for how I verified #162: I ran `vue-tsc --noEmit`, but the build script runs `vue-tsc -b`, which uses the project-reference config and is stricter. The two disagree, so `--noEmit` alone is not evidence that the build passes. #166 did run a full build, but it was branched off #165 and so never contained this code. Amountless behaviour is unchanged, re-verified after the narrowing: amountless BOLT11 -> 0 (amount_msat sent) live 777-sat -> 777000 (amount_msat omitted) malformed -> null (defer to server) `npm run build:wallet` now succeeds. --- src/modules/wallet/services/WalletService.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/modules/wallet/services/WalletService.ts b/src/modules/wallet/services/WalletService.ts index 0448e64..9ef9d84 100644 --- a/src/modules/wallet/services/WalletService.ts +++ b/src/modules/wallet/services/WalletService.ts @@ -4,6 +4,9 @@ import { injectService, SERVICE_TOKENS } from '@/core/di-container' import { config } from '@/lib/config' import { decode as decodeBolt11 } from 'light-bolt11-decoder' +/** The `amount` member of light-bolt11-decoder's `Section` union. */ +type AmountSection = { name: 'amount'; letters: string; value: string } + export interface PayLink { id: string wallet: string @@ -344,7 +347,14 @@ export default class WalletService extends BaseService { private getInvoiceAmountMsat(bolt11: string): number | null { try { const decoded = decodeBolt11(bolt11) - const section = decoded.sections.find((s: any) => s.name === 'amount') + // `sections` is a discriminated union, and not every member carries a + // `value` — the "checksum" member has only `letters`. Narrow with a + // type predicate so the compiler knows which member we are reading; + // an `(s: any)` callback is not a type guard, so `find` still returned + // the whole union and `.value` failed to resolve under `vue-tsc -b`. + const section = decoded.sections.find( + (s): s is AmountSection => s.name === 'amount' + ) if (!section || section.value === undefined || section.value === null) return 0 return Number(section.value) } catch (error) { -- 2.55.0