@getalby/lightning-tools 6.1.0 → 8.0.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 +111 -29
  2. package/dist/cjs/402/l402.cjs +55 -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 +1313 -0
  7. package/dist/cjs/402/x402.cjs.map +1 -0
  8. package/dist/cjs/402.cjs +1585 -0
  9. package/dist/cjs/402.cjs.map +1 -0
  10. package/dist/cjs/bolt11.cjs +8 -0
  11. package/dist/cjs/bolt11.cjs.map +1 -1
  12. package/dist/cjs/index.cjs +304 -52
  13. package/dist/cjs/index.cjs.map +1 -1
  14. package/dist/cjs/lnurl.cjs +8 -0
  15. package/dist/cjs/lnurl.cjs.map +1 -1
  16. package/dist/esm/402/l402.js +53 -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 +1311 -0
  21. package/dist/esm/402/x402.js.map +1 -0
  22. package/dist/esm/402.js +1579 -0
  23. package/dist/esm/402.js.map +1 -0
  24. package/dist/esm/bolt11.js +8 -0
  25. package/dist/esm/bolt11.js.map +1 -1
  26. package/dist/esm/index.js +301 -50
  27. package/dist/esm/index.js.map +1 -1
  28. package/dist/esm/lnurl.js +8 -0
  29. package/dist/esm/lnurl.js.map +1 -1
  30. package/dist/lightning-tools.umd.js +2 -2
  31. package/dist/lightning-tools.umd.js.map +1 -1
  32. package/dist/types/402/l402.d.ts +13 -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 +41 -0
  36. package/dist/types/bolt11.d.ts +4 -0
  37. package/dist/types/index.d.ts +40 -20
  38. package/dist/types/lnurl.d.ts +2 -0
  39. package/package.json +20 -5
  40. package/dist/cjs/l402.cjs +0 -89
  41. package/dist/cjs/l402.cjs.map +0 -1
  42. package/dist/esm/l402.js +0 -84
  43. package/dist/esm/l402.js.map +0 -1
  44. package/dist/types/l402.d.ts +0 -27
@@ -0,0 +1,1579 @@
1
+ function bytes(b, ...lengths) {
2
+ if (!(b instanceof Uint8Array))
3
+ throw new Error('Expected Uint8Array');
4
+ if (lengths.length > 0 && !lengths.includes(b.length))
5
+ throw new Error(`Expected Uint8Array of length ${lengths}, not of length=${b.length}`);
6
+ }
7
+ function exists(instance, checkFinished = true) {
8
+ if (instance.destroyed)
9
+ throw new Error('Hash instance has been destroyed');
10
+ if (checkFinished && instance.finished)
11
+ throw new Error('Hash#digest() has already been called');
12
+ }
13
+ function output(out, instance) {
14
+ bytes(out);
15
+ const min = instance.outputLen;
16
+ if (out.length < min) {
17
+ throw new Error(`digestInto() expects output buffer of length at least ${min}`);
18
+ }
19
+ }
20
+
21
+ /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
22
+ // We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
23
+ // node.js versions earlier than v19 don't declare it in global scope.
24
+ // For node.js, package.json#exports field mapping rewrites import
25
+ // from `crypto` to `cryptoNode`, which imports native module.
26
+ // Makes the utils un-importable in browsers without a bundler.
27
+ // Once node.js 18 is deprecated, we can just drop the import.
28
+ const u8a = (a) => a instanceof Uint8Array;
29
+ // Cast array to view
30
+ const createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
31
+ // The rotate right (circular right shift) operation for uint32
32
+ const rotr = (word, shift) => (word << (32 - shift)) | (word >>> shift);
33
+ // big-endian hardware is rare. Just in case someone still decides to run hashes:
34
+ // early-throw an error because we don't support BE yet.
35
+ const isLE = new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44;
36
+ if (!isLE)
37
+ throw new Error('Non little-endian hardware is not supported');
38
+ const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
39
+ /**
40
+ * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'
41
+ */
42
+ function bytesToHex(bytes) {
43
+ if (!u8a(bytes))
44
+ throw new Error('Uint8Array expected');
45
+ // pre-caching improves the speed 6x
46
+ let hex = '';
47
+ for (let i = 0; i < bytes.length; i++) {
48
+ hex += hexes[bytes[i]];
49
+ }
50
+ return hex;
51
+ }
52
+ /**
53
+ * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
54
+ */
55
+ function utf8ToBytes(str) {
56
+ if (typeof str !== 'string')
57
+ throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
58
+ return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
59
+ }
60
+ /**
61
+ * Normalizes (non-hex) string or Uint8Array to Uint8Array.
62
+ * Warning: when Uint8Array is passed, it would NOT get copied.
63
+ * Keep in mind for future mutable operations.
64
+ */
65
+ function toBytes(data) {
66
+ if (typeof data === 'string')
67
+ data = utf8ToBytes(data);
68
+ if (!u8a(data))
69
+ throw new Error(`expected Uint8Array, got ${typeof data}`);
70
+ return data;
71
+ }
72
+ // For runtime check if class implements interface
73
+ class Hash {
74
+ // Safe version that clones internal state
75
+ clone() {
76
+ return this._cloneInto();
77
+ }
78
+ }
79
+ function wrapConstructor(hashCons) {
80
+ const hashC = (msg) => hashCons().update(toBytes(msg)).digest();
81
+ const tmp = hashCons();
82
+ hashC.outputLen = tmp.outputLen;
83
+ hashC.blockLen = tmp.blockLen;
84
+ hashC.create = () => hashCons();
85
+ return hashC;
86
+ }
87
+
88
+ // Polyfill for Safari 14
89
+ function setBigUint64(view, byteOffset, value, isLE) {
90
+ if (typeof view.setBigUint64 === 'function')
91
+ return view.setBigUint64(byteOffset, value, isLE);
92
+ const _32n = BigInt(32);
93
+ const _u32_max = BigInt(0xffffffff);
94
+ const wh = Number((value >> _32n) & _u32_max);
95
+ const wl = Number(value & _u32_max);
96
+ const h = isLE ? 4 : 0;
97
+ const l = isLE ? 0 : 4;
98
+ view.setUint32(byteOffset + h, wh, isLE);
99
+ view.setUint32(byteOffset + l, wl, isLE);
100
+ }
101
+ // Base SHA2 class (RFC 6234)
102
+ class SHA2 extends Hash {
103
+ constructor(blockLen, outputLen, padOffset, isLE) {
104
+ super();
105
+ this.blockLen = blockLen;
106
+ this.outputLen = outputLen;
107
+ this.padOffset = padOffset;
108
+ this.isLE = isLE;
109
+ this.finished = false;
110
+ this.length = 0;
111
+ this.pos = 0;
112
+ this.destroyed = false;
113
+ this.buffer = new Uint8Array(blockLen);
114
+ this.view = createView(this.buffer);
115
+ }
116
+ update(data) {
117
+ exists(this);
118
+ const { view, buffer, blockLen } = this;
119
+ data = toBytes(data);
120
+ const len = data.length;
121
+ for (let pos = 0; pos < len;) {
122
+ const take = Math.min(blockLen - this.pos, len - pos);
123
+ // Fast path: we have at least one block in input, cast it to view and process
124
+ if (take === blockLen) {
125
+ const dataView = createView(data);
126
+ for (; blockLen <= len - pos; pos += blockLen)
127
+ this.process(dataView, pos);
128
+ continue;
129
+ }
130
+ buffer.set(data.subarray(pos, pos + take), this.pos);
131
+ this.pos += take;
132
+ pos += take;
133
+ if (this.pos === blockLen) {
134
+ this.process(view, 0);
135
+ this.pos = 0;
136
+ }
137
+ }
138
+ this.length += data.length;
139
+ this.roundClean();
140
+ return this;
141
+ }
142
+ digestInto(out) {
143
+ exists(this);
144
+ output(out, this);
145
+ this.finished = true;
146
+ // Padding
147
+ // We can avoid allocation of buffer for padding completely if it
148
+ // was previously not allocated here. But it won't change performance.
149
+ const { buffer, view, blockLen, isLE } = this;
150
+ let { pos } = this;
151
+ // append the bit '1' to the message
152
+ buffer[pos++] = 0b10000000;
153
+ this.buffer.subarray(pos).fill(0);
154
+ // we have less than padOffset left in buffer, so we cannot put length in current block, need process it and pad again
155
+ if (this.padOffset > blockLen - pos) {
156
+ this.process(view, 0);
157
+ pos = 0;
158
+ }
159
+ // Pad until full block byte with zeros
160
+ for (let i = pos; i < blockLen; i++)
161
+ buffer[i] = 0;
162
+ // Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that
163
+ // You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen.
164
+ // So we just write lowest 64 bits of that value.
165
+ setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);
166
+ this.process(view, 0);
167
+ const oview = createView(out);
168
+ const len = this.outputLen;
169
+ // NOTE: we do division by 4 later, which should be fused in single op with modulo by JIT
170
+ if (len % 4)
171
+ throw new Error('_sha2: outputLen should be aligned to 32bit');
172
+ const outLen = len / 4;
173
+ const state = this.get();
174
+ if (outLen > state.length)
175
+ throw new Error('_sha2: outputLen bigger than state');
176
+ for (let i = 0; i < outLen; i++)
177
+ oview.setUint32(4 * i, state[i], isLE);
178
+ }
179
+ digest() {
180
+ const { buffer, outputLen } = this;
181
+ this.digestInto(buffer);
182
+ const res = buffer.slice(0, outputLen);
183
+ this.destroy();
184
+ return res;
185
+ }
186
+ _cloneInto(to) {
187
+ to || (to = new this.constructor());
188
+ to.set(...this.get());
189
+ const { blockLen, buffer, length, finished, destroyed, pos } = this;
190
+ to.length = length;
191
+ to.pos = pos;
192
+ to.finished = finished;
193
+ to.destroyed = destroyed;
194
+ if (length % blockLen)
195
+ to.buffer.set(buffer);
196
+ return to;
197
+ }
198
+ }
199
+
200
+ // SHA2-256 need to try 2^128 hashes to execute birthday attack.
201
+ // BTC network is doing 2^67 hashes/sec as per early 2023.
202
+ // Choice: a ? b : c
203
+ const Chi = (a, b, c) => (a & b) ^ (~a & c);
204
+ // Majority function, true if any two inpust is true
205
+ const Maj = (a, b, c) => (a & b) ^ (a & c) ^ (b & c);
206
+ // Round constants:
207
+ // first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
208
+ // prettier-ignore
209
+ const SHA256_K = /* @__PURE__ */ new Uint32Array([
210
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
211
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
212
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
213
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
214
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
215
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
216
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
217
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
218
+ ]);
219
+ // Initial state (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
220
+ // prettier-ignore
221
+ const IV = /* @__PURE__ */ new Uint32Array([
222
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
223
+ ]);
224
+ // Temporary buffer, not used to store anything between runs
225
+ // Named this way because it matches specification.
226
+ const SHA256_W = /* @__PURE__ */ new Uint32Array(64);
227
+ class SHA256 extends SHA2 {
228
+ constructor() {
229
+ super(64, 32, 8, false);
230
+ // We cannot use array here since array allows indexing by variable
231
+ // which means optimizer/compiler cannot use registers.
232
+ this.A = IV[0] | 0;
233
+ this.B = IV[1] | 0;
234
+ this.C = IV[2] | 0;
235
+ this.D = IV[3] | 0;
236
+ this.E = IV[4] | 0;
237
+ this.F = IV[5] | 0;
238
+ this.G = IV[6] | 0;
239
+ this.H = IV[7] | 0;
240
+ }
241
+ get() {
242
+ const { A, B, C, D, E, F, G, H } = this;
243
+ return [A, B, C, D, E, F, G, H];
244
+ }
245
+ // prettier-ignore
246
+ set(A, B, C, D, E, F, G, H) {
247
+ this.A = A | 0;
248
+ this.B = B | 0;
249
+ this.C = C | 0;
250
+ this.D = D | 0;
251
+ this.E = E | 0;
252
+ this.F = F | 0;
253
+ this.G = G | 0;
254
+ this.H = H | 0;
255
+ }
256
+ process(view, offset) {
257
+ // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array
258
+ for (let i = 0; i < 16; i++, offset += 4)
259
+ SHA256_W[i] = view.getUint32(offset, false);
260
+ for (let i = 16; i < 64; i++) {
261
+ const W15 = SHA256_W[i - 15];
262
+ const W2 = SHA256_W[i - 2];
263
+ const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3);
264
+ const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10);
265
+ SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0;
266
+ }
267
+ // Compression function main loop, 64 rounds
268
+ let { A, B, C, D, E, F, G, H } = this;
269
+ for (let i = 0; i < 64; i++) {
270
+ const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
271
+ const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;
272
+ const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
273
+ const T2 = (sigma0 + Maj(A, B, C)) | 0;
274
+ H = G;
275
+ G = F;
276
+ F = E;
277
+ E = (D + T1) | 0;
278
+ D = C;
279
+ C = B;
280
+ B = A;
281
+ A = (T1 + T2) | 0;
282
+ }
283
+ // Add the compressed chunk to the current hash value
284
+ A = (A + this.A) | 0;
285
+ B = (B + this.B) | 0;
286
+ C = (C + this.C) | 0;
287
+ D = (D + this.D) | 0;
288
+ E = (E + this.E) | 0;
289
+ F = (F + this.F) | 0;
290
+ G = (G + this.G) | 0;
291
+ H = (H + this.H) | 0;
292
+ this.set(A, B, C, D, E, F, G, H);
293
+ }
294
+ roundClean() {
295
+ SHA256_W.fill(0);
296
+ }
297
+ destroy() {
298
+ this.set(0, 0, 0, 0, 0, 0, 0, 0);
299
+ this.buffer.fill(0);
300
+ }
301
+ }
302
+ /**
303
+ * SHA2-256 hash function
304
+ * @param message - data that would be hashed
305
+ */
306
+ const sha256 = /* @__PURE__ */ wrapConstructor(() => new SHA256());
307
+
308
+ var lib = {};
309
+
310
+ var hasRequiredLib;
311
+
312
+ function requireLib () {
313
+ if (hasRequiredLib) return lib;
314
+ hasRequiredLib = 1;
315
+ (function (exports) {
316
+ /*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */
317
+ Object.defineProperty(exports, "__esModule", { value: true });
318
+ exports.bytes = exports.stringToBytes = exports.str = exports.bytesToString = exports.hex = exports.utf8 = exports.bech32m = exports.bech32 = exports.base58check = exports.base58xmr = exports.base58xrp = exports.base58flickr = exports.base58 = exports.base64url = exports.base64 = exports.base32crockford = exports.base32hex = exports.base32 = exports.base16 = exports.utils = exports.assertNumber = void 0;
319
+ function assertNumber(n) {
320
+ if (!Number.isSafeInteger(n))
321
+ throw new Error(`Wrong integer: ${n}`);
322
+ }
323
+ exports.assertNumber = assertNumber;
324
+ function chain(...args) {
325
+ const wrap = (a, b) => (c) => a(b(c));
326
+ const encode = Array.from(args)
327
+ .reverse()
328
+ .reduce((acc, i) => (acc ? wrap(acc, i.encode) : i.encode), undefined);
329
+ const decode = args.reduce((acc, i) => (acc ? wrap(acc, i.decode) : i.decode), undefined);
330
+ return { encode, decode };
331
+ }
332
+ function alphabet(alphabet) {
333
+ return {
334
+ encode: (digits) => {
335
+ if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
336
+ throw new Error('alphabet.encode input should be an array of numbers');
337
+ return digits.map((i) => {
338
+ assertNumber(i);
339
+ if (i < 0 || i >= alphabet.length)
340
+ throw new Error(`Digit index outside alphabet: ${i} (alphabet: ${alphabet.length})`);
341
+ return alphabet[i];
342
+ });
343
+ },
344
+ decode: (input) => {
345
+ if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string'))
346
+ throw new Error('alphabet.decode input should be array of strings');
347
+ return input.map((letter) => {
348
+ if (typeof letter !== 'string')
349
+ throw new Error(`alphabet.decode: not string element=${letter}`);
350
+ const index = alphabet.indexOf(letter);
351
+ if (index === -1)
352
+ throw new Error(`Unknown letter: "${letter}". Allowed: ${alphabet}`);
353
+ return index;
354
+ });
355
+ },
356
+ };
357
+ }
358
+ function join(separator = '') {
359
+ if (typeof separator !== 'string')
360
+ throw new Error('join separator should be string');
361
+ return {
362
+ encode: (from) => {
363
+ if (!Array.isArray(from) || (from.length && typeof from[0] !== 'string'))
364
+ throw new Error('join.encode input should be array of strings');
365
+ for (let i of from)
366
+ if (typeof i !== 'string')
367
+ throw new Error(`join.encode: non-string input=${i}`);
368
+ return from.join(separator);
369
+ },
370
+ decode: (to) => {
371
+ if (typeof to !== 'string')
372
+ throw new Error('join.decode input should be string');
373
+ return to.split(separator);
374
+ },
375
+ };
376
+ }
377
+ function padding(bits, chr = '=') {
378
+ assertNumber(bits);
379
+ if (typeof chr !== 'string')
380
+ throw new Error('padding chr should be string');
381
+ return {
382
+ encode(data) {
383
+ if (!Array.isArray(data) || (data.length && typeof data[0] !== 'string'))
384
+ throw new Error('padding.encode input should be array of strings');
385
+ for (let i of data)
386
+ if (typeof i !== 'string')
387
+ throw new Error(`padding.encode: non-string input=${i}`);
388
+ while ((data.length * bits) % 8)
389
+ data.push(chr);
390
+ return data;
391
+ },
392
+ decode(input) {
393
+ if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string'))
394
+ throw new Error('padding.encode input should be array of strings');
395
+ for (let i of input)
396
+ if (typeof i !== 'string')
397
+ throw new Error(`padding.decode: non-string input=${i}`);
398
+ let end = input.length;
399
+ if ((end * bits) % 8)
400
+ throw new Error('Invalid padding: string should have whole number of bytes');
401
+ for (; end > 0 && input[end - 1] === chr; end--) {
402
+ if (!(((end - 1) * bits) % 8))
403
+ throw new Error('Invalid padding: string has too much padding');
404
+ }
405
+ return input.slice(0, end);
406
+ },
407
+ };
408
+ }
409
+ function normalize(fn) {
410
+ if (typeof fn !== 'function')
411
+ throw new Error('normalize fn should be function');
412
+ return { encode: (from) => from, decode: (to) => fn(to) };
413
+ }
414
+ function convertRadix(data, from, to) {
415
+ if (from < 2)
416
+ throw new Error(`convertRadix: wrong from=${from}, base cannot be less than 2`);
417
+ if (to < 2)
418
+ throw new Error(`convertRadix: wrong to=${to}, base cannot be less than 2`);
419
+ if (!Array.isArray(data))
420
+ throw new Error('convertRadix: data should be array');
421
+ if (!data.length)
422
+ return [];
423
+ let pos = 0;
424
+ const res = [];
425
+ const digits = Array.from(data);
426
+ digits.forEach((d) => {
427
+ assertNumber(d);
428
+ if (d < 0 || d >= from)
429
+ throw new Error(`Wrong integer: ${d}`);
430
+ });
431
+ while (true) {
432
+ let carry = 0;
433
+ let done = true;
434
+ for (let i = pos; i < digits.length; i++) {
435
+ const digit = digits[i];
436
+ const digitBase = from * carry + digit;
437
+ if (!Number.isSafeInteger(digitBase) ||
438
+ (from * carry) / from !== carry ||
439
+ digitBase - digit !== from * carry) {
440
+ throw new Error('convertRadix: carry overflow');
441
+ }
442
+ carry = digitBase % to;
443
+ digits[i] = Math.floor(digitBase / to);
444
+ if (!Number.isSafeInteger(digits[i]) || digits[i] * to + carry !== digitBase)
445
+ throw new Error('convertRadix: carry overflow');
446
+ if (!done)
447
+ continue;
448
+ else if (!digits[i])
449
+ pos = i;
450
+ else
451
+ done = false;
452
+ }
453
+ res.push(carry);
454
+ if (done)
455
+ break;
456
+ }
457
+ for (let i = 0; i < data.length - 1 && data[i] === 0; i++)
458
+ res.push(0);
459
+ return res.reverse();
460
+ }
461
+ const gcd = (a, b) => (!b ? a : gcd(b, a % b));
462
+ const radix2carry = (from, to) => from + (to - gcd(from, to));
463
+ function convertRadix2(data, from, to, padding) {
464
+ if (!Array.isArray(data))
465
+ throw new Error('convertRadix2: data should be array');
466
+ if (from <= 0 || from > 32)
467
+ throw new Error(`convertRadix2: wrong from=${from}`);
468
+ if (to <= 0 || to > 32)
469
+ throw new Error(`convertRadix2: wrong to=${to}`);
470
+ if (radix2carry(from, to) > 32) {
471
+ throw new Error(`convertRadix2: carry overflow from=${from} to=${to} carryBits=${radix2carry(from, to)}`);
472
+ }
473
+ let carry = 0;
474
+ let pos = 0;
475
+ const mask = 2 ** to - 1;
476
+ const res = [];
477
+ for (const n of data) {
478
+ assertNumber(n);
479
+ if (n >= 2 ** from)
480
+ throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);
481
+ carry = (carry << from) | n;
482
+ if (pos + from > 32)
483
+ throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`);
484
+ pos += from;
485
+ for (; pos >= to; pos -= to)
486
+ res.push(((carry >> (pos - to)) & mask) >>> 0);
487
+ carry &= 2 ** pos - 1;
488
+ }
489
+ carry = (carry << (to - pos)) & mask;
490
+ if (!padding && pos >= from)
491
+ throw new Error('Excess padding');
492
+ if (!padding && carry)
493
+ throw new Error(`Non-zero padding: ${carry}`);
494
+ if (padding && pos > 0)
495
+ res.push(carry >>> 0);
496
+ return res;
497
+ }
498
+ function radix(num) {
499
+ assertNumber(num);
500
+ return {
501
+ encode: (bytes) => {
502
+ if (!(bytes instanceof Uint8Array))
503
+ throw new Error('radix.encode input should be Uint8Array');
504
+ return convertRadix(Array.from(bytes), 2 ** 8, num);
505
+ },
506
+ decode: (digits) => {
507
+ if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
508
+ throw new Error('radix.decode input should be array of strings');
509
+ return Uint8Array.from(convertRadix(digits, num, 2 ** 8));
510
+ },
511
+ };
512
+ }
513
+ function radix2(bits, revPadding = false) {
514
+ assertNumber(bits);
515
+ if (bits <= 0 || bits > 32)
516
+ throw new Error('radix2: bits should be in (0..32]');
517
+ if (radix2carry(8, bits) > 32 || radix2carry(bits, 8) > 32)
518
+ throw new Error('radix2: carry overflow');
519
+ return {
520
+ encode: (bytes) => {
521
+ if (!(bytes instanceof Uint8Array))
522
+ throw new Error('radix2.encode input should be Uint8Array');
523
+ return convertRadix2(Array.from(bytes), 8, bits, !revPadding);
524
+ },
525
+ decode: (digits) => {
526
+ if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
527
+ throw new Error('radix2.decode input should be array of strings');
528
+ return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));
529
+ },
530
+ };
531
+ }
532
+ function unsafeWrapper(fn) {
533
+ if (typeof fn !== 'function')
534
+ throw new Error('unsafeWrapper fn should be function');
535
+ return function (...args) {
536
+ try {
537
+ return fn.apply(null, args);
538
+ }
539
+ catch (e) { }
540
+ };
541
+ }
542
+ function checksum(len, fn) {
543
+ assertNumber(len);
544
+ if (typeof fn !== 'function')
545
+ throw new Error('checksum fn should be function');
546
+ return {
547
+ encode(data) {
548
+ if (!(data instanceof Uint8Array))
549
+ throw new Error('checksum.encode: input should be Uint8Array');
550
+ const checksum = fn(data).slice(0, len);
551
+ const res = new Uint8Array(data.length + len);
552
+ res.set(data);
553
+ res.set(checksum, data.length);
554
+ return res;
555
+ },
556
+ decode(data) {
557
+ if (!(data instanceof Uint8Array))
558
+ throw new Error('checksum.decode: input should be Uint8Array');
559
+ const payload = data.slice(0, -len);
560
+ const newChecksum = fn(payload).slice(0, len);
561
+ const oldChecksum = data.slice(-len);
562
+ for (let i = 0; i < len; i++)
563
+ if (newChecksum[i] !== oldChecksum[i])
564
+ throw new Error('Invalid checksum');
565
+ return payload;
566
+ },
567
+ };
568
+ }
569
+ exports.utils = { alphabet, chain, checksum, radix, radix2, join, padding };
570
+ exports.base16 = chain(radix2(4), alphabet('0123456789ABCDEF'), join(''));
571
+ exports.base32 = chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), padding(5), join(''));
572
+ exports.base32hex = chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), padding(5), join(''));
573
+ exports.base32crockford = chain(radix2(5), alphabet('0123456789ABCDEFGHJKMNPQRSTVWXYZ'), join(''), normalize((s) => s.toUpperCase().replace(/O/g, '0').replace(/[IL]/g, '1')));
574
+ exports.base64 = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), padding(6), join(''));
575
+ exports.base64url = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), padding(6), join(''));
576
+ const genBase58 = (abc) => chain(radix(58), alphabet(abc), join(''));
577
+ exports.base58 = genBase58('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
578
+ exports.base58flickr = genBase58('123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ');
579
+ exports.base58xrp = genBase58('rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz');
580
+ const XMR_BLOCK_LEN = [0, 2, 3, 5, 6, 7, 9, 10, 11];
581
+ exports.base58xmr = {
582
+ encode(data) {
583
+ let res = '';
584
+ for (let i = 0; i < data.length; i += 8) {
585
+ const block = data.subarray(i, i + 8);
586
+ res += exports.base58.encode(block).padStart(XMR_BLOCK_LEN[block.length], '1');
587
+ }
588
+ return res;
589
+ },
590
+ decode(str) {
591
+ let res = [];
592
+ for (let i = 0; i < str.length; i += 11) {
593
+ const slice = str.slice(i, i + 11);
594
+ const blockLen = XMR_BLOCK_LEN.indexOf(slice.length);
595
+ const block = exports.base58.decode(slice);
596
+ for (let j = 0; j < block.length - blockLen; j++) {
597
+ if (block[j] !== 0)
598
+ throw new Error('base58xmr: wrong padding');
599
+ }
600
+ res = res.concat(Array.from(block.slice(block.length - blockLen)));
601
+ }
602
+ return Uint8Array.from(res);
603
+ },
604
+ };
605
+ const base58check = (sha256) => chain(checksum(4, (data) => sha256(sha256(data))), exports.base58);
606
+ exports.base58check = base58check;
607
+ const BECH_ALPHABET = chain(alphabet('qpzry9x8gf2tvdw0s3jn54khce6mua7l'), join(''));
608
+ const POLYMOD_GENERATORS = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
609
+ function bech32Polymod(pre) {
610
+ const b = pre >> 25;
611
+ let chk = (pre & 0x1ffffff) << 5;
612
+ for (let i = 0; i < POLYMOD_GENERATORS.length; i++) {
613
+ if (((b >> i) & 1) === 1)
614
+ chk ^= POLYMOD_GENERATORS[i];
615
+ }
616
+ return chk;
617
+ }
618
+ function bechChecksum(prefix, words, encodingConst = 1) {
619
+ const len = prefix.length;
620
+ let chk = 1;
621
+ for (let i = 0; i < len; i++) {
622
+ const c = prefix.charCodeAt(i);
623
+ if (c < 33 || c > 126)
624
+ throw new Error(`Invalid prefix (${prefix})`);
625
+ chk = bech32Polymod(chk) ^ (c >> 5);
626
+ }
627
+ chk = bech32Polymod(chk);
628
+ for (let i = 0; i < len; i++)
629
+ chk = bech32Polymod(chk) ^ (prefix.charCodeAt(i) & 0x1f);
630
+ for (let v of words)
631
+ chk = bech32Polymod(chk) ^ v;
632
+ for (let i = 0; i < 6; i++)
633
+ chk = bech32Polymod(chk);
634
+ chk ^= encodingConst;
635
+ return BECH_ALPHABET.encode(convertRadix2([chk % 2 ** 30], 30, 5, false));
636
+ }
637
+ function genBech32(encoding) {
638
+ const ENCODING_CONST = encoding === 'bech32' ? 1 : 0x2bc830a3;
639
+ const _words = radix2(5);
640
+ const fromWords = _words.decode;
641
+ const toWords = _words.encode;
642
+ const fromWordsUnsafe = unsafeWrapper(fromWords);
643
+ function encode(prefix, words, limit = 90) {
644
+ if (typeof prefix !== 'string')
645
+ throw new Error(`bech32.encode prefix should be string, not ${typeof prefix}`);
646
+ if (!Array.isArray(words) || (words.length && typeof words[0] !== 'number'))
647
+ throw new Error(`bech32.encode words should be array of numbers, not ${typeof words}`);
648
+ const actualLength = prefix.length + 7 + words.length;
649
+ if (limit !== false && actualLength > limit)
650
+ throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`);
651
+ prefix = prefix.toLowerCase();
652
+ return `${prefix}1${BECH_ALPHABET.encode(words)}${bechChecksum(prefix, words, ENCODING_CONST)}`;
653
+ }
654
+ function decode(str, limit = 90) {
655
+ if (typeof str !== 'string')
656
+ throw new Error(`bech32.decode input should be string, not ${typeof str}`);
657
+ if (str.length < 8 || (limit !== false && str.length > limit))
658
+ throw new TypeError(`Wrong string length: ${str.length} (${str}). Expected (8..${limit})`);
659
+ const lowered = str.toLowerCase();
660
+ if (str !== lowered && str !== str.toUpperCase())
661
+ throw new Error(`String must be lowercase or uppercase`);
662
+ str = lowered;
663
+ const sepIndex = str.lastIndexOf('1');
664
+ if (sepIndex === 0 || sepIndex === -1)
665
+ throw new Error(`Letter "1" must be present between prefix and data only`);
666
+ const prefix = str.slice(0, sepIndex);
667
+ const _words = str.slice(sepIndex + 1);
668
+ if (_words.length < 6)
669
+ throw new Error('Data must be at least 6 characters long');
670
+ const words = BECH_ALPHABET.decode(_words).slice(0, -6);
671
+ const sum = bechChecksum(prefix, words, ENCODING_CONST);
672
+ if (!_words.endsWith(sum))
673
+ throw new Error(`Invalid checksum in ${str}: expected "${sum}"`);
674
+ return { prefix, words };
675
+ }
676
+ const decodeUnsafe = unsafeWrapper(decode);
677
+ function decodeToBytes(str) {
678
+ const { prefix, words } = decode(str, false);
679
+ return { prefix, words, bytes: fromWords(words) };
680
+ }
681
+ return { encode, decode, decodeToBytes, decodeUnsafe, fromWords, fromWordsUnsafe, toWords };
682
+ }
683
+ exports.bech32 = genBech32('bech32');
684
+ exports.bech32m = genBech32('bech32m');
685
+ exports.utf8 = {
686
+ encode: (data) => new TextDecoder().decode(data),
687
+ decode: (str) => new TextEncoder().encode(str),
688
+ };
689
+ exports.hex = chain(radix2(4), alphabet('0123456789abcdef'), join(''), normalize((s) => {
690
+ if (typeof s !== 'string' || s.length % 2)
691
+ throw new TypeError(`hex.decode: expected string, got ${typeof s} with length ${s.length}`);
692
+ return s.toLowerCase();
693
+ }));
694
+ const CODERS = {
695
+ utf8: exports.utf8, hex: exports.hex, base16: exports.base16, base32: exports.base32, base64: exports.base64, base64url: exports.base64url, base58: exports.base58, base58xmr: exports.base58xmr
696
+ };
697
+ const coderTypeError = `Invalid encoding type. Available types: ${Object.keys(CODERS).join(', ')}`;
698
+ const bytesToString = (type, bytes) => {
699
+ if (typeof type !== 'string' || !CODERS.hasOwnProperty(type))
700
+ throw new TypeError(coderTypeError);
701
+ if (!(bytes instanceof Uint8Array))
702
+ throw new TypeError('bytesToString() expects Uint8Array');
703
+ return CODERS[type].encode(bytes);
704
+ };
705
+ exports.bytesToString = bytesToString;
706
+ exports.str = exports.bytesToString;
707
+ const stringToBytes = (type, str) => {
708
+ if (!CODERS.hasOwnProperty(type))
709
+ throw new TypeError(coderTypeError);
710
+ if (typeof str !== 'string')
711
+ throw new TypeError('stringToBytes() expects string');
712
+ return CODERS[type].decode(str);
713
+ };
714
+ exports.stringToBytes = stringToBytes;
715
+ exports.bytes = exports.stringToBytes;
716
+ } (lib));
717
+ return lib;
718
+ }
719
+
720
+ var bolt11;
721
+ var hasRequiredBolt11;
722
+
723
+ function requireBolt11 () {
724
+ if (hasRequiredBolt11) return bolt11;
725
+ hasRequiredBolt11 = 1;
726
+ const {bech32, hex, utf8} = requireLib();
727
+
728
+ // defaults for encode; default timestamp is current time at call
729
+ const DEFAULTNETWORK = {
730
+ // default network is bitcoin
731
+ bech32: 'bc',
732
+ pubKeyHash: 0x00,
733
+ scriptHash: 0x05,
734
+ validWitnessVersions: [0]
735
+ };
736
+ const TESTNETWORK = {
737
+ bech32: 'tb',
738
+ pubKeyHash: 0x6f,
739
+ scriptHash: 0xc4,
740
+ validWitnessVersions: [0]
741
+ };
742
+ const SIGNETNETWORK = {
743
+ bech32: 'tbs',
744
+ pubKeyHash: 0x6f,
745
+ scriptHash: 0xc4,
746
+ validWitnessVersions: [0]
747
+ };
748
+ const REGTESTNETWORK = {
749
+ bech32: 'bcrt',
750
+ pubKeyHash: 0x6f,
751
+ scriptHash: 0xc4,
752
+ validWitnessVersions: [0]
753
+ };
754
+ const SIMNETWORK = {
755
+ bech32: 'sb',
756
+ pubKeyHash: 0x3f,
757
+ scriptHash: 0x7b,
758
+ validWitnessVersions: [0]
759
+ };
760
+
761
+ const FEATUREBIT_ORDER = [
762
+ 'option_data_loss_protect',
763
+ 'initial_routing_sync',
764
+ 'option_upfront_shutdown_script',
765
+ 'gossip_queries',
766
+ 'var_onion_optin',
767
+ 'gossip_queries_ex',
768
+ 'option_static_remotekey',
769
+ 'payment_secret',
770
+ 'basic_mpp',
771
+ 'option_support_large_channel'
772
+ ];
773
+
774
+ const DIVISORS = {
775
+ m: BigInt(1e3),
776
+ u: BigInt(1e6),
777
+ n: BigInt(1e9),
778
+ p: BigInt(1e12)
779
+ };
780
+
781
+ const MAX_MILLISATS = BigInt('2100000000000000000');
782
+
783
+ const MILLISATS_PER_BTC = BigInt(1e11);
784
+
785
+ const TAGCODES = {
786
+ payment_hash: 1,
787
+ payment_secret: 16,
788
+ description: 13,
789
+ payee: 19,
790
+ description_hash: 23, // commit to longer descriptions (used by lnurl-pay)
791
+ expiry: 6, // default: 3600 (1 hour)
792
+ min_final_cltv_expiry: 24, // default: 9
793
+ fallback_address: 9,
794
+ route_hint: 3, // for extra routing info (private etc.)
795
+ feature_bits: 5,
796
+ metadata: 27
797
+ };
798
+
799
+ // reverse the keys and values of TAGCODES and insert into TAGNAMES
800
+ const TAGNAMES = {};
801
+ for (let i = 0, keys = Object.keys(TAGCODES); i < keys.length; i++) {
802
+ const currentName = keys[i];
803
+ const currentCode = TAGCODES[keys[i]].toString();
804
+ TAGNAMES[currentCode] = currentName;
805
+ }
806
+
807
+ const TAGPARSERS = {
808
+ 1: words => hex.encode(bech32.fromWordsUnsafe(words)), // 256 bits
809
+ 16: words => hex.encode(bech32.fromWordsUnsafe(words)), // 256 bits
810
+ 13: words => utf8.encode(bech32.fromWordsUnsafe(words)), // string variable length
811
+ 19: words => hex.encode(bech32.fromWordsUnsafe(words)), // 264 bits
812
+ 23: words => hex.encode(bech32.fromWordsUnsafe(words)), // 256 bits
813
+ 27: words => hex.encode(bech32.fromWordsUnsafe(words)), // variable
814
+ 6: wordsToIntBE, // default: 3600 (1 hour)
815
+ 24: wordsToIntBE, // default: 9
816
+ 3: routingInfoParser, // for extra routing info (private etc.)
817
+ 5: featureBitsParser // keep feature bits as array of 5 bit words
818
+ };
819
+
820
+ function getUnknownParser(tagCode) {
821
+ return words => ({
822
+ tagCode: parseInt(tagCode),
823
+ words: bech32.encode('unknown', words, Number.MAX_SAFE_INTEGER)
824
+ })
825
+ }
826
+
827
+ function wordsToIntBE(words) {
828
+ return words.reverse().reduce((total, item, index) => {
829
+ return total + item * Math.pow(32, index)
830
+ }, 0)
831
+ }
832
+
833
+ // first convert from words to buffer, trimming padding where necessary
834
+ // parse in 51 byte chunks. See encoder for details.
835
+ function routingInfoParser(words) {
836
+ const routes = [];
837
+ let pubkey,
838
+ shortChannelId,
839
+ feeBaseMSats,
840
+ feeProportionalMillionths,
841
+ cltvExpiryDelta;
842
+ let routesBuffer = bech32.fromWordsUnsafe(words);
843
+ while (routesBuffer.length > 0) {
844
+ pubkey = hex.encode(routesBuffer.slice(0, 33)); // 33 bytes
845
+ shortChannelId = hex.encode(routesBuffer.slice(33, 41)); // 8 bytes
846
+ feeBaseMSats = parseInt(hex.encode(routesBuffer.slice(41, 45)), 16); // 4 bytes
847
+ feeProportionalMillionths = parseInt(
848
+ hex.encode(routesBuffer.slice(45, 49)),
849
+ 16
850
+ ); // 4 bytes
851
+ cltvExpiryDelta = parseInt(hex.encode(routesBuffer.slice(49, 51)), 16); // 2 bytes
852
+
853
+ routesBuffer = routesBuffer.slice(51);
854
+
855
+ routes.push({
856
+ pubkey,
857
+ short_channel_id: shortChannelId,
858
+ fee_base_msat: feeBaseMSats,
859
+ fee_proportional_millionths: feeProportionalMillionths,
860
+ cltv_expiry_delta: cltvExpiryDelta
861
+ });
862
+ }
863
+ return routes
864
+ }
865
+
866
+ function featureBitsParser(words) {
867
+ const bools = words
868
+ .slice()
869
+ .reverse()
870
+ .map(word => [
871
+ !!(word & 0b1),
872
+ !!(word & 0b10),
873
+ !!(word & 0b100),
874
+ !!(word & 0b1000),
875
+ !!(word & 0b10000)
876
+ ])
877
+ .reduce((finalArr, itemArr) => finalArr.concat(itemArr), []);
878
+ while (bools.length < FEATUREBIT_ORDER.length * 2) {
879
+ bools.push(false);
880
+ }
881
+
882
+ const featureBits = {};
883
+
884
+ FEATUREBIT_ORDER.forEach((featureName, index) => {
885
+ let status;
886
+ if (bools[index * 2]) {
887
+ status = 'required';
888
+ } else if (bools[index * 2 + 1]) {
889
+ status = 'supported';
890
+ } else {
891
+ status = 'unsupported';
892
+ }
893
+ featureBits[featureName] = status;
894
+ });
895
+
896
+ const extraBits = bools.slice(FEATUREBIT_ORDER.length * 2);
897
+ featureBits.extra_bits = {
898
+ start_bit: FEATUREBIT_ORDER.length * 2,
899
+ bits: extraBits,
900
+ has_required: extraBits.reduce(
901
+ (result, bit, index) =>
902
+ index % 2 !== 0 ? result || false : result || bit,
903
+ false
904
+ )
905
+ };
906
+
907
+ return featureBits
908
+ }
909
+
910
+ function hrpToMillisat(hrpString, outputString) {
911
+ let divisor, value;
912
+ if (hrpString.slice(-1).match(/^[munp]$/)) {
913
+ divisor = hrpString.slice(-1);
914
+ value = hrpString.slice(0, -1);
915
+ } else if (hrpString.slice(-1).match(/^[^munp0-9]$/)) {
916
+ throw new Error('Not a valid multiplier for the amount')
917
+ } else {
918
+ value = hrpString;
919
+ }
920
+
921
+ if (!value.match(/^\d+$/))
922
+ throw new Error('Not a valid human readable amount')
923
+
924
+ const valueBN = BigInt(value);
925
+
926
+ const millisatoshisBN = divisor
927
+ ? (valueBN * MILLISATS_PER_BTC) / DIVISORS[divisor]
928
+ : valueBN * MILLISATS_PER_BTC;
929
+
930
+ if (
931
+ (divisor === 'p' && !(valueBN % BigInt(10) === BigInt(0))) ||
932
+ millisatoshisBN > MAX_MILLISATS
933
+ ) {
934
+ throw new Error('Amount is outside of valid range')
935
+ }
936
+
937
+ return outputString ? millisatoshisBN.toString() : millisatoshisBN
938
+ }
939
+
940
+ // decode will only have extra comments that aren't covered in encode comments.
941
+ // also if anything is hard to read I'll comment.
942
+ function decode(paymentRequest, network) {
943
+ if (typeof paymentRequest !== 'string')
944
+ throw new Error('Lightning Payment Request must be string')
945
+ if (paymentRequest.slice(0, 2).toLowerCase() !== 'ln')
946
+ throw new Error('Not a proper lightning payment request')
947
+
948
+ const sections = [];
949
+ const decoded = bech32.decode(paymentRequest, Number.MAX_SAFE_INTEGER);
950
+ paymentRequest = paymentRequest.toLowerCase();
951
+ const prefix = decoded.prefix;
952
+ let words = decoded.words;
953
+ let letters = paymentRequest.slice(prefix.length + 1);
954
+ let sigWords = words.slice(-104);
955
+ words = words.slice(0, -104);
956
+
957
+ // Without reverse lookups, can't say that the multipier at the end must
958
+ // have a number before it, so instead we parse, and if the second group
959
+ // doesn't have anything, there's a good chance the last letter of the
960
+ // coin type got captured by the third group, so just re-regex without
961
+ // the number.
962
+ let prefixMatches = prefix.match(/^ln(\S+?)(\d*)([a-zA-Z]?)$/);
963
+ if (prefixMatches && !prefixMatches[2])
964
+ prefixMatches = prefix.match(/^ln(\S+)$/);
965
+ if (!prefixMatches) {
966
+ throw new Error('Not a proper lightning payment request')
967
+ }
968
+
969
+ // "ln" section
970
+ sections.push({
971
+ name: 'lightning_network',
972
+ letters: 'ln'
973
+ });
974
+
975
+ // "bc" section
976
+ const bech32Prefix = prefixMatches[1];
977
+ let coinNetwork;
978
+ if (!network) {
979
+ switch (bech32Prefix) {
980
+ case DEFAULTNETWORK.bech32:
981
+ coinNetwork = DEFAULTNETWORK;
982
+ break
983
+ case TESTNETWORK.bech32:
984
+ coinNetwork = TESTNETWORK;
985
+ break
986
+ case SIGNETNETWORK.bech32:
987
+ coinNetwork = SIGNETNETWORK;
988
+ break
989
+ case REGTESTNETWORK.bech32:
990
+ coinNetwork = REGTESTNETWORK;
991
+ break
992
+ case SIMNETWORK.bech32:
993
+ coinNetwork = SIMNETWORK;
994
+ break
995
+ }
996
+ } else {
997
+ if (
998
+ network.bech32 === undefined ||
999
+ network.pubKeyHash === undefined ||
1000
+ network.scriptHash === undefined ||
1001
+ !Array.isArray(network.validWitnessVersions)
1002
+ )
1003
+ throw new Error('Invalid network')
1004
+ coinNetwork = network;
1005
+ }
1006
+ if (!coinNetwork || coinNetwork.bech32 !== bech32Prefix) {
1007
+ throw new Error('Unknown coin bech32 prefix')
1008
+ }
1009
+ sections.push({
1010
+ name: 'coin_network',
1011
+ letters: bech32Prefix,
1012
+ value: coinNetwork
1013
+ });
1014
+
1015
+ // amount section
1016
+ const value = prefixMatches[2];
1017
+ let millisatoshis;
1018
+ if (value) {
1019
+ const divisor = prefixMatches[3];
1020
+ millisatoshis = hrpToMillisat(value + divisor, true);
1021
+ sections.push({
1022
+ name: 'amount',
1023
+ letters: prefixMatches[2] + prefixMatches[3],
1024
+ value: millisatoshis
1025
+ });
1026
+ } else {
1027
+ millisatoshis = null;
1028
+ }
1029
+
1030
+ // "1" separator
1031
+ sections.push({
1032
+ name: 'separator',
1033
+ letters: '1'
1034
+ });
1035
+
1036
+ // timestamp
1037
+ const timestamp = wordsToIntBE(words.slice(0, 7));
1038
+ words = words.slice(7); // trim off the left 7 words
1039
+ sections.push({
1040
+ name: 'timestamp',
1041
+ letters: letters.slice(0, 7),
1042
+ value: timestamp
1043
+ });
1044
+ letters = letters.slice(7);
1045
+
1046
+ let tagName, parser, tagLength, tagWords;
1047
+ // we have no tag count to go on, so just keep hacking off words
1048
+ // until we have none.
1049
+ while (words.length > 0) {
1050
+ const tagCode = words[0].toString();
1051
+ tagName = TAGNAMES[tagCode] || 'unknown_tag';
1052
+ parser = TAGPARSERS[tagCode] || getUnknownParser(tagCode);
1053
+ words = words.slice(1);
1054
+
1055
+ tagLength = wordsToIntBE(words.slice(0, 2));
1056
+ words = words.slice(2);
1057
+
1058
+ tagWords = words.slice(0, tagLength);
1059
+ words = words.slice(tagLength);
1060
+
1061
+ sections.push({
1062
+ name: tagName,
1063
+ tag: letters[0],
1064
+ letters: letters.slice(0, 1 + 2 + tagLength),
1065
+ value: parser(tagWords) // see: parsers for more comments
1066
+ });
1067
+ letters = letters.slice(1 + 2 + tagLength);
1068
+ }
1069
+
1070
+ // signature
1071
+ sections.push({
1072
+ name: 'signature',
1073
+ letters: letters.slice(0, 104),
1074
+ value: hex.encode(bech32.fromWordsUnsafe(sigWords))
1075
+ });
1076
+ letters = letters.slice(104);
1077
+
1078
+ // checksum
1079
+ sections.push({
1080
+ name: 'checksum',
1081
+ letters: letters
1082
+ });
1083
+
1084
+ let result = {
1085
+ paymentRequest,
1086
+ sections,
1087
+
1088
+ get expiry() {
1089
+ let exp = sections.find(s => s.name === 'expiry');
1090
+ if (exp) return getValue('timestamp') + exp.value
1091
+ },
1092
+
1093
+ get route_hints() {
1094
+ return sections.filter(s => s.name === 'route_hint').map(s => s.value)
1095
+ }
1096
+ };
1097
+
1098
+ for (let name in TAGCODES) {
1099
+ if (name === 'route_hint') {
1100
+ // route hints can be multiple, so this won't work for them
1101
+ continue
1102
+ }
1103
+
1104
+ Object.defineProperty(result, name, {
1105
+ get() {
1106
+ return getValue(name)
1107
+ }
1108
+ });
1109
+ }
1110
+
1111
+ return result
1112
+
1113
+ function getValue(name) {
1114
+ let section = sections.find(s => s.name === name);
1115
+ return section ? section.value : undefined
1116
+ }
1117
+ }
1118
+
1119
+ bolt11 = {
1120
+ decode,
1121
+ hrpToMillisat
1122
+ };
1123
+ return bolt11;
1124
+ }
1125
+
1126
+ var bolt11Exports = requireBolt11();
1127
+
1128
+ // from https://stackoverflow.com/a/50868276
1129
+ const fromHexString = (hexString) => Uint8Array.from(hexString.match(/.{1,2}/g).map((byte) => parseInt(byte, 16)));
1130
+ const decodeInvoice = (paymentRequest) => {
1131
+ if (!paymentRequest)
1132
+ return null;
1133
+ try {
1134
+ const decoded = bolt11Exports.decode(paymentRequest);
1135
+ if (!decoded || !decoded.sections)
1136
+ return null;
1137
+ const hashTag = decoded.sections.find((value) => value.name === "payment_hash");
1138
+ if (hashTag?.name !== "payment_hash" || !hashTag.value)
1139
+ return null;
1140
+ const paymentHash = hashTag.value;
1141
+ let satoshi = 0;
1142
+ let millisatoshi = 0;
1143
+ let amountRaw = "0";
1144
+ const amountTag = decoded.sections.find((value) => value.name === "amount");
1145
+ if (amountTag?.name === "amount" && amountTag.value) {
1146
+ amountRaw = amountTag.value;
1147
+ millisatoshi = parseInt(amountTag.value);
1148
+ satoshi = parseInt(amountTag.value) / 1000; // millisats
1149
+ }
1150
+ const timestampTag = decoded.sections.find((value) => value.name === "timestamp");
1151
+ if (timestampTag?.name !== "timestamp" || !timestampTag.value)
1152
+ return null;
1153
+ const timestamp = timestampTag.value;
1154
+ let expiry;
1155
+ const expiryTag = decoded.sections.find((value) => value.name === "expiry");
1156
+ if (expiryTag?.name === "expiry") {
1157
+ expiry = expiryTag.value;
1158
+ }
1159
+ const descriptionTag = decoded.sections.find((value) => value.name === "description");
1160
+ const description = descriptionTag?.name === "description"
1161
+ ? descriptionTag?.value
1162
+ : undefined;
1163
+ return {
1164
+ paymentHash,
1165
+ satoshi,
1166
+ millisatoshi,
1167
+ amountRaw,
1168
+ timestamp,
1169
+ expiry,
1170
+ description,
1171
+ };
1172
+ }
1173
+ catch {
1174
+ return null;
1175
+ }
1176
+ };
1177
+
1178
+ class Invoice {
1179
+ constructor(args) {
1180
+ this.paymentRequest = args.pr;
1181
+ if (!this.paymentRequest) {
1182
+ throw new Error("Invalid payment request");
1183
+ }
1184
+ const decodedInvoice = decodeInvoice(this.paymentRequest);
1185
+ if (!decodedInvoice) {
1186
+ throw new Error("Failed to decode payment request");
1187
+ }
1188
+ this.paymentHash = decodedInvoice.paymentHash;
1189
+ this.satoshi = decodedInvoice.satoshi;
1190
+ this.millisatoshi = decodedInvoice.millisatoshi;
1191
+ this.amountRaw = decodedInvoice.amountRaw;
1192
+ this.timestamp = decodedInvoice.timestamp;
1193
+ this.expiry = decodedInvoice.expiry;
1194
+ this.createdDate = new Date(this.timestamp * 1000);
1195
+ this.expiryDate = this.expiry
1196
+ ? new Date((this.timestamp + this.expiry) * 1000)
1197
+ : undefined;
1198
+ this.description = decodedInvoice.description ?? null;
1199
+ this.verify = args.verify ?? null;
1200
+ this.preimage = args.preimage ?? null;
1201
+ this.successAction = args.successAction ?? null;
1202
+ }
1203
+ async isPaid() {
1204
+ if (this.preimage)
1205
+ return this.validatePreimage(this.preimage);
1206
+ else if (this.verify) {
1207
+ return await this.verifyPayment();
1208
+ }
1209
+ else {
1210
+ throw new Error("Could not verify payment");
1211
+ }
1212
+ }
1213
+ validatePreimage(preimage) {
1214
+ if (!preimage || !this.paymentHash)
1215
+ return false;
1216
+ try {
1217
+ const preimageHash = bytesToHex(sha256(fromHexString(preimage)));
1218
+ return this.paymentHash === preimageHash;
1219
+ }
1220
+ catch {
1221
+ return false;
1222
+ }
1223
+ }
1224
+ async verifyPayment() {
1225
+ try {
1226
+ if (!this.verify) {
1227
+ throw new Error("LNURL verify not available");
1228
+ }
1229
+ const response = await fetch(this.verify);
1230
+ if (!response.ok) {
1231
+ throw new Error(`Verification request failed: ${response.status} ${response.statusText}`);
1232
+ }
1233
+ const json = await response.json();
1234
+ if (json.preimage) {
1235
+ this.preimage = json.preimage;
1236
+ }
1237
+ return json.settled;
1238
+ }
1239
+ catch (error) {
1240
+ console.error("Failed to check LNURL-verify", error);
1241
+ return false;
1242
+ }
1243
+ }
1244
+ hasExpired() {
1245
+ const { expiryDate } = this;
1246
+ if (expiryDate) {
1247
+ return expiryDate.getTime() < Date.now();
1248
+ }
1249
+ return false;
1250
+ }
1251
+ }
1252
+
1253
+ function createGuardedWallet(wallet, maxAmountSats) {
1254
+ return {
1255
+ payInvoice: async (args) => {
1256
+ const invoice = new Invoice({ pr: args.invoice });
1257
+ if (invoice.satoshi > maxAmountSats) {
1258
+ throw new Error(`Invoice amount (${invoice.satoshi} sats) exceeds maxAmount (${maxAmountSats} sats)`);
1259
+ }
1260
+ return wallet.payInvoice(args);
1261
+ },
1262
+ };
1263
+ }
1264
+
1265
+ const parseL402 = (input) => {
1266
+ // Remove the L402 and LSAT identifiers
1267
+ const string = input.replace("L402", "").replace("LSAT", "").trim();
1268
+ // Initialize an object to store the key-value pairs
1269
+ const keyValuePairs = {};
1270
+ // Regular expression to match key and (quoted or unquoted) value
1271
+ const regex = /(\w+)=("([^"]*)"|'([^']*)'|([^,]*))/g;
1272
+ let match;
1273
+ // Use regex to find all key-value pairs
1274
+ while ((match = regex.exec(string)) !== null) {
1275
+ // Key is always match[1]
1276
+ // Value is either match[3] (double-quoted), match[4] (single-quoted), or match[5] (unquoted)
1277
+ keyValuePairs[match[1]] = match[3] || match[4] || match[5];
1278
+ }
1279
+ return keyValuePairs;
1280
+ };
1281
+
1282
+ const handleL402Payment = async (l402Header, url, fetchArgs, headers, wallet) => {
1283
+ const details = parseL402(l402Header);
1284
+ const token = details.token || details.macaroon;
1285
+ const invoice = details.invoice;
1286
+ if (!token) {
1287
+ throw new Error("L402: missing token/macaroon in WWW-Authenticate header");
1288
+ }
1289
+ if (!invoice) {
1290
+ throw new Error("L402: missing invoice in WWW-Authenticate header");
1291
+ }
1292
+ const invResp = await wallet.payInvoice({ invoice });
1293
+ headers.set("Authorization", `L402 ${token}:${invResp.preimage}`);
1294
+ return fetch(url, fetchArgs);
1295
+ };
1296
+ const fetchWithL402 = async (url, fetchArgs, options) => {
1297
+ const wallet = options.wallet;
1298
+ if (!wallet) {
1299
+ throw new Error("wallet is missing");
1300
+ }
1301
+ if (!fetchArgs) {
1302
+ fetchArgs = {};
1303
+ }
1304
+ fetchArgs.cache = "no-store";
1305
+ fetchArgs.mode = "cors";
1306
+ const headers = new Headers(fetchArgs.headers ?? undefined);
1307
+ fetchArgs.headers = headers;
1308
+ const initResp = await fetch(url, fetchArgs);
1309
+ const header = initResp.headers.get("www-authenticate");
1310
+ if (!header) {
1311
+ return initResp;
1312
+ }
1313
+ return handleL402Payment(header, url, fetchArgs, headers, wallet);
1314
+ };
1315
+
1316
+ const buildX402PaymentSignature = (scheme, network, invoice, requirements) => {
1317
+ const json = JSON.stringify({
1318
+ x402Version: 2,
1319
+ scheme,
1320
+ network,
1321
+ payload: { invoice },
1322
+ accepted: requirements,
1323
+ });
1324
+ // btoa only handles latin1; encode via UTF-8 to be safe
1325
+ return btoa(unescape(encodeURIComponent(json)));
1326
+ };
1327
+
1328
+ const handleX402Payment = async (x402Header, url, fetchArgs, headers, wallet) => {
1329
+ let parsed;
1330
+ try {
1331
+ parsed = JSON.parse(decodeURIComponent(escape(atob(x402Header))));
1332
+ }
1333
+ catch (_) {
1334
+ throw new Error("x402: invalid PAYMENT-REQUIRED header (not valid base64-encoded JSON)");
1335
+ }
1336
+ if (!Array.isArray(parsed.accepts) || parsed.accepts.length === 0) {
1337
+ throw new Error("x402: PAYMENT-REQUIRED header contains no payment options");
1338
+ }
1339
+ const requirements = parsed.accepts.find((e) => {
1340
+ return e.extra?.paymentMethod === "lightning";
1341
+ });
1342
+ if (!requirements) {
1343
+ throw new Error("x402: unsupported x402 network, only Bitcoin lightning network is supported.");
1344
+ }
1345
+ if (!requirements.extra?.invoice) {
1346
+ throw new Error("x402: payment requirements missing lightning invoice");
1347
+ }
1348
+ const invoice = new Invoice({ pr: requirements.extra.invoice });
1349
+ if (invoice.amountRaw != requirements.amount) {
1350
+ throw new Error(`Invalid invoice amount: ${invoice.amountRaw}. expected ${requirements.amount}`);
1351
+ }
1352
+ await wallet.payInvoice({ invoice: invoice.paymentRequest });
1353
+ headers.set("payment-signature", buildX402PaymentSignature(requirements.scheme, requirements.network, invoice.paymentRequest, requirements));
1354
+ return fetch(url, fetchArgs);
1355
+ };
1356
+ const fetchWithX402 = async (url, fetchArgs, options) => {
1357
+ const wallet = options.wallet;
1358
+ if (!fetchArgs) {
1359
+ fetchArgs = {};
1360
+ }
1361
+ fetchArgs.cache = "no-store";
1362
+ fetchArgs.mode = "cors";
1363
+ const headers = new Headers(fetchArgs.headers ?? undefined);
1364
+ fetchArgs.headers = headers;
1365
+ const initResp = await fetch(url, fetchArgs);
1366
+ const header = initResp.headers.get("PAYMENT-REQUIRED");
1367
+ if (!header) {
1368
+ return initResp;
1369
+ }
1370
+ return handleX402Payment(header, url, fetchArgs, headers, wallet);
1371
+ };
1372
+
1373
+ /**
1374
+ * Parse a `WWW-Authenticate: Payment …` header produced by a
1375
+ * draft-lightning-charge-00 server. Expected format:
1376
+ *
1377
+ * Payment id="<id>", realm="<realm>", method="lightning",
1378
+ * intent="charge", request="<base64url>" [, expires="<rfc3339>"]
1379
+ *
1380
+ * Returns null when the header is not a Payment lightning/charge challenge.
1381
+ */
1382
+ const parseMppChallenge = (header) => {
1383
+ if (!header.trimStart().toLowerCase().startsWith("payment")) {
1384
+ return null;
1385
+ }
1386
+ const rest = header
1387
+ .slice(header.toLowerCase().indexOf("payment") + "payment".length)
1388
+ .trim();
1389
+ const result = {};
1390
+ const regex = /(\w+)=("([^"]*)"|'([^']*)'|([^,\s]*))/g;
1391
+ let match;
1392
+ while ((match = regex.exec(rest)) !== null) {
1393
+ result[match[1]] = match[3] ?? match[4] ?? match[5] ?? "";
1394
+ }
1395
+ if (result.method !== "lightning" ||
1396
+ result.intent !== "charge" ||
1397
+ !result.id ||
1398
+ !result.realm ||
1399
+ !result.request) {
1400
+ return null;
1401
+ }
1402
+ return {
1403
+ id: result.id,
1404
+ realm: result.realm,
1405
+ method: result.method,
1406
+ intent: result.intent,
1407
+ request: result.request,
1408
+ ...(result.expires ? { expires: result.expires } : {}),
1409
+ };
1410
+ };
1411
+ /** Decode a base64url string (no padding required) to a UTF-8 string. */
1412
+ const decodeBase64url = (input) => {
1413
+ const base64 = input.replace(/-/g, "+").replace(/_/g, "/");
1414
+ const binary = atob(base64);
1415
+ const bytes = new Uint8Array(binary.length);
1416
+ for (let i = 0; i < binary.length; i++) {
1417
+ bytes[i] = binary.charCodeAt(i);
1418
+ }
1419
+ return new TextDecoder("utf-8").decode(bytes);
1420
+ };
1421
+ /** Encode a UTF-8 string to base64url without padding. */
1422
+ const encodeBase64url = (input) => {
1423
+ const bytes = new TextEncoder().encode(input);
1424
+ let binary = "";
1425
+ for (let i = 0; i < bytes.length; i++) {
1426
+ binary += String.fromCharCode(bytes[i]);
1427
+ }
1428
+ return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
1429
+ };
1430
+ /**
1431
+ * JSON Canonicalization Scheme (RFC 8785).
1432
+ * Produces compact JSON with object keys sorted lexicographically.
1433
+ */
1434
+ const jcs = (value) => {
1435
+ if (value === null || typeof value !== "object") {
1436
+ return JSON.stringify(value);
1437
+ }
1438
+ if (Array.isArray(value)) {
1439
+ return "[" + value.map(jcs).join(",") + "]";
1440
+ }
1441
+ const keys = Object.keys(value).sort();
1442
+ return ("{" +
1443
+ keys
1444
+ .map((k) => JSON.stringify(k) + ":" + jcs(value[k]))
1445
+ .join(",") +
1446
+ "}");
1447
+ };
1448
+ /**
1449
+ * Build the base64url-encoded credential token for the `Authorization` header.
1450
+ *
1451
+ * Per the spec the credential is a JCS-serialised JSON object that echoes all
1452
+ * challenge auth-params (id, realm, method, intent, request, expires) and
1453
+ * carries the HTLC preimage that proves payment:
1454
+ *
1455
+ * {
1456
+ * "challenge": { "id": "…", "intent": "charge",
1457
+ * "method": "lightning", "realm": "…", "request": "…" },
1458
+ * "payload": { "preimage": "<64-char lowercase hex>" }
1459
+ * }
1460
+ *
1461
+ * Keys are sorted lexicographically at every level per JCS.
1462
+ */
1463
+ const buildMppCredential = (challenge, preimage, source) => {
1464
+ const challengeEcho = {
1465
+ id: challenge.id,
1466
+ intent: challenge.intent,
1467
+ method: challenge.method,
1468
+ realm: challenge.realm,
1469
+ request: challenge.request,
1470
+ };
1471
+ if (challenge.expires) {
1472
+ challengeEcho.expires = challenge.expires;
1473
+ }
1474
+ const credential = {
1475
+ challenge: challengeEcho,
1476
+ payload: { preimage },
1477
+ };
1478
+ return encodeBase64url(jcs(credential));
1479
+ };
1480
+
1481
+ /**
1482
+ * Handle a `WWW-Authenticate: Payment …` challenge produced by a
1483
+ * draft-lightning-charge-00 server.
1484
+ *
1485
+ * Flow:
1486
+ * 1. Parse the challenge from the header.
1487
+ * 2. Decode the `request` auth-param to find the BOLT11 invoice.
1488
+ * 3. Pay the invoice via the wallet; receive the HTLC preimage.
1489
+ * 4. Build the `Authorization: Payment <credential>` header.
1490
+ * 5. Retry the original request with the credential.
1491
+ */
1492
+ const handleMppChargePayment = async (wwwAuthHeader, url, fetchArgs, headers, wallet) => {
1493
+ const challenge = parseMppChallenge(wwwAuthHeader);
1494
+ if (!challenge) {
1495
+ throw new Error("mpp: invalid or unsupported WWW-Authenticate challenge (expected Payment method=lightning intent=charge)");
1496
+ }
1497
+ let request;
1498
+ try {
1499
+ request = JSON.parse(decodeBase64url(challenge.request));
1500
+ }
1501
+ catch (_) {
1502
+ throw new Error("mpp: invalid request auth-param (not valid base64url-encoded JSON)");
1503
+ }
1504
+ const invoice = request.methodDetails?.invoice;
1505
+ if (!invoice) {
1506
+ throw new Error("mpp: missing invoice in charge request");
1507
+ }
1508
+ const invResp = await wallet.payInvoice({ invoice });
1509
+ // Per spec: Authorization: Payment <base64url-token> (single token, no wrapper)
1510
+ const credential = buildMppCredential(challenge, invResp.preimage);
1511
+ headers.set("Authorization", `Payment ${credential}`);
1512
+ return fetch(url, fetchArgs);
1513
+ };
1514
+ /**
1515
+ * Fetch a resource protected by the draft-lightning-charge-00 payment
1516
+ * authentication protocol.
1517
+ *
1518
+ * On a `402 Payment Required` response that carries a
1519
+ * `WWW-Authenticate: Payment method="lightning" intent="charge" …` header
1520
+ * the function pays the embedded BOLT11 invoice and retries with the
1521
+ * resulting preimage as the credential.
1522
+ *
1523
+ * Note: lightning-charge uses consume-once challenge semantics – each
1524
+ * challenge embeds a fresh invoice, so paid credentials cannot be reused.
1525
+ * The `store` option is accepted for API consistency but is not used.
1526
+ */
1527
+ const fetchWithMpp = async (url, fetchArgs, options) => {
1528
+ const wallet = options.wallet;
1529
+ if (!wallet) {
1530
+ throw new Error("wallet is missing");
1531
+ }
1532
+ if (!fetchArgs) {
1533
+ fetchArgs = {};
1534
+ }
1535
+ fetchArgs.cache = "no-store";
1536
+ fetchArgs.mode = "cors";
1537
+ const headers = new Headers(fetchArgs.headers ?? undefined);
1538
+ fetchArgs.headers = headers;
1539
+ const initResp = await fetch(url, fetchArgs);
1540
+ const wwwAuthHeader = initResp.headers.get("www-authenticate");
1541
+ if (!wwwAuthHeader ||
1542
+ !wwwAuthHeader.trimStart().toLowerCase().startsWith("payment")) {
1543
+ return initResp;
1544
+ }
1545
+ return handleMppChargePayment(wwwAuthHeader, url, fetchArgs, headers, wallet);
1546
+ };
1547
+
1548
+ const fetch402 = async (url, fetchArgs, options) => {
1549
+ const wallet = options.maxAmount
1550
+ ? createGuardedWallet(options.wallet, options.maxAmount)
1551
+ : options.wallet;
1552
+ if (!fetchArgs) {
1553
+ fetchArgs = {};
1554
+ }
1555
+ fetchArgs.cache = "no-store";
1556
+ fetchArgs.mode = "cors";
1557
+ const headers = new Headers(fetchArgs.headers ?? undefined);
1558
+ fetchArgs.headers = headers;
1559
+ const initResp = await fetch(url, fetchArgs);
1560
+ const wwwAuthHeader = initResp.headers.get("www-authenticate");
1561
+ if (wwwAuthHeader) {
1562
+ const trimmed = wwwAuthHeader.trimStart().toLowerCase();
1563
+ if (trimmed.startsWith("payment")) {
1564
+ return handleMppChargePayment(wwwAuthHeader, url, fetchArgs, headers, wallet);
1565
+ }
1566
+ if (trimmed.startsWith("l402") || trimmed.startsWith("lsat")) {
1567
+ return handleL402Payment(wwwAuthHeader, url, fetchArgs, headers, wallet);
1568
+ }
1569
+ throw new Error(`fetch402: unsupported WWW-Authenticate scheme: ${wwwAuthHeader}`);
1570
+ }
1571
+ const x402Header = initResp.headers.get("PAYMENT-REQUIRED");
1572
+ if (x402Header) {
1573
+ return handleX402Payment(x402Header, url, fetchArgs, headers, wallet);
1574
+ }
1575
+ return initResp;
1576
+ };
1577
+
1578
+ export { createGuardedWallet, fetch402, fetchWithL402, fetchWithMpp, fetchWithX402 };
1579
+ //# sourceMappingURL=402.js.map