@astrasyncai/verification-gateway 2.4.11 → 2.4.14
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/adapter-interface/interface.d.mts +2 -2
- package/dist/adapter-interface/interface.d.ts +2 -2
- package/dist/adapters/express.d.mts +2 -2
- package/dist/adapters/express.d.ts +2 -2
- package/dist/adapters/express.js +129 -36
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +129 -36
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.d.mts +26 -4
- package/dist/adapters/mcp.d.ts +26 -4
- package/dist/adapters/mcp.js +94 -28
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +94 -28
- package/dist/adapters/mcp.mjs.map +1 -1
- package/dist/adapters/nextjs.d.mts +2 -2
- package/dist/adapters/nextjs.d.ts +2 -2
- package/dist/adapters/nextjs.js +75 -29
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +75 -29
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.d.mts +2 -2
- package/dist/adapters/sdk.d.ts +2 -2
- package/dist/adapters/sdk.js +45 -22
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +45 -22
- package/dist/adapters/sdk.mjs.map +1 -1
- package/dist/agent/index.d.mts +2 -2
- package/dist/agent/index.d.ts +2 -2
- package/dist/agent/index.js +29 -0
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/index.mjs +29 -0
- package/dist/agent/index.mjs.map +1 -1
- package/dist/browser/background.js +86 -24
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +86 -24
- package/dist/browser/background.mjs.map +1 -1
- package/dist/browser/browser-adapter.d.mts +2 -2
- package/dist/browser/browser-adapter.d.ts +2 -2
- package/dist/cli/index.d.mts +2 -2
- package/dist/cli/index.d.ts +2 -2
- package/dist/cursor/cursor-adapter.d.mts +2 -2
- package/dist/cursor/cursor-adapter.d.ts +2 -2
- package/dist/cursor/extension.d.mts +2 -2
- package/dist/cursor/extension.d.ts +2 -2
- package/dist/cursor/extension.js +86 -24
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +86 -24
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/{express-C1ePFB7n.d.ts → express-CrfwoNAR.d.ts} +1 -1
- package/dist/{express-4WStX3PV.d.mts → express-ienhAXps.d.mts} +1 -1
- package/dist/gateway/gateway.d.mts +2 -2
- package/dist/gateway/gateway.d.ts +2 -2
- package/dist/gateway/gateway.js +86 -24
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +86 -24
- package/dist/gateway/gateway.mjs.map +1 -1
- package/dist/git-trigger/git-hooks.d.mts +2 -2
- package/dist/git-trigger/git-hooks.d.ts +2 -2
- package/dist/{index-ChPX4WHl.d.mts → index-B5e2IDWU.d.mts} +1 -1
- package/dist/{index-CzJMCgEy.d.ts → index-CCdZxvAr.d.ts} +71 -6
- package/dist/{index-D8IEntil.d.mts → index-CEg_WG6y.d.mts} +71 -6
- package/dist/{index-Cjm-zBeZ.d.ts → index-DC5f8eoQ.d.ts} +1 -1
- package/dist/index.d.mts +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.js +344 -73
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +344 -73
- package/dist/index.mjs.map +1 -1
- package/dist/local-evaluator/evaluator.d.mts +2 -2
- package/dist/local-evaluator/evaluator.d.ts +2 -2
- package/dist/local-evaluator/evaluator.js +12 -2
- package/dist/local-evaluator/evaluator.js.map +1 -1
- package/dist/local-evaluator/evaluator.mjs +12 -2
- package/dist/local-evaluator/evaluator.mjs.map +1 -1
- package/dist/{nextjs-BIORS__0.d.ts → nextjs-66R1KW8e.d.ts} +1 -1
- package/dist/{nextjs-CjzHdaXA.d.mts → nextjs-DSpisQst.d.mts} +1 -1
- package/dist/{sdk-Chhz-FcT.d.mts → sdk-5U_CBRpr.d.mts} +1 -1
- package/dist/{sdk-CqTEQAc6.d.ts → sdk-Bm8np66n.d.ts} +1 -1
- package/dist/transport/index.d.mts +2 -2
- package/dist/transport/index.d.ts +2 -2
- package/dist/transport/index.js +146 -28
- package/dist/transport/index.js.map +1 -1
- package/dist/transport/index.mjs +146 -28
- package/dist/transport/index.mjs.map +1 -1
- package/dist/{types-L15pYd2c.d.mts → types-B3USs-Kx.d.mts} +42 -1
- package/dist/{types-L15pYd2c.d.ts → types-B3USs-Kx.d.ts} +42 -1
- package/dist/{types-DNK2BgIf.d.mts → types-CgDCUfo8.d.mts} +1 -1
- package/dist/{types-DoWIuzfj.d.ts → types-R5N4ET6x.d.ts} +1 -1
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/transport/index.js
CHANGED
|
@@ -503,12 +503,45 @@ function bufferToBase64(bytes) {
|
|
|
503
503
|
|
|
504
504
|
// src/transport/rfc9421-verify.ts
|
|
505
505
|
var import_http_message_signatures = require("http-message-signatures");
|
|
506
|
+
|
|
507
|
+
// src/transport/nonce-store.ts
|
|
508
|
+
var InMemoryNonceStore = class {
|
|
509
|
+
constructor(capacity = 1e4) {
|
|
510
|
+
this.entries = /* @__PURE__ */ new Map();
|
|
511
|
+
this.lastSweepMs = 0;
|
|
512
|
+
this.capacity = capacity;
|
|
513
|
+
}
|
|
514
|
+
seen(key, expiresAtMs) {
|
|
515
|
+
const nowMs = Date.now();
|
|
516
|
+
if (nowMs - this.lastSweepMs > 1e3) {
|
|
517
|
+
for (const [k, exp] of this.entries) {
|
|
518
|
+
if (exp <= nowMs) this.entries.delete(k);
|
|
519
|
+
}
|
|
520
|
+
this.lastSweepMs = nowMs;
|
|
521
|
+
}
|
|
522
|
+
const existing = this.entries.get(key);
|
|
523
|
+
if (existing !== void 0 && existing > nowMs) {
|
|
524
|
+
return true;
|
|
525
|
+
}
|
|
526
|
+
if (this.entries.size >= this.capacity) {
|
|
527
|
+
const oldest = this.entries.keys().next().value;
|
|
528
|
+
if (oldest !== void 0) this.entries.delete(oldest);
|
|
529
|
+
}
|
|
530
|
+
this.entries.set(key, expiresAtMs);
|
|
531
|
+
return false;
|
|
532
|
+
}
|
|
533
|
+
};
|
|
534
|
+
var defaultNonceStore = new InMemoryNonceStore();
|
|
535
|
+
|
|
536
|
+
// src/transport/rfc9421-verify.ts
|
|
506
537
|
async function verifyRFC9421(request, options) {
|
|
507
538
|
const { resolver } = options;
|
|
508
|
-
const tolerance = options.clockSkewSec ??
|
|
539
|
+
const tolerance = options.clockSkewSec ?? 60;
|
|
509
540
|
const nowSec = options.now ? options.now() : Math.floor(Date.now() / 1e3);
|
|
541
|
+
const nonceStore = options.nonceStore ?? defaultNonceStore;
|
|
510
542
|
let resolvedKid;
|
|
511
543
|
let resolvedAlg;
|
|
544
|
+
let replayDetected = false;
|
|
512
545
|
const keyLookup = async (parameters) => {
|
|
513
546
|
const kid = typeof parameters.keyid === "string" ? parameters.keyid : void 0;
|
|
514
547
|
if (!kid) return null;
|
|
@@ -522,6 +555,14 @@ async function verifyRFC9421(request, options) {
|
|
|
522
555
|
const expires = toUnixSeconds(parameters.expires);
|
|
523
556
|
if (created !== void 0 && Math.abs(nowSec - created) > tolerance) return null;
|
|
524
557
|
if (expires !== void 0 && nowSec > expires + tolerance) return null;
|
|
558
|
+
const nonce = typeof parameters.nonce === "string" ? parameters.nonce : void 0;
|
|
559
|
+
if (nonce) {
|
|
560
|
+
const expiresAtMs = (expires !== void 0 ? expires + tolerance : nowSec + tolerance) * 1e3;
|
|
561
|
+
if (nonceStore.seen(`rfc9421:${kid}:${nonce}`, expiresAtMs)) {
|
|
562
|
+
replayDetected = true;
|
|
563
|
+
return null;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
525
566
|
return jwkToVerifyingKey(kid, jwk, alg);
|
|
526
567
|
};
|
|
527
568
|
try {
|
|
@@ -544,7 +585,7 @@ async function verifyRFC9421(request, options) {
|
|
|
544
585
|
kid: resolvedKid,
|
|
545
586
|
registry: resolver.name,
|
|
546
587
|
algorithm: resolvedAlg,
|
|
547
|
-
error: result === false ? "signature invalid" : "no signature found"
|
|
588
|
+
error: replayDetected ? "RFC9421 signature replay \u2014 already seen within tolerance window" : result === false ? "signature invalid" : "no signature found"
|
|
548
589
|
};
|
|
549
590
|
} catch (err) {
|
|
550
591
|
return {
|
|
@@ -1369,14 +1410,26 @@ function sha256Sync2(data) {
|
|
|
1369
1410
|
function verifyAP2Chain(input) {
|
|
1370
1411
|
const { triple } = input;
|
|
1371
1412
|
const errors = [];
|
|
1413
|
+
const toleranceSec = input.clockSkewSec ?? 60;
|
|
1414
|
+
const nonceStore = input.nonceStore ?? defaultNonceStore;
|
|
1372
1415
|
const intentPresent = triple.intent !== void 0;
|
|
1373
1416
|
const cartRefOk = checkCartRef(triple, errors);
|
|
1374
1417
|
const paymentRefOk = checkPaymentRef(triple, errors);
|
|
1375
1418
|
const { ok: agentIdContinuity, agentId } = checkAgentContinuity(triple, errors);
|
|
1376
1419
|
const paymentMethodAllowed = checkPaymentMethod(triple, errors);
|
|
1377
1420
|
const totalsConsistent = checkTotals(triple, errors);
|
|
1378
|
-
const expiryOk = checkExpiries(triple,
|
|
1379
|
-
|
|
1421
|
+
const expiryOk = checkExpiries(triple, toleranceSec, input.now, errors);
|
|
1422
|
+
let replayOk = true;
|
|
1423
|
+
const replayId = triple.payment?.raw?.id ?? triple.cart?.raw?.id;
|
|
1424
|
+
if (typeof replayId === "string" && replayId.length > 0) {
|
|
1425
|
+
const now = input.now ? input.now() : Math.floor(Date.now() / 1e3);
|
|
1426
|
+
const expiresAt = (now + toleranceSec) * 1e3;
|
|
1427
|
+
if (nonceStore.seen(`ap2:${replayId}`, expiresAt)) {
|
|
1428
|
+
errors.push(`AP2 chain replay \u2014 mandate ${replayId} already seen within tolerance window`);
|
|
1429
|
+
replayOk = false;
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
const ok = cartRefOk && paymentRefOk && agentIdContinuity && paymentMethodAllowed && totalsConsistent && expiryOk && replayOk;
|
|
1380
1433
|
return {
|
|
1381
1434
|
ok,
|
|
1382
1435
|
checks: {
|
|
@@ -1422,7 +1475,10 @@ function checkAgentContinuity(triple, errors) {
|
|
|
1422
1475
|
const ids = [triple.intent?.agent_id, triple.cart?.agent_id, triple.payment?.agent_id].filter(
|
|
1423
1476
|
(id) => typeof id === "string" && id.length > 0
|
|
1424
1477
|
);
|
|
1425
|
-
if (ids.length === 0)
|
|
1478
|
+
if (ids.length === 0) {
|
|
1479
|
+
errors.push("agent_id missing across all three mandates (intent/cart/payment)");
|
|
1480
|
+
return { ok: false };
|
|
1481
|
+
}
|
|
1426
1482
|
const unique = new Set(ids);
|
|
1427
1483
|
if (unique.size > 1) {
|
|
1428
1484
|
errors.push(`agent_id mismatch across mandates: ${Array.from(unique).join(", ")}`);
|
|
@@ -1431,9 +1487,16 @@ function checkAgentContinuity(triple, errors) {
|
|
|
1431
1487
|
return { ok: true, agentId: ids[0] };
|
|
1432
1488
|
}
|
|
1433
1489
|
function checkPaymentMethod(triple, errors) {
|
|
1434
|
-
const paymentMethod = triple.payment?.payment_method;
|
|
1435
1490
|
const allowed = triple.intent?.paymentMethods;
|
|
1436
|
-
if (!
|
|
1491
|
+
if (!allowed || allowed.length === 0) return true;
|
|
1492
|
+
if (!triple.payment) return true;
|
|
1493
|
+
const paymentMethod = triple.payment.payment_method;
|
|
1494
|
+
if (!paymentMethod) {
|
|
1495
|
+
errors.push(
|
|
1496
|
+
`payment.payment_method missing but intent declares allowlist [${allowed.join(", ")}]`
|
|
1497
|
+
);
|
|
1498
|
+
return false;
|
|
1499
|
+
}
|
|
1437
1500
|
if (!allowed.includes(paymentMethod)) {
|
|
1438
1501
|
errors.push(
|
|
1439
1502
|
`payment_method "${paymentMethod}" not in intent.paymentMethods [${allowed.join(", ")}]`
|
|
@@ -1467,19 +1530,24 @@ function checkTotals(triple, errors) {
|
|
|
1467
1530
|
function checkExpiries(triple, toleranceSec, nowFn, errors) {
|
|
1468
1531
|
const now = nowFn ? nowFn() : Math.floor(Date.now() / 1e3);
|
|
1469
1532
|
let ok = true;
|
|
1470
|
-
|
|
1471
|
-
["intent", triple.intent],
|
|
1472
|
-
["cart", triple.cart]
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1533
|
+
const layers = [
|
|
1534
|
+
["intent", triple.intent?.expires],
|
|
1535
|
+
["cart", triple.cart?.expires],
|
|
1536
|
+
[
|
|
1537
|
+
"payment",
|
|
1538
|
+
typeof triple.payment?.raw?.expires === "string" ? triple.payment.raw.expires : typeof triple.payment?.raw?.exp === "string" ? triple.payment.raw.exp : void 0
|
|
1539
|
+
]
|
|
1540
|
+
];
|
|
1541
|
+
for (const [name, expires] of layers) {
|
|
1542
|
+
if (!expires) continue;
|
|
1543
|
+
const parsed = parseExpiry(expires);
|
|
1476
1544
|
if (parsed === null) {
|
|
1477
1545
|
errors.push(`${name}.expires unparseable`);
|
|
1478
1546
|
ok = false;
|
|
1479
1547
|
continue;
|
|
1480
1548
|
}
|
|
1481
1549
|
if (now > parsed + toleranceSec) {
|
|
1482
|
-
errors.push(`${name} mandate expired at ${
|
|
1550
|
+
errors.push(`${name} mandate expired at ${expires}`);
|
|
1483
1551
|
ok = false;
|
|
1484
1552
|
}
|
|
1485
1553
|
}
|
|
@@ -1506,10 +1574,21 @@ async function verifyACPSignature(input) {
|
|
|
1506
1574
|
if (!input.signatureHeader) {
|
|
1507
1575
|
return { ok: false, error: "missing Signature header" };
|
|
1508
1576
|
}
|
|
1509
|
-
const
|
|
1577
|
+
const tolerance = input.clockSkewSec ?? 60;
|
|
1578
|
+
const nonceStore = input.nonceStore ?? defaultNonceStore;
|
|
1579
|
+
const freshness = checkTimestamp(input.timestampHeader, tolerance, input.now);
|
|
1510
1580
|
if (!freshness.ok) {
|
|
1511
1581
|
return { ok: false, error: freshness.error, timestampStale: true };
|
|
1512
1582
|
}
|
|
1583
|
+
const nowSec = input.now ? input.now() : Math.floor(Date.now() / 1e3);
|
|
1584
|
+
const expiresAtMs = (nowSec + tolerance) * 1e3;
|
|
1585
|
+
const replayKey = `acp:${input.signatureHeader}:${input.timestampHeader ?? ""}`;
|
|
1586
|
+
if (nonceStore.seen(replayKey, expiresAtMs)) {
|
|
1587
|
+
return {
|
|
1588
|
+
ok: false,
|
|
1589
|
+
error: "ACP signature replay \u2014 already seen within tolerance window"
|
|
1590
|
+
};
|
|
1591
|
+
}
|
|
1513
1592
|
const signatureBytes = decodeBase64(input.signatureHeader);
|
|
1514
1593
|
if (!signatureBytes) {
|
|
1515
1594
|
return { ok: false, error: "signature header is not valid base64" };
|
|
@@ -1727,8 +1806,9 @@ function coerceString6(v) {
|
|
|
1727
1806
|
var import_mppx2 = require("mppx");
|
|
1728
1807
|
function verifyMPP(input) {
|
|
1729
1808
|
const { context } = input;
|
|
1730
|
-
const tolerance = input.clockSkewSec ??
|
|
1809
|
+
const tolerance = input.clockSkewSec ?? 60;
|
|
1731
1810
|
const nowSec = input.now ? input.now() : Math.floor(Date.now() / 1e3);
|
|
1811
|
+
const nonceStore = input.nonceStore ?? defaultNonceStore;
|
|
1732
1812
|
const challenge = context.credential?.challenge ?? (context.challenges && context.challenges[0]);
|
|
1733
1813
|
const source = context.credential?.source;
|
|
1734
1814
|
const method = challenge?.method;
|
|
@@ -1751,21 +1831,38 @@ function verifyMPP(input) {
|
|
|
1751
1831
|
}
|
|
1752
1832
|
}
|
|
1753
1833
|
let bodyDigestOk = null;
|
|
1754
|
-
if (
|
|
1755
|
-
|
|
1756
|
-
|
|
1834
|
+
if (input.rawBody !== void 0) {
|
|
1835
|
+
if (!challenge?.digest) {
|
|
1836
|
+
bodyDigestOk = false;
|
|
1837
|
+
} else {
|
|
1838
|
+
try {
|
|
1839
|
+
if (!/^sha-256=/.test(challenge.digest)) {
|
|
1840
|
+
bodyDigestOk = false;
|
|
1841
|
+
} else {
|
|
1842
|
+
bodyDigestOk = import_mppx2.BodyDigest.verify(challenge.digest, input.rawBody);
|
|
1843
|
+
}
|
|
1844
|
+
} catch {
|
|
1757
1845
|
bodyDigestOk = false;
|
|
1758
|
-
} else {
|
|
1759
|
-
bodyDigestOk = import_mppx2.BodyDigest.verify(challenge.digest, input.rawBody);
|
|
1760
1846
|
}
|
|
1761
|
-
} catch {
|
|
1762
|
-
bodyDigestOk = false;
|
|
1763
1847
|
}
|
|
1764
1848
|
}
|
|
1765
|
-
|
|
1849
|
+
let replayOk = true;
|
|
1850
|
+
if (challenge?.digest && expiryOk) {
|
|
1851
|
+
const replayKey = `mpp:${challenge.digest}:${challenge.nonce ?? ""}`;
|
|
1852
|
+
const expiresAt = (nowSec + tolerance) * 1e3;
|
|
1853
|
+
if (nonceStore.seen(replayKey, expiresAt)) {
|
|
1854
|
+
replayOk = false;
|
|
1855
|
+
}
|
|
1856
|
+
}
|
|
1857
|
+
const ok = expiryOk && (bodyDigestOk === null || bodyDigestOk === true) && replayOk;
|
|
1766
1858
|
const errors = [];
|
|
1767
1859
|
if (!expiryOk) errors.push("challenge expired");
|
|
1768
|
-
if (bodyDigestOk === false)
|
|
1860
|
+
if (bodyDigestOk === false) {
|
|
1861
|
+
errors.push(
|
|
1862
|
+
input.rawBody !== void 0 && !challenge?.digest ? "body digest required when rawBody present" : "body digest mismatch"
|
|
1863
|
+
);
|
|
1864
|
+
}
|
|
1865
|
+
if (!replayOk) errors.push("MPP challenge replay \u2014 already seen within tolerance window");
|
|
1769
1866
|
return {
|
|
1770
1867
|
ok,
|
|
1771
1868
|
expiryOk,
|
|
@@ -1926,14 +2023,32 @@ function readHeader4(headers, name) {
|
|
|
1926
2023
|
var import_node_crypto4 = require("crypto");
|
|
1927
2024
|
async function verifyVIChain(input) {
|
|
1928
2025
|
const errors = [];
|
|
1929
|
-
const tolerance = input.clockSkewSec ??
|
|
2026
|
+
const tolerance = input.clockSkewSec ?? 60;
|
|
1930
2027
|
const now = input.now ? input.now() : Math.floor(Date.now() / 1e3);
|
|
1931
2028
|
const { l1, l2, l3a, l3b } = input.layers;
|
|
2029
|
+
const nonceStore = input.nonceStore ?? defaultNonceStore;
|
|
2030
|
+
if (!l1) {
|
|
2031
|
+
if (!input.allowUnboundChain) {
|
|
2032
|
+
errors.push(
|
|
2033
|
+
"L1 missing \u2014 chain root unbound (set allowUnboundChain + expectedL2Key to override)"
|
|
2034
|
+
);
|
|
2035
|
+
} else if (!input.expectedL2Key) {
|
|
2036
|
+
errors.push("allowUnboundChain set but expectedL2Key missing");
|
|
2037
|
+
}
|
|
2038
|
+
}
|
|
1932
2039
|
const l1SigOk = l1 ? await input.verifySignature(l1, null) : null;
|
|
1933
2040
|
if (l1 && !l1SigOk) errors.push("L1 signature invalid");
|
|
1934
2041
|
const l1Cnf = extractCnfJwk(l1?.payload);
|
|
1935
|
-
const
|
|
2042
|
+
const l2ExpectedKey = l1Cnf ?? input.expectedL2Key ?? null;
|
|
2043
|
+
const l2SigOk = await input.verifySignature(l2, l2ExpectedKey);
|
|
1936
2044
|
if (!l2SigOk) errors.push("L2 signature invalid");
|
|
2045
|
+
if (l2SigOk) {
|
|
2046
|
+
const replayKey = `vi:l2:${l2.compact}`;
|
|
2047
|
+
const expiresAt = now * 1e3 + tolerance * 1e3;
|
|
2048
|
+
if (nonceStore.seen(replayKey, expiresAt)) {
|
|
2049
|
+
errors.push("L2 signature replay \u2014 already seen within tolerance window");
|
|
2050
|
+
}
|
|
2051
|
+
}
|
|
1937
2052
|
const l2Cnf = extractCnfJwk(l2.payload);
|
|
1938
2053
|
const l3aSigOk = l3a ? await input.verifySignature(l3a, l2Cnf ?? null) : null;
|
|
1939
2054
|
if (l3a && !l3aSigOk) errors.push("L3a signature invalid");
|
|
@@ -1977,7 +2092,10 @@ async function verifyVIChain(input) {
|
|
|
1977
2092
|
}
|
|
1978
2093
|
}
|
|
1979
2094
|
const expiryOk = checkExpiryAcross([l1, l2, l3a, l3b], tolerance, now, errors);
|
|
1980
|
-
const
|
|
2095
|
+
const noUnboundChainOrReplayErrors = !errors.some(
|
|
2096
|
+
(e) => e.startsWith("L1 missing") || e.startsWith("allowUnboundChain set") || e.startsWith("L2 signature replay")
|
|
2097
|
+
);
|
|
2098
|
+
const ok = l1SigOk !== false && l2SigOk && l3aSigOk !== false && l3bSigOk !== false && l1BindsL2 && l2BindsL3 && l3aL3bTxnIdMatch !== false && checkoutHashOk !== false && expiryOk && noUnboundChainOrReplayErrors;
|
|
1981
2099
|
return {
|
|
1982
2100
|
ok,
|
|
1983
2101
|
checks: {
|