@getalby/lightning-tools 7.0.2 → 8.1.0

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.
Files changed (44) hide show
  1. package/README.md +108 -28
  2. package/dist/cjs/402/l402.cjs +157 -0
  3. package/dist/cjs/402/l402.cjs.map +1 -0
  4. package/dist/cjs/402/mpp.cjs +179 -0
  5. package/dist/cjs/402/mpp.cjs.map +1 -0
  6. package/dist/cjs/402/x402.cjs +1320 -0
  7. package/dist/cjs/402/x402.cjs.map +1 -0
  8. package/dist/cjs/402.cjs +1694 -0
  9. package/dist/cjs/402.cjs.map +1 -0
  10. package/dist/cjs/bolt11.cjs +534 -518
  11. package/dist/cjs/bolt11.cjs.map +1 -1
  12. package/dist/cjs/index.cjs +811 -453
  13. package/dist/cjs/index.cjs.map +1 -1
  14. package/dist/cjs/lnurl.cjs +22 -7
  15. package/dist/cjs/lnurl.cjs.map +1 -1
  16. package/dist/esm/402/l402.js +150 -0
  17. package/dist/esm/402/l402.js.map +1 -0
  18. package/dist/esm/402/mpp.js +177 -0
  19. package/dist/esm/402/mpp.js.map +1 -0
  20. package/dist/esm/402/x402.js +1318 -0
  21. package/dist/esm/402/x402.js.map +1 -0
  22. package/dist/esm/402.js +1683 -0
  23. package/dist/esm/402.js.map +1 -0
  24. package/dist/esm/bolt11.js +534 -519
  25. package/dist/esm/bolt11.js.map +1 -1
  26. package/dist/esm/index.js +803 -451
  27. package/dist/esm/index.js.map +1 -1
  28. package/dist/esm/lnurl.js +22 -7
  29. package/dist/esm/lnurl.js.map +1 -1
  30. package/dist/lightning-tools.umd.js +3 -3
  31. package/dist/lightning-tools.umd.js.map +1 -1
  32. package/dist/types/402/l402.d.ts +51 -0
  33. package/dist/types/402/mpp.d.ts +26 -0
  34. package/dist/types/402/x402.d.ts +13 -0
  35. package/dist/types/402.d.ts +78 -0
  36. package/dist/types/bolt11.d.ts +6 -1
  37. package/dist/types/index.d.ts +76 -28
  38. package/dist/types/lnurl.d.ts +2 -0
  39. package/package.json +20 -5
  40. package/dist/cjs/l402.cjs +0 -93
  41. package/dist/cjs/l402.cjs.map +0 -1
  42. package/dist/esm/l402.js +0 -87
  43. package/dist/esm/l402.js.map +0 -1
  44. package/dist/types/l402.d.ts +0 -35
@@ -0,0 +1,51 @@
1
+ interface Wallet {
2
+ payInvoice(args: {
3
+ invoice: string;
4
+ }): Promise<{
5
+ preimage: string;
6
+ }>;
7
+ }
8
+
9
+ declare const fetchWithL402: (url: string, fetchArgs: RequestInit, options: {
10
+ wallet: Wallet;
11
+ }) => Promise<Response>;
12
+
13
+ interface WwwAuthenticatePayload {
14
+ token: string;
15
+ invoice: string;
16
+ [key: string]: string;
17
+ }
18
+ /**
19
+ * Client: parse "www-authenticate" header from server response
20
+ * @param input
21
+ * @returns details from the header value (token or macaroon, invoice)
22
+ */
23
+ declare const parseL402: (input: string) => WwwAuthenticatePayload;
24
+
25
+ type MacaroonPayload<T> = T & {
26
+ paymentHash: string;
27
+ };
28
+ declare function issueL402Macaroon<T extends Record<string, unknown>>(secret: string, paymentHash: string, params?: T): Promise<string>;
29
+ declare function verifyL402Macaroon<T = unknown>(secret: string, token: string): Promise<MacaroonPayload<T>>;
30
+
31
+ /**
32
+ * Server: create a WWW-Authenticate header for a given macaroon and invoice
33
+ * @param args the macaroon/token and invoice generated for the client's request
34
+ * @returns the header value
35
+ */
36
+ declare const makeL402AuthenticateHeader: (args: {
37
+ token?: string;
38
+ invoice: string;
39
+ }) => string;
40
+ /**
41
+ * Server: parse "authorization" header sent from client
42
+ * @param input value from authorization header
43
+ * @returns the macaroon and preimage
44
+ */
45
+ declare function parseL402Authorization(input: string): {
46
+ token: string;
47
+ preimage: string;
48
+ } | null;
49
+
50
+ export { fetchWithL402, issueL402Macaroon, makeL402AuthenticateHeader, parseL402, parseL402Authorization, verifyL402Macaroon };
51
+ export type { MacaroonPayload };
@@ -0,0 +1,26 @@
1
+ interface Wallet {
2
+ payInvoice(args: {
3
+ invoice: string;
4
+ }): Promise<{
5
+ preimage: string;
6
+ }>;
7
+ }
8
+
9
+ /**
10
+ * Fetch a resource protected by the draft-lightning-charge-00 payment
11
+ * authentication protocol.
12
+ *
13
+ * On a `402 Payment Required` response that carries a
14
+ * `WWW-Authenticate: Payment method="lightning" intent="charge" …` header
15
+ * the function pays the embedded BOLT11 invoice and retries with the
16
+ * resulting preimage as the credential.
17
+ *
18
+ * Note: lightning-charge uses consume-once challenge semantics – each
19
+ * challenge embeds a fresh invoice, so paid credentials cannot be reused.
20
+ * The `store` option is accepted for API consistency but is not used.
21
+ */
22
+ declare const fetchWithMpp: (url: string, fetchArgs: RequestInit, options: {
23
+ wallet: Wallet;
24
+ }) => Promise<Response>;
25
+
26
+ export { fetchWithMpp };
@@ -0,0 +1,13 @@
1
+ interface Wallet {
2
+ payInvoice(args: {
3
+ invoice: string;
4
+ }): Promise<{
5
+ preimage: string;
6
+ }>;
7
+ }
8
+
9
+ declare const fetchWithX402: (url: string, fetchArgs: RequestInit, options: {
10
+ wallet: Wallet;
11
+ }) => Promise<Response>;
12
+
13
+ export { fetchWithX402 };
@@ -0,0 +1,78 @@
1
+ interface Wallet {
2
+ payInvoice(args: {
3
+ invoice: string;
4
+ }): Promise<{
5
+ preimage: string;
6
+ }>;
7
+ }
8
+ declare function createGuardedWallet(wallet: Wallet, maxAmountSats: number): Wallet;
9
+
10
+ declare const fetch402: (url: string, fetchArgs: RequestInit, options: {
11
+ wallet: Wallet;
12
+ maxAmount?: number;
13
+ }) => Promise<Response>;
14
+
15
+ declare const fetchWithL402: (url: string, fetchArgs: RequestInit, options: {
16
+ wallet: Wallet;
17
+ }) => Promise<Response>;
18
+
19
+ interface WwwAuthenticatePayload {
20
+ token: string;
21
+ invoice: string;
22
+ [key: string]: string;
23
+ }
24
+ /**
25
+ * Client: parse "www-authenticate" header from server response
26
+ * @param input
27
+ * @returns details from the header value (token or macaroon, invoice)
28
+ */
29
+ declare const parseL402: (input: string) => WwwAuthenticatePayload;
30
+
31
+ type MacaroonPayload<T> = T & {
32
+ paymentHash: string;
33
+ };
34
+ declare function issueL402Macaroon<T extends Record<string, unknown>>(secret: string, paymentHash: string, params?: T): Promise<string>;
35
+ declare function verifyL402Macaroon<T = unknown>(secret: string, token: string): Promise<MacaroonPayload<T>>;
36
+
37
+ /**
38
+ * Server: create a WWW-Authenticate header for a given macaroon and invoice
39
+ * @param args the macaroon/token and invoice generated for the client's request
40
+ * @returns the header value
41
+ */
42
+ declare const makeL402AuthenticateHeader: (args: {
43
+ token?: string;
44
+ invoice: string;
45
+ }) => string;
46
+ /**
47
+ * Server: parse "authorization" header sent from client
48
+ * @param input value from authorization header
49
+ * @returns the macaroon and preimage
50
+ */
51
+ declare function parseL402Authorization(input: string): {
52
+ token: string;
53
+ preimage: string;
54
+ } | null;
55
+
56
+ declare const fetchWithX402: (url: string, fetchArgs: RequestInit, options: {
57
+ wallet: Wallet;
58
+ }) => Promise<Response>;
59
+
60
+ /**
61
+ * Fetch a resource protected by the draft-lightning-charge-00 payment
62
+ * authentication protocol.
63
+ *
64
+ * On a `402 Payment Required` response that carries a
65
+ * `WWW-Authenticate: Payment method="lightning" intent="charge" …` header
66
+ * the function pays the embedded BOLT11 invoice and retries with the
67
+ * resulting preimage as the credential.
68
+ *
69
+ * Note: lightning-charge uses consume-once challenge semantics – each
70
+ * challenge embeds a fresh invoice, so paid credentials cannot be reused.
71
+ * The `store` option is accepted for API consistency but is not used.
72
+ */
73
+ declare const fetchWithMpp: (url: string, fetchArgs: RequestInit, options: {
74
+ wallet: Wallet;
75
+ }) => Promise<Response>;
76
+
77
+ export { createGuardedWallet, fetch402, fetchWithL402, fetchWithMpp, fetchWithX402, issueL402Macaroon, makeL402AuthenticateHeader, parseL402, parseL402Authorization, verifyL402Macaroon };
78
+ export type { MacaroonPayload, Wallet };
@@ -17,11 +17,14 @@ declare const fromHexString: (hexString: string) => Uint8Array<ArrayBuffer>;
17
17
  type DecodedInvoice = {
18
18
  paymentHash: string;
19
19
  satoshi: number;
20
+ millisatoshi: number;
21
+ amountRaw: string;
20
22
  timestamp: number;
21
23
  expiry: number | undefined;
22
24
  description: string | undefined;
23
25
  };
24
26
  declare const decodeInvoice: (paymentRequest: string) => DecodedInvoice | null;
27
+ declare function validatePreimage(preimage: string, paymentHash: string): boolean;
25
28
 
26
29
  declare class Invoice {
27
30
  paymentRequest: string;
@@ -29,6 +32,8 @@ declare class Invoice {
29
32
  preimage: string | null;
30
33
  verify: string | null;
31
34
  satoshi: number;
35
+ millisatoshi: number;
36
+ amountRaw: string;
32
37
  expiry: number | undefined;
33
38
  timestamp: number;
34
39
  createdDate: Date;
@@ -42,5 +47,5 @@ declare class Invoice {
42
47
  hasExpired(): boolean;
43
48
  }
44
49
 
45
- export { Invoice, decodeInvoice, fromHexString };
50
+ export { Invoice, decodeInvoice, fromHexString, validatePreimage };
46
51
  export type { InvoiceArgs, SuccessAction };
@@ -20,11 +20,14 @@ declare const fromHexString: (hexString: string) => Uint8Array<ArrayBuffer>;
20
20
  type DecodedInvoice = {
21
21
  paymentHash: string;
22
22
  satoshi: number;
23
+ millisatoshi: number;
24
+ amountRaw: string;
23
25
  timestamp: number;
24
26
  expiry: number | undefined;
25
27
  description: string | undefined;
26
28
  };
27
29
  declare const decodeInvoice: (paymentRequest: string) => DecodedInvoice | null;
30
+ declare function validatePreimage(preimage: string, paymentHash: string): boolean;
28
31
 
29
32
  declare class Invoice {
30
33
  paymentRequest: string;
@@ -32,6 +35,8 @@ declare class Invoice {
32
35
  preimage: string | null;
33
36
  verify: string | null;
34
37
  satoshi: number;
38
+ millisatoshi: number;
39
+ amountRaw: string;
35
40
  expiry: number | undefined;
36
41
  timestamp: number;
37
42
  createdDate: Date;
@@ -235,37 +240,80 @@ declare class LightningAddress {
235
240
  private parseNostrResponse;
236
241
  }
237
242
 
238
- interface KVStorage {
239
- getItem(key: string): string | null;
240
- setItem(key: string, value: string): void;
241
- }
242
- declare class MemoryStorage implements KVStorage {
243
- storage: any;
244
- constructor(initial?: Record<string, unknown>);
245
- getItem(key: string): any;
246
- setItem(key: string, value: unknown): void;
247
- }
248
- declare class NoStorage implements KVStorage {
249
- constructor(initial?: unknown);
250
- getItem(key: string): null;
251
- setItem(key: string, value: unknown): void;
252
- }
253
- declare const parseL402: (input: string) => Record<string, string>;
254
- declare const makeAuthenticateHeader: (args: {
255
- macaroon: string;
256
- invoice: string;
257
- key?: string;
258
- }) => string;
259
-
260
243
  interface Wallet {
261
- sendPayment(paymentRequest: string): Promise<{
244
+ payInvoice(args: {
245
+ invoice: string;
246
+ }): Promise<{
262
247
  preimage: string;
263
248
  }>;
264
249
  }
250
+ declare function createGuardedWallet(wallet: Wallet, maxAmountSats: number): Wallet;
251
+
252
+ declare const fetch402: (url: string, fetchArgs: RequestInit, options: {
253
+ wallet: Wallet;
254
+ maxAmount?: number;
255
+ }) => Promise<Response>;
256
+
265
257
  declare const fetchWithL402: (url: string, fetchArgs: RequestInit, options: {
266
- headerKey?: string;
267
- wallet?: Wallet;
268
- store?: KVStorage;
258
+ wallet: Wallet;
259
+ }) => Promise<Response>;
260
+
261
+ interface WwwAuthenticatePayload {
262
+ token: string;
263
+ invoice: string;
264
+ [key: string]: string;
265
+ }
266
+ /**
267
+ * Client: parse "www-authenticate" header from server response
268
+ * @param input
269
+ * @returns details from the header value (token or macaroon, invoice)
270
+ */
271
+ declare const parseL402: (input: string) => WwwAuthenticatePayload;
272
+
273
+ type MacaroonPayload<T> = T & {
274
+ paymentHash: string;
275
+ };
276
+ declare function issueL402Macaroon<T extends Record<string, unknown>>(secret: string, paymentHash: string, params?: T): Promise<string>;
277
+ declare function verifyL402Macaroon<T = unknown>(secret: string, token: string): Promise<MacaroonPayload<T>>;
278
+
279
+ /**
280
+ * Server: create a WWW-Authenticate header for a given macaroon and invoice
281
+ * @param args the macaroon/token and invoice generated for the client's request
282
+ * @returns the header value
283
+ */
284
+ declare const makeL402AuthenticateHeader: (args: {
285
+ token?: string;
286
+ invoice: string;
287
+ }) => string;
288
+ /**
289
+ * Server: parse "authorization" header sent from client
290
+ * @param input value from authorization header
291
+ * @returns the macaroon and preimage
292
+ */
293
+ declare function parseL402Authorization(input: string): {
294
+ token: string;
295
+ preimage: string;
296
+ } | null;
297
+
298
+ declare const fetchWithX402: (url: string, fetchArgs: RequestInit, options: {
299
+ wallet: Wallet;
300
+ }) => Promise<Response>;
301
+
302
+ /**
303
+ * Fetch a resource protected by the draft-lightning-charge-00 payment
304
+ * authentication protocol.
305
+ *
306
+ * On a `402 Payment Required` response that carries a
307
+ * `WWW-Authenticate: Payment method="lightning" intent="charge" …` header
308
+ * the function pays the embedded BOLT11 invoice and retries with the
309
+ * resulting preimage as the credential.
310
+ *
311
+ * Note: lightning-charge uses consume-once challenge semantics – each
312
+ * challenge embeds a fresh invoice, so paid credentials cannot be reused.
313
+ * The `store` option is accepted for API consistency but is not used.
314
+ */
315
+ declare const fetchWithMpp: (url: string, fetchArgs: RequestInit, options: {
316
+ wallet: Wallet;
269
317
  }) => Promise<Response>;
270
318
 
271
319
  interface FiatCurrency {
@@ -290,5 +338,5 @@ declare const getFormattedFiatValue: ({ satoshi, currency, locale, }: {
290
338
  locale: string;
291
339
  }) => Promise<string>;
292
340
 
293
- export { DEFAULT_PROXY, Invoice, LN_ADDRESS_REGEX, LightningAddress, MemoryStorage, NoStorage, decodeInvoice, fetchWithL402, fromHexString, generateZapEvent, getEventHash, getFiatBtcRate, getFiatCurrencies, getFiatValue, getFormattedFiatValue, getSatoshiValue, isUrl, isValidAmount, makeAuthenticateHeader, parseKeysendResponse, parseL402, parseLnUrlPayResponse, parseNostrResponse, sendBoostagram, serializeEvent, validateEvent };
294
- export type { Boost, BoostArguments, BoostOptions, Event, FiatCurrency, InvoiceArgs, KVStorage, KeySendRawData, KeysendResponse, LUD18PayerData, LUD18ServicePayerData, LnUrlPayResponse, LnUrlRawData, NostrProvider, NostrResponse, RequestInvoiceArgs, SuccessAction, WeblnBoostParams, ZapArgs, ZapOptions };
341
+ export { DEFAULT_PROXY, Invoice, LN_ADDRESS_REGEX, LightningAddress, createGuardedWallet, decodeInvoice, fetch402, fetchWithL402, fetchWithMpp, fetchWithX402, fromHexString, generateZapEvent, getEventHash, getFiatBtcRate, getFiatCurrencies, getFiatValue, getFormattedFiatValue, getSatoshiValue, isUrl, isValidAmount, issueL402Macaroon, makeL402AuthenticateHeader, parseKeysendResponse, parseL402, parseL402Authorization, parseLnUrlPayResponse, parseNostrResponse, sendBoostagram, serializeEvent, validateEvent, validatePreimage, verifyL402Macaroon };
342
+ export type { Boost, BoostArguments, BoostOptions, Event, FiatCurrency, InvoiceArgs, KeySendRawData, KeysendResponse, LUD18PayerData, LUD18ServicePayerData, LnUrlPayResponse, LnUrlRawData, MacaroonPayload, NostrProvider, NostrResponse, RequestInvoiceArgs, SuccessAction, Wallet, WeblnBoostParams, ZapArgs, ZapOptions };
@@ -140,6 +140,8 @@ declare class Invoice {
140
140
  preimage: string | null;
141
141
  verify: string | null;
142
142
  satoshi: number;
143
+ millisatoshi: number;
144
+ amountRaw: string;
143
145
  expiry: number | undefined;
144
146
  timestamp: number;
145
147
  createdDate: Date;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getalby/lightning-tools",
3
- "version": "7.0.2",
3
+ "version": "8.1.0",
4
4
  "description": "Collection of helpful building blocks and tools to develop Bitcoin Lightning web apps",
5
5
  "type": "module",
6
6
  "repository": "https://github.com/getAlby/js-lightning-tools.git",
@@ -39,10 +39,25 @@
39
39
  "require": "./dist/cjs/fiat.cjs",
40
40
  "types": "./dist/types/fiat.d.ts"
41
41
  },
42
- "./l402": {
43
- "import": "./dist/esm/l402.js",
44
- "require": "./dist/cjs/l402.cjs",
45
- "types": "./dist/types/l402.d.ts"
42
+ "./402": {
43
+ "import": "./dist/esm/402.js",
44
+ "require": "./dist/cjs/402.cjs",
45
+ "types": "./dist/types/402.d.ts"
46
+ },
47
+ "./402/l402": {
48
+ "import": "./dist/esm/402/l402.js",
49
+ "require": "./dist/cjs/402/l402.cjs",
50
+ "types": "./dist/types/402/l402.d.ts"
51
+ },
52
+ "./402/x402": {
53
+ "import": "./dist/esm/402/x402.js",
54
+ "require": "./dist/cjs/402/x402.cjs",
55
+ "types": "./dist/types/402/x402.d.ts"
56
+ },
57
+ "./402/mpp": {
58
+ "import": "./dist/esm/402/mpp.js",
59
+ "require": "./dist/cjs/402/mpp.cjs",
60
+ "types": "./dist/types/402/mpp.d.ts"
46
61
  },
47
62
  "./lnurl": {
48
63
  "import": "./dist/esm/lnurl.js",
package/dist/cjs/l402.cjs DELETED
@@ -1,93 +0,0 @@
1
- 'use strict';
2
-
3
- class MemoryStorage {
4
- constructor(initial) {
5
- this.storage = initial || {};
6
- }
7
- getItem(key) {
8
- return this.storage[key];
9
- }
10
- setItem(key, value) {
11
- this.storage[key] = value;
12
- }
13
- }
14
- class NoStorage {
15
- constructor(initial) { }
16
- getItem(key) {
17
- return null;
18
- }
19
- setItem(key, value) { }
20
- }
21
- const parseL402 = (input) => {
22
- // Remove the L402 and LSAT identifiers
23
- const string = input.replace("L402", "").replace("LSAT", "").trim();
24
- // Initialize an object to store the key-value pairs
25
- const keyValuePairs = {};
26
- // Regular expression to match key and (quoted or unquoted) value
27
- const regex = /(\w+)=("([^"]*)"|'([^']*)'|([^,]*))/g;
28
- let match;
29
- // Use regex to find all key-value pairs
30
- while ((match = regex.exec(string)) !== null) {
31
- // Key is always match[1]
32
- // Value is either match[3] (double-quoted), match[4] (single-quoted), or match[5] (unquoted)
33
- keyValuePairs[match[1]] = match[3] || match[4] || match[5];
34
- }
35
- return keyValuePairs;
36
- };
37
- const makeAuthenticateHeader = (args) => {
38
- const key = args.key || "L402";
39
- return `${key} macaroon="${args.macaroon}", invoice="${args.invoice}"`;
40
- };
41
-
42
- const memoryStorage = new MemoryStorage();
43
- const HEADER_KEY = "L402";
44
- const fetchWithL402 = async (url, fetchArgs, options) => {
45
- if (!options) {
46
- options = {};
47
- }
48
- const headerKey = options.headerKey || HEADER_KEY;
49
- const wallet = options.wallet;
50
- if (!wallet) {
51
- throw new Error("wallet is missing");
52
- }
53
- const store = options.store || memoryStorage;
54
- if (!fetchArgs) {
55
- fetchArgs = {};
56
- }
57
- fetchArgs.cache = "no-store";
58
- fetchArgs.mode = "cors";
59
- if (!fetchArgs.headers) {
60
- fetchArgs.headers = {};
61
- }
62
- const cachedL402Data = store.getItem(url);
63
- if (cachedL402Data) {
64
- const data = JSON.parse(cachedL402Data);
65
- fetchArgs.headers["Authorization"] =
66
- `${headerKey} ${data.token}:${data.preimage}`;
67
- return await fetch(url, fetchArgs);
68
- }
69
- fetchArgs.headers["Accept-Authenticate"] = headerKey;
70
- const initResp = await fetch(url, fetchArgs);
71
- const header = initResp.headers.get("www-authenticate");
72
- if (!header) {
73
- return initResp;
74
- }
75
- const details = parseL402(header);
76
- const token = details.token || details.macaroon;
77
- const inv = details.invoice;
78
- const invResp = await wallet.sendPayment(inv);
79
- store.setItem(url, JSON.stringify({
80
- token: token,
81
- preimage: invResp.preimage,
82
- }));
83
- fetchArgs.headers["Authorization"] =
84
- `${headerKey} ${token}:${invResp.preimage}`;
85
- return await fetch(url, fetchArgs);
86
- };
87
-
88
- exports.MemoryStorage = MemoryStorage;
89
- exports.NoStorage = NoStorage;
90
- exports.fetchWithL402 = fetchWithL402;
91
- exports.makeAuthenticateHeader = makeAuthenticateHeader;
92
- exports.parseL402 = parseL402;
93
- //# sourceMappingURL=l402.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"l402.cjs","sources":["../../src/l402/utils.ts","../../src/l402/l402.ts"],"sourcesContent":["export interface KVStorage {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n}\n\nexport class MemoryStorage implements KVStorage {\n storage;\n\n constructor(initial?: Record<string, unknown>) {\n this.storage = initial || {};\n }\n\n getItem(key: string) {\n return this.storage[key];\n }\n\n setItem(key: string, value: unknown) {\n this.storage[key] = value;\n }\n}\n\nexport class NoStorage implements KVStorage {\n constructor(initial?: unknown) {}\n\n getItem(key: string) {\n return null;\n }\n\n setItem(key: string, value: unknown) {}\n}\n\nexport const parseL402 = (input: string): Record<string, string> => {\n // Remove the L402 and LSAT identifiers\n const string = input.replace(\"L402\", \"\").replace(\"LSAT\", \"\").trim();\n\n // Initialize an object to store the key-value pairs\n const keyValuePairs = {};\n\n // Regular expression to match key and (quoted or unquoted) value\n const regex = /(\\w+)=(\"([^\"]*)\"|'([^']*)'|([^,]*))/g;\n let match;\n\n // Use regex to find all key-value pairs\n while ((match = regex.exec(string)) !== null) {\n // Key is always match[1]\n // Value is either match[3] (double-quoted), match[4] (single-quoted), or match[5] (unquoted)\n keyValuePairs[match[1]] = match[3] || match[4] || match[5];\n }\n\n return keyValuePairs;\n};\n\nexport const makeAuthenticateHeader = (args: { macaroon: string, invoice: string, key?: string }) => {\n const key = args.key || \"L402\";\n\n return `${key} macaroon=\"${args.macaroon}\", invoice=\"${args.invoice}\"`;\n}\n","import { KVStorage, MemoryStorage, parseL402 } from \"./utils\";\n\nconst memoryStorage = new MemoryStorage();\n\nconst HEADER_KEY = \"L402\";\n\ninterface Wallet {\n sendPayment(paymentRequest: string): Promise<{ preimage: string }>;\n}\n\nexport const fetchWithL402 = async (\n url: string,\n fetchArgs: RequestInit,\n options: {\n headerKey?: string;\n wallet?: Wallet;\n store?: KVStorage;\n },\n) => {\n if (!options) {\n options = {};\n }\n const headerKey = options.headerKey || HEADER_KEY;\n const wallet: Wallet | undefined = options.wallet;\n if (!wallet) {\n throw new Error(\"wallet is missing\");\n }\n const store = options.store || memoryStorage;\n if (!fetchArgs) {\n fetchArgs = {};\n }\n fetchArgs.cache = \"no-store\";\n fetchArgs.mode = \"cors\";\n if (!fetchArgs.headers) {\n fetchArgs.headers = {};\n }\n const cachedL402Data = store.getItem(url);\n if (cachedL402Data) {\n const data = JSON.parse(cachedL402Data);\n fetchArgs.headers[\"Authorization\"] =\n `${headerKey} ${data.token}:${data.preimage}`;\n return await fetch(url, fetchArgs);\n }\n\n fetchArgs.headers[\"Accept-Authenticate\"] = headerKey;\n const initResp = await fetch(url, fetchArgs);\n const header = initResp.headers.get(\"www-authenticate\");\n if (!header) {\n return initResp;\n }\n\n const details = parseL402(header);\n const token = details.token || details.macaroon;\n const inv = details.invoice;\n\n const invResp = await wallet.sendPayment(inv);\n\n store.setItem(\n url,\n JSON.stringify({\n token: token,\n preimage: invResp.preimage,\n }),\n );\n\n fetchArgs.headers[\"Authorization\"] =\n `${headerKey} ${token}:${invResp.preimage}`;\n return await fetch(url, fetchArgs);\n};\n"],"names":[],"mappings":"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"}
package/dist/esm/l402.js DELETED
@@ -1,87 +0,0 @@
1
- class MemoryStorage {
2
- constructor(initial) {
3
- this.storage = initial || {};
4
- }
5
- getItem(key) {
6
- return this.storage[key];
7
- }
8
- setItem(key, value) {
9
- this.storage[key] = value;
10
- }
11
- }
12
- class NoStorage {
13
- constructor(initial) { }
14
- getItem(key) {
15
- return null;
16
- }
17
- setItem(key, value) { }
18
- }
19
- const parseL402 = (input) => {
20
- // Remove the L402 and LSAT identifiers
21
- const string = input.replace("L402", "").replace("LSAT", "").trim();
22
- // Initialize an object to store the key-value pairs
23
- const keyValuePairs = {};
24
- // Regular expression to match key and (quoted or unquoted) value
25
- const regex = /(\w+)=("([^"]*)"|'([^']*)'|([^,]*))/g;
26
- let match;
27
- // Use regex to find all key-value pairs
28
- while ((match = regex.exec(string)) !== null) {
29
- // Key is always match[1]
30
- // Value is either match[3] (double-quoted), match[4] (single-quoted), or match[5] (unquoted)
31
- keyValuePairs[match[1]] = match[3] || match[4] || match[5];
32
- }
33
- return keyValuePairs;
34
- };
35
- const makeAuthenticateHeader = (args) => {
36
- const key = args.key || "L402";
37
- return `${key} macaroon="${args.macaroon}", invoice="${args.invoice}"`;
38
- };
39
-
40
- const memoryStorage = new MemoryStorage();
41
- const HEADER_KEY = "L402";
42
- const fetchWithL402 = async (url, fetchArgs, options) => {
43
- if (!options) {
44
- options = {};
45
- }
46
- const headerKey = options.headerKey || HEADER_KEY;
47
- const wallet = options.wallet;
48
- if (!wallet) {
49
- throw new Error("wallet is missing");
50
- }
51
- const store = options.store || memoryStorage;
52
- if (!fetchArgs) {
53
- fetchArgs = {};
54
- }
55
- fetchArgs.cache = "no-store";
56
- fetchArgs.mode = "cors";
57
- if (!fetchArgs.headers) {
58
- fetchArgs.headers = {};
59
- }
60
- const cachedL402Data = store.getItem(url);
61
- if (cachedL402Data) {
62
- const data = JSON.parse(cachedL402Data);
63
- fetchArgs.headers["Authorization"] =
64
- `${headerKey} ${data.token}:${data.preimage}`;
65
- return await fetch(url, fetchArgs);
66
- }
67
- fetchArgs.headers["Accept-Authenticate"] = headerKey;
68
- const initResp = await fetch(url, fetchArgs);
69
- const header = initResp.headers.get("www-authenticate");
70
- if (!header) {
71
- return initResp;
72
- }
73
- const details = parseL402(header);
74
- const token = details.token || details.macaroon;
75
- const inv = details.invoice;
76
- const invResp = await wallet.sendPayment(inv);
77
- store.setItem(url, JSON.stringify({
78
- token: token,
79
- preimage: invResp.preimage,
80
- }));
81
- fetchArgs.headers["Authorization"] =
82
- `${headerKey} ${token}:${invResp.preimage}`;
83
- return await fetch(url, fetchArgs);
84
- };
85
-
86
- export { MemoryStorage, NoStorage, fetchWithL402, makeAuthenticateHeader, parseL402 };
87
- //# sourceMappingURL=l402.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"l402.js","sources":["../../src/l402/utils.ts","../../src/l402/l402.ts"],"sourcesContent":["export interface KVStorage {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n}\n\nexport class MemoryStorage implements KVStorage {\n storage;\n\n constructor(initial?: Record<string, unknown>) {\n this.storage = initial || {};\n }\n\n getItem(key: string) {\n return this.storage[key];\n }\n\n setItem(key: string, value: unknown) {\n this.storage[key] = value;\n }\n}\n\nexport class NoStorage implements KVStorage {\n constructor(initial?: unknown) {}\n\n getItem(key: string) {\n return null;\n }\n\n setItem(key: string, value: unknown) {}\n}\n\nexport const parseL402 = (input: string): Record<string, string> => {\n // Remove the L402 and LSAT identifiers\n const string = input.replace(\"L402\", \"\").replace(\"LSAT\", \"\").trim();\n\n // Initialize an object to store the key-value pairs\n const keyValuePairs = {};\n\n // Regular expression to match key and (quoted or unquoted) value\n const regex = /(\\w+)=(\"([^\"]*)\"|'([^']*)'|([^,]*))/g;\n let match;\n\n // Use regex to find all key-value pairs\n while ((match = regex.exec(string)) !== null) {\n // Key is always match[1]\n // Value is either match[3] (double-quoted), match[4] (single-quoted), or match[5] (unquoted)\n keyValuePairs[match[1]] = match[3] || match[4] || match[5];\n }\n\n return keyValuePairs;\n};\n\nexport const makeAuthenticateHeader = (args: { macaroon: string, invoice: string, key?: string }) => {\n const key = args.key || \"L402\";\n\n return `${key} macaroon=\"${args.macaroon}\", invoice=\"${args.invoice}\"`;\n}\n","import { KVStorage, MemoryStorage, parseL402 } from \"./utils\";\n\nconst memoryStorage = new MemoryStorage();\n\nconst HEADER_KEY = \"L402\";\n\ninterface Wallet {\n sendPayment(paymentRequest: string): Promise<{ preimage: string }>;\n}\n\nexport const fetchWithL402 = async (\n url: string,\n fetchArgs: RequestInit,\n options: {\n headerKey?: string;\n wallet?: Wallet;\n store?: KVStorage;\n },\n) => {\n if (!options) {\n options = {};\n }\n const headerKey = options.headerKey || HEADER_KEY;\n const wallet: Wallet | undefined = options.wallet;\n if (!wallet) {\n throw new Error(\"wallet is missing\");\n }\n const store = options.store || memoryStorage;\n if (!fetchArgs) {\n fetchArgs = {};\n }\n fetchArgs.cache = \"no-store\";\n fetchArgs.mode = \"cors\";\n if (!fetchArgs.headers) {\n fetchArgs.headers = {};\n }\n const cachedL402Data = store.getItem(url);\n if (cachedL402Data) {\n const data = JSON.parse(cachedL402Data);\n fetchArgs.headers[\"Authorization\"] =\n `${headerKey} ${data.token}:${data.preimage}`;\n return await fetch(url, fetchArgs);\n }\n\n fetchArgs.headers[\"Accept-Authenticate\"] = headerKey;\n const initResp = await fetch(url, fetchArgs);\n const header = initResp.headers.get(\"www-authenticate\");\n if (!header) {\n return initResp;\n }\n\n const details = parseL402(header);\n const token = details.token || details.macaroon;\n const inv = details.invoice;\n\n const invResp = await wallet.sendPayment(inv);\n\n store.setItem(\n url,\n JSON.stringify({\n token: token,\n preimage: invResp.preimage,\n }),\n );\n\n fetchArgs.headers[\"Authorization\"] =\n `${headerKey} ${token}:${invResp.preimage}`;\n return await fetch(url, fetchArgs);\n};\n"],"names":[],"mappings":"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"}
@@ -1,35 +0,0 @@
1
- interface KVStorage {
2
- getItem(key: string): string | null;
3
- setItem(key: string, value: string): void;
4
- }
5
- declare class MemoryStorage implements KVStorage {
6
- storage: any;
7
- constructor(initial?: Record<string, unknown>);
8
- getItem(key: string): any;
9
- setItem(key: string, value: unknown): void;
10
- }
11
- declare class NoStorage implements KVStorage {
12
- constructor(initial?: unknown);
13
- getItem(key: string): null;
14
- setItem(key: string, value: unknown): void;
15
- }
16
- declare const parseL402: (input: string) => Record<string, string>;
17
- declare const makeAuthenticateHeader: (args: {
18
- macaroon: string;
19
- invoice: string;
20
- key?: string;
21
- }) => string;
22
-
23
- interface Wallet {
24
- sendPayment(paymentRequest: string): Promise<{
25
- preimage: string;
26
- }>;
27
- }
28
- declare const fetchWithL402: (url: string, fetchArgs: RequestInit, options: {
29
- headerKey?: string;
30
- wallet?: Wallet;
31
- store?: KVStorage;
32
- }) => Promise<Response>;
33
-
34
- export { MemoryStorage, NoStorage, fetchWithL402, makeAuthenticateHeader, parseL402 };
35
- export type { KVStorage };