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 +34 -28
- package/dist/server.js +34 -28
- package/package.json +1 -1
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
|
|
412
|
-
const response = await
|
|
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
|
|
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
|
|
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
|
|
812
|
-
const minted = { ...
|
|
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:
|
|
817
|
-
verifyUrl:
|
|
818
|
-
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:
|
|
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
|
|
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:
|
|
920
|
+
paymentHash: resolved2.paymentHash,
|
|
915
921
|
verifyUrl: relay ? await relayedVerifyUrl(
|
|
916
922
|
relay.endpoint,
|
|
917
|
-
{ url:
|
|
923
|
+
{ url: resolved2.verifyUrl, hash: resolved2.paymentHash },
|
|
918
924
|
relay.secret
|
|
919
|
-
) :
|
|
920
|
-
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:
|
|
930
|
-
qr: encodeForQr(
|
|
931
|
-
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
|
|
373
|
-
const response = await
|
|
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
|
|
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
|
|
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
|
|
773
|
-
const minted = { ...
|
|
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:
|
|
778
|
-
verifyUrl:
|
|
779
|
-
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:
|
|
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
|
|
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:
|
|
881
|
+
paymentHash: resolved2.paymentHash,
|
|
876
882
|
verifyUrl: relay ? await relayedVerifyUrl(
|
|
877
883
|
relay.endpoint,
|
|
878
|
-
{ url:
|
|
884
|
+
{ url: resolved2.verifyUrl, hash: resolved2.paymentHash },
|
|
879
885
|
relay.secret
|
|
880
|
-
) :
|
|
881
|
-
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:
|
|
891
|
-
qr: encodeForQr(
|
|
892
|
-
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.
|
|
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",
|