xytara 2.5.0 → 2.6.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.
Files changed (61) hide show
  1. package/.env.example +29 -0
  2. package/BSV_TERANODE_SETUP.md +43 -0
  3. package/README.md +66 -7
  4. package/REAL_PAYMENT_SETUP.md +61 -0
  5. package/RELEASE_NOTES.md +12 -6
  6. package/SERVICE_CONTRACT.md +31 -0
  7. package/START_HERE.md +107 -6
  8. package/TREASURY_DESTINATIONS.example.json +66 -0
  9. package/TREASURY_DESTINATIONS.production.template.json +108 -0
  10. package/adapters/examples/langchain-reference-execution-adapter.js +81 -0
  11. package/adapters/examples/langchain-reference-execution-adapter.manifest.json +79 -0
  12. package/adapters/examples/langgraph-reference-execution-adapter.js +81 -0
  13. package/adapters/examples/langgraph-reference-execution-adapter.manifest.json +79 -0
  14. package/bin/xytara-first-run.js +244 -0
  15. package/bin/xytara.js +30 -5
  16. package/integrations/dispatch.js +7 -2
  17. package/integrations/registry.js +123 -2
  18. package/lib/activity_audit_contract.js +322 -0
  19. package/lib/adapter_depth_contract.js +156 -0
  20. package/lib/bolt_lane_contract.js +55 -0
  21. package/lib/bolt_payment_front.js +172 -0
  22. package/lib/capability_execution_truth.js +269 -0
  23. package/lib/capability_registry.js +39 -2
  24. package/lib/checkout_event_security.js +142 -0
  25. package/lib/command_flow.js +169 -36
  26. package/lib/commerce_artifacts.js +23 -4
  27. package/lib/commerce_checkout.js +134 -4
  28. package/lib/commerce_client.js +20 -0
  29. package/lib/commerce_economics.js +109 -9
  30. package/lib/commerce_runtime.js +38 -2
  31. package/lib/commerce_shell.js +4 -2
  32. package/lib/external_execution_runtime.js +132 -0
  33. package/lib/go_live_operator_pack.js +339 -0
  34. package/lib/http_transport.js +32 -0
  35. package/lib/integration_matrix_contract.js +6 -0
  36. package/lib/l402_lane_contract.js +55 -0
  37. package/lib/l402_payment_front.js +192 -0
  38. package/lib/network_transport.js +110 -0
  39. package/lib/operator_intelligence.js +215 -1
  40. package/lib/payment_config.js +80 -3
  41. package/lib/payment_front_registry.js +53 -0
  42. package/lib/payment_protocol_contract.js +165 -0
  43. package/lib/payment_verification.js +23 -3
  44. package/lib/pricing_optimization_contract.js +556 -0
  45. package/lib/release_history.js +15 -0
  46. package/lib/request_rate_limit.js +144 -0
  47. package/lib/runtime_bridge.js +10 -2
  48. package/lib/runtime_operations_worker.js +282 -0
  49. package/lib/settlement_bsv_live.js +79 -4
  50. package/lib/stripe_mpp_lane_contract.js +3 -0
  51. package/lib/stripe_mpp_payment_front.js +158 -0
  52. package/lib/treasury_destinations_contract.js +543 -0
  53. package/lib/treasury_egress_policy_contract.js +91 -0
  54. package/package.json +14 -21
  55. package/server.js +627 -88
  56. package/OPERATIONS_RUNBOOK.md +0 -66
  57. package/OPERATOR_START_HERE.md +0 -63
  58. package/PROGRAM_COMPLETE_RELEASE.md +0 -63
  59. package/PROGRAM_STATUS.md +0 -57
  60. package/PUBLISH_PLAN.md +0 -14
  61. package/RELEASE_CHECKLIST.md +0 -16
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+
3
+ const dns = require("dns");
4
+ let Agent = null;
5
+ try {
6
+ ({ Agent } = require("undici"));
7
+ } catch (_) {
8
+ Agent = null;
9
+ }
10
+
11
+ const dispatcherCache = new Map();
12
+ let configuredDnsResultOrder = null;
13
+
14
+ function normalizeString(value, fallback = "") {
15
+ const raw = typeof value === "string" ? value.trim() : "";
16
+ return raw || fallback;
17
+ }
18
+
19
+ function normalizeFamily(value) {
20
+ const normalized = normalizeString(value).toLowerCase();
21
+ if (!normalized || normalized === "auto" || normalized === "any" || normalized === "0") return null;
22
+ if (normalized === "4" || normalized === "ipv4") return 4;
23
+ if (normalized === "6" || normalized === "ipv6") return 6;
24
+ return null;
25
+ }
26
+
27
+ function normalizeDnsResultOrder(value) {
28
+ const normalized = normalizeString(value).toLowerCase();
29
+ if (!normalized) return "verbatim";
30
+ if (normalized === "ipv4first" || normalized === "ipv6first" || normalized === "verbatim") return normalized;
31
+ return "verbatim";
32
+ }
33
+
34
+ function loadNetworkTransportConfig() {
35
+ const globalFamily = normalizeFamily(process.env.XYTARA_NETWORK_PREFERRED_IP_FAMILY);
36
+ const dnsResultOrder = normalizeDnsResultOrder(process.env.XYTARA_NETWORK_DNS_RESULT_ORDER);
37
+ return {
38
+ dns_result_order: dnsResultOrder,
39
+ global_family: globalFamily,
40
+ external_execution_family: normalizeFamily(process.env.XYTARA_EXTERNAL_EXECUTION_IP_FAMILY) || globalFamily,
41
+ callback_family: normalizeFamily(process.env.XYTARA_CALLBACK_IP_FAMILY) || globalFamily,
42
+ settlement_family: normalizeFamily(process.env.XYTARA_SETTLEMENT_IP_FAMILY) || globalFamily
43
+ };
44
+ }
45
+
46
+ function ensureDnsResultOrderConfigured(config) {
47
+ const effective = config && config.dns_result_order ? config.dns_result_order : "verbatim";
48
+ if (configuredDnsResultOrder === effective) return;
49
+ dns.setDefaultResultOrder(effective);
50
+ configuredDnsResultOrder = effective;
51
+ }
52
+
53
+ function getDispatcherForFamily(family) {
54
+ if (!Agent) return null;
55
+ if (!family) return null;
56
+ const key = String(family);
57
+ if (dispatcherCache.has(key)) return dispatcherCache.get(key);
58
+ const dispatcher = new Agent({
59
+ connect: {
60
+ family
61
+ }
62
+ });
63
+ dispatcherCache.set(key, dispatcher);
64
+ return dispatcher;
65
+ }
66
+
67
+ function buildFetchOptionsForPurpose(purpose, baseOptions = {}) {
68
+ const config = loadNetworkTransportConfig();
69
+ ensureDnsResultOrderConfigured(config);
70
+ const purposeKey = normalizeString(purpose, "external_execution");
71
+ const family = purposeKey === "callback"
72
+ ? config.callback_family
73
+ : purposeKey === "settlement"
74
+ ? config.settlement_family
75
+ : config.external_execution_family;
76
+ const dispatcher = getDispatcherForFamily(family);
77
+ return dispatcher
78
+ ? { ...baseOptions, dispatcher }
79
+ : { ...baseOptions };
80
+ }
81
+
82
+ function buildNetworkTransportSummary() {
83
+ const config = loadNetworkTransportConfig();
84
+ ensureDnsResultOrderConfigured(config);
85
+ const classify = (family) => family === 4 ? "ipv4" : family === 6 ? "ipv6" : "auto";
86
+ return {
87
+ ok: true,
88
+ category: "machine-commerce-network-transport-summary",
89
+ summary_version: "xytara-network-transport-summary-v1",
90
+ dns_result_order: config.dns_result_order,
91
+ preferred_families: {
92
+ global: classify(config.global_family),
93
+ external_execution: classify(config.external_execution_family),
94
+ callback_delivery: classify(config.callback_family),
95
+ settlement_transport: classify(config.settlement_family)
96
+ },
97
+ posture: "dual-stack_capable_with_operator-selectable_ip_family_preferences",
98
+ linked_surfaces: {
99
+ external_execution_ref: "/v1/capability-registry/execution-truth",
100
+ callback_security_ref: "/v1/checkout/events/security",
101
+ settlement_readiness_ref: "/v1/settlement/bsv-teranode/readiness"
102
+ }
103
+ };
104
+ }
105
+
106
+ module.exports = {
107
+ buildFetchOptionsForPurpose,
108
+ buildNetworkTransportSummary,
109
+ loadNetworkTransportConfig
110
+ };
@@ -1,7 +1,103 @@
1
1
  "use strict";
2
2
 
3
+ const { summarizeActivityLedger } = require("./activity_audit_contract");
3
4
  const { buildEconomicsIntelligenceSummary } = require("./commerce_economics");
4
5
  const { buildPartnerIntelligencePack } = require("./partner_intelligence");
6
+ const { buildRevenueSignalSummary } = require("./pricing_optimization_contract");
7
+
8
+ function valuesFromCollection(collection) {
9
+ if (!collection) return [];
10
+ if (collection instanceof Map) return Array.from(collection.values());
11
+ return Array.isArray(collection) ? collection : [];
12
+ }
13
+
14
+ function unwrapTransaction(entry) {
15
+ if (entry && entry.transaction) return entry.transaction;
16
+ return entry || null;
17
+ }
18
+
19
+ function countBy(values, selector) {
20
+ return values.reduce((acc, value) => {
21
+ const key = selector(value) || "unknown";
22
+ acc[key] = (acc[key] || 0) + 1;
23
+ return acc;
24
+ }, {});
25
+ }
26
+
27
+ function countAdapterFailures(transactions) {
28
+ return transactions.filter((transaction) => {
29
+ const execution = transaction && transaction.execution;
30
+ const results = execution && execution.results_by_task_id && typeof execution.results_by_task_id === "object"
31
+ ? Object.values(execution.results_by_task_id)
32
+ : [];
33
+ return transaction && transaction.status === "failed"
34
+ || execution && execution.status === "failed"
35
+ || results.some((result) => result && (
36
+ result.status === "failed"
37
+ || result.invocation_status === "provider_failed"
38
+ || result.provider_status === "failed"
39
+ ));
40
+ }).length;
41
+ }
42
+
43
+ function latestIso(values, fieldNames) {
44
+ const timestamps = values
45
+ .flatMap((value) => fieldNames.map((fieldName) => value && value[fieldName]).filter(Boolean))
46
+ .map((value) => Date.parse(value))
47
+ .filter((value) => Number.isFinite(value))
48
+ .sort((left, right) => right - left);
49
+ return timestamps.length ? new Date(timestamps[0]).toISOString() : null;
50
+ }
51
+
52
+ function buildAttentionQueue({ counts, revenueSignals }) {
53
+ const queue = [];
54
+ if (counts.adapter_failure_count > 0) {
55
+ queue.push({
56
+ lane: "adapter_execution",
57
+ priority: "high",
58
+ action: "inspect_adapter_failures",
59
+ surface_ref: "/v1/runtime-bridge/dispatches",
60
+ reason: "provider-backed execution reported failed adapter outcomes"
61
+ });
62
+ }
63
+ if (counts.failed_settlement_count > 0 || counts.pending_settlement_count > 0) {
64
+ queue.push({
65
+ lane: "settlement",
66
+ priority: counts.failed_settlement_count > 0 ? "high" : "medium",
67
+ action: "inspect_native_settlement_records",
68
+ surface_ref: "/v1/settlement/bsv-teranode",
69
+ reason: "settlement records are failed or waiting for submission/finality"
70
+ });
71
+ }
72
+ if (counts.payment_count > counts.delivery_count) {
73
+ queue.push({
74
+ lane: "delivery",
75
+ priority: "medium",
76
+ action: "compare_payment_ledger_to_deliveries",
77
+ surface_ref: "/v1/deliveries",
78
+ reason: "payment count is higher than delivery count"
79
+ });
80
+ }
81
+ if (revenueSignals.sample_maturity === "sparse_live_signals") {
82
+ queue.push({
83
+ lane: "pricing_telemetry",
84
+ priority: "low",
85
+ action: "continue_collecting_live_quote_and_execution_metrics",
86
+ surface_ref: "/v1/pricing-optimization/revenue-signal-summary",
87
+ reason: "pricing recommendations should stay conservative while live samples are sparse"
88
+ });
89
+ }
90
+ if (queue.length === 0) {
91
+ queue.push({
92
+ lane: "operator_posture",
93
+ priority: "low",
94
+ action: "continue_current_observability_cadence",
95
+ surface_ref: "/v1/operator-observability/summary",
96
+ reason: "no immediate operator attention item crossed the current thresholds"
97
+ });
98
+ }
99
+ return queue;
100
+ }
5
101
 
6
102
  function buildOperatorIntelligencePack(state, input) {
7
103
  const payload = input && typeof input === "object" && !Array.isArray(input) ? input : {};
@@ -84,7 +180,125 @@ function summarizeOperatorIntelligencePack(state, input) {
84
180
  };
85
181
  }
86
182
 
183
+ function buildOperatorObservabilityPack(state, input) {
184
+ const payload = input && typeof input === "object" && !Array.isArray(input) ? input : {};
185
+ const accountId = String(payload.account_id || "").trim() || null;
186
+ const quotes = valuesFromCollection(state && state.quotes).filter((quote) => !accountId || quote.account_id === accountId);
187
+ const transactions = valuesFromCollection(state && state.transactions)
188
+ .map(unwrapTransaction)
189
+ .filter(Boolean)
190
+ .filter((transaction) => !accountId || transaction.account_id === accountId);
191
+ const receipts = valuesFromCollection(state && state.receipts)
192
+ .map((entry) => entry && entry.receipt ? entry.receipt : entry)
193
+ .filter(Boolean)
194
+ .filter((receipt) => !accountId || receipt.account_id === accountId);
195
+ const deliveries = valuesFromCollection(state && state.deliveries).filter((delivery) => !accountId || delivery.account_id === accountId);
196
+ const payments = (Array.isArray(state && state.paymentLedger) ? state.paymentLedger : [])
197
+ .filter((payment) => !accountId || payment.account_id === accountId);
198
+ const externalCreditGrants = valuesFromCollection(state && state.externalCreditGrants)
199
+ .filter((grant) => !accountId || grant.account_id === accountId);
200
+ const settlements = valuesFromCollection(state && state.bsvSettlementRecords)
201
+ .filter((settlement) => !accountId || settlement.account_id === accountId);
202
+ const activitySummary = summarizeActivityLedger(state, { account_id: accountId });
203
+ const revenueSignals = buildRevenueSignalSummary(state);
204
+ const failedSettlementCount = settlements.filter((settlement) => settlement && settlement.status === "failed").length;
205
+ const pendingSettlementCount = settlements.filter((settlement) => settlement && (
206
+ settlement.status === "ready_for_submission"
207
+ || settlement.finality_status === "pending_submission"
208
+ || settlement.finality_status === "pending_confirmation"
209
+ )).length;
210
+ const counts = {
211
+ quote_count: quotes.length,
212
+ transaction_count: transactions.length,
213
+ receipt_count: receipts.length,
214
+ payment_count: payments.length,
215
+ delivery_count: deliveries.length,
216
+ external_credit_grant_count: externalCreditGrants.length,
217
+ settlement_count: settlements.length,
218
+ finalized_settlement_count: settlements.filter((settlement) => settlement && settlement.finality_status === "finalized").length,
219
+ pending_settlement_count: pendingSettlementCount,
220
+ failed_settlement_count: failedSettlementCount,
221
+ adapter_failure_count: countAdapterFailures(transactions)
222
+ };
223
+ const attentionQueue = buildAttentionQueue({ counts, revenueSignals });
224
+ return {
225
+ ok: true,
226
+ product: "xytara",
227
+ category: "machine-commerce-operator-observability-pack",
228
+ pack_version: "xytara-operator-observability-pack-v1",
229
+ posture: "read_only_operator_visibility_across_money_execution_delivery_settlement_and_pricing",
230
+ account_scope: accountId || "all_accounts",
231
+ operator_state: attentionQueue.some((entry) => entry.priority === "high")
232
+ ? "attention_required"
233
+ : attentionQueue.some((entry) => entry.priority === "medium")
234
+ ? "watch"
235
+ : "steady",
236
+ counts,
237
+ status_counts: {
238
+ quotes: countBy(quotes, (quote) => quote && quote.status),
239
+ transactions: countBy(transactions, (transaction) => transaction && transaction.status),
240
+ deliveries: countBy(deliveries, (delivery) => delivery && delivery.status),
241
+ payments: countBy(payments, (payment) => payment && payment.status || payment && payment.payment && payment.payment.status),
242
+ settlements: countBy(settlements, (settlement) => settlement && settlement.status),
243
+ settlement_finality: countBy(settlements, (settlement) => settlement && settlement.finality_status)
244
+ },
245
+ latest_activity: {
246
+ quote_at_iso: latestIso(quotes, ["created_at_iso", "executed_at_iso", "payment_recorded_at_iso"]),
247
+ transaction_at_iso: latestIso(transactions, ["completed_at_iso", "created_at_iso"]),
248
+ payment_at_iso: latestIso(payments, ["recorded_at_iso"]),
249
+ delivery_at_iso: latestIso(deliveries, ["delivered_at_iso", "created_at_iso"]),
250
+ grant_at_iso: latestIso(externalCreditGrants, ["created_at_iso", "granted_at_iso", "recorded_at_iso"]),
251
+ settlement_at_iso: latestIso(settlements, ["finalized_at_iso", "confirmed_at_iso", "submitted_at_iso", "created_at_iso"])
252
+ },
253
+ activity_summary: activitySummary,
254
+ pricing_telemetry_summary: {
255
+ sample_maturity: revenueSignals.sample_maturity,
256
+ pricing_change_posture: revenueSignals.pricing_change_posture,
257
+ quote_conversion_rate: revenueSignals.rates.quote_conversion_rate,
258
+ quote_abandonment_rate: revenueSignals.rates.quote_abandonment_rate,
259
+ revenue_capture_rate: revenueSignals.rates.revenue_capture_rate
260
+ },
261
+ attention_queue: attentionQueue,
262
+ linked_surfaces: {
263
+ activity_ledger_ref: "/v1/activity-ledger",
264
+ payment_ledger_ref: "/v1/payment-ledger",
265
+ reconciliation_report_ref: "/v1/reconciliation-report",
266
+ deliveries_ref: "/v1/deliveries",
267
+ settlement_ref: "/v1/settlement/bsv-teranode",
268
+ adapter_depth_ref: "/v1/adapter-depth/summary",
269
+ pricing_revenue_signal_ref: "/v1/pricing-optimization/revenue-signal-summary",
270
+ operator_intelligence_ref: "/v1/operator-intelligence"
271
+ },
272
+ boundary: "read_only_operator_visibility_no_fund_movement_no_settlement_submission_no_secret_material"
273
+ };
274
+ }
275
+
276
+ function summarizeOperatorObservabilityPack(state, input) {
277
+ const pack = buildOperatorObservabilityPack(state, input);
278
+ return {
279
+ ok: true,
280
+ product: pack.product,
281
+ category: "machine-commerce-operator-observability-pack-summary",
282
+ summary_version: "xytara-operator-observability-pack-summary-v1",
283
+ account_scope: pack.account_scope,
284
+ operator_state: pack.operator_state,
285
+ quote_count: pack.counts.quote_count,
286
+ payment_count: pack.counts.payment_count,
287
+ transaction_count: pack.counts.transaction_count,
288
+ delivery_count: pack.counts.delivery_count,
289
+ external_credit_grant_count: pack.counts.external_credit_grant_count,
290
+ settlement_count: pack.counts.settlement_count,
291
+ pending_settlement_count: pack.counts.pending_settlement_count,
292
+ adapter_failure_count: pack.counts.adapter_failure_count,
293
+ pricing_sample_maturity: pack.pricing_telemetry_summary.sample_maturity,
294
+ attention_item_count: pack.attention_queue.length,
295
+ linked_surfaces: pack.linked_surfaces
296
+ };
297
+ }
298
+
87
299
  module.exports = {
88
300
  buildOperatorIntelligencePack,
89
- summarizeOperatorIntelligencePack
301
+ summarizeOperatorIntelligencePack,
302
+ buildOperatorObservabilityPack,
303
+ summarizeOperatorObservabilityPack
90
304
  };
@@ -59,14 +59,64 @@ function loadTreasuryDestinationMap() {
59
59
  process.env.XYTARA_TREASURY_DESTINATIONS_PATH,
60
60
  {}
61
61
  );
62
- return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
62
+ const input = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
63
+ const normalized = {};
64
+ for (const [settlementMode, entry] of Object.entries(input)) {
65
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) continue;
66
+ normalized[normalizeSettlementMode(settlementMode)] = {
67
+ destination_id: typeof entry.destination_id === "string" && entry.destination_id.trim()
68
+ ? entry.destination_id.trim()
69
+ : null,
70
+ destination_kind: typeof entry.destination_kind === "string" && entry.destination_kind.trim()
71
+ ? entry.destination_kind.trim()
72
+ : null,
73
+ account_id: typeof entry.account_id === "string" && entry.account_id.trim()
74
+ ? entry.account_id.trim()
75
+ : null,
76
+ external_ref: typeof entry.external_ref === "string" && entry.external_ref.trim()
77
+ ? entry.external_ref.trim()
78
+ : null,
79
+ custody_ref: typeof entry.custody_ref === "string" && entry.custody_ref.trim()
80
+ ? entry.custody_ref.trim()
81
+ : null,
82
+ reporting_ref: typeof entry.reporting_ref === "string" && entry.reporting_ref.trim()
83
+ ? entry.reporting_ref.trim()
84
+ : null,
85
+ wallet_ref: typeof entry.wallet_ref === "string" && entry.wallet_ref.trim()
86
+ ? entry.wallet_ref.trim()
87
+ : null,
88
+ provider_ref: typeof entry.provider_ref === "string" && entry.provider_ref.trim()
89
+ ? entry.provider_ref.trim()
90
+ : null,
91
+ network: typeof entry.network === "string" && entry.network.trim()
92
+ ? entry.network.trim()
93
+ : null,
94
+ chain_id: typeof entry.chain_id === "string" && entry.chain_id.trim()
95
+ ? entry.chain_id.trim()
96
+ : null,
97
+ asset_symbol: typeof entry.asset_symbol === "string" && entry.asset_symbol.trim()
98
+ ? entry.asset_symbol.trim()
99
+ : null,
100
+ policy_scope: typeof entry.policy_scope === "string" && entry.policy_scope.trim()
101
+ ? entry.policy_scope.trim()
102
+ : null,
103
+ storage_class: typeof entry.storage_class === "string" && entry.storage_class.trim()
104
+ ? entry.storage_class.trim()
105
+ : null,
106
+ enabled: entry.enabled !== false,
107
+ accept_inbound: entry.accept_inbound !== false
108
+ };
109
+ }
110
+ return normalized;
63
111
  }
64
112
 
65
113
  function loadPaymentConfig() {
66
- const verificationMode = String(process.env.XYTARA_PAYMENT_VERIFICATION_MODE || "presence").trim() || "presence";
114
+ const verificationModeInput = String(process.env.XYTARA_PAYMENT_VERIFICATION_MODE || "presence").trim() || "presence";
115
+ const verificationMode = verificationModeInput === "signed" ? "local_signed" : verificationModeInput;
67
116
  const maxAgeSeconds = Number(process.env.XYTARA_PAYMENT_MAX_AGE_SECONDS || 300);
68
117
  return {
69
118
  verification_mode: verificationMode,
119
+ verification_mode_input: verificationModeInput,
70
120
  payment_max_age_seconds: Number.isFinite(maxAgeSeconds) && maxAgeSeconds > 0 ? maxAgeSeconds : 300,
71
121
  wallet_registry: loadWalletRegistry(),
72
122
  treasury_destination_id: String(process.env.XYTARA_TREASURY_DESTINATION_ID || "").trim() || null,
@@ -104,7 +154,34 @@ function buildConfiguredTreasuryDestination(accountId, settlementMode) {
104
154
  external_ref:
105
155
  (mapEntry && typeof mapEntry.external_ref === "string" && mapEntry.external_ref.trim())
106
156
  || config.treasury_external_ref
107
- || null
157
+ || null,
158
+ custody_ref: mapEntry && typeof mapEntry.custody_ref === "string" && mapEntry.custody_ref.trim()
159
+ ? mapEntry.custody_ref.trim()
160
+ : null,
161
+ reporting_ref: mapEntry && typeof mapEntry.reporting_ref === "string" && mapEntry.reporting_ref.trim()
162
+ ? mapEntry.reporting_ref.trim()
163
+ : null,
164
+ wallet_ref: mapEntry && typeof mapEntry.wallet_ref === "string" && mapEntry.wallet_ref.trim()
165
+ ? mapEntry.wallet_ref.trim()
166
+ : null,
167
+ provider_ref: mapEntry && typeof mapEntry.provider_ref === "string" && mapEntry.provider_ref.trim()
168
+ ? mapEntry.provider_ref.trim()
169
+ : null,
170
+ network: mapEntry && typeof mapEntry.network === "string" && mapEntry.network.trim()
171
+ ? mapEntry.network.trim()
172
+ : null,
173
+ chain_id: mapEntry && typeof mapEntry.chain_id === "string" && mapEntry.chain_id.trim()
174
+ ? mapEntry.chain_id.trim()
175
+ : null,
176
+ asset_symbol: mapEntry && typeof mapEntry.asset_symbol === "string" && mapEntry.asset_symbol.trim()
177
+ ? mapEntry.asset_symbol.trim()
178
+ : null,
179
+ policy_scope: mapEntry && typeof mapEntry.policy_scope === "string" && mapEntry.policy_scope.trim()
180
+ ? mapEntry.policy_scope.trim()
181
+ : null,
182
+ storage_class: mapEntry && typeof mapEntry.storage_class === "string" && mapEntry.storage_class.trim()
183
+ ? mapEntry.storage_class.trim()
184
+ : null
108
185
  };
109
186
  }
110
187
 
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+
3
+ const { summarizeX402LanePack } = require("./x402_lane_contract");
4
+ const { summarizeStripeMppLanePack } = require("./stripe_mpp_lane_contract");
5
+ const { summarizeL402LanePack } = require("./l402_lane_contract");
6
+ const { summarizeBoltLanePack } = require("./bolt_lane_contract");
7
+
8
+ function buildPaymentFrontRegistryPack() {
9
+ return {
10
+ product: "xytara",
11
+ category: "machine-commerce-payment-front-registry-pack",
12
+ pack_version: "xytara-payment-front-registry-pack-v1",
13
+ posture: "multiple_payment_fronts_one_runtime_core",
14
+ fronts: {
15
+ x402: summarizeX402LanePack(),
16
+ hosted_checkout: summarizeStripeMppLanePack(),
17
+ l402: summarizeL402LanePack(),
18
+ bolt_utxo_spv: summarizeBoltLanePack(),
19
+ account_credits: {
20
+ product: "xytara",
21
+ category: "machine-commerce-account-credits-front",
22
+ summary_version: "xytara-account-credits-front-summary-v1",
23
+ posture: "repeat_use_spend_surface"
24
+ }
25
+ },
26
+ operator_rule: "add payment fronts where they improve adoption or economics, but keep execution/governance/proof semantics centralized",
27
+ linked_surfaces: {
28
+ payment_protocols_ref: "/v1/payment-protocols",
29
+ payment_protocol_strategy_ref: "/v1/payment-protocols/strategy",
30
+ x402_ref: "/v1/x402",
31
+ stripe_mpp_ref: "/v1/stripe-mpp",
32
+ l402_ref: "/v1/l402",
33
+ bolt_ref: "/v1/bolt"
34
+ }
35
+ };
36
+ }
37
+
38
+ function summarizePaymentFrontRegistryPack() {
39
+ const pack = buildPaymentFrontRegistryPack();
40
+ return {
41
+ product: pack.product,
42
+ category: pack.category,
43
+ summary_version: "xytara-payment-front-registry-pack-summary-v1",
44
+ posture: pack.posture,
45
+ front_count: Object.keys(pack.fronts).length,
46
+ linked_surfaces: pack.linked_surfaces
47
+ };
48
+ }
49
+
50
+ module.exports = {
51
+ buildPaymentFrontRegistryPack,
52
+ summarizePaymentFrontRegistryPack
53
+ };
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+
3
+ function buildPaymentProtocolPack() {
4
+ return {
5
+ product: "xytara",
6
+ category: "machine-commerce-payment-protocol-pack",
7
+ pack_version: "xytara-payment-protocol-pack-v1",
8
+ lane_state: "default_machine_payment_plus_credit_and_adapter_expansion",
9
+ default_protocol: "x402",
10
+ current_native_payment_paths: [
11
+ {
12
+ protocol_id: "x402",
13
+ state: "first_party_default",
14
+ why_it_exists: "default machine-native quote -> challenge -> pay -> execute handshake"
15
+ },
16
+ {
17
+ protocol_id: "account_credits",
18
+ state: "first_party_repeat_use",
19
+ why_it_exists: "best repeat-use path for agents and operators that should not re-negotiate every call"
20
+ },
21
+ {
22
+ protocol_id: "stripe_mpp",
23
+ state: "first_party_human_checkout_lane",
24
+ why_it_exists: "human checkout, top-up, and hosted payment entry without making human checkout the center of the stack"
25
+ }
26
+ ],
27
+ adapter_ready_external_fronts: [
28
+ {
29
+ protocol_id: "l402",
30
+ state: "adapter_ready_current",
31
+ why_it_matters: "lightning-native service payment can matter for agents that want highly permissionless micropayment access"
32
+ },
33
+ {
34
+ protocol_id: "utxo_spv_payment_fronts",
35
+ state: "adapter_ready_current",
36
+ why_it_matters: "native UTXO verification and SPV-style settlement proofs can matter where facilitator dependence is undesirable"
37
+ },
38
+ {
39
+ protocol_id: "circle_nanopayments",
40
+ state: "adapter_ready_next",
41
+ why_it_matters: "high-frequency stable-value collection can complement machine-native pricing and credit replenishment"
42
+ },
43
+ {
44
+ protocol_id: "circle_cctp",
45
+ state: "adapter_ready_next",
46
+ why_it_matters: "stable-value treasury mobility can expand settlement reach without redefining runtime execution"
47
+ },
48
+ {
49
+ protocol_id: "future_payment_front_protocols",
50
+ state: "adapter_front_only",
51
+ why_it_matters: "similar future negotiation and payment protocols should be absorbed by the payment front instead of hardwiring brand-specific ideology into the runtime"
52
+ }
53
+ ],
54
+ charging_boundary: {
55
+ keep_free: [
56
+ "auth",
57
+ "discovery",
58
+ "docs",
59
+ "catalog_inspection",
60
+ "contract_views",
61
+ "release_and_start_paths",
62
+ "lightweight_preview_and_readiness_surfaces"
63
+ ],
64
+ keep_paid: [
65
+ "execution",
66
+ "quoted_runtime_work",
67
+ "credit_consumption",
68
+ "settlement_bearing_operations",
69
+ "resource_consuming_runtime_consequence",
70
+ "high_consequence_or_governed_machine_actions"
71
+ ],
72
+ principle: "do_not_charge_before_value_is_felt_but_do_not_give_runtime_consequence_away_for_free"
73
+ },
74
+ supported_surfaces: {
75
+ x402_lane_ref: "/v1/x402",
76
+ stripe_mpp_lane_ref: "/v1/stripe-mpp",
77
+ l402_lane_ref: "/v1/l402",
78
+ bolt_lane_ref: "/v1/bolt",
79
+ payment_front_registry_ref: "/v1/payment-fronts",
80
+ stablecoin_lane_ref: "/v1/stablecoins",
81
+ pricing_optimization_ref: "/v1/pricing-optimization",
82
+ treasury_destinations_ref: "/v1/treasury-destinations"
83
+ }
84
+ };
85
+ }
86
+
87
+ function buildPaymentProtocolStrategyPack() {
88
+ const pack = buildPaymentProtocolPack();
89
+ return {
90
+ product: "xytara",
91
+ category: "machine-commerce-payment-protocol-strategy-pack",
92
+ pack_version: "xytara-payment-protocol-strategy-pack-v1",
93
+ primary_protocol_thesis: {
94
+ machine_native_default: "x402",
95
+ repeat_use_default: "account_credits",
96
+ human_procurement_default: "hosted_checkout",
97
+ strategy_rule: "keep the commerce core protocol-agnostic while using the least-friction lane that fits the actor and operating constraint"
98
+ },
99
+ protocol_roles: [
100
+ {
101
+ protocol_id: "x402",
102
+ role: "machine_native_http_payment",
103
+ why_now: "strong fit for agent-call monetization, quote-to-pay flows, and interoperable HTTP-native machine commerce"
104
+ },
105
+ {
106
+ protocol_id: "account_credits",
107
+ role: "repeat_use_and_metered_runtime_spend",
108
+ why_now: "best fit for repeated agent use where renegotiating payment every call adds friction"
109
+ },
110
+ {
111
+ protocol_id: "hosted_checkout",
112
+ role: "human_checkout_and_procurement_entry",
113
+ why_now: "best fit for public SaaS sales, enterprise procurement, and external fiat money-in lanes"
114
+ },
115
+ {
116
+ protocol_id: "l402_or_other_permissionless_fronts",
117
+ role: "permissionless_adapter_payment_front",
118
+ why_now: "worth supporting through adapter fronts now when customers strongly value lower dependency or Lightning-native / UTXO-native settlement"
119
+ }
120
+ ],
121
+ commercialization_rules: [
122
+ "Use x402 as the primary self-serve machine paywall.",
123
+ "Use credits as the primary repeat-use spend posture after first conversion.",
124
+ "Use hosted checkout for humans and enterprise buyers, then convert that funding into internal authorization or credits.",
125
+ "Treat future permissionless fronts as adapter lanes into the same execution, proof, and governance core rather than as a fork of the product."
126
+ ],
127
+ operator_decisions: {
128
+ launch_primary_machine_lane: "x402",
129
+ launch_primary_human_lane: "hosted_checkout",
130
+ launch_repeat_use_lane: "account_credits",
131
+ current_optional_permissionless_lanes: ["l402", "utxo_spv_payment_fronts"]
132
+ },
133
+ linked_surfaces: {
134
+ payment_protocols_ref: "/v1/payment-protocols",
135
+ x402_lane_ref: "/v1/x402",
136
+ hosted_checkout_lane_ref: "/v1/stripe-mpp",
137
+ l402_lane_ref: "/v1/l402",
138
+ bolt_lane_ref: "/v1/bolt",
139
+ payment_front_registry_ref: "/v1/payment-fronts",
140
+ commercialization_summary_ref: "/v1/capability-registry/commercialization-summary",
141
+ execution_truth_ref: "/v1/capability-registry/execution-truth"
142
+ }
143
+ };
144
+ }
145
+
146
+ function summarizePaymentProtocolPack() {
147
+ const pack = buildPaymentProtocolPack();
148
+ return {
149
+ product: "xytara",
150
+ category: "machine-commerce-payment-protocol-pack-summary",
151
+ summary_version: "xytara-payment-protocol-pack-summary-v1",
152
+ default_protocol: pack.default_protocol,
153
+ current_path_count: pack.current_native_payment_paths.length,
154
+ adapter_ready_external_front_count: pack.adapter_ready_external_fronts.length,
155
+ free_boundary_count: pack.charging_boundary.keep_free.length,
156
+ paid_boundary_count: pack.charging_boundary.keep_paid.length,
157
+ linked_surfaces: pack.supported_surfaces
158
+ };
159
+ }
160
+
161
+ module.exports = {
162
+ buildPaymentProtocolPack,
163
+ buildPaymentProtocolStrategyPack,
164
+ summarizePaymentProtocolPack
165
+ };