xytara 3.1.13 → 3.1.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.
Files changed (55) hide show
  1. package/.env.example +8 -1
  2. package/BSV_TERANODE_PLATFORM_DISCONTINUITY_RUNBOOK.md +126 -126
  3. package/RELEASE_NOTES.md +6 -4
  4. package/lib/a2a_rpc.js +280 -280
  5. package/lib/account_auth.js +585 -585
  6. package/lib/agent_identity.js +162 -162
  7. package/lib/bolt_adapter.js +187 -187
  8. package/lib/bolt_payment_front.js +224 -224
  9. package/lib/checkout_processor_adapter.js +217 -217
  10. package/lib/command_flow.js +722 -722
  11. package/lib/commerce_artifacts.js +591 -591
  12. package/lib/commerce_bridge.js +274 -274
  13. package/lib/commerce_cases.js +399 -399
  14. package/lib/commerce_client.js +7694 -7694
  15. package/lib/commerce_quotes.js +29 -0
  16. package/lib/commerce_runtime.js +322 -322
  17. package/lib/execution_dedupe.js +86 -86
  18. package/lib/external_credit_bridge.js +142 -142
  19. package/lib/http_transport.js +81 -81
  20. package/lib/l402_adapter.js +241 -241
  21. package/lib/l402_payment_front.js +265 -265
  22. package/lib/mpp_adapter.js +237 -237
  23. package/lib/payment_config.js +253 -253
  24. package/lib/payment_verification.js +357 -357
  25. package/lib/provider_payout_execution.js +155 -155
  26. package/lib/provider_registry.js +842 -842
  27. package/lib/rate_limiter.js +81 -81
  28. package/lib/runtime_state_store.js +491 -369
  29. package/lib/settlement_bsv_live.js +600 -600
  30. package/lib/settlement_bsv_teranode.js +117 -117
  31. package/lib/stripe_mpp_payment_front.js +258 -258
  32. package/lib/x402_facilitator.js +191 -191
  33. package/package.json +5 -3
  34. package/scripts/state_backup_offsite.js +196 -0
  35. package/scripts/verify_a2a_rpc.js +105 -105
  36. package/scripts/verify_agent_identity.js +153 -153
  37. package/scripts/verify_all.js +1 -1
  38. package/scripts/verify_bolt_adapter.js +128 -128
  39. package/scripts/verify_cdp_facilitator.js +110 -110
  40. package/scripts/verify_checkout_processor.js +109 -109
  41. package/scripts/verify_commerce_bridge.js +177 -177
  42. package/scripts/verify_execution_dedupe.js +189 -189
  43. package/scripts/verify_execution_surfacing.js +76 -76
  44. package/scripts/verify_final_activation.js +191 -191
  45. package/scripts/verify_l402_adapter.js +86 -86
  46. package/scripts/verify_mpp_adapter.js +128 -128
  47. package/scripts/verify_production_readiness.js +268 -268
  48. package/scripts/verify_rate_limiter.js +52 -52
  49. package/scripts/verify_refund_credit.js +106 -106
  50. package/scripts/verify_release_candidate.js +81 -81
  51. package/scripts/verify_runtime_state_guard.js +117 -0
  52. package/scripts/verify_service.js +15421 -15421
  53. package/scripts/verify_verify_execute_settle.js +208 -208
  54. package/scripts/verify_x402_facilitator.js +286 -286
  55. package/server.js +11976 -11974
@@ -1,81 +1,81 @@
1
- "use strict";
2
-
3
- // Minimal in-memory fixed-window rate limiter. Dependency-free.
4
- //
5
- // Used to gate expensive unauthenticated work (e.g. L402 invoice creation, which
6
- // makes an outbound call to a Lightning provider on every UNPAID request) so a
7
- // flood cannot amplify into unbounded cost. Two independent ceilings apply:
8
- // - per key (typically client IP): `max` hits per `windowMs`
9
- // - global (all keys combined): `maxGlobal` hits per `windowMs`
10
- // A hit counts against both; exceeding either denies the request.
11
- //
12
- // Scope: single process. Horizontally-scaled deployments should front this with a
13
- // shared store (Redis) or an edge/proxy limiter; this module is the in-process
14
- // floor, not a distributed guarantee. Callers should still deploy behind the
15
- // platform's own rate limiting for defense in depth.
16
-
17
- function now() {
18
- return Date.now();
19
- }
20
-
21
- function createRateLimiter(options) {
22
- const opts = options || {};
23
- const windowMs = Math.max(1000, Number(opts.windowMs) || 60000);
24
- const max = Math.max(1, Number(opts.max) || 30);
25
- const maxGlobal = Math.max(max, Number(opts.maxGlobal) || max * 20);
26
- // Map<key, { count, resetAt }>
27
- const buckets = new Map();
28
- let global = { count: 0, resetAt: now() + windowMs };
29
- let lastSweep = now();
30
-
31
- function sweep(t) {
32
- // Opportunistic cleanup so the Map cannot grow without bound.
33
- if (t - lastSweep < windowMs) return;
34
- lastSweep = t;
35
- for (const [key, bucket] of buckets) {
36
- if (bucket.resetAt <= t) buckets.delete(key);
37
- }
38
- }
39
-
40
- function rollGlobal(t) {
41
- if (global.resetAt <= t) global = { count: 0, resetAt: t + windowMs };
42
- }
43
-
44
- // Record one hit for `key` and report whether it is allowed. The hit is only
45
- // counted when allowed, so a denied caller does not push its own reset further
46
- // out (no self-inflicted lockout extension).
47
- function check(key) {
48
- const t = now();
49
- sweep(t);
50
- rollGlobal(t);
51
- const k = String(key == null ? "" : key);
52
- let bucket = buckets.get(k);
53
- if (!bucket || bucket.resetAt <= t) {
54
- bucket = { count: 0, resetAt: t + windowMs };
55
- buckets.set(k, bucket);
56
- }
57
- if (global.count >= maxGlobal) {
58
- return { allowed: false, scope: "global", remaining: 0, retryAfterMs: Math.max(0, global.resetAt - t) };
59
- }
60
- if (bucket.count >= max) {
61
- return { allowed: false, scope: "key", remaining: 0, retryAfterMs: Math.max(0, bucket.resetAt - t) };
62
- }
63
- bucket.count += 1;
64
- global.count += 1;
65
- return {
66
- allowed: true,
67
- scope: null,
68
- remaining: Math.max(0, max - bucket.count),
69
- retryAfterMs: Math.max(0, bucket.resetAt - t)
70
- };
71
- }
72
-
73
- function reset() {
74
- buckets.clear();
75
- global = { count: 0, resetAt: now() + windowMs };
76
- }
77
-
78
- return { check, reset, config: { windowMs, max, maxGlobal } };
79
- }
80
-
81
- module.exports = { createRateLimiter };
1
+ "use strict";
2
+
3
+ // Minimal in-memory fixed-window rate limiter. Dependency-free.
4
+ //
5
+ // Used to gate expensive unauthenticated work (e.g. L402 invoice creation, which
6
+ // makes an outbound call to a Lightning provider on every UNPAID request) so a
7
+ // flood cannot amplify into unbounded cost. Two independent ceilings apply:
8
+ // - per key (typically client IP): `max` hits per `windowMs`
9
+ // - global (all keys combined): `maxGlobal` hits per `windowMs`
10
+ // A hit counts against both; exceeding either denies the request.
11
+ //
12
+ // Scope: single process. Horizontally-scaled deployments should front this with a
13
+ // shared store (Redis) or an edge/proxy limiter; this module is the in-process
14
+ // floor, not a distributed guarantee. Callers should still deploy behind the
15
+ // platform's own rate limiting for defense in depth.
16
+
17
+ function now() {
18
+ return Date.now();
19
+ }
20
+
21
+ function createRateLimiter(options) {
22
+ const opts = options || {};
23
+ const windowMs = Math.max(1000, Number(opts.windowMs) || 60000);
24
+ const max = Math.max(1, Number(opts.max) || 30);
25
+ const maxGlobal = Math.max(max, Number(opts.maxGlobal) || max * 20);
26
+ // Map<key, { count, resetAt }>
27
+ const buckets = new Map();
28
+ let global = { count: 0, resetAt: now() + windowMs };
29
+ let lastSweep = now();
30
+
31
+ function sweep(t) {
32
+ // Opportunistic cleanup so the Map cannot grow without bound.
33
+ if (t - lastSweep < windowMs) return;
34
+ lastSweep = t;
35
+ for (const [key, bucket] of buckets) {
36
+ if (bucket.resetAt <= t) buckets.delete(key);
37
+ }
38
+ }
39
+
40
+ function rollGlobal(t) {
41
+ if (global.resetAt <= t) global = { count: 0, resetAt: t + windowMs };
42
+ }
43
+
44
+ // Record one hit for `key` and report whether it is allowed. The hit is only
45
+ // counted when allowed, so a denied caller does not push its own reset further
46
+ // out (no self-inflicted lockout extension).
47
+ function check(key) {
48
+ const t = now();
49
+ sweep(t);
50
+ rollGlobal(t);
51
+ const k = String(key == null ? "" : key);
52
+ let bucket = buckets.get(k);
53
+ if (!bucket || bucket.resetAt <= t) {
54
+ bucket = { count: 0, resetAt: t + windowMs };
55
+ buckets.set(k, bucket);
56
+ }
57
+ if (global.count >= maxGlobal) {
58
+ return { allowed: false, scope: "global", remaining: 0, retryAfterMs: Math.max(0, global.resetAt - t) };
59
+ }
60
+ if (bucket.count >= max) {
61
+ return { allowed: false, scope: "key", remaining: 0, retryAfterMs: Math.max(0, bucket.resetAt - t) };
62
+ }
63
+ bucket.count += 1;
64
+ global.count += 1;
65
+ return {
66
+ allowed: true,
67
+ scope: null,
68
+ remaining: Math.max(0, max - bucket.count),
69
+ retryAfterMs: Math.max(0, bucket.resetAt - t)
70
+ };
71
+ }
72
+
73
+ function reset() {
74
+ buckets.clear();
75
+ global = { count: 0, resetAt: now() + windowMs };
76
+ }
77
+
78
+ return { check, reset, config: { windowMs, max, maxGlobal } };
79
+ }
80
+
81
+ module.exports = { createRateLimiter };