@ambosstech/lightning-mpp-adapter-lnd 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,298 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ LndLightningProvider: () => LndLightningProvider,
34
+ createGrpcTransport: () => createGrpcTransport,
35
+ createRestTransport: () => createRestTransport,
36
+ mapLndError: () => mapLndError
37
+ });
38
+ module.exports = __toCommonJS(index_exports);
39
+
40
+ // ../../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.8_typescript@5.7.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js
41
+ var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
42
+ var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
43
+
44
+ // src/grpc-client.ts
45
+ var grpc = __toESM(require("@grpc/grpc-js"), 1);
46
+ var protoLoader = __toESM(require("@grpc/proto-loader"), 1);
47
+ var import_node_url = require("url");
48
+ var import_node_path = require("path");
49
+ var __dirname = (0, import_node_path.dirname)((0, import_node_url.fileURLToPath)(importMetaUrl));
50
+ var PROTO_PATH = (0, import_node_path.join)(__dirname, "..", "proto", "lightning.proto");
51
+ function createGrpcTransport(config) {
52
+ const tlsCert = typeof config.tlsCert === "string" ? Buffer.from(config.tlsCert, "utf-8") : config.tlsCert;
53
+ const macaroonHex = typeof config.macaroon === "string" ? config.macaroon : config.macaroon.toString("hex");
54
+ const sslCreds = grpc.credentials.createSsl(tlsCert);
55
+ const macaroonCreds = grpc.credentials.createFromMetadataGenerator(
56
+ (_params, callback) => {
57
+ const metadata = new grpc.Metadata();
58
+ metadata.add("macaroon", macaroonHex);
59
+ callback(null, metadata);
60
+ }
61
+ );
62
+ const combinedCreds = grpc.credentials.combineChannelCredentials(
63
+ sslCreds,
64
+ macaroonCreds
65
+ );
66
+ const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
67
+ keepCase: true,
68
+ longs: String,
69
+ enums: String,
70
+ defaults: true,
71
+ oneofs: true
72
+ });
73
+ const lnrpc = grpc.loadPackageDefinition(packageDefinition).lnrpc;
74
+ const client = new lnrpc.Lightning(config.host, combinedCreds);
75
+ function promisify(method) {
76
+ return (req) => new Promise((resolve, reject) => {
77
+ method.call(client, req, (err, res) => {
78
+ if (err) reject(err);
79
+ else resolve(res);
80
+ });
81
+ });
82
+ }
83
+ const grpcAddInvoice = promisify(client.addInvoice);
84
+ const grpcSendPaymentSync = promisify(client.sendPaymentSync);
85
+ const grpcLookupInvoice = promisify(client.lookupInvoice);
86
+ return {
87
+ async addInvoice(params) {
88
+ const res = await grpcAddInvoice(params);
89
+ return {
90
+ r_hash: Buffer.from(res.r_hash).toString("hex"),
91
+ payment_request: res.payment_request
92
+ };
93
+ },
94
+ async sendPaymentSync(params) {
95
+ const res = await grpcSendPaymentSync(params);
96
+ return {
97
+ payment_preimage: Buffer.from(res.payment_preimage).toString("hex"),
98
+ payment_error: res.payment_error,
99
+ payment_hash: Buffer.from(res.payment_hash).toString("hex")
100
+ };
101
+ },
102
+ async lookupInvoice(params) {
103
+ const res = await grpcLookupInvoice(params);
104
+ return {
105
+ state: res.state,
106
+ r_preimage: Buffer.from(res.r_preimage).toString("hex"),
107
+ value: res.value
108
+ };
109
+ },
110
+ close() {
111
+ client.close();
112
+ }
113
+ };
114
+ }
115
+
116
+ // src/rest-client.ts
117
+ var import_lightning_mpp_sdk = require("@ambosstech/lightning-mpp-sdk");
118
+ function createRestTransport(config) {
119
+ const baseUrl = config.url.replace(/\/$/, "");
120
+ const macaroonHex = typeof config.macaroon === "string" ? config.macaroon : config.macaroon.toString("hex");
121
+ const fetchFn = config.fetch ?? globalThis.fetch;
122
+ async function request(path, options = {}) {
123
+ const url = `${baseUrl}${path}`;
124
+ let response;
125
+ try {
126
+ response = await fetchFn(url, {
127
+ ...options,
128
+ headers: {
129
+ "Grpc-Metadata-macaroon": macaroonHex,
130
+ "Content-Type": "application/json",
131
+ ...options.headers
132
+ }
133
+ });
134
+ } catch (error) {
135
+ throw new import_lightning_mpp_sdk.ConnectionError(`LND REST request failed: ${url}`, {
136
+ cause: error
137
+ });
138
+ }
139
+ const body = await response.json();
140
+ if (!response.ok) {
141
+ const err = new Error(
142
+ body.message ?? body.error ?? `HTTP ${response.status}`
143
+ );
144
+ err.code = body.code;
145
+ err.details = body.message ?? body.error;
146
+ throw err;
147
+ }
148
+ return body;
149
+ }
150
+ return {
151
+ async addInvoice(params) {
152
+ const body = { value: String(params.value) };
153
+ if (params.memo) body.memo = params.memo;
154
+ if (params.expiry) body.expiry = String(params.expiry);
155
+ const res = await request(
156
+ "/v1/invoices",
157
+ { method: "POST", body: JSON.stringify(body) }
158
+ );
159
+ return {
160
+ r_hash: (0, import_lightning_mpp_sdk.base64ToHex)(res.r_hash),
161
+ payment_request: res.payment_request
162
+ };
163
+ },
164
+ async sendPaymentSync(params) {
165
+ const body = { payment_request: params.payment_request };
166
+ if (params.amt !== void 0) {
167
+ body.amt = String(params.amt);
168
+ }
169
+ if (params.fee_limit) {
170
+ body.fee_limit = { fixed: String(params.fee_limit.fixed) };
171
+ }
172
+ const res = await request("/v1/channels/transactions", {
173
+ method: "POST",
174
+ body: JSON.stringify(body)
175
+ });
176
+ return {
177
+ payment_preimage: res.payment_preimage ? (0, import_lightning_mpp_sdk.base64ToHex)(res.payment_preimage) : "",
178
+ payment_error: res.payment_error ?? "",
179
+ payment_hash: res.payment_hash ? (0, import_lightning_mpp_sdk.base64ToHex)(res.payment_hash) : ""
180
+ };
181
+ },
182
+ async lookupInvoice(params) {
183
+ const hashUrl = (0, import_lightning_mpp_sdk.hexToBase64Url)(params.r_hash_str);
184
+ const res = await request(`/v1/invoice/${hashUrl}`);
185
+ return {
186
+ state: res.state,
187
+ r_preimage: res.r_preimage ? (0, import_lightning_mpp_sdk.base64ToHex)(res.r_preimage) : "",
188
+ value: res.value ?? "0"
189
+ };
190
+ },
191
+ close() {
192
+ }
193
+ };
194
+ }
195
+
196
+ // src/error-mapper.ts
197
+ var import_lightning_mpp_sdk2 = require("@ambosstech/lightning-mpp-sdk");
198
+ var UNAVAILABLE = 14;
199
+ var UNAUTHENTICATED = 16;
200
+ var DEADLINE_EXCEEDED = 4;
201
+ function mapLndError(error) {
202
+ const grpcError = error;
203
+ const code = grpcError.code;
204
+ const details = (grpcError.details ?? grpcError.message ?? "").toLowerCase();
205
+ if (code === UNAUTHENTICATED) {
206
+ return new import_lightning_mpp_sdk2.AuthenticationError("LND authentication failed", {
207
+ cause: error
208
+ });
209
+ }
210
+ if (code === UNAVAILABLE) {
211
+ return new import_lightning_mpp_sdk2.ConnectionError("LND node unavailable", { cause: error });
212
+ }
213
+ if (code === DEADLINE_EXCEEDED) {
214
+ return new import_lightning_mpp_sdk2.PaymentTimeoutError("LND request timed out", { cause: error });
215
+ }
216
+ if (details.includes("invoice expired") || details.includes("invoice is expired")) {
217
+ return new import_lightning_mpp_sdk2.InvoiceExpiredError("Invoice has expired", { cause: error });
218
+ }
219
+ if (details.includes("unable to find a path") || details.includes("no route") || details.includes("insufficient capacity")) {
220
+ return new import_lightning_mpp_sdk2.RouteNotFoundError("No route found", { cause: error });
221
+ }
222
+ if (details.includes("insufficient balance") || details.includes("not enough balance") || details.includes("insufficient funds")) {
223
+ return new import_lightning_mpp_sdk2.InsufficientBalanceError("Insufficient balance", {
224
+ cause: error
225
+ });
226
+ }
227
+ return new import_lightning_mpp_sdk2.ConnectionError(
228
+ `LND error: ${grpcError.details ?? grpcError.message ?? "unknown"}`,
229
+ { cause: error }
230
+ );
231
+ }
232
+
233
+ // src/lnd-provider.ts
234
+ var LndLightningProvider = class {
235
+ transport;
236
+ constructor(config) {
237
+ this.transport = config.transport === "rest" ? createRestTransport(config) : createGrpcTransport(config);
238
+ }
239
+ async createInvoice(params) {
240
+ try {
241
+ const response = await this.transport.addInvoice({
242
+ value: params.amountSats,
243
+ memo: params.memo,
244
+ expiry: params.expirySecs
245
+ });
246
+ return {
247
+ bolt11: response.payment_request,
248
+ paymentHash: response.r_hash
249
+ };
250
+ } catch (error) {
251
+ throw mapLndError(error);
252
+ }
253
+ }
254
+ async payInvoice(params) {
255
+ try {
256
+ const request = { payment_request: params.bolt11 };
257
+ if (params.amountSats !== void 0) {
258
+ request.amt = params.amountSats;
259
+ }
260
+ if (params.maxFeeSats !== void 0) {
261
+ request.fee_limit = { fixed: params.maxFeeSats };
262
+ }
263
+ const response = await this.transport.sendPaymentSync(request);
264
+ if (response.payment_error) {
265
+ throw new Error(response.payment_error);
266
+ }
267
+ return { preimage: response.payment_preimage };
268
+ } catch (error) {
269
+ throw mapLndError(error);
270
+ }
271
+ }
272
+ async lookupInvoice(params) {
273
+ try {
274
+ const response = await this.transport.lookupInvoice({
275
+ r_hash_str: params.paymentHash
276
+ });
277
+ const settled = response.state === "SETTLED";
278
+ return {
279
+ settled,
280
+ preimage: settled ? response.r_preimage : void 0,
281
+ amountSats: response.value ? Number(response.value) : void 0
282
+ };
283
+ } catch (error) {
284
+ throw mapLndError(error);
285
+ }
286
+ }
287
+ close() {
288
+ this.transport.close();
289
+ }
290
+ };
291
+ // Annotate the CommonJS export names for ESM import in node:
292
+ 0 && (module.exports = {
293
+ LndLightningProvider,
294
+ createGrpcTransport,
295
+ createRestTransport,
296
+ mapLndError
297
+ });
298
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../../../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.8_typescript@5.7.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js","../src/grpc-client.ts","../src/rest-client.ts","../src/error-mapper.ts","../src/lnd-provider.ts"],"sourcesContent":["export { LndLightningProvider } from \"./lnd-provider.js\";\nexport { createGrpcTransport } from \"./grpc-client.js\";\nexport { createRestTransport } from \"./rest-client.js\";\nexport { mapLndError } from \"./error-mapper.js\";\nexport type {\n LndConfig,\n LndGrpcConfig,\n LndRestConfig,\n LndTransport,\n} from \"./types.js\";\n","// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","import * as grpc from \"@grpc/grpc-js\";\nimport * as protoLoader from \"@grpc/proto-loader\";\nimport { fileURLToPath } from \"node:url\";\nimport { dirname, join } from \"node:path\";\nimport type { LndGrpcConfig, LndTransport } from \"./types.js\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nconst PROTO_PATH = join(__dirname, \"..\", \"proto\", \"lightning.proto\");\n\nexport function createGrpcTransport(config: LndGrpcConfig): LndTransport {\n const tlsCert =\n typeof config.tlsCert === \"string\"\n ? Buffer.from(config.tlsCert, \"utf-8\")\n : config.tlsCert;\n\n const macaroonHex =\n typeof config.macaroon === \"string\"\n ? config.macaroon\n : config.macaroon.toString(\"hex\");\n\n const sslCreds = grpc.credentials.createSsl(tlsCert);\n\n const macaroonCreds = grpc.credentials.createFromMetadataGenerator(\n (_params, callback) => {\n const metadata = new grpc.Metadata();\n metadata.add(\"macaroon\", macaroonHex);\n callback(null, metadata);\n },\n );\n\n const combinedCreds = grpc.credentials.combineChannelCredentials(\n sslCreds,\n macaroonCreds,\n );\n\n const packageDefinition = protoLoader.loadSync(PROTO_PATH, {\n keepCase: true,\n longs: String,\n enums: String,\n defaults: true,\n oneofs: true,\n });\n\n const lnrpc = grpc.loadPackageDefinition(packageDefinition).lnrpc as any;\n const client = new lnrpc.Lightning(config.host, combinedCreds);\n\n function promisify<TReq, TRes>(\n method: (req: TReq, cb: (err: any, res: TRes) => void) => void,\n ): (req: TReq) => Promise<TRes> {\n return (req: TReq) =>\n new Promise((resolve, reject) => {\n method.call(client, req, (err: any, res: TRes) => {\n if (err) reject(err);\n else resolve(res);\n });\n });\n }\n\n const grpcAddInvoice = promisify(client.addInvoice);\n const grpcSendPaymentSync = promisify(client.sendPaymentSync);\n const grpcLookupInvoice = promisify(client.lookupInvoice);\n\n return {\n async addInvoice(params) {\n const res: any = await grpcAddInvoice(params);\n return {\n r_hash: Buffer.from(res.r_hash).toString(\"hex\"),\n payment_request: res.payment_request,\n };\n },\n async sendPaymentSync(params) {\n const res: any = await grpcSendPaymentSync(params);\n return {\n payment_preimage: Buffer.from(res.payment_preimage).toString(\"hex\"),\n payment_error: res.payment_error,\n payment_hash: Buffer.from(res.payment_hash).toString(\"hex\"),\n };\n },\n async lookupInvoice(params) {\n const res: any = await grpcLookupInvoice(params);\n return {\n state: res.state,\n r_preimage: Buffer.from(res.r_preimage).toString(\"hex\"),\n value: res.value,\n };\n },\n close() {\n client.close();\n },\n };\n}\n","import {\n ConnectionError,\n base64ToHex,\n hexToBase64Url,\n} from \"@ambosstech/lightning-mpp-sdk\";\nimport type { LndRestConfig, LndTransport } from \"./types.js\";\n\nexport function createRestTransport(config: LndRestConfig): LndTransport {\n const baseUrl = config.url.replace(/\\/$/, \"\");\n\n const macaroonHex =\n typeof config.macaroon === \"string\"\n ? config.macaroon\n : config.macaroon.toString(\"hex\");\n\n const fetchFn = config.fetch ?? globalThis.fetch;\n\n async function request<T>(\n path: string,\n options: RequestInit = {},\n ): Promise<T> {\n const url = `${baseUrl}${path}`;\n let response: Response;\n try {\n response = await fetchFn(url, {\n ...options,\n headers: {\n \"Grpc-Metadata-macaroon\": macaroonHex,\n \"Content-Type\": \"application/json\",\n ...options.headers,\n },\n });\n } catch (error) {\n throw new ConnectionError(`LND REST request failed: ${url}`, {\n cause: error,\n });\n }\n\n const body = (await response.json()) as any;\n if (!response.ok) {\n const err: any = new Error(\n body.message ?? body.error ?? `HTTP ${response.status}`,\n );\n err.code = body.code;\n err.details = body.message ?? body.error;\n throw err;\n }\n return body as T;\n }\n\n return {\n async addInvoice(params) {\n const body: any = { value: String(params.value) };\n if (params.memo) body.memo = params.memo;\n if (params.expiry) body.expiry = String(params.expiry);\n\n const res = await request<{ r_hash: string; payment_request: string }>(\n \"/v1/invoices\",\n { method: \"POST\", body: JSON.stringify(body) },\n );\n\n return {\n r_hash: base64ToHex(res.r_hash),\n payment_request: res.payment_request,\n };\n },\n\n async sendPaymentSync(params) {\n const body: any = { payment_request: params.payment_request };\n if (params.amt !== undefined) {\n body.amt = String(params.amt);\n }\n if (params.fee_limit) {\n body.fee_limit = { fixed: String(params.fee_limit.fixed) };\n }\n\n const res = await request<{\n payment_preimage: string;\n payment_error: string;\n payment_hash: string;\n }>(\"/v1/channels/transactions\", {\n method: \"POST\",\n body: JSON.stringify(body),\n });\n\n return {\n payment_preimage: res.payment_preimage\n ? base64ToHex(res.payment_preimage)\n : \"\",\n payment_error: res.payment_error ?? \"\",\n payment_hash: res.payment_hash ? base64ToHex(res.payment_hash) : \"\",\n };\n },\n\n async lookupInvoice(params) {\n const hashUrl = hexToBase64Url(params.r_hash_str);\n const res = await request<{\n state: string;\n r_preimage: string;\n value: string;\n }>(`/v1/invoice/${hashUrl}`);\n\n return {\n state: res.state,\n r_preimage: res.r_preimage ? base64ToHex(res.r_preimage) : \"\",\n value: res.value ?? \"0\",\n };\n },\n\n close() {\n // no-op for REST\n },\n };\n}\n","import {\n AuthenticationError,\n ConnectionError,\n InsufficientBalanceError,\n InvoiceExpiredError,\n type LightningError,\n PaymentTimeoutError,\n RouteNotFoundError,\n} from \"@ambosstech/lightning-mpp-sdk\";\n\ninterface GrpcError {\n code?: number;\n details?: string;\n message?: string;\n}\n\n// gRPC status codes\nconst UNAVAILABLE = 14;\nconst UNAUTHENTICATED = 16;\nconst DEADLINE_EXCEEDED = 4;\n\nexport function mapLndError(error: unknown): LightningError {\n const grpcError = error as GrpcError;\n const code = grpcError.code;\n const details = (grpcError.details ?? grpcError.message ?? \"\").toLowerCase();\n\n if (code === UNAUTHENTICATED) {\n return new AuthenticationError(\"LND authentication failed\", {\n cause: error,\n });\n }\n\n if (code === UNAVAILABLE) {\n return new ConnectionError(\"LND node unavailable\", { cause: error });\n }\n\n if (code === DEADLINE_EXCEEDED) {\n return new PaymentTimeoutError(\"LND request timed out\", { cause: error });\n }\n\n if (\n details.includes(\"invoice expired\") ||\n details.includes(\"invoice is expired\")\n ) {\n return new InvoiceExpiredError(\"Invoice has expired\", { cause: error });\n }\n\n if (\n details.includes(\"unable to find a path\") ||\n details.includes(\"no route\") ||\n details.includes(\"insufficient capacity\")\n ) {\n return new RouteNotFoundError(\"No route found\", { cause: error });\n }\n\n if (\n details.includes(\"insufficient balance\") ||\n details.includes(\"not enough balance\") ||\n details.includes(\"insufficient funds\")\n ) {\n return new InsufficientBalanceError(\"Insufficient balance\", {\n cause: error,\n });\n }\n\n // Fallback\n return new ConnectionError(\n `LND error: ${grpcError.details ?? grpcError.message ?? \"unknown\"}`,\n { cause: error },\n );\n}\n","import type {\n CreateInvoiceParams,\n CreateInvoiceResult,\n LightningProvider,\n LookupInvoiceParams,\n LookupInvoiceResult,\n PayInvoiceParams,\n PayInvoiceResult,\n} from \"@ambosstech/lightning-mpp-sdk\";\nimport { createGrpcTransport } from \"./grpc-client.js\";\nimport { createRestTransport } from \"./rest-client.js\";\nimport { mapLndError } from \"./error-mapper.js\";\nimport type { LndConfig, LndTransport } from \"./types.js\";\n\nexport class LndLightningProvider implements LightningProvider {\n private transport: LndTransport;\n\n constructor(config: LndConfig) {\n this.transport =\n config.transport === \"rest\"\n ? createRestTransport(config)\n : createGrpcTransport(config);\n }\n\n async createInvoice(\n params: CreateInvoiceParams,\n ): Promise<CreateInvoiceResult> {\n try {\n const response = await this.transport.addInvoice({\n value: params.amountSats,\n memo: params.memo,\n expiry: params.expirySecs,\n });\n\n return {\n bolt11: response.payment_request,\n paymentHash: response.r_hash,\n };\n } catch (error) {\n throw mapLndError(error);\n }\n }\n\n async payInvoice(params: PayInvoiceParams): Promise<PayInvoiceResult> {\n try {\n const request: any = { payment_request: params.bolt11 };\n if (params.amountSats !== undefined) {\n request.amt = params.amountSats;\n }\n if (params.maxFeeSats !== undefined) {\n request.fee_limit = { fixed: params.maxFeeSats };\n }\n\n const response = await this.transport.sendPaymentSync(request);\n\n if (response.payment_error) {\n throw new Error(response.payment_error);\n }\n\n return { preimage: response.payment_preimage };\n } catch (error) {\n throw mapLndError(error);\n }\n }\n\n async lookupInvoice(\n params: LookupInvoiceParams,\n ): Promise<LookupInvoiceResult> {\n try {\n const response = await this.transport.lookupInvoice({\n r_hash_str: params.paymentHash,\n });\n\n const settled = response.state === \"SETTLED\";\n return {\n settled,\n preimage: settled ? response.r_preimage : undefined,\n amountSats: response.value ? Number(response.value) : undefined,\n };\n } catch (error) {\n throw mapLndError(error);\n }\n }\n\n close(): void {\n this.transport.close();\n }\n}\n"],"mappings":"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","names":["import_lightning_mpp_sdk"]}
@@ -0,0 +1,68 @@
1
+ import { LightningProvider, CreateInvoiceParams, CreateInvoiceResult, PayInvoiceParams, PayInvoiceResult, LookupInvoiceParams, LookupInvoiceResult, LightningError } from '@ambosstech/lightning-mpp-sdk';
2
+
3
+ interface LndGrpcConfig {
4
+ transport: "grpc";
5
+ /** LND gRPC host:port, e.g. "127.0.0.1:10009" */
6
+ host: string;
7
+ /** TLS certificate as PEM string or raw bytes */
8
+ tlsCert: string | Buffer;
9
+ /** Admin macaroon as hex string or raw bytes */
10
+ macaroon: string | Buffer;
11
+ }
12
+ interface LndRestConfig {
13
+ transport: "rest";
14
+ /** LND REST URL, e.g. "https://127.0.0.1:8080" */
15
+ url: string;
16
+ /** Admin macaroon as hex string or raw bytes */
17
+ macaroon: string | Buffer;
18
+ /** Optional: custom fetch for environments that need TLS cert handling */
19
+ fetch?: typeof globalThis.fetch;
20
+ }
21
+ type LndConfig = LndGrpcConfig | LndRestConfig;
22
+ /** Internal transport interface shared by gRPC and REST clients */
23
+ interface LndTransport {
24
+ addInvoice(params: {
25
+ value: number;
26
+ memo?: string;
27
+ expiry?: number;
28
+ }): Promise<{
29
+ r_hash: string;
30
+ payment_request: string;
31
+ }>;
32
+ sendPaymentSync(params: {
33
+ payment_request: string;
34
+ amt?: number;
35
+ fee_limit?: {
36
+ fixed: number;
37
+ };
38
+ }): Promise<{
39
+ payment_preimage: string;
40
+ payment_error: string;
41
+ payment_hash: string;
42
+ }>;
43
+ lookupInvoice(params: {
44
+ r_hash_str: string;
45
+ }): Promise<{
46
+ state: string;
47
+ r_preimage: string;
48
+ value: string;
49
+ }>;
50
+ close(): void;
51
+ }
52
+
53
+ declare class LndLightningProvider implements LightningProvider {
54
+ private transport;
55
+ constructor(config: LndConfig);
56
+ createInvoice(params: CreateInvoiceParams): Promise<CreateInvoiceResult>;
57
+ payInvoice(params: PayInvoiceParams): Promise<PayInvoiceResult>;
58
+ lookupInvoice(params: LookupInvoiceParams): Promise<LookupInvoiceResult>;
59
+ close(): void;
60
+ }
61
+
62
+ declare function createGrpcTransport(config: LndGrpcConfig): LndTransport;
63
+
64
+ declare function createRestTransport(config: LndRestConfig): LndTransport;
65
+
66
+ declare function mapLndError(error: unknown): LightningError;
67
+
68
+ export { type LndConfig, type LndGrpcConfig, LndLightningProvider, type LndRestConfig, type LndTransport, createGrpcTransport, createRestTransport, mapLndError };
@@ -0,0 +1,68 @@
1
+ import { LightningProvider, CreateInvoiceParams, CreateInvoiceResult, PayInvoiceParams, PayInvoiceResult, LookupInvoiceParams, LookupInvoiceResult, LightningError } from '@ambosstech/lightning-mpp-sdk';
2
+
3
+ interface LndGrpcConfig {
4
+ transport: "grpc";
5
+ /** LND gRPC host:port, e.g. "127.0.0.1:10009" */
6
+ host: string;
7
+ /** TLS certificate as PEM string or raw bytes */
8
+ tlsCert: string | Buffer;
9
+ /** Admin macaroon as hex string or raw bytes */
10
+ macaroon: string | Buffer;
11
+ }
12
+ interface LndRestConfig {
13
+ transport: "rest";
14
+ /** LND REST URL, e.g. "https://127.0.0.1:8080" */
15
+ url: string;
16
+ /** Admin macaroon as hex string or raw bytes */
17
+ macaroon: string | Buffer;
18
+ /** Optional: custom fetch for environments that need TLS cert handling */
19
+ fetch?: typeof globalThis.fetch;
20
+ }
21
+ type LndConfig = LndGrpcConfig | LndRestConfig;
22
+ /** Internal transport interface shared by gRPC and REST clients */
23
+ interface LndTransport {
24
+ addInvoice(params: {
25
+ value: number;
26
+ memo?: string;
27
+ expiry?: number;
28
+ }): Promise<{
29
+ r_hash: string;
30
+ payment_request: string;
31
+ }>;
32
+ sendPaymentSync(params: {
33
+ payment_request: string;
34
+ amt?: number;
35
+ fee_limit?: {
36
+ fixed: number;
37
+ };
38
+ }): Promise<{
39
+ payment_preimage: string;
40
+ payment_error: string;
41
+ payment_hash: string;
42
+ }>;
43
+ lookupInvoice(params: {
44
+ r_hash_str: string;
45
+ }): Promise<{
46
+ state: string;
47
+ r_preimage: string;
48
+ value: string;
49
+ }>;
50
+ close(): void;
51
+ }
52
+
53
+ declare class LndLightningProvider implements LightningProvider {
54
+ private transport;
55
+ constructor(config: LndConfig);
56
+ createInvoice(params: CreateInvoiceParams): Promise<CreateInvoiceResult>;
57
+ payInvoice(params: PayInvoiceParams): Promise<PayInvoiceResult>;
58
+ lookupInvoice(params: LookupInvoiceParams): Promise<LookupInvoiceResult>;
59
+ close(): void;
60
+ }
61
+
62
+ declare function createGrpcTransport(config: LndGrpcConfig): LndTransport;
63
+
64
+ declare function createRestTransport(config: LndRestConfig): LndTransport;
65
+
66
+ declare function mapLndError(error: unknown): LightningError;
67
+
68
+ export { type LndConfig, type LndGrpcConfig, LndLightningProvider, type LndRestConfig, type LndTransport, createGrpcTransport, createRestTransport, mapLndError };
package/dist/index.js ADDED
@@ -0,0 +1,265 @@
1
+ // src/grpc-client.ts
2
+ import * as grpc from "@grpc/grpc-js";
3
+ import * as protoLoader from "@grpc/proto-loader";
4
+ import { fileURLToPath } from "url";
5
+ import { dirname, join } from "path";
6
+ var __dirname = dirname(fileURLToPath(import.meta.url));
7
+ var PROTO_PATH = join(__dirname, "..", "proto", "lightning.proto");
8
+ function createGrpcTransport(config) {
9
+ const tlsCert = typeof config.tlsCert === "string" ? Buffer.from(config.tlsCert, "utf-8") : config.tlsCert;
10
+ const macaroonHex = typeof config.macaroon === "string" ? config.macaroon : config.macaroon.toString("hex");
11
+ const sslCreds = grpc.credentials.createSsl(tlsCert);
12
+ const macaroonCreds = grpc.credentials.createFromMetadataGenerator(
13
+ (_params, callback) => {
14
+ const metadata = new grpc.Metadata();
15
+ metadata.add("macaroon", macaroonHex);
16
+ callback(null, metadata);
17
+ }
18
+ );
19
+ const combinedCreds = grpc.credentials.combineChannelCredentials(
20
+ sslCreds,
21
+ macaroonCreds
22
+ );
23
+ const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
24
+ keepCase: true,
25
+ longs: String,
26
+ enums: String,
27
+ defaults: true,
28
+ oneofs: true
29
+ });
30
+ const lnrpc = grpc.loadPackageDefinition(packageDefinition).lnrpc;
31
+ const client = new lnrpc.Lightning(config.host, combinedCreds);
32
+ function promisify(method) {
33
+ return (req) => new Promise((resolve, reject) => {
34
+ method.call(client, req, (err, res) => {
35
+ if (err) reject(err);
36
+ else resolve(res);
37
+ });
38
+ });
39
+ }
40
+ const grpcAddInvoice = promisify(client.addInvoice);
41
+ const grpcSendPaymentSync = promisify(client.sendPaymentSync);
42
+ const grpcLookupInvoice = promisify(client.lookupInvoice);
43
+ return {
44
+ async addInvoice(params) {
45
+ const res = await grpcAddInvoice(params);
46
+ return {
47
+ r_hash: Buffer.from(res.r_hash).toString("hex"),
48
+ payment_request: res.payment_request
49
+ };
50
+ },
51
+ async sendPaymentSync(params) {
52
+ const res = await grpcSendPaymentSync(params);
53
+ return {
54
+ payment_preimage: Buffer.from(res.payment_preimage).toString("hex"),
55
+ payment_error: res.payment_error,
56
+ payment_hash: Buffer.from(res.payment_hash).toString("hex")
57
+ };
58
+ },
59
+ async lookupInvoice(params) {
60
+ const res = await grpcLookupInvoice(params);
61
+ return {
62
+ state: res.state,
63
+ r_preimage: Buffer.from(res.r_preimage).toString("hex"),
64
+ value: res.value
65
+ };
66
+ },
67
+ close() {
68
+ client.close();
69
+ }
70
+ };
71
+ }
72
+
73
+ // src/rest-client.ts
74
+ import {
75
+ ConnectionError,
76
+ base64ToHex,
77
+ hexToBase64Url
78
+ } from "@ambosstech/lightning-mpp-sdk";
79
+ function createRestTransport(config) {
80
+ const baseUrl = config.url.replace(/\/$/, "");
81
+ const macaroonHex = typeof config.macaroon === "string" ? config.macaroon : config.macaroon.toString("hex");
82
+ const fetchFn = config.fetch ?? globalThis.fetch;
83
+ async function request(path, options = {}) {
84
+ const url = `${baseUrl}${path}`;
85
+ let response;
86
+ try {
87
+ response = await fetchFn(url, {
88
+ ...options,
89
+ headers: {
90
+ "Grpc-Metadata-macaroon": macaroonHex,
91
+ "Content-Type": "application/json",
92
+ ...options.headers
93
+ }
94
+ });
95
+ } catch (error) {
96
+ throw new ConnectionError(`LND REST request failed: ${url}`, {
97
+ cause: error
98
+ });
99
+ }
100
+ const body = await response.json();
101
+ if (!response.ok) {
102
+ const err = new Error(
103
+ body.message ?? body.error ?? `HTTP ${response.status}`
104
+ );
105
+ err.code = body.code;
106
+ err.details = body.message ?? body.error;
107
+ throw err;
108
+ }
109
+ return body;
110
+ }
111
+ return {
112
+ async addInvoice(params) {
113
+ const body = { value: String(params.value) };
114
+ if (params.memo) body.memo = params.memo;
115
+ if (params.expiry) body.expiry = String(params.expiry);
116
+ const res = await request(
117
+ "/v1/invoices",
118
+ { method: "POST", body: JSON.stringify(body) }
119
+ );
120
+ return {
121
+ r_hash: base64ToHex(res.r_hash),
122
+ payment_request: res.payment_request
123
+ };
124
+ },
125
+ async sendPaymentSync(params) {
126
+ const body = { payment_request: params.payment_request };
127
+ if (params.amt !== void 0) {
128
+ body.amt = String(params.amt);
129
+ }
130
+ if (params.fee_limit) {
131
+ body.fee_limit = { fixed: String(params.fee_limit.fixed) };
132
+ }
133
+ const res = await request("/v1/channels/transactions", {
134
+ method: "POST",
135
+ body: JSON.stringify(body)
136
+ });
137
+ return {
138
+ payment_preimage: res.payment_preimage ? base64ToHex(res.payment_preimage) : "",
139
+ payment_error: res.payment_error ?? "",
140
+ payment_hash: res.payment_hash ? base64ToHex(res.payment_hash) : ""
141
+ };
142
+ },
143
+ async lookupInvoice(params) {
144
+ const hashUrl = hexToBase64Url(params.r_hash_str);
145
+ const res = await request(`/v1/invoice/${hashUrl}`);
146
+ return {
147
+ state: res.state,
148
+ r_preimage: res.r_preimage ? base64ToHex(res.r_preimage) : "",
149
+ value: res.value ?? "0"
150
+ };
151
+ },
152
+ close() {
153
+ }
154
+ };
155
+ }
156
+
157
+ // src/error-mapper.ts
158
+ import {
159
+ AuthenticationError,
160
+ ConnectionError as ConnectionError2,
161
+ InsufficientBalanceError,
162
+ InvoiceExpiredError,
163
+ PaymentTimeoutError,
164
+ RouteNotFoundError
165
+ } from "@ambosstech/lightning-mpp-sdk";
166
+ var UNAVAILABLE = 14;
167
+ var UNAUTHENTICATED = 16;
168
+ var DEADLINE_EXCEEDED = 4;
169
+ function mapLndError(error) {
170
+ const grpcError = error;
171
+ const code = grpcError.code;
172
+ const details = (grpcError.details ?? grpcError.message ?? "").toLowerCase();
173
+ if (code === UNAUTHENTICATED) {
174
+ return new AuthenticationError("LND authentication failed", {
175
+ cause: error
176
+ });
177
+ }
178
+ if (code === UNAVAILABLE) {
179
+ return new ConnectionError2("LND node unavailable", { cause: error });
180
+ }
181
+ if (code === DEADLINE_EXCEEDED) {
182
+ return new PaymentTimeoutError("LND request timed out", { cause: error });
183
+ }
184
+ if (details.includes("invoice expired") || details.includes("invoice is expired")) {
185
+ return new InvoiceExpiredError("Invoice has expired", { cause: error });
186
+ }
187
+ if (details.includes("unable to find a path") || details.includes("no route") || details.includes("insufficient capacity")) {
188
+ return new RouteNotFoundError("No route found", { cause: error });
189
+ }
190
+ if (details.includes("insufficient balance") || details.includes("not enough balance") || details.includes("insufficient funds")) {
191
+ return new InsufficientBalanceError("Insufficient balance", {
192
+ cause: error
193
+ });
194
+ }
195
+ return new ConnectionError2(
196
+ `LND error: ${grpcError.details ?? grpcError.message ?? "unknown"}`,
197
+ { cause: error }
198
+ );
199
+ }
200
+
201
+ // src/lnd-provider.ts
202
+ var LndLightningProvider = class {
203
+ transport;
204
+ constructor(config) {
205
+ this.transport = config.transport === "rest" ? createRestTransport(config) : createGrpcTransport(config);
206
+ }
207
+ async createInvoice(params) {
208
+ try {
209
+ const response = await this.transport.addInvoice({
210
+ value: params.amountSats,
211
+ memo: params.memo,
212
+ expiry: params.expirySecs
213
+ });
214
+ return {
215
+ bolt11: response.payment_request,
216
+ paymentHash: response.r_hash
217
+ };
218
+ } catch (error) {
219
+ throw mapLndError(error);
220
+ }
221
+ }
222
+ async payInvoice(params) {
223
+ try {
224
+ const request = { payment_request: params.bolt11 };
225
+ if (params.amountSats !== void 0) {
226
+ request.amt = params.amountSats;
227
+ }
228
+ if (params.maxFeeSats !== void 0) {
229
+ request.fee_limit = { fixed: params.maxFeeSats };
230
+ }
231
+ const response = await this.transport.sendPaymentSync(request);
232
+ if (response.payment_error) {
233
+ throw new Error(response.payment_error);
234
+ }
235
+ return { preimage: response.payment_preimage };
236
+ } catch (error) {
237
+ throw mapLndError(error);
238
+ }
239
+ }
240
+ async lookupInvoice(params) {
241
+ try {
242
+ const response = await this.transport.lookupInvoice({
243
+ r_hash_str: params.paymentHash
244
+ });
245
+ const settled = response.state === "SETTLED";
246
+ return {
247
+ settled,
248
+ preimage: settled ? response.r_preimage : void 0,
249
+ amountSats: response.value ? Number(response.value) : void 0
250
+ };
251
+ } catch (error) {
252
+ throw mapLndError(error);
253
+ }
254
+ }
255
+ close() {
256
+ this.transport.close();
257
+ }
258
+ };
259
+ export {
260
+ LndLightningProvider,
261
+ createGrpcTransport,
262
+ createRestTransport,
263
+ mapLndError
264
+ };
265
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/grpc-client.ts","../src/rest-client.ts","../src/error-mapper.ts","../src/lnd-provider.ts"],"sourcesContent":["import * as grpc from \"@grpc/grpc-js\";\nimport * as protoLoader from \"@grpc/proto-loader\";\nimport { fileURLToPath } from \"node:url\";\nimport { dirname, join } from \"node:path\";\nimport type { LndGrpcConfig, LndTransport } from \"./types.js\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nconst PROTO_PATH = join(__dirname, \"..\", \"proto\", \"lightning.proto\");\n\nexport function createGrpcTransport(config: LndGrpcConfig): LndTransport {\n const tlsCert =\n typeof config.tlsCert === \"string\"\n ? Buffer.from(config.tlsCert, \"utf-8\")\n : config.tlsCert;\n\n const macaroonHex =\n typeof config.macaroon === \"string\"\n ? config.macaroon\n : config.macaroon.toString(\"hex\");\n\n const sslCreds = grpc.credentials.createSsl(tlsCert);\n\n const macaroonCreds = grpc.credentials.createFromMetadataGenerator(\n (_params, callback) => {\n const metadata = new grpc.Metadata();\n metadata.add(\"macaroon\", macaroonHex);\n callback(null, metadata);\n },\n );\n\n const combinedCreds = grpc.credentials.combineChannelCredentials(\n sslCreds,\n macaroonCreds,\n );\n\n const packageDefinition = protoLoader.loadSync(PROTO_PATH, {\n keepCase: true,\n longs: String,\n enums: String,\n defaults: true,\n oneofs: true,\n });\n\n const lnrpc = grpc.loadPackageDefinition(packageDefinition).lnrpc as any;\n const client = new lnrpc.Lightning(config.host, combinedCreds);\n\n function promisify<TReq, TRes>(\n method: (req: TReq, cb: (err: any, res: TRes) => void) => void,\n ): (req: TReq) => Promise<TRes> {\n return (req: TReq) =>\n new Promise((resolve, reject) => {\n method.call(client, req, (err: any, res: TRes) => {\n if (err) reject(err);\n else resolve(res);\n });\n });\n }\n\n const grpcAddInvoice = promisify(client.addInvoice);\n const grpcSendPaymentSync = promisify(client.sendPaymentSync);\n const grpcLookupInvoice = promisify(client.lookupInvoice);\n\n return {\n async addInvoice(params) {\n const res: any = await grpcAddInvoice(params);\n return {\n r_hash: Buffer.from(res.r_hash).toString(\"hex\"),\n payment_request: res.payment_request,\n };\n },\n async sendPaymentSync(params) {\n const res: any = await grpcSendPaymentSync(params);\n return {\n payment_preimage: Buffer.from(res.payment_preimage).toString(\"hex\"),\n payment_error: res.payment_error,\n payment_hash: Buffer.from(res.payment_hash).toString(\"hex\"),\n };\n },\n async lookupInvoice(params) {\n const res: any = await grpcLookupInvoice(params);\n return {\n state: res.state,\n r_preimage: Buffer.from(res.r_preimage).toString(\"hex\"),\n value: res.value,\n };\n },\n close() {\n client.close();\n },\n };\n}\n","import {\n ConnectionError,\n base64ToHex,\n hexToBase64Url,\n} from \"@ambosstech/lightning-mpp-sdk\";\nimport type { LndRestConfig, LndTransport } from \"./types.js\";\n\nexport function createRestTransport(config: LndRestConfig): LndTransport {\n const baseUrl = config.url.replace(/\\/$/, \"\");\n\n const macaroonHex =\n typeof config.macaroon === \"string\"\n ? config.macaroon\n : config.macaroon.toString(\"hex\");\n\n const fetchFn = config.fetch ?? globalThis.fetch;\n\n async function request<T>(\n path: string,\n options: RequestInit = {},\n ): Promise<T> {\n const url = `${baseUrl}${path}`;\n let response: Response;\n try {\n response = await fetchFn(url, {\n ...options,\n headers: {\n \"Grpc-Metadata-macaroon\": macaroonHex,\n \"Content-Type\": \"application/json\",\n ...options.headers,\n },\n });\n } catch (error) {\n throw new ConnectionError(`LND REST request failed: ${url}`, {\n cause: error,\n });\n }\n\n const body = (await response.json()) as any;\n if (!response.ok) {\n const err: any = new Error(\n body.message ?? body.error ?? `HTTP ${response.status}`,\n );\n err.code = body.code;\n err.details = body.message ?? body.error;\n throw err;\n }\n return body as T;\n }\n\n return {\n async addInvoice(params) {\n const body: any = { value: String(params.value) };\n if (params.memo) body.memo = params.memo;\n if (params.expiry) body.expiry = String(params.expiry);\n\n const res = await request<{ r_hash: string; payment_request: string }>(\n \"/v1/invoices\",\n { method: \"POST\", body: JSON.stringify(body) },\n );\n\n return {\n r_hash: base64ToHex(res.r_hash),\n payment_request: res.payment_request,\n };\n },\n\n async sendPaymentSync(params) {\n const body: any = { payment_request: params.payment_request };\n if (params.amt !== undefined) {\n body.amt = String(params.amt);\n }\n if (params.fee_limit) {\n body.fee_limit = { fixed: String(params.fee_limit.fixed) };\n }\n\n const res = await request<{\n payment_preimage: string;\n payment_error: string;\n payment_hash: string;\n }>(\"/v1/channels/transactions\", {\n method: \"POST\",\n body: JSON.stringify(body),\n });\n\n return {\n payment_preimage: res.payment_preimage\n ? base64ToHex(res.payment_preimage)\n : \"\",\n payment_error: res.payment_error ?? \"\",\n payment_hash: res.payment_hash ? base64ToHex(res.payment_hash) : \"\",\n };\n },\n\n async lookupInvoice(params) {\n const hashUrl = hexToBase64Url(params.r_hash_str);\n const res = await request<{\n state: string;\n r_preimage: string;\n value: string;\n }>(`/v1/invoice/${hashUrl}`);\n\n return {\n state: res.state,\n r_preimage: res.r_preimage ? base64ToHex(res.r_preimage) : \"\",\n value: res.value ?? \"0\",\n };\n },\n\n close() {\n // no-op for REST\n },\n };\n}\n","import {\n AuthenticationError,\n ConnectionError,\n InsufficientBalanceError,\n InvoiceExpiredError,\n type LightningError,\n PaymentTimeoutError,\n RouteNotFoundError,\n} from \"@ambosstech/lightning-mpp-sdk\";\n\ninterface GrpcError {\n code?: number;\n details?: string;\n message?: string;\n}\n\n// gRPC status codes\nconst UNAVAILABLE = 14;\nconst UNAUTHENTICATED = 16;\nconst DEADLINE_EXCEEDED = 4;\n\nexport function mapLndError(error: unknown): LightningError {\n const grpcError = error as GrpcError;\n const code = grpcError.code;\n const details = (grpcError.details ?? grpcError.message ?? \"\").toLowerCase();\n\n if (code === UNAUTHENTICATED) {\n return new AuthenticationError(\"LND authentication failed\", {\n cause: error,\n });\n }\n\n if (code === UNAVAILABLE) {\n return new ConnectionError(\"LND node unavailable\", { cause: error });\n }\n\n if (code === DEADLINE_EXCEEDED) {\n return new PaymentTimeoutError(\"LND request timed out\", { cause: error });\n }\n\n if (\n details.includes(\"invoice expired\") ||\n details.includes(\"invoice is expired\")\n ) {\n return new InvoiceExpiredError(\"Invoice has expired\", { cause: error });\n }\n\n if (\n details.includes(\"unable to find a path\") ||\n details.includes(\"no route\") ||\n details.includes(\"insufficient capacity\")\n ) {\n return new RouteNotFoundError(\"No route found\", { cause: error });\n }\n\n if (\n details.includes(\"insufficient balance\") ||\n details.includes(\"not enough balance\") ||\n details.includes(\"insufficient funds\")\n ) {\n return new InsufficientBalanceError(\"Insufficient balance\", {\n cause: error,\n });\n }\n\n // Fallback\n return new ConnectionError(\n `LND error: ${grpcError.details ?? grpcError.message ?? \"unknown\"}`,\n { cause: error },\n );\n}\n","import type {\n CreateInvoiceParams,\n CreateInvoiceResult,\n LightningProvider,\n LookupInvoiceParams,\n LookupInvoiceResult,\n PayInvoiceParams,\n PayInvoiceResult,\n} from \"@ambosstech/lightning-mpp-sdk\";\nimport { createGrpcTransport } from \"./grpc-client.js\";\nimport { createRestTransport } from \"./rest-client.js\";\nimport { mapLndError } from \"./error-mapper.js\";\nimport type { LndConfig, LndTransport } from \"./types.js\";\n\nexport class LndLightningProvider implements LightningProvider {\n private transport: LndTransport;\n\n constructor(config: LndConfig) {\n this.transport =\n config.transport === \"rest\"\n ? createRestTransport(config)\n : createGrpcTransport(config);\n }\n\n async createInvoice(\n params: CreateInvoiceParams,\n ): Promise<CreateInvoiceResult> {\n try {\n const response = await this.transport.addInvoice({\n value: params.amountSats,\n memo: params.memo,\n expiry: params.expirySecs,\n });\n\n return {\n bolt11: response.payment_request,\n paymentHash: response.r_hash,\n };\n } catch (error) {\n throw mapLndError(error);\n }\n }\n\n async payInvoice(params: PayInvoiceParams): Promise<PayInvoiceResult> {\n try {\n const request: any = { payment_request: params.bolt11 };\n if (params.amountSats !== undefined) {\n request.amt = params.amountSats;\n }\n if (params.maxFeeSats !== undefined) {\n request.fee_limit = { fixed: params.maxFeeSats };\n }\n\n const response = await this.transport.sendPaymentSync(request);\n\n if (response.payment_error) {\n throw new Error(response.payment_error);\n }\n\n return { preimage: response.payment_preimage };\n } catch (error) {\n throw mapLndError(error);\n }\n }\n\n async lookupInvoice(\n params: LookupInvoiceParams,\n ): Promise<LookupInvoiceResult> {\n try {\n const response = await this.transport.lookupInvoice({\n r_hash_str: params.paymentHash,\n });\n\n const settled = response.state === \"SETTLED\";\n return {\n settled,\n preimage: settled ? response.r_preimage : undefined,\n amountSats: response.value ? Number(response.value) : undefined,\n };\n } catch (error) {\n throw mapLndError(error);\n }\n }\n\n close(): void {\n this.transport.close();\n }\n}\n"],"mappings":"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","names":["ConnectionError"]}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@ambosstech/lightning-mpp-adapter-lnd",
3
+ "version": "0.1.1",
4
+ "type": "module",
5
+ "main": "./dist/index.cjs",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "require": "./dist/index.cjs"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "proto",
18
+ "README.md",
19
+ "LICENSE"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsup",
23
+ "test": "vitest run",
24
+ "test:watch": "vitest",
25
+ "typecheck": "tsc --noEmit",
26
+ "clean": "rm -rf dist"
27
+ },
28
+ "dependencies": {
29
+ "@ambosstech/lightning-mpp-sdk": "workspace:*",
30
+ "@grpc/grpc-js": "^1.12.0",
31
+ "@grpc/proto-loader": "^0.7.13"
32
+ },
33
+ "devDependencies": {
34
+ "tsup": "^8.3.0",
35
+ "typescript": "~5.7.0",
36
+ "vitest": "^2.1.0"
37
+ }
38
+ }
@@ -0,0 +1,56 @@
1
+ syntax = "proto3";
2
+
3
+ package lnrpc;
4
+
5
+ option go_package = "github.com/lightningnetwork/lnd/lnrpc";
6
+
7
+ service Lightning {
8
+ rpc AddInvoice (Invoice) returns (AddInvoiceResponse);
9
+ rpc LookupInvoice (PaymentHash) returns (Invoice);
10
+ rpc SendPaymentSync (SendRequest) returns (SendResponse);
11
+ }
12
+
13
+ message Invoice {
14
+ string memo = 1;
15
+ bytes r_preimage = 3;
16
+ bytes r_hash = 4;
17
+ int64 value = 5;
18
+ bool settled = 6;
19
+ int64 creation_date = 7;
20
+ int64 settle_date = 8;
21
+ string payment_request = 9;
22
+ int64 expiry = 15;
23
+ string state = 30;
24
+ }
25
+
26
+ message AddInvoiceResponse {
27
+ bytes r_hash = 1;
28
+ string payment_request = 2;
29
+ uint64 add_index = 16;
30
+ }
31
+
32
+ message PaymentHash {
33
+ string r_hash_str = 1;
34
+ bytes r_hash = 2;
35
+ }
36
+
37
+ message SendRequest {
38
+ bytes dest = 1;
39
+ int64 amt = 2;
40
+ string payment_request = 6;
41
+ FeeLimit fee_limit = 8;
42
+ }
43
+
44
+ message FeeLimit {
45
+ oneof limit {
46
+ int64 fixed = 1;
47
+ int64 fixed_msat = 3;
48
+ int64 percent = 2;
49
+ }
50
+ }
51
+
52
+ message SendResponse {
53
+ string payment_error = 1;
54
+ bytes payment_preimage = 2;
55
+ bytes payment_hash = 5;
56
+ }