From 716701e63cccbd0123f0515a0ff9dea50f59efab Mon Sep 17 00:00:00 2001
From: Danswar <48102227+Danswar@users.noreply.github.com>
Date: Wed, 10 Jun 2026 12:35:41 -0300
Subject: [PATCH] feat(config): load LND TLS cert from file with env fallback
(#200)
* feat(config): load LND TLS cert from file with env fallback
Add support for an optional LIGHTNING_API_CERTIFICATE_PATH env var. When
set and readable, the LND TLS certificate is read from that file on disk
(the live cert), avoiding the recurring 'self-signed certificate' errors
that occur when the hand-copied LIGHTNING_API_CERTIFICATE env var drifts
after LND regenerates its cert.
Fully backward compatible: if the path is unset or unreadable, falls back
to the existing LIGHTNING_API_CERTIFICATE env-var behavior unchanged.
* Use named readFileSync import in config to match repo convention
The rest of the repo imports { readFileSync } from 'fs' (app.controller,
monitoring.controller); align readCert with that instead of import * as fs.
* Read LND cert from file only, drop env-var fallback
Address review: if LIGHTNING_API_CERTIFICATE_PATH is set, read it or throw.
The LIGHTNING_API_CERTIFICATE env var was the stale copy this change fixes,
so keeping it as a silent fallback only masks a broken mount. Remove it.
---
src/config/config.ts | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/src/config/config.ts b/src/config/config.ts
index f8626ed30..dac6f892d 100644
--- a/src/config/config.ts
+++ b/src/config/config.ts
@@ -1,5 +1,6 @@
import { Injectable, Optional } from '@nestjs/common';
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
+import { readFileSync } from 'fs';
export enum Process {
SYNC_ONCHAIN_TRANSACTIONS = 'SyncOnchainTransactions',
@@ -22,6 +23,17 @@ export function GetConfig(): Configuration {
return new Configuration();
}
+// Reads the live LND TLS certificate from the file pointed to by LIGHTNING_API_CERTIFICATE_PATH.
+// If the path is unset, returns undefined (environments without Lightning, e.g. tests, still boot).
+// If the path is set but the file is missing/unreadable, readFileSync throws so a broken mount
+// surfaces immediately instead of being masked by a stale fallback.
+function readCert(): string | undefined {
+ const path = process.env.LIGHTNING_API_CERTIFICATE_PATH;
+ if (!path) return undefined;
+
+ return readFileSync(path, 'utf8');
+}
+
export class Configuration {
port = process.env.PORT ?? 3000;
environment: Environment = process.env.ENVIRONMENT as Environment;
@@ -117,7 +129,7 @@ export class Configuration {
wsInvoicesUrl: process.env.LIGHTNING_LND_WS_INVOICES_URL ?? '',
wsPaymentsUrl: process.env.LIGHTNING_LND_WS_PAYMENTS_URL ?? '',
},
- certificate: process.env.LIGHTNING_API_CERTIFICATE?.split('
').join('\n'),
+ certificate: readCert(),
lnbitsapi: {
apiUrl: process.env.LIGHTNING_LNBITSAPI_API_URL ?? '',
certificate: process.env.LIGHTNING_LNBITSAPI_CERTIFICATE?.split('
').join('\n') ?? '',