xytara 2.3.0 → 2.4.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.
package/server.js CHANGED
@@ -65,7 +65,12 @@ const {
65
65
  applyRailCredits,
66
66
  buildCreditBalanceSummary,
67
67
  buildWalletSummary,
68
+ buildWalletLifecycleSummary,
69
+ buildWalletReserveSummary,
70
+ buildWalletCommitSummary,
71
+ buildWalletLedgerBundle,
68
72
  buildWalletLedgerSummary,
73
+ applyWalletLifecycleEvent,
69
74
  buildEconomicsIntelligenceSummary,
70
75
  buildTreasuryIntelligenceSummary,
71
76
  buildTreasurySummary,
@@ -78,6 +83,56 @@ const {
78
83
  buildPolicySummary,
79
84
  buildAccountCreditSpendPolicyPack,
80
85
  buildAgentCreditSpendPolicyView,
86
+ buildPricingPolicySummary,
87
+ buildPricingPolicyOperatorBundle,
88
+ buildPricingPolicyPack,
89
+ buildPricingPolicyApplicationSummary,
90
+ buildPricingPolicyPackage,
91
+ buildQuotePolicyDecisionSummary,
92
+ buildPricingBandDecisionSummary,
93
+ buildQuotePolicyOperatorBundle,
94
+ summarizeQuotePolicyOperatorBundle,
95
+ buildQuotePolicyPack,
96
+ summarizeQuotePolicyPack,
97
+ buildQuotePolicyApplicationSummary,
98
+ buildQuotePolicyPackage,
99
+ summarizeQuotePolicyPackage,
100
+ buildTrustInputSummary,
101
+ buildTrustLayerSummary,
102
+ buildTrustLayerOperatorBundle,
103
+ summarizeTrustLayerOperatorBundle,
104
+ buildTrustLayerPolicyPack,
105
+ summarizeTrustLayerPolicyPack,
106
+ buildTrustLayerApplicationSummary,
107
+ buildTrustLayerPackage,
108
+ summarizeTrustLayerPackage,
109
+ listNetworkParticipants,
110
+ getNetworkParticipant,
111
+ buildNetworkParticipationAdmissionPreview,
112
+ createNetworkParticipant,
113
+ buildNetworkParticipationReviewBundle,
114
+ buildNetworkParticipationAttentionSummary,
115
+ buildNetworkParticipationSummary,
116
+ buildNetworkParticipationOperatorBundle,
117
+ buildNetworkParticipationPackage,
118
+ listMultiOperatorParticipants,
119
+ getMultiOperatorParticipant,
120
+ buildMultiOperatorAdmissionPreview,
121
+ createMultiOperatorParticipant,
122
+ renewMultiOperatorParticipant,
123
+ revokeMultiOperatorParticipant,
124
+ rotateMultiOperatorParticipant,
125
+ buildMultiOperatorParticipantRotationSummary,
126
+ buildMultiOperatorReviewBundle,
127
+ buildMultiOperatorAttentionSummary,
128
+ buildMultiOperatorParticipationSummary,
129
+ buildMultiOperatorParticipationOperatorBundle,
130
+ summarizeMultiOperatorParticipationOperatorBundle,
131
+ buildMultiOperatorParticipationPolicyPack,
132
+ summarizeMultiOperatorParticipationPolicyPack,
133
+ buildMultiOperatorParticipationApplicationSummary,
134
+ buildMultiOperatorParticipationPackage,
135
+ summarizeMultiOperatorParticipationPackage,
81
136
  buildRailSummary,
82
137
  buildEntitlementSummary,
83
138
  buildEntitlementReplenishmentSummary,
@@ -112,17 +167,60 @@ const {
112
167
  buildOperatorExportPack,
113
168
  buildReconciliationReport
114
169
  } = require("./lib/commerce_reports");
170
+ const {
171
+ buildAuthoritySummary,
172
+ buildAuthorityBundle,
173
+ buildAuthorityUsageSummary,
174
+ buildAuthorityReviewBundle,
175
+ buildAuthorityAttentionSummary,
176
+ buildAuthorityLineageSummary,
177
+ buildAuthorityPolicyPack,
178
+ buildAuthorityPolicyPackSummary
179
+ } = require("./lib/commerce_authority");
180
+ const {
181
+ buildMachineIdentitySummary,
182
+ buildMachineIdentityBundle,
183
+ buildMachineIdentityAttachmentSummary,
184
+ buildMachineIdentityLineageSummary,
185
+ buildMachineIdentityBindingLineageSummary,
186
+ buildMachineIdentityProfile,
187
+ buildMachineIdentityPolicyPack,
188
+ buildMachineIdentityPolicyPackSummary,
189
+ buildMachineIdentityPolicyApplicationSummary,
190
+ buildMachineIdentityReviewBundle,
191
+ buildMachineIdentityAttentionSummary,
192
+ buildMachineIdentityOperatorBundle
193
+ } = require("./lib/commerce_identity");
115
194
  const {
116
195
  createExternalCreditGrant,
117
196
  getExternalCreditGrant,
118
197
  listExternalCreditGrants
119
198
  } = require("./lib/external_credit_bridge");
120
199
  const {
200
+ createAuthorityBinding,
121
201
  createSpendCredential,
202
+ evaluateAuthorityBindingAction,
203
+ getAuthorityBinding,
204
+ getAuthorityBindingContractSummary,
205
+ getAuthorityBindingRotationSummary,
122
206
  getSpendCredential,
207
+ listAuthorityBindings,
123
208
  listSpendCredentials,
209
+ renewAuthorityBinding,
210
+ resolveSpendCredential,
211
+ rotateAuthorityBinding,
212
+ revokeAuthorityBinding,
124
213
  revokeSpendCredential
125
214
  } = require("./lib/account_auth");
215
+ const {
216
+ createIdentityBinding,
217
+ listIdentityBindings,
218
+ getIdentityBinding,
219
+ getIdentityBindingRotationSummary,
220
+ renewIdentityBinding,
221
+ revokeIdentityBinding,
222
+ rotateIdentityBinding
223
+ } = require("./lib/identity_auth");
126
224
  const {
127
225
  getBsvSettlementRecord,
128
226
  listBsvSettlementRecords,
@@ -246,6 +344,19 @@ const {
246
344
  buildAdapterPartnerPack,
247
345
  summarizeAdapterPartnerPack
248
346
  } = require("./lib/adapter_partner_pack");
347
+ const {
348
+ buildCapabilityRegistrySummary,
349
+ buildCapabilityRegistryBundle,
350
+ buildCapabilityRegistryClassificationSummary,
351
+ buildCapabilityRegistryLineageSummary,
352
+ buildCapabilityRegistryOperatorBundle,
353
+ buildCapabilityRegistryPolicyPack,
354
+ summarizeCapabilityRegistryPolicyPack,
355
+ buildCapabilityRegistryPolicyApplicationSummary,
356
+ buildCapabilityRegistryPackage,
357
+ summarizeCapabilityRegistryPackage,
358
+ summarizeCapabilityRegistryOperatorBundle
359
+ } = require("./lib/capability_registry");
249
360
  const {
250
361
  buildPartnerIntelligencePack,
251
362
  summarizePartnerIntelligencePack
@@ -875,6 +986,19 @@ function parseBearerToken(headers) {
875
986
  return match ? match[1].trim() : null;
876
987
  }
877
988
 
989
+ function resolveDelegatedAuthorityForHeaders(state, headers) {
990
+ const bearerToken = parseBearerToken(headers);
991
+ const delegatedSpendRequested = typeof bearerToken === "string" && bearerToken.startsWith("xytara_spend_");
992
+ if (!delegatedSpendRequested) {
993
+ return { requested: false, ok: false, reason: "spend_credential_not_requested" };
994
+ }
995
+ const delegatedSpend = resolveSpendCredential(state, bearerToken);
996
+ return {
997
+ requested: true,
998
+ ...delegatedSpend
999
+ };
1000
+ }
1001
+
878
1002
  function verifyAccountAuthWriteAccess(headers) {
879
1003
  const expectedToken = getAccountAuthBearerToken();
880
1004
  if (!expectedToken) {
@@ -900,6 +1024,18 @@ function verifyAccountAuthWriteAccess(headers) {
900
1024
  };
901
1025
  }
902
1026
 
1027
+ function mergeIdentityBindingPolicyPayload(policySummary, body, accountId) {
1028
+ const payload = body && typeof body === "object" && !Array.isArray(body) ? body : {};
1029
+ const suggested = policySummary && policySummary.suggested_binding_payload && typeof policySummary.suggested_binding_payload === "object"
1030
+ ? policySummary.suggested_binding_payload
1031
+ : {};
1032
+ return {
1033
+ ...suggested,
1034
+ ...payload,
1035
+ account_id: accountId
1036
+ };
1037
+ }
1038
+
903
1039
  function verifyCreditBridgeWriteAccess(headers) {
904
1040
  const expectedToken = getCreditBridgeBearerToken();
905
1041
  if (!expectedToken) {
@@ -3271,6 +3407,76 @@ async function routeRequest(req, res) {
3271
3407
  return;
3272
3408
  }
3273
3409
 
3410
+ if (req.method === "GET" && url.pathname === "/v1/capability-registry") {
3411
+ sendJson(res, 200, buildCapabilityRegistryBundle());
3412
+ return;
3413
+ }
3414
+
3415
+ if (req.method === "GET" && url.pathname === "/v1/capability-registry/summary") {
3416
+ sendJson(res, 200, buildCapabilityRegistrySummary());
3417
+ return;
3418
+ }
3419
+
3420
+ if (req.method === "GET" && url.pathname === "/v1/capability-registry/classification-summary") {
3421
+ sendJson(res, 200, buildCapabilityRegistryClassificationSummary());
3422
+ return;
3423
+ }
3424
+
3425
+ if (req.method === "GET" && url.pathname === "/v1/capability-registry/lineage-summary") {
3426
+ sendJson(res, 200, buildCapabilityRegistryLineageSummary());
3427
+ return;
3428
+ }
3429
+
3430
+ if (req.method === "GET" && url.pathname === "/v1/capability-registry/operator-bundle") {
3431
+ sendJson(res, 200, buildCapabilityRegistryOperatorBundle(state, {
3432
+ account_id: url.searchParams.get("account_id") || "acct_demo"
3433
+ }));
3434
+ return;
3435
+ }
3436
+
3437
+ if (req.method === "GET" && url.pathname === "/v1/capability-registry/operator-bundle/summary") {
3438
+ sendJson(res, 200, summarizeCapabilityRegistryOperatorBundle(state, {
3439
+ account_id: url.searchParams.get("account_id") || "acct_demo"
3440
+ }));
3441
+ return;
3442
+ }
3443
+
3444
+ if (req.method === "GET" && url.pathname === "/v1/capability-registry/policy-pack") {
3445
+ sendJson(res, 200, buildCapabilityRegistryPolicyPack(state, {
3446
+ account_id: url.searchParams.get("account_id") || "acct_demo"
3447
+ }));
3448
+ return;
3449
+ }
3450
+
3451
+ if (req.method === "GET" && url.pathname === "/v1/capability-registry/policy-pack/summary") {
3452
+ sendJson(res, 200, summarizeCapabilityRegistryPolicyPack(state, {
3453
+ account_id: url.searchParams.get("account_id") || "acct_demo"
3454
+ }));
3455
+ return;
3456
+ }
3457
+
3458
+ if (req.method === "GET" && url.pathname === "/v1/capability-registry/policy-application-summary") {
3459
+ sendJson(res, 200, buildCapabilityRegistryPolicyApplicationSummary(state, {
3460
+ account_id: url.searchParams.get("account_id") || "acct_demo",
3461
+ template_id: url.searchParams.get("template_id") || ""
3462
+ }));
3463
+ return;
3464
+ }
3465
+
3466
+ if (req.method === "GET" && url.pathname === "/v1/capability-registry/package") {
3467
+ sendJson(res, 200, buildCapabilityRegistryPackage(state, {
3468
+ account_id: url.searchParams.get("account_id") || "acct_demo"
3469
+ }));
3470
+ return;
3471
+ }
3472
+
3473
+ if (req.method === "GET" && url.pathname === "/v1/capability-registry/package/summary") {
3474
+ sendJson(res, 200, summarizeCapabilityRegistryPackage(state, {
3475
+ account_id: url.searchParams.get("account_id") || "acct_demo"
3476
+ }));
3477
+ return;
3478
+ }
3479
+
3274
3480
  if (req.method === "GET" && url.pathname === "/v1/partner-intelligence") {
3275
3481
  sendJson(res, 200, buildPartnerIntelligencePack());
3276
3482
  return;
@@ -5318,6 +5524,78 @@ async function routeRequest(req, res) {
5318
5524
  return;
5319
5525
  }
5320
5526
 
5527
+ if (req.method === "POST" && url.pathname === "/v1/economics/rails/credits/reserve") {
5528
+ const body = await readJsonBody(req);
5529
+ const delegatedAuthority = resolveDelegatedAuthorityForHeaders(state, req.headers || {});
5530
+ if (delegatedAuthority.requested && !delegatedAuthority.ok) {
5531
+ sendJson(res, 403, { ok: false, reason: delegatedAuthority.reason });
5532
+ return;
5533
+ }
5534
+ if (delegatedAuthority.ok && delegatedAuthority.binding) {
5535
+ const units = typeof body.units === "number" ? body.units : 0;
5536
+ const authorityDecision = evaluateAuthorityBindingAction(delegatedAuthority.binding, "reserve", units);
5537
+ if (!authorityDecision.ok) {
5538
+ sendJson(res, 403, authorityDecision);
5539
+ return;
5540
+ }
5541
+ }
5542
+ const result = applyWalletLifecycleEvent(state, body, "reserve");
5543
+ if (!result.ok) {
5544
+ sendJson(res, 409, result);
5545
+ return;
5546
+ }
5547
+ sendJson(res, 200, result);
5548
+ return;
5549
+ }
5550
+
5551
+ if (req.method === "POST" && url.pathname === "/v1/economics/rails/credits/release") {
5552
+ const body = await readJsonBody(req);
5553
+ const delegatedAuthority = resolveDelegatedAuthorityForHeaders(state, req.headers || {});
5554
+ if (delegatedAuthority.requested && !delegatedAuthority.ok) {
5555
+ sendJson(res, 403, { ok: false, reason: delegatedAuthority.reason });
5556
+ return;
5557
+ }
5558
+ if (delegatedAuthority.ok && delegatedAuthority.binding) {
5559
+ const units = typeof body.units === "number" ? body.units : 0;
5560
+ const authorityDecision = evaluateAuthorityBindingAction(delegatedAuthority.binding, "release", units);
5561
+ if (!authorityDecision.ok) {
5562
+ sendJson(res, 403, authorityDecision);
5563
+ return;
5564
+ }
5565
+ }
5566
+ const result = applyWalletLifecycleEvent(state, body, "release");
5567
+ if (!result.ok) {
5568
+ sendJson(res, 409, result);
5569
+ return;
5570
+ }
5571
+ sendJson(res, 200, result);
5572
+ return;
5573
+ }
5574
+
5575
+ if (req.method === "POST" && url.pathname === "/v1/economics/rails/credits/reverse") {
5576
+ const body = await readJsonBody(req);
5577
+ const delegatedAuthority = resolveDelegatedAuthorityForHeaders(state, req.headers || {});
5578
+ if (delegatedAuthority.requested && !delegatedAuthority.ok) {
5579
+ sendJson(res, 403, { ok: false, reason: delegatedAuthority.reason });
5580
+ return;
5581
+ }
5582
+ if (delegatedAuthority.ok && delegatedAuthority.binding) {
5583
+ const units = typeof body.units === "number" ? body.units : 0;
5584
+ const authorityDecision = evaluateAuthorityBindingAction(delegatedAuthority.binding, "reverse", units);
5585
+ if (!authorityDecision.ok) {
5586
+ sendJson(res, 403, authorityDecision);
5587
+ return;
5588
+ }
5589
+ }
5590
+ const result = applyWalletLifecycleEvent(state, body, "reverse");
5591
+ if (!result.ok) {
5592
+ sendJson(res, 409, result);
5593
+ return;
5594
+ }
5595
+ sendJson(res, 200, result);
5596
+ return;
5597
+ }
5598
+
5321
5599
  if (req.method === "POST" && url.pathname === "/v1/economics/rails/credits/consume") {
5322
5600
  const body = await readJsonBody(req);
5323
5601
  const result = consumeAccountCredits(state, body);
@@ -5439,128 +5717,433 @@ async function routeRequest(req, res) {
5439
5717
  return;
5440
5718
  }
5441
5719
 
5442
- if (req.method === "POST" && url.pathname.endsWith("/revoke") && url.pathname.startsWith("/v1/account-auth/spend-credentials/")) {
5720
+ if (req.method === "GET" && url.pathname === "/v1/account-auth/authority-bindings") {
5443
5721
  const authorization = verifyAccountAuthWriteAccess(req.headers || {});
5444
5722
  if (!authorization.ok) {
5445
5723
  sendJson(res, authorization.status, authorization.payload);
5446
5724
  return;
5447
5725
  }
5448
- const credentialId = getDecodedSuffixId(url.pathname, "/v1/account-auth/spend-credentials/").replace(/\/revoke$/, "");
5449
- const credential = revokeSpendCredential(state, credentialId, await readJsonBody(req));
5450
- if (!credential) {
5451
- sendJson(res, 404, { ok: false, reason: "spend_credential_not_found" });
5452
- return;
5453
- }
5726
+ const bindings = listAuthorityBindings(state, Object.fromEntries(url.searchParams.entries()));
5454
5727
  sendJson(res, 200, {
5455
5728
  ok: true,
5456
5729
  auth_mode: authorization.auth_mode,
5457
- spend_credential: credential
5730
+ authority_bindings: bindings
5458
5731
  });
5459
5732
  return;
5460
5733
  }
5461
5734
 
5462
- if (req.method === "GET" && url.pathname.startsWith("/v1/account-auth/spend-credentials/")) {
5735
+ if (req.method === "GET" && url.pathname === "/v1/identity/bindings") {
5463
5736
  const authorization = verifyAccountAuthWriteAccess(req.headers || {});
5464
5737
  if (!authorization.ok) {
5465
5738
  sendJson(res, authorization.status, authorization.payload);
5466
5739
  return;
5467
5740
  }
5468
- const credentialId = getDecodedSuffixId(url.pathname, "/v1/account-auth/spend-credentials/");
5469
- const credential = getSpendCredential(state, credentialId);
5470
- if (!credential) {
5471
- sendJson(res, 404, { ok: false, reason: "spend_credential_not_found" });
5472
- return;
5473
- }
5741
+ const bindings = listIdentityBindings(state, Object.fromEntries(url.searchParams.entries()));
5474
5742
  sendJson(res, 200, {
5475
5743
  ok: true,
5476
5744
  auth_mode: authorization.auth_mode,
5477
- spend_credential: credential
5745
+ identity_bindings: bindings
5478
5746
  });
5479
5747
  return;
5480
5748
  }
5481
5749
 
5482
- if (req.method === "GET" && url.pathname === "/v1/checkout/purchase-intents") {
5750
+ if (req.method === "POST" && url.pathname === "/v1/identity/bindings") {
5751
+ const authorization = verifyAccountAuthWriteAccess(req.headers || {});
5752
+ if (!authorization.ok) {
5753
+ sendJson(res, authorization.status, authorization.payload);
5754
+ return;
5755
+ }
5756
+ const body = await readJsonBody(req);
5483
5757
  sendJson(res, 200, {
5484
5758
  ok: true,
5485
- purchase_intents: listHostedCheckoutPurchaseIntents(state, url.searchParams.get("account_id"))
5759
+ auth_mode: authorization.auth_mode,
5760
+ identity_binding: createIdentityBinding(state, body)
5486
5761
  });
5487
5762
  return;
5488
5763
  }
5489
5764
 
5490
- if (req.method === "POST" && url.pathname === "/v1/checkout/purchase-intents") {
5765
+ if (req.method === "POST" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/machine-identity-policy-bindings")) {
5766
+ const authorization = verifyAccountAuthWriteAccess(req.headers || {});
5767
+ if (!authorization.ok) {
5768
+ sendJson(res, authorization.status, authorization.payload);
5769
+ return;
5770
+ }
5771
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/machine-identity-policy-bindings$/, "");
5491
5772
  const body = await readJsonBody(req);
5492
- sendJson(res, 200, { ok: true, purchase_intent: createHostedCheckoutPurchaseIntent(state, body) });
5773
+ const policySummary = buildMachineIdentityPolicyApplicationSummary(state, accountId, body && body.template_id ? body.template_id : null);
5774
+ const identityBinding = createIdentityBinding(state, mergeIdentityBindingPolicyPayload(policySummary, body, accountId));
5775
+ sendJson(res, 200, {
5776
+ ok: true,
5777
+ auth_mode: authorization.auth_mode,
5778
+ machine_identity_policy_application_summary: policySummary,
5779
+ identity_binding: identityBinding
5780
+ });
5493
5781
  return;
5494
5782
  }
5495
5783
 
5496
- if (
5497
- req.method === "GET"
5498
- && url.pathname.startsWith("/v1/checkout/purchase-intents/")
5499
- && !url.pathname.endsWith("/sessions")
5500
- && !url.pathname.endsWith("/refunds")
5501
- ) {
5502
- const purchaseIntentId = getDecodedSuffixId(url.pathname, "/v1/checkout/purchase-intents/");
5503
- const response = buildNamedRecordResponse(
5504
- "purchase_intent",
5505
- getHostedCheckoutPurchaseIntent(state, purchaseIntentId),
5506
- "purchase_intent_not_found"
5507
- );
5508
- sendJson(res, response.status, response.payload);
5784
+ if (req.method === "POST" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.includes("/machine-identity-policy-rotations/")) {
5785
+ const authorization = verifyAccountAuthWriteAccess(req.headers || {});
5786
+ if (!authorization.ok) {
5787
+ sendJson(res, authorization.status, authorization.payload);
5788
+ return;
5789
+ }
5790
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/machine-identity-policy-rotations\/.*$/, "");
5791
+ const bindingId = getDecodedSuffixId(url.pathname, `/v1/economics/accounts/${encodeURIComponent(accountId)}/machine-identity-policy-rotations/`);
5792
+ const body = await readJsonBody(req);
5793
+ const policySummary = buildMachineIdentityPolicyApplicationSummary(state, accountId, body && body.template_id ? body.template_id : null);
5794
+ const rotation = rotateIdentityBinding(state, bindingId, mergeIdentityBindingPolicyPayload(policySummary, body, accountId));
5795
+ if (!rotation) {
5796
+ sendJson(res, 404, { ok: false, reason: "identity_binding_not_found" });
5797
+ return;
5798
+ }
5799
+ sendJson(res, 200, {
5800
+ ok: true,
5801
+ auth_mode: authorization.auth_mode,
5802
+ machine_identity_policy_application_summary: policySummary,
5803
+ rotation
5804
+ });
5509
5805
  return;
5510
5806
  }
5511
5807
 
5512
- if (req.method === "GET" && url.pathname.startsWith("/v1/checkout/purchase-intents/") && url.pathname.endsWith("/sessions")) {
5513
- const purchaseIntentId = getDecodedSuffixId(url.pathname, "/v1/checkout/purchase-intents/").replace(/\/sessions$/, "");
5808
+ if (req.method === "POST" && url.pathname.endsWith("/revoke") && url.pathname.startsWith("/v1/identity/bindings/")) {
5809
+ const authorization = verifyAccountAuthWriteAccess(req.headers || {});
5810
+ if (!authorization.ok) {
5811
+ sendJson(res, authorization.status, authorization.payload);
5812
+ return;
5813
+ }
5814
+ const bindingId = getDecodedSuffixId(url.pathname, "/v1/identity/bindings/").replace(/\/revoke$/, "");
5815
+ const binding = revokeIdentityBinding(state, bindingId, await readJsonBody(req));
5816
+ if (!binding) {
5817
+ sendJson(res, 404, { ok: false, reason: "identity_binding_not_found" });
5818
+ return;
5819
+ }
5514
5820
  sendJson(res, 200, {
5515
5821
  ok: true,
5516
- checkout_sessions: listHostedCheckoutSessions(state, purchaseIntentId)
5822
+ auth_mode: authorization.auth_mode,
5823
+ identity_binding: binding
5517
5824
  });
5518
5825
  return;
5519
5826
  }
5520
5827
 
5521
- if (req.method === "POST" && url.pathname.startsWith("/v1/checkout/purchase-intents/") && url.pathname.endsWith("/session")) {
5522
- const purchaseIntentId = getDecodedSuffixId(url.pathname, "/v1/checkout/purchase-intents/").replace(/\/session$/, "");
5523
- const body = await readJsonBody(req);
5524
- const session = createHostedCheckoutSession(state, purchaseIntentId, body);
5525
- const response = buildNamedRecordResponse("checkout_session", session, "purchase_intent_not_found");
5526
- sendJson(res, response.status, response.payload);
5828
+ if (req.method === "POST" && url.pathname.endsWith("/renew") && url.pathname.startsWith("/v1/identity/bindings/")) {
5829
+ const authorization = verifyAccountAuthWriteAccess(req.headers || {});
5830
+ if (!authorization.ok) {
5831
+ sendJson(res, authorization.status, authorization.payload);
5832
+ return;
5833
+ }
5834
+ const bindingId = getDecodedSuffixId(url.pathname, "/v1/identity/bindings/").replace(/\/renew$/, "");
5835
+ const binding = renewIdentityBinding(state, bindingId, await readJsonBody(req));
5836
+ if (!binding) {
5837
+ sendJson(res, 404, { ok: false, reason: "identity_binding_not_found" });
5838
+ return;
5839
+ }
5840
+ sendJson(res, 200, {
5841
+ ok: true,
5842
+ auth_mode: authorization.auth_mode,
5843
+ identity_binding: binding
5844
+ });
5527
5845
  return;
5528
5846
  }
5529
5847
 
5530
- if (req.method === "GET" && url.pathname.startsWith("/v1/checkout/purchase-intents/") && url.pathname.endsWith("/refunds")) {
5531
- const purchaseIntentId = getDecodedSuffixId(url.pathname, "/v1/checkout/purchase-intents/").replace(/\/refunds$/, "");
5848
+ if (req.method === "POST" && url.pathname.endsWith("/rotate") && url.pathname.startsWith("/v1/identity/bindings/")) {
5849
+ const authorization = verifyAccountAuthWriteAccess(req.headers || {});
5850
+ if (!authorization.ok) {
5851
+ sendJson(res, authorization.status, authorization.payload);
5852
+ return;
5853
+ }
5854
+ const bindingId = getDecodedSuffixId(url.pathname, "/v1/identity/bindings/").replace(/\/rotate$/, "");
5855
+ const rotation = rotateIdentityBinding(state, bindingId, await readJsonBody(req));
5856
+ if (!rotation) {
5857
+ sendJson(res, 404, { ok: false, reason: "identity_binding_not_found" });
5858
+ return;
5859
+ }
5532
5860
  sendJson(res, 200, {
5533
5861
  ok: true,
5534
- refunds: listHostedCheckoutRefunds(state, purchaseIntentId)
5862
+ auth_mode: authorization.auth_mode,
5863
+ rotation
5535
5864
  });
5536
5865
  return;
5537
5866
  }
5538
5867
 
5539
- if (req.method === "POST" && url.pathname.startsWith("/v1/checkout/purchase-intents/") && url.pathname.endsWith("/refund-request")) {
5540
- const purchaseIntentId = getDecodedSuffixId(url.pathname, "/v1/checkout/purchase-intents/").replace(/\/refund-request$/, "");
5541
- const body = await readJsonBody(req);
5542
- const refund = requestHostedCheckoutRefund(state, purchaseIntentId, body);
5543
- const response = buildNamedRecordResponse("refund", refund, "purchase_intent_not_found");
5544
- sendJson(res, response.status, response.payload);
5868
+ if (req.method === "GET" && url.pathname.startsWith("/v1/identity/bindings/")) {
5869
+ const authorization = verifyAccountAuthWriteAccess(req.headers || {});
5870
+ if (!authorization.ok) {
5871
+ sendJson(res, authorization.status, authorization.payload);
5872
+ return;
5873
+ }
5874
+ if (url.pathname.endsWith("/rotation-summary")) {
5875
+ const bindingId = getDecodedSuffixId(url.pathname, "/v1/identity/bindings/").replace(/\/rotation-summary$/, "");
5876
+ const bindingSummary = getIdentityBindingRotationSummary(state, bindingId);
5877
+ if (!bindingSummary) {
5878
+ sendJson(res, 404, { ok: false, reason: "identity_binding_not_found" });
5879
+ return;
5880
+ }
5881
+ sendJson(res, 200, {
5882
+ ok: true,
5883
+ auth_mode: authorization.auth_mode,
5884
+ identity_binding_rotation_summary: bindingSummary
5885
+ });
5886
+ return;
5887
+ }
5888
+ const bindingId = getDecodedSuffixId(url.pathname, "/v1/identity/bindings/");
5889
+ const binding = getIdentityBinding(state, bindingId);
5890
+ if (!binding) {
5891
+ sendJson(res, 404, { ok: false, reason: "identity_binding_not_found" });
5892
+ return;
5893
+ }
5894
+ sendJson(res, 200, {
5895
+ ok: true,
5896
+ auth_mode: authorization.auth_mode,
5897
+ identity_binding: binding
5898
+ });
5545
5899
  return;
5546
5900
  }
5547
5901
 
5548
- if (req.method === "GET" && url.pathname.startsWith("/v1/checkout/sessions/")) {
5549
- const checkoutSessionId = getDecodedSuffixId(url.pathname, "/v1/checkout/sessions/");
5550
- const response = buildNamedRecordResponse(
5551
- "checkout_session",
5552
- getHostedCheckoutSession(state, checkoutSessionId),
5553
- "checkout_session_not_found"
5554
- );
5555
- sendJson(res, response.status, response.payload);
5902
+ if (req.method === "POST" && url.pathname === "/v1/account-auth/authority-bindings") {
5903
+ const authorization = verifyAccountAuthWriteAccess(req.headers || {});
5904
+ if (!authorization.ok) {
5905
+ sendJson(res, authorization.status, authorization.payload);
5906
+ return;
5907
+ }
5908
+ const body = await readJsonBody(req);
5909
+ sendJson(res, 200, {
5910
+ ok: true,
5911
+ auth_mode: authorization.auth_mode,
5912
+ authority_binding: createAuthorityBinding(state, body)
5913
+ });
5556
5914
  return;
5557
5915
  }
5558
5916
 
5559
- if (req.method === "POST" && url.pathname === "/v1/checkout/events/normalize") {
5560
- const body = await readJsonBody(req);
5561
- const event = normalizeHostedCheckoutEvent(state, body);
5562
- const response = buildNamedRecordResponse("checkout_event", event, "purchase_intent_not_found");
5563
- sendJson(res, response.status, response.payload);
5917
+ if (req.method === "POST" && url.pathname.endsWith("/revoke") && url.pathname.startsWith("/v1/account-auth/authority-bindings/")) {
5918
+ const authorization = verifyAccountAuthWriteAccess(req.headers || {});
5919
+ if (!authorization.ok) {
5920
+ sendJson(res, authorization.status, authorization.payload);
5921
+ return;
5922
+ }
5923
+ const bindingId = getDecodedSuffixId(url.pathname, "/v1/account-auth/authority-bindings/").replace(/\/revoke$/, "");
5924
+ const binding = revokeAuthorityBinding(state, bindingId, await readJsonBody(req));
5925
+ if (!binding) {
5926
+ sendJson(res, 404, { ok: false, reason: "authority_binding_not_found" });
5927
+ return;
5928
+ }
5929
+ sendJson(res, 200, {
5930
+ ok: true,
5931
+ auth_mode: authorization.auth_mode,
5932
+ authority_binding: binding
5933
+ });
5934
+ return;
5935
+ }
5936
+
5937
+ if (req.method === "POST" && url.pathname.endsWith("/renew") && url.pathname.startsWith("/v1/account-auth/authority-bindings/")) {
5938
+ const authorization = verifyAccountAuthWriteAccess(req.headers || {});
5939
+ if (!authorization.ok) {
5940
+ sendJson(res, authorization.status, authorization.payload);
5941
+ return;
5942
+ }
5943
+ const bindingId = getDecodedSuffixId(url.pathname, "/v1/account-auth/authority-bindings/").replace(/\/renew$/, "");
5944
+ const binding = renewAuthorityBinding(state, bindingId, await readJsonBody(req));
5945
+ if (!binding) {
5946
+ sendJson(res, 404, { ok: false, reason: "authority_binding_not_found" });
5947
+ return;
5948
+ }
5949
+ sendJson(res, 200, {
5950
+ ok: true,
5951
+ auth_mode: authorization.auth_mode,
5952
+ authority_binding: binding
5953
+ });
5954
+ return;
5955
+ }
5956
+
5957
+ if (req.method === "POST" && url.pathname.endsWith("/rotate") && url.pathname.startsWith("/v1/account-auth/authority-bindings/")) {
5958
+ const authorization = verifyAccountAuthWriteAccess(req.headers || {});
5959
+ if (!authorization.ok) {
5960
+ sendJson(res, authorization.status, authorization.payload);
5961
+ return;
5962
+ }
5963
+ const bindingId = getDecodedSuffixId(url.pathname, "/v1/account-auth/authority-bindings/").replace(/\/rotate$/, "");
5964
+ const rotation = rotateAuthorityBinding(state, bindingId, await readJsonBody(req));
5965
+ if (!rotation) {
5966
+ sendJson(res, 404, { ok: false, reason: "authority_binding_not_found" });
5967
+ return;
5968
+ }
5969
+ sendJson(res, 200, {
5970
+ ok: true,
5971
+ auth_mode: authorization.auth_mode,
5972
+ rotation
5973
+ });
5974
+ return;
5975
+ }
5976
+
5977
+ if (req.method === "GET" && url.pathname.startsWith("/v1/account-auth/authority-bindings/")) {
5978
+ const authorization = verifyAccountAuthWriteAccess(req.headers || {});
5979
+ if (!authorization.ok) {
5980
+ sendJson(res, authorization.status, authorization.payload);
5981
+ return;
5982
+ }
5983
+ if (url.pathname.endsWith("/contract-summary")) {
5984
+ const bindingId = getDecodedSuffixId(url.pathname, "/v1/account-auth/authority-bindings/").replace(/\/contract-summary$/, "");
5985
+ const bindingSummary = getAuthorityBindingContractSummary(state, bindingId);
5986
+ if (!bindingSummary) {
5987
+ sendJson(res, 404, { ok: false, reason: "authority_binding_not_found" });
5988
+ return;
5989
+ }
5990
+ sendJson(res, 200, {
5991
+ ok: true,
5992
+ auth_mode: authorization.auth_mode,
5993
+ authority_binding_contract_summary: bindingSummary
5994
+ });
5995
+ return;
5996
+ }
5997
+ if (url.pathname.endsWith("/rotation-summary")) {
5998
+ const bindingId = getDecodedSuffixId(url.pathname, "/v1/account-auth/authority-bindings/").replace(/\/rotation-summary$/, "");
5999
+ const bindingSummary = getAuthorityBindingRotationSummary(state, bindingId);
6000
+ if (!bindingSummary) {
6001
+ sendJson(res, 404, { ok: false, reason: "authority_binding_not_found" });
6002
+ return;
6003
+ }
6004
+ sendJson(res, 200, {
6005
+ ok: true,
6006
+ auth_mode: authorization.auth_mode,
6007
+ authority_binding_rotation_summary: bindingSummary
6008
+ });
6009
+ return;
6010
+ }
6011
+ const bindingId = getDecodedSuffixId(url.pathname, "/v1/account-auth/authority-bindings/");
6012
+ const binding = getAuthorityBinding(state, bindingId);
6013
+ if (!binding) {
6014
+ sendJson(res, 404, { ok: false, reason: "authority_binding_not_found" });
6015
+ return;
6016
+ }
6017
+ sendJson(res, 200, {
6018
+ ok: true,
6019
+ auth_mode: authorization.auth_mode,
6020
+ authority_binding: binding
6021
+ });
6022
+ return;
6023
+ }
6024
+
6025
+ if (req.method === "POST" && url.pathname.endsWith("/revoke") && url.pathname.startsWith("/v1/account-auth/spend-credentials/")) {
6026
+ const authorization = verifyAccountAuthWriteAccess(req.headers || {});
6027
+ if (!authorization.ok) {
6028
+ sendJson(res, authorization.status, authorization.payload);
6029
+ return;
6030
+ }
6031
+ const credentialId = getDecodedSuffixId(url.pathname, "/v1/account-auth/spend-credentials/").replace(/\/revoke$/, "");
6032
+ const credential = revokeSpendCredential(state, credentialId, await readJsonBody(req));
6033
+ if (!credential) {
6034
+ sendJson(res, 404, { ok: false, reason: "spend_credential_not_found" });
6035
+ return;
6036
+ }
6037
+ sendJson(res, 200, {
6038
+ ok: true,
6039
+ auth_mode: authorization.auth_mode,
6040
+ spend_credential: credential
6041
+ });
6042
+ return;
6043
+ }
6044
+
6045
+ if (req.method === "GET" && url.pathname.startsWith("/v1/account-auth/spend-credentials/")) {
6046
+ const authorization = verifyAccountAuthWriteAccess(req.headers || {});
6047
+ if (!authorization.ok) {
6048
+ sendJson(res, authorization.status, authorization.payload);
6049
+ return;
6050
+ }
6051
+ const credentialId = getDecodedSuffixId(url.pathname, "/v1/account-auth/spend-credentials/");
6052
+ const credential = getSpendCredential(state, credentialId);
6053
+ if (!credential) {
6054
+ sendJson(res, 404, { ok: false, reason: "spend_credential_not_found" });
6055
+ return;
6056
+ }
6057
+ sendJson(res, 200, {
6058
+ ok: true,
6059
+ auth_mode: authorization.auth_mode,
6060
+ spend_credential: credential
6061
+ });
6062
+ return;
6063
+ }
6064
+
6065
+ if (req.method === "GET" && url.pathname === "/v1/checkout/purchase-intents") {
6066
+ sendJson(res, 200, {
6067
+ ok: true,
6068
+ purchase_intents: listHostedCheckoutPurchaseIntents(state, url.searchParams.get("account_id"))
6069
+ });
6070
+ return;
6071
+ }
6072
+
6073
+ if (req.method === "POST" && url.pathname === "/v1/checkout/purchase-intents") {
6074
+ const body = await readJsonBody(req);
6075
+ sendJson(res, 200, { ok: true, purchase_intent: createHostedCheckoutPurchaseIntent(state, body) });
6076
+ return;
6077
+ }
6078
+
6079
+ if (
6080
+ req.method === "GET"
6081
+ && url.pathname.startsWith("/v1/checkout/purchase-intents/")
6082
+ && !url.pathname.endsWith("/sessions")
6083
+ && !url.pathname.endsWith("/refunds")
6084
+ ) {
6085
+ const purchaseIntentId = getDecodedSuffixId(url.pathname, "/v1/checkout/purchase-intents/");
6086
+ const response = buildNamedRecordResponse(
6087
+ "purchase_intent",
6088
+ getHostedCheckoutPurchaseIntent(state, purchaseIntentId),
6089
+ "purchase_intent_not_found"
6090
+ );
6091
+ sendJson(res, response.status, response.payload);
6092
+ return;
6093
+ }
6094
+
6095
+ if (req.method === "GET" && url.pathname.startsWith("/v1/checkout/purchase-intents/") && url.pathname.endsWith("/sessions")) {
6096
+ const purchaseIntentId = getDecodedSuffixId(url.pathname, "/v1/checkout/purchase-intents/").replace(/\/sessions$/, "");
6097
+ sendJson(res, 200, {
6098
+ ok: true,
6099
+ checkout_sessions: listHostedCheckoutSessions(state, purchaseIntentId)
6100
+ });
6101
+ return;
6102
+ }
6103
+
6104
+ if (req.method === "POST" && url.pathname.startsWith("/v1/checkout/purchase-intents/") && url.pathname.endsWith("/session")) {
6105
+ const purchaseIntentId = getDecodedSuffixId(url.pathname, "/v1/checkout/purchase-intents/").replace(/\/session$/, "");
6106
+ const body = await readJsonBody(req);
6107
+ const session = createHostedCheckoutSession(state, purchaseIntentId, body);
6108
+ const response = buildNamedRecordResponse("checkout_session", session, "purchase_intent_not_found");
6109
+ sendJson(res, response.status, response.payload);
6110
+ return;
6111
+ }
6112
+
6113
+ if (req.method === "GET" && url.pathname.startsWith("/v1/checkout/purchase-intents/") && url.pathname.endsWith("/refunds")) {
6114
+ const purchaseIntentId = getDecodedSuffixId(url.pathname, "/v1/checkout/purchase-intents/").replace(/\/refunds$/, "");
6115
+ sendJson(res, 200, {
6116
+ ok: true,
6117
+ refunds: listHostedCheckoutRefunds(state, purchaseIntentId)
6118
+ });
6119
+ return;
6120
+ }
6121
+
6122
+ if (req.method === "POST" && url.pathname.startsWith("/v1/checkout/purchase-intents/") && url.pathname.endsWith("/refund-request")) {
6123
+ const purchaseIntentId = getDecodedSuffixId(url.pathname, "/v1/checkout/purchase-intents/").replace(/\/refund-request$/, "");
6124
+ const body = await readJsonBody(req);
6125
+ const refund = requestHostedCheckoutRefund(state, purchaseIntentId, body);
6126
+ const response = buildNamedRecordResponse("refund", refund, "purchase_intent_not_found");
6127
+ sendJson(res, response.status, response.payload);
6128
+ return;
6129
+ }
6130
+
6131
+ if (req.method === "GET" && url.pathname.startsWith("/v1/checkout/sessions/")) {
6132
+ const checkoutSessionId = getDecodedSuffixId(url.pathname, "/v1/checkout/sessions/");
6133
+ const response = buildNamedRecordResponse(
6134
+ "checkout_session",
6135
+ getHostedCheckoutSession(state, checkoutSessionId),
6136
+ "checkout_session_not_found"
6137
+ );
6138
+ sendJson(res, response.status, response.payload);
6139
+ return;
6140
+ }
6141
+
6142
+ if (req.method === "POST" && url.pathname === "/v1/checkout/events/normalize") {
6143
+ const body = await readJsonBody(req);
6144
+ const event = normalizeHostedCheckoutEvent(state, body);
6145
+ const response = buildNamedRecordResponse("checkout_event", event, "purchase_intent_not_found");
6146
+ sendJson(res, response.status, response.payload);
5564
6147
  return;
5565
6148
  }
5566
6149
 
@@ -5811,6 +6394,150 @@ async function routeRequest(req, res) {
5811
6394
  return;
5812
6395
  }
5813
6396
 
6397
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/wallet-lifecycle-summary")) {
6398
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/wallet-lifecycle-summary$/, "");
6399
+ sendJson(res, 200, buildWalletLifecycleSummary(state, accountId));
6400
+ return;
6401
+ }
6402
+
6403
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/wallet-reserve-summary")) {
6404
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/wallet-reserve-summary$/, "");
6405
+ sendJson(res, 200, buildWalletReserveSummary(state, accountId));
6406
+ return;
6407
+ }
6408
+
6409
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/wallet-commit-summary")) {
6410
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/wallet-commit-summary$/, "");
6411
+ sendJson(res, 200, buildWalletCommitSummary(state, accountId));
6412
+ return;
6413
+ }
6414
+
6415
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/wallet-ledger-bundle")) {
6416
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/wallet-ledger-bundle$/, "");
6417
+ sendJson(res, 200, buildWalletLedgerBundle(state, accountId));
6418
+ return;
6419
+ }
6420
+
6421
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/authority-summary")) {
6422
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/authority-summary$/, "");
6423
+ sendJson(res, 200, buildAuthoritySummary(state, accountId));
6424
+ return;
6425
+ }
6426
+
6427
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/authority-bundle")) {
6428
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/authority-bundle$/, "");
6429
+ sendJson(res, 200, buildAuthorityBundle(state, accountId));
6430
+ return;
6431
+ }
6432
+
6433
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/authority-usage-summary")) {
6434
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/authority-usage-summary$/, "");
6435
+ sendJson(res, 200, buildAuthorityUsageSummary(state, accountId));
6436
+ return;
6437
+ }
6438
+
6439
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/authority-review-bundle")) {
6440
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/authority-review-bundle$/, "");
6441
+ sendJson(res, 200, buildAuthorityReviewBundle(state, accountId));
6442
+ return;
6443
+ }
6444
+
6445
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/authority-attention-summary")) {
6446
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/authority-attention-summary$/, "");
6447
+ sendJson(res, 200, buildAuthorityAttentionSummary(state, accountId));
6448
+ return;
6449
+ }
6450
+
6451
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/authority-lineage-summary")) {
6452
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/authority-lineage-summary$/, "");
6453
+ sendJson(res, 200, buildAuthorityLineageSummary(state, accountId));
6454
+ return;
6455
+ }
6456
+
6457
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/authority-policy-pack/summary")) {
6458
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/authority-policy-pack\/summary$/, "");
6459
+ sendJson(res, 200, buildAuthorityPolicyPackSummary(state, accountId));
6460
+ return;
6461
+ }
6462
+
6463
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/authority-policy-pack")) {
6464
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/authority-policy-pack$/, "");
6465
+ sendJson(res, 200, buildAuthorityPolicyPack(state, accountId));
6466
+ return;
6467
+ }
6468
+
6469
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/machine-identity-summary")) {
6470
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/machine-identity-summary$/, "");
6471
+ sendJson(res, 200, buildMachineIdentitySummary(state, accountId));
6472
+ return;
6473
+ }
6474
+
6475
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/machine-identity-bundle")) {
6476
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/machine-identity-bundle$/, "");
6477
+ sendJson(res, 200, buildMachineIdentityBundle(state, accountId));
6478
+ return;
6479
+ }
6480
+
6481
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/machine-identity-attachment-summary")) {
6482
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/machine-identity-attachment-summary$/, "");
6483
+ sendJson(res, 200, buildMachineIdentityAttachmentSummary(state, accountId));
6484
+ return;
6485
+ }
6486
+
6487
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/machine-identity-lineage-summary")) {
6488
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/machine-identity-lineage-summary$/, "");
6489
+ sendJson(res, 200, buildMachineIdentityLineageSummary(state, accountId));
6490
+ return;
6491
+ }
6492
+
6493
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/machine-identity-binding-lineage-summary")) {
6494
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/machine-identity-binding-lineage-summary$/, "");
6495
+ sendJson(res, 200, buildMachineIdentityBindingLineageSummary(state, accountId));
6496
+ return;
6497
+ }
6498
+
6499
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/machine-identity-profile")) {
6500
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/machine-identity-profile$/, "");
6501
+ sendJson(res, 200, buildMachineIdentityProfile(state, accountId));
6502
+ return;
6503
+ }
6504
+
6505
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/machine-identity-policy-pack/summary")) {
6506
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/machine-identity-policy-pack\/summary$/, "");
6507
+ sendJson(res, 200, buildMachineIdentityPolicyPackSummary(state, accountId));
6508
+ return;
6509
+ }
6510
+
6511
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/machine-identity-policy-application-summary")) {
6512
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/machine-identity-policy-application-summary$/, "");
6513
+ sendJson(res, 200, buildMachineIdentityPolicyApplicationSummary(state, accountId, url.searchParams.get("template_id")));
6514
+ return;
6515
+ }
6516
+
6517
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/machine-identity-policy-pack")) {
6518
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/machine-identity-policy-pack$/, "");
6519
+ sendJson(res, 200, buildMachineIdentityPolicyPack(state, accountId));
6520
+ return;
6521
+ }
6522
+
6523
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/machine-identity-review-bundle")) {
6524
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/machine-identity-review-bundle$/, "");
6525
+ sendJson(res, 200, buildMachineIdentityReviewBundle(state, accountId));
6526
+ return;
6527
+ }
6528
+
6529
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/machine-identity-attention-summary")) {
6530
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/machine-identity-attention-summary$/, "");
6531
+ sendJson(res, 200, buildMachineIdentityAttentionSummary(state, accountId));
6532
+ return;
6533
+ }
6534
+
6535
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/machine-identity-operator-bundle")) {
6536
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/machine-identity-operator-bundle$/, "");
6537
+ sendJson(res, 200, buildMachineIdentityOperatorBundle(state, accountId));
6538
+ return;
6539
+ }
6540
+
5814
6541
  if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/wallet-ledger-summary")) {
5815
6542
  const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/wallet-ledger-summary$/, "");
5816
6543
  sendJson(res, 200, buildWalletLedgerSummary(state, accountId));
@@ -5980,6 +6707,456 @@ async function routeRequest(req, res) {
5980
6707
  return;
5981
6708
  }
5982
6709
 
6710
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/pricing-policy-summary")) {
6711
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/pricing-policy-summary$/, "");
6712
+ sendJson(res, 200, buildPricingPolicySummary(state, accountId));
6713
+ return;
6714
+ }
6715
+
6716
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/pricing-policy-operator-bundle")) {
6717
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/pricing-policy-operator-bundle$/, "");
6718
+ sendJson(res, 200, buildPricingPolicyOperatorBundle(state, accountId));
6719
+ return;
6720
+ }
6721
+
6722
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/pricing-policy-pack")) {
6723
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/pricing-policy-pack$/, "");
6724
+ sendJson(res, 200, buildPricingPolicyPack(state, accountId));
6725
+ return;
6726
+ }
6727
+
6728
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/pricing-policy-application-summary")) {
6729
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/pricing-policy-application-summary$/, "");
6730
+ sendJson(res, 200, buildPricingPolicyApplicationSummary(state, accountId, url.searchParams.get("template_id") || null));
6731
+ return;
6732
+ }
6733
+
6734
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/pricing-policy-package")) {
6735
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/pricing-policy-package$/, "");
6736
+ sendJson(res, 200, buildPricingPolicyPackage(state, accountId));
6737
+ return;
6738
+ }
6739
+
6740
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/quote-policy-decision-summary")) {
6741
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/quote-policy-decision-summary$/, "");
6742
+ sendJson(res, 200, buildQuotePolicyDecisionSummary(state, {
6743
+ account_id: accountId,
6744
+ task_ref: url.searchParams.get("task_ref") || null,
6745
+ workflow_ref: url.searchParams.get("workflow_ref") || null,
6746
+ quoted_units: Number.isFinite(Number(url.searchParams.get("quoted_units"))) ? Number(url.searchParams.get("quoted_units")) : null,
6747
+ agent_id: url.searchParams.get("agent_id") || null,
6748
+ budget_id: url.searchParams.get("budget_id") || null
6749
+ }));
6750
+ return;
6751
+ }
6752
+
6753
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/pricing-band-decision-summary")) {
6754
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/pricing-band-decision-summary$/, "");
6755
+ sendJson(res, 200, buildPricingBandDecisionSummary(state, {
6756
+ account_id: accountId,
6757
+ task_ref: url.searchParams.get("task_ref") || null,
6758
+ workflow_ref: url.searchParams.get("workflow_ref") || null,
6759
+ quoted_units: Number.isFinite(Number(url.searchParams.get("quoted_units"))) ? Number(url.searchParams.get("quoted_units")) : null
6760
+ }));
6761
+ return;
6762
+ }
6763
+
6764
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/quote-policy-operator-bundle")) {
6765
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/quote-policy-operator-bundle$/, "");
6766
+ sendJson(res, 200, buildQuotePolicyOperatorBundle(state, {
6767
+ account_id: accountId,
6768
+ task_ref: url.searchParams.get("task_ref") || null,
6769
+ workflow_ref: url.searchParams.get("workflow_ref") || null,
6770
+ quoted_units: Number.isFinite(Number(url.searchParams.get("quoted_units"))) ? Number(url.searchParams.get("quoted_units")) : null,
6771
+ agent_id: url.searchParams.get("agent_id") || null,
6772
+ budget_id: url.searchParams.get("budget_id") || null
6773
+ }));
6774
+ return;
6775
+ }
6776
+
6777
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/quote-policy-operator-bundle/summary")) {
6778
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/quote-policy-operator-bundle\/summary$/, "");
6779
+ sendJson(res, 200, summarizeQuotePolicyOperatorBundle(state, {
6780
+ account_id: accountId,
6781
+ task_ref: url.searchParams.get("task_ref") || null,
6782
+ workflow_ref: url.searchParams.get("workflow_ref") || null,
6783
+ quoted_units: Number.isFinite(Number(url.searchParams.get("quoted_units"))) ? Number(url.searchParams.get("quoted_units")) : null,
6784
+ agent_id: url.searchParams.get("agent_id") || null,
6785
+ budget_id: url.searchParams.get("budget_id") || null
6786
+ }));
6787
+ return;
6788
+ }
6789
+
6790
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/quote-policy-pack")) {
6791
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/quote-policy-pack$/, "");
6792
+ sendJson(res, 200, buildQuotePolicyPack(state, {
6793
+ account_id: accountId,
6794
+ task_ref: url.searchParams.get("task_ref") || null,
6795
+ workflow_ref: url.searchParams.get("workflow_ref") || null,
6796
+ quoted_units: Number.isFinite(Number(url.searchParams.get("quoted_units"))) ? Number(url.searchParams.get("quoted_units")) : null,
6797
+ agent_id: url.searchParams.get("agent_id") || null,
6798
+ budget_id: url.searchParams.get("budget_id") || null
6799
+ }));
6800
+ return;
6801
+ }
6802
+
6803
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/quote-policy-pack/summary")) {
6804
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/quote-policy-pack\/summary$/, "");
6805
+ sendJson(res, 200, summarizeQuotePolicyPack(state, {
6806
+ account_id: accountId,
6807
+ task_ref: url.searchParams.get("task_ref") || null,
6808
+ workflow_ref: url.searchParams.get("workflow_ref") || null,
6809
+ quoted_units: Number.isFinite(Number(url.searchParams.get("quoted_units"))) ? Number(url.searchParams.get("quoted_units")) : null,
6810
+ agent_id: url.searchParams.get("agent_id") || null,
6811
+ budget_id: url.searchParams.get("budget_id") || null
6812
+ }));
6813
+ return;
6814
+ }
6815
+
6816
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/quote-policy-application-summary")) {
6817
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/quote-policy-application-summary$/, "");
6818
+ sendJson(res, 200, buildQuotePolicyApplicationSummary(state, {
6819
+ account_id: accountId,
6820
+ task_ref: url.searchParams.get("task_ref") || null,
6821
+ workflow_ref: url.searchParams.get("workflow_ref") || null,
6822
+ quoted_units: Number.isFinite(Number(url.searchParams.get("quoted_units"))) ? Number(url.searchParams.get("quoted_units")) : null,
6823
+ agent_id: url.searchParams.get("agent_id") || null,
6824
+ budget_id: url.searchParams.get("budget_id") || null,
6825
+ template_id: url.searchParams.get("template_id") || null
6826
+ }));
6827
+ return;
6828
+ }
6829
+
6830
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/quote-policy-package")) {
6831
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/quote-policy-package$/, "");
6832
+ sendJson(res, 200, buildQuotePolicyPackage(state, {
6833
+ account_id: accountId,
6834
+ task_ref: url.searchParams.get("task_ref") || null,
6835
+ workflow_ref: url.searchParams.get("workflow_ref") || null,
6836
+ quoted_units: Number.isFinite(Number(url.searchParams.get("quoted_units"))) ? Number(url.searchParams.get("quoted_units")) : null,
6837
+ agent_id: url.searchParams.get("agent_id") || null,
6838
+ budget_id: url.searchParams.get("budget_id") || null
6839
+ }));
6840
+ return;
6841
+ }
6842
+
6843
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/quote-policy-package/summary")) {
6844
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/quote-policy-package\/summary$/, "");
6845
+ sendJson(res, 200, summarizeQuotePolicyPackage(state, {
6846
+ account_id: accountId,
6847
+ task_ref: url.searchParams.get("task_ref") || null,
6848
+ workflow_ref: url.searchParams.get("workflow_ref") || null,
6849
+ quoted_units: Number.isFinite(Number(url.searchParams.get("quoted_units"))) ? Number(url.searchParams.get("quoted_units")) : null,
6850
+ agent_id: url.searchParams.get("agent_id") || null,
6851
+ budget_id: url.searchParams.get("budget_id") || null
6852
+ }));
6853
+ return;
6854
+ }
6855
+
6856
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/trust-layer-summary")) {
6857
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/trust-layer-summary$/, "");
6858
+ sendJson(res, 200, buildTrustLayerSummary(state, accountId));
6859
+ return;
6860
+ }
6861
+
6862
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/trust-input-summary")) {
6863
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/trust-input-summary$/, "");
6864
+ sendJson(res, 200, buildTrustInputSummary(state, accountId));
6865
+ return;
6866
+ }
6867
+
6868
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/trust-layer-operator-bundle")) {
6869
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/trust-layer-operator-bundle$/, "");
6870
+ sendJson(res, 200, buildTrustLayerOperatorBundle(state, accountId));
6871
+ return;
6872
+ }
6873
+
6874
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/trust-layer-operator-bundle/summary")) {
6875
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/trust-layer-operator-bundle\/summary$/, "");
6876
+ sendJson(res, 200, summarizeTrustLayerOperatorBundle(state, accountId));
6877
+ return;
6878
+ }
6879
+
6880
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/trust-layer-policy-pack")) {
6881
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/trust-layer-policy-pack$/, "");
6882
+ sendJson(res, 200, buildTrustLayerPolicyPack(state, accountId));
6883
+ return;
6884
+ }
6885
+
6886
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/trust-layer-policy-pack/summary")) {
6887
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/trust-layer-policy-pack\/summary$/, "");
6888
+ sendJson(res, 200, summarizeTrustLayerPolicyPack(state, accountId));
6889
+ return;
6890
+ }
6891
+
6892
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/trust-layer-application-summary")) {
6893
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/trust-layer-application-summary$/, "");
6894
+ sendJson(res, 200, buildTrustLayerApplicationSummary(state, accountId, url.searchParams.get("template_id") || null));
6895
+ return;
6896
+ }
6897
+
6898
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/trust-layer-package")) {
6899
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/trust-layer-package$/, "");
6900
+ sendJson(res, 200, buildTrustLayerPackage(state, accountId));
6901
+ return;
6902
+ }
6903
+
6904
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/trust-layer-package/summary")) {
6905
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/trust-layer-package\/summary$/, "");
6906
+ sendJson(res, 200, summarizeTrustLayerPackage(state, accountId));
6907
+ return;
6908
+ }
6909
+
6910
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/multi-operator-participation-summary")) {
6911
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/multi-operator-participation-summary$/, "");
6912
+ sendJson(res, 200, buildMultiOperatorParticipationSummary(state, accountId));
6913
+ return;
6914
+ }
6915
+
6916
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/multi-operator-participation-operator-bundle")) {
6917
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/multi-operator-participation-operator-bundle$/, "");
6918
+ sendJson(res, 200, buildMultiOperatorParticipationOperatorBundle(state, accountId));
6919
+ return;
6920
+ }
6921
+
6922
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/multi-operator-participation-operator-bundle/summary")) {
6923
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/multi-operator-participation-operator-bundle\/summary$/, "");
6924
+ sendJson(res, 200, summarizeMultiOperatorParticipationOperatorBundle(state, accountId));
6925
+ return;
6926
+ }
6927
+
6928
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/multi-operator-participation-policy-pack")) {
6929
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/multi-operator-participation-policy-pack$/, "");
6930
+ sendJson(res, 200, buildMultiOperatorParticipationPolicyPack(state, accountId));
6931
+ return;
6932
+ }
6933
+
6934
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/multi-operator-participation-policy-pack/summary")) {
6935
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/multi-operator-participation-policy-pack\/summary$/, "");
6936
+ sendJson(res, 200, summarizeMultiOperatorParticipationPolicyPack(state, accountId));
6937
+ return;
6938
+ }
6939
+
6940
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/multi-operator-participation-application-summary")) {
6941
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/multi-operator-participation-application-summary$/, "");
6942
+ sendJson(res, 200, buildMultiOperatorParticipationApplicationSummary(state, accountId, url.searchParams.get("template_id") || null));
6943
+ return;
6944
+ }
6945
+
6946
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/multi-operator-participation-package")) {
6947
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/multi-operator-participation-package$/, "");
6948
+ sendJson(res, 200, buildMultiOperatorParticipationPackage(state, accountId));
6949
+ return;
6950
+ }
6951
+
6952
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/multi-operator-participation-package/summary")) {
6953
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/multi-operator-participation-package\/summary$/, "");
6954
+ sendJson(res, 200, summarizeMultiOperatorParticipationPackage(state, accountId));
6955
+ return;
6956
+ }
6957
+
6958
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/network-participation-summary")) {
6959
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/network-participation-summary$/, "");
6960
+ sendJson(res, 200, buildNetworkParticipationSummary(state, accountId));
6961
+ return;
6962
+ }
6963
+
6964
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/network-participation-operator-bundle")) {
6965
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/network-participation-operator-bundle$/, "");
6966
+ sendJson(res, 200, buildNetworkParticipationOperatorBundle(state, accountId));
6967
+ return;
6968
+ }
6969
+
6970
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/network-participation-package")) {
6971
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/network-participation-package$/, "");
6972
+ sendJson(res, 200, buildNetworkParticipationPackage(state, accountId));
6973
+ return;
6974
+ }
6975
+
6976
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/network-participation-review-bundle")) {
6977
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/network-participation-review-bundle$/, "");
6978
+ sendJson(res, 200, buildNetworkParticipationReviewBundle(state, accountId));
6979
+ return;
6980
+ }
6981
+
6982
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/network-participation-attention-summary")) {
6983
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/network-participation-attention-summary$/, "");
6984
+ sendJson(res, 200, buildNetworkParticipationAttentionSummary(state, accountId));
6985
+ return;
6986
+ }
6987
+
6988
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/network-participants")) {
6989
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/network-participants$/, "");
6990
+ sendJson(res, 200, {
6991
+ ok: true,
6992
+ account_id: accountId,
6993
+ count: listNetworkParticipants(state, accountId).length,
6994
+ participants: listNetworkParticipants(state, accountId)
6995
+ });
6996
+ return;
6997
+ }
6998
+
6999
+ if (
7000
+ req.method === "GET"
7001
+ && url.pathname.startsWith("/v1/economics/accounts/")
7002
+ && url.pathname.includes("/network-participants/")
7003
+ ) {
7004
+ const remainder = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/");
7005
+ const [accountId, participantPath] = remainder.split("/network-participants/");
7006
+ const participantId = participantPath;
7007
+ const participant = getNetworkParticipant(state, accountId, participantId);
7008
+ if (!participant) {
7009
+ sendJson(res, 404, { ok: false, reason: "network_participant_not_found" });
7010
+ return;
7011
+ }
7012
+ sendJson(res, 200, { ok: true, participant });
7013
+ return;
7014
+ }
7015
+
7016
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/multi-operator-participants")) {
7017
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/multi-operator-participants$/, "");
7018
+ sendJson(res, 200, {
7019
+ ok: true,
7020
+ account_id: accountId,
7021
+ count: listMultiOperatorParticipants(state, accountId).length,
7022
+ participants: listMultiOperatorParticipants(state, accountId)
7023
+ });
7024
+ return;
7025
+ }
7026
+
7027
+ if (req.method === "POST" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/multi-operator-participants")) {
7028
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/multi-operator-participants$/, "");
7029
+ const body = await readJsonBody(req);
7030
+ sendJson(res, 200, { ok: true, admission: createMultiOperatorParticipant(state, accountId, body) });
7031
+ return;
7032
+ }
7033
+
7034
+ if (
7035
+ req.method === "GET"
7036
+ && url.pathname.startsWith("/v1/economics/accounts/")
7037
+ && url.pathname.includes("/multi-operator-participants/")
7038
+ && !url.pathname.endsWith("/rotation-summary")
7039
+ ) {
7040
+ const remainder = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/");
7041
+ const [accountId, participantPath] = remainder.split("/multi-operator-participants/");
7042
+ const participantId = participantPath;
7043
+ const participant = getMultiOperatorParticipant(state, accountId, participantId);
7044
+ if (!participant) {
7045
+ sendJson(res, 404, { ok: false, reason: "multi_operator_participant_not_found" });
7046
+ return;
7047
+ }
7048
+ sendJson(res, 200, { ok: true, participant });
7049
+ return;
7050
+ }
7051
+
7052
+ if (
7053
+ req.method === "GET"
7054
+ && url.pathname.startsWith("/v1/economics/accounts/")
7055
+ && url.pathname.includes("/multi-operator-participants/")
7056
+ && url.pathname.endsWith("/rotation-summary")
7057
+ ) {
7058
+ const remainder = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/");
7059
+ const [accountId, participantPath] = remainder.split("/multi-operator-participants/");
7060
+ const participantId = participantPath.replace(/\/rotation-summary$/, "");
7061
+ const summary = buildMultiOperatorParticipantRotationSummary(state, accountId, participantId);
7062
+ if (!summary) {
7063
+ sendJson(res, 404, { ok: false, reason: "multi_operator_participant_not_found" });
7064
+ return;
7065
+ }
7066
+ sendJson(res, 200, summary);
7067
+ return;
7068
+ }
7069
+
7070
+ if (
7071
+ req.method === "POST"
7072
+ && url.pathname.startsWith("/v1/economics/accounts/")
7073
+ && url.pathname.includes("/multi-operator-participants/")
7074
+ && url.pathname.endsWith("/renew")
7075
+ ) {
7076
+ const remainder = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/");
7077
+ const [accountId, participantPath] = remainder.split("/multi-operator-participants/");
7078
+ const participantId = participantPath.replace(/\/renew$/, "");
7079
+ const body = await readJsonBody(req);
7080
+ const renewed = renewMultiOperatorParticipant(state, accountId, participantId, body);
7081
+ if (!renewed) {
7082
+ sendJson(res, 404, { ok: false, reason: "multi_operator_participant_not_found" });
7083
+ return;
7084
+ }
7085
+ sendJson(res, 200, { ok: true, renewal: renewed });
7086
+ return;
7087
+ }
7088
+
7089
+ if (
7090
+ req.method === "POST"
7091
+ && url.pathname.startsWith("/v1/economics/accounts/")
7092
+ && url.pathname.includes("/multi-operator-participants/")
7093
+ && url.pathname.endsWith("/rotate")
7094
+ ) {
7095
+ const remainder = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/");
7096
+ const [accountId, participantPath] = remainder.split("/multi-operator-participants/");
7097
+ const participantId = participantPath.replace(/\/rotate$/, "");
7098
+ const body = await readJsonBody(req);
7099
+ const rotation = rotateMultiOperatorParticipant(state, accountId, participantId, body);
7100
+ if (!rotation) {
7101
+ sendJson(res, 404, { ok: false, reason: "multi_operator_participant_not_found" });
7102
+ return;
7103
+ }
7104
+ sendJson(res, 200, { ok: true, rotation });
7105
+ return;
7106
+ }
7107
+
7108
+ if (
7109
+ req.method === "POST"
7110
+ && url.pathname.startsWith("/v1/economics/accounts/")
7111
+ && url.pathname.includes("/multi-operator-participants/")
7112
+ && url.pathname.endsWith("/revoke")
7113
+ ) {
7114
+ const remainder = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/");
7115
+ const [accountId, participantPath] = remainder.split("/multi-operator-participants/");
7116
+ const participantId = participantPath.replace(/\/revoke$/, "");
7117
+ const body = await readJsonBody(req);
7118
+ const revoked = revokeMultiOperatorParticipant(state, accountId, participantId, body);
7119
+ if (!revoked) {
7120
+ sendJson(res, 404, { ok: false, reason: "multi_operator_participant_not_found" });
7121
+ return;
7122
+ }
7123
+ sendJson(res, 200, { ok: true, revocation: revoked });
7124
+ return;
7125
+ }
7126
+
7127
+ if (req.method === "POST" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/multi-operator-participation/admission-preview")) {
7128
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/multi-operator-participation\/admission-preview$/, "");
7129
+ const body = await readJsonBody(req);
7130
+ sendJson(res, 200, { ok: true, admission_preview: buildMultiOperatorAdmissionPreview(state, accountId, body) });
7131
+ return;
7132
+ }
7133
+
7134
+ if (req.method === "POST" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/network-participation/admission-preview")) {
7135
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/network-participation\/admission-preview$/, "");
7136
+ const body = await readJsonBody(req);
7137
+ sendJson(res, 200, { ok: true, admission_preview: buildNetworkParticipationAdmissionPreview(state, accountId, body) });
7138
+ return;
7139
+ }
7140
+
7141
+ if (req.method === "POST" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/network-participants")) {
7142
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/network-participants$/, "");
7143
+ const body = await readJsonBody(req);
7144
+ sendJson(res, 200, { ok: true, admission: createNetworkParticipant(state, accountId, body) });
7145
+ return;
7146
+ }
7147
+
7148
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/multi-operator-review-bundle")) {
7149
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/multi-operator-review-bundle$/, "");
7150
+ sendJson(res, 200, buildMultiOperatorReviewBundle(state, accountId));
7151
+ return;
7152
+ }
7153
+
7154
+ if (req.method === "GET" && url.pathname.startsWith("/v1/economics/accounts/") && url.pathname.endsWith("/multi-operator-attention-summary")) {
7155
+ const accountId = getDecodedSuffixId(url.pathname, "/v1/economics/accounts/").replace(/\/multi-operator-attention-summary$/, "");
7156
+ sendJson(res, 200, buildMultiOperatorAttentionSummary(state, accountId));
7157
+ return;
7158
+ }
7159
+
5983
7160
  if (
5984
7161
  req.method === "GET"
5985
7162
  && url.pathname.startsWith("/v1/economics/accounts/")