thunder-bridge 0.8.9 → 0.8.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/server.cjs CHANGED
@@ -402,20 +402,22 @@ var REDIRECTS = [301, 302, 303, 307, 308];
402
402
  var KEEPS_THE_METHOD = [307, 308];
403
403
  var CREDENTIALS = ["authorization", "cookie", "proxy-authorization"];
404
404
  var BODY_LIMIT_BYTES = 262144;
405
+ var throughFetch = (url, sent, signal) => fetch(url, {
406
+ method: sent.method ?? "GET",
407
+ headers: sent.headers ?? {},
408
+ body: sent.body,
409
+ redirect: "manual",
410
+ signal
411
+ });
412
+ var send = throughFetch;
405
413
  async function ask(url, sent = {}) {
406
414
  const capped = AbortSignal.timeout(HTTP_TIMEOUT_MS);
407
415
  const signal = sent.deadline ? AbortSignal.any([sent.deadline, capped]) : capped;
408
416
  let target = url;
409
417
  let carried = sent;
410
418
  for (let hop = 0; hop <= HOPS_FOLLOWED; hop += 1) {
411
- await refuseUnlessPublic(target);
412
- const response = await fetch(target, {
413
- method: carried.method ?? "GET",
414
- headers: carried.headers ?? {},
415
- body: carried.body,
416
- redirect: "manual",
417
- signal
418
- });
419
+ const at = await addressesToReach(target);
420
+ const response = await send(target, carried, signal, at);
419
421
  if (!REDIRECTS.includes(response.status)) return await answerOf(response);
420
422
  const location = response.headers.get("location");
421
423
  if (location === null) {
@@ -429,7 +431,15 @@ async function ask(url, sent = {}) {
429
431
  }
430
432
  throw new Error(`${url} redirected more than ${HOPS_FOLLOWED} times`);
431
433
  }
432
- async function resolvesNothingPrivate(url) {
434
+ async function addressesToReach(url) {
435
+ if (!publicHttps(url)) throw new Error(`${url} is not a public https URL`);
436
+ const found = await resolved(url);
437
+ if (found.length === 0 || !found.every((one) => publicAddress(one.address))) {
438
+ throw new Error(`${url} resolves to an address we do not reach`);
439
+ }
440
+ return found;
441
+ }
442
+ async function resolved(url) {
433
443
  const { lookup } = await import("dns/promises");
434
444
  const { setTimeout: sleep } = await import("timers/promises");
435
445
  const host = new URL(url).hostname.replace(/^\[|]$/g, "");
@@ -437,11 +447,7 @@ async function resolvesNothingPrivate(url) {
437
447
  lookup(host, { all: true, verbatim: true }).catch(() => []),
438
448
  sleep(LOOKUP_TIMEOUT_MS, null, { ref: false })
439
449
  ]);
440
- return found !== null && found.every((one) => publicAddress(one.address));
441
- }
442
- async function refuseUnlessPublic(url) {
443
- if (!publicHttps(url)) throw new Error(`${url} is not a public https URL`);
444
- if (!await resolvesNothingPrivate(url)) throw new Error(`${url} resolves to an address we do not reach`);
450
+ return found ?? [];
445
451
  }
446
452
  async function answerOf(response) {
447
453
  const { status, ok, headers } = response;
@@ -808,21 +814,21 @@ async function mintThroughGateway(config, address, amountMsat, nonce) {
808
814
  return { bolt11: payment.bolt11, verifyUrl: payment.verifyUrl };
809
815
  }
810
816
  async function mintBlind(config, address, amountMsat) {
811
- const resolved = await resolve([address], amountMsat);
812
- const minted = { ...resolved, amountMsat, lnAddress: resolved.address };
817
+ const resolved2 = await resolve([address], amountMsat);
818
+ const minted = { ...resolved2, amountMsat, lnAddress: resolved2.address };
813
819
  const locked = config.sealed;
814
820
  try {
815
821
  await config.gateway.watchPayment({
816
- paymentHash: resolved.paymentHash,
817
- verifyUrl: resolved.verifyUrl,
818
- expiresAt: resolved.expiresAt,
822
+ paymentHash: resolved2.paymentHash,
823
+ verifyUrl: resolved2.verifyUrl,
824
+ expiresAt: resolved2.expiresAt,
819
825
  trigger: config.watchSecret,
820
826
  sealed: locked ? await seal(locked.secret, JSON.stringify(locked.data(minted))) : void 0
821
827
  });
822
828
  } catch (refused) {
823
829
  if (!alreadyWatched(refused)) throw refused;
824
830
  }
825
- return { bolt11: resolved.bolt11, verifyUrl: resolved.verifyUrl };
831
+ return { bolt11: resolved2.bolt11, verifyUrl: resolved2.verifyUrl };
826
832
  }
827
833
  function alreadyWatched(refused) {
828
834
  return refused instanceof ProblemError && isProblemType(refused, PAYMENT_ALREADY_WATCHED);
@@ -908,16 +914,16 @@ async function relayedVerifyUrl(endpoint, wallet, secret) {
908
914
  var LIGHTNING = "lightning";
909
915
  function blindLightningRail(config) {
910
916
  return async (order) => {
911
- const resolved = await invoiceFrom(config.lnAddresses, await config.amountMsat(order));
917
+ const resolved2 = await invoiceFrom(config.lnAddresses, await config.amountMsat(order));
912
918
  const relay = config.relayVerifyThrough;
913
919
  const watched = await config.gateway.watchPayment({
914
- paymentHash: resolved.paymentHash,
920
+ paymentHash: resolved2.paymentHash,
915
921
  verifyUrl: relay ? await relayedVerifyUrl(
916
922
  relay.endpoint,
917
- { url: resolved.verifyUrl, hash: resolved.paymentHash },
923
+ { url: resolved2.verifyUrl, hash: resolved2.paymentHash },
918
924
  relay.secret
919
- ) : resolved.verifyUrl,
920
- expiresAt: resolved.expiresAt,
925
+ ) : resolved2.verifyUrl,
926
+ expiresAt: resolved2.expiresAt,
921
927
  trigger: config.trigger,
922
928
  sealed: await config.sealed?.(order),
923
929
  webhookUrl: config.webhookUrl,
@@ -926,9 +932,9 @@ function blindLightningRail(config) {
926
932
  return {
927
933
  id: watched.id,
928
934
  rail: config.name ?? LIGHTNING,
929
- scan: resolved.bolt11,
930
- qr: encodeForQr(resolved.bolt11),
931
- expiresAt: resolved.expiresAt
935
+ scan: resolved2.bolt11,
936
+ qr: encodeForQr(resolved2.bolt11),
937
+ expiresAt: resolved2.expiresAt
932
938
  };
933
939
  };
934
940
  }
package/dist/server.js CHANGED
@@ -363,20 +363,22 @@ var REDIRECTS = [301, 302, 303, 307, 308];
363
363
  var KEEPS_THE_METHOD = [307, 308];
364
364
  var CREDENTIALS = ["authorization", "cookie", "proxy-authorization"];
365
365
  var BODY_LIMIT_BYTES = 262144;
366
+ var throughFetch = (url, sent, signal) => fetch(url, {
367
+ method: sent.method ?? "GET",
368
+ headers: sent.headers ?? {},
369
+ body: sent.body,
370
+ redirect: "manual",
371
+ signal
372
+ });
373
+ var send = throughFetch;
366
374
  async function ask(url, sent = {}) {
367
375
  const capped = AbortSignal.timeout(HTTP_TIMEOUT_MS);
368
376
  const signal = sent.deadline ? AbortSignal.any([sent.deadline, capped]) : capped;
369
377
  let target = url;
370
378
  let carried = sent;
371
379
  for (let hop = 0; hop <= HOPS_FOLLOWED; hop += 1) {
372
- await refuseUnlessPublic(target);
373
- const response = await fetch(target, {
374
- method: carried.method ?? "GET",
375
- headers: carried.headers ?? {},
376
- body: carried.body,
377
- redirect: "manual",
378
- signal
379
- });
380
+ const at = await addressesToReach(target);
381
+ const response = await send(target, carried, signal, at);
380
382
  if (!REDIRECTS.includes(response.status)) return await answerOf(response);
381
383
  const location = response.headers.get("location");
382
384
  if (location === null) {
@@ -390,7 +392,15 @@ async function ask(url, sent = {}) {
390
392
  }
391
393
  throw new Error(`${url} redirected more than ${HOPS_FOLLOWED} times`);
392
394
  }
393
- async function resolvesNothingPrivate(url) {
395
+ async function addressesToReach(url) {
396
+ if (!publicHttps(url)) throw new Error(`${url} is not a public https URL`);
397
+ const found = await resolved(url);
398
+ if (found.length === 0 || !found.every((one) => publicAddress(one.address))) {
399
+ throw new Error(`${url} resolves to an address we do not reach`);
400
+ }
401
+ return found;
402
+ }
403
+ async function resolved(url) {
394
404
  const { lookup } = await import("dns/promises");
395
405
  const { setTimeout: sleep } = await import("timers/promises");
396
406
  const host = new URL(url).hostname.replace(/^\[|]$/g, "");
@@ -398,11 +408,7 @@ async function resolvesNothingPrivate(url) {
398
408
  lookup(host, { all: true, verbatim: true }).catch(() => []),
399
409
  sleep(LOOKUP_TIMEOUT_MS, null, { ref: false })
400
410
  ]);
401
- return found !== null && found.every((one) => publicAddress(one.address));
402
- }
403
- async function refuseUnlessPublic(url) {
404
- if (!publicHttps(url)) throw new Error(`${url} is not a public https URL`);
405
- if (!await resolvesNothingPrivate(url)) throw new Error(`${url} resolves to an address we do not reach`);
411
+ return found ?? [];
406
412
  }
407
413
  async function answerOf(response) {
408
414
  const { status, ok, headers } = response;
@@ -769,21 +775,21 @@ async function mintThroughGateway(config, address, amountMsat, nonce) {
769
775
  return { bolt11: payment.bolt11, verifyUrl: payment.verifyUrl };
770
776
  }
771
777
  async function mintBlind(config, address, amountMsat) {
772
- const resolved = await resolve([address], amountMsat);
773
- const minted = { ...resolved, amountMsat, lnAddress: resolved.address };
778
+ const resolved2 = await resolve([address], amountMsat);
779
+ const minted = { ...resolved2, amountMsat, lnAddress: resolved2.address };
774
780
  const locked = config.sealed;
775
781
  try {
776
782
  await config.gateway.watchPayment({
777
- paymentHash: resolved.paymentHash,
778
- verifyUrl: resolved.verifyUrl,
779
- expiresAt: resolved.expiresAt,
783
+ paymentHash: resolved2.paymentHash,
784
+ verifyUrl: resolved2.verifyUrl,
785
+ expiresAt: resolved2.expiresAt,
780
786
  trigger: config.watchSecret,
781
787
  sealed: locked ? await seal(locked.secret, JSON.stringify(locked.data(minted))) : void 0
782
788
  });
783
789
  } catch (refused) {
784
790
  if (!alreadyWatched(refused)) throw refused;
785
791
  }
786
- return { bolt11: resolved.bolt11, verifyUrl: resolved.verifyUrl };
792
+ return { bolt11: resolved2.bolt11, verifyUrl: resolved2.verifyUrl };
787
793
  }
788
794
  function alreadyWatched(refused) {
789
795
  return refused instanceof ProblemError && isProblemType(refused, PAYMENT_ALREADY_WATCHED);
@@ -869,16 +875,16 @@ async function relayedVerifyUrl(endpoint, wallet, secret) {
869
875
  var LIGHTNING = "lightning";
870
876
  function blindLightningRail(config) {
871
877
  return async (order) => {
872
- const resolved = await invoiceFrom(config.lnAddresses, await config.amountMsat(order));
878
+ const resolved2 = await invoiceFrom(config.lnAddresses, await config.amountMsat(order));
873
879
  const relay = config.relayVerifyThrough;
874
880
  const watched = await config.gateway.watchPayment({
875
- paymentHash: resolved.paymentHash,
881
+ paymentHash: resolved2.paymentHash,
876
882
  verifyUrl: relay ? await relayedVerifyUrl(
877
883
  relay.endpoint,
878
- { url: resolved.verifyUrl, hash: resolved.paymentHash },
884
+ { url: resolved2.verifyUrl, hash: resolved2.paymentHash },
879
885
  relay.secret
880
- ) : resolved.verifyUrl,
881
- expiresAt: resolved.expiresAt,
886
+ ) : resolved2.verifyUrl,
887
+ expiresAt: resolved2.expiresAt,
882
888
  trigger: config.trigger,
883
889
  sealed: await config.sealed?.(order),
884
890
  webhookUrl: config.webhookUrl,
@@ -887,9 +893,9 @@ function blindLightningRail(config) {
887
893
  return {
888
894
  id: watched.id,
889
895
  rail: config.name ?? LIGHTNING,
890
- scan: resolved.bolt11,
891
- qr: encodeForQr(resolved.bolt11),
892
- expiresAt: resolved.expiresAt
896
+ scan: resolved2.bolt11,
897
+ qr: encodeForQr(resolved2.bolt11),
898
+ expiresAt: resolved2.expiresAt
893
899
  };
894
900
  };
895
901
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thunder-bridge",
3
- "version": "0.8.9",
3
+ "version": "0.8.10",
4
4
  "description": "Trustless JavaScript client for the Thunder Bridge Lightning payment gateway. Proves the invoice came from your own wallet before the payer sees it.",
5
5
  "author": "i-am-fatik",
6
6
  "homepage": "https://agora.gripe/en/tools/thunder-bridge",