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.
- package/.env.example +29 -0
- package/BSV_TERANODE_SETUP.md +43 -0
- package/README.md +66 -7
- package/REAL_PAYMENT_SETUP.md +61 -0
- package/RELEASE_NOTES.md +12 -6
- package/SERVICE_CONTRACT.md +31 -0
- package/START_HERE.md +107 -6
- package/TREASURY_DESTINATIONS.example.json +66 -0
- package/TREASURY_DESTINATIONS.production.template.json +108 -0
- package/adapters/examples/langchain-reference-execution-adapter.js +81 -0
- package/adapters/examples/langchain-reference-execution-adapter.manifest.json +79 -0
- package/adapters/examples/langgraph-reference-execution-adapter.js +81 -0
- package/adapters/examples/langgraph-reference-execution-adapter.manifest.json +79 -0
- package/bin/xytara-first-run.js +244 -0
- package/bin/xytara.js +30 -5
- package/integrations/dispatch.js +7 -2
- package/integrations/registry.js +123 -2
- package/lib/activity_audit_contract.js +322 -0
- package/lib/adapter_depth_contract.js +156 -0
- package/lib/bolt_lane_contract.js +55 -0
- package/lib/bolt_payment_front.js +172 -0
- package/lib/capability_execution_truth.js +269 -0
- package/lib/capability_registry.js +39 -2
- package/lib/checkout_event_security.js +142 -0
- package/lib/command_flow.js +169 -36
- package/lib/commerce_artifacts.js +23 -4
- package/lib/commerce_checkout.js +134 -4
- package/lib/commerce_client.js +20 -0
- package/lib/commerce_economics.js +109 -9
- package/lib/commerce_runtime.js +38 -2
- package/lib/commerce_shell.js +4 -2
- package/lib/external_execution_runtime.js +132 -0
- package/lib/go_live_operator_pack.js +339 -0
- package/lib/http_transport.js +32 -0
- package/lib/integration_matrix_contract.js +6 -0
- package/lib/l402_lane_contract.js +55 -0
- package/lib/l402_payment_front.js +192 -0
- package/lib/network_transport.js +110 -0
- package/lib/operator_intelligence.js +215 -1
- package/lib/payment_config.js +80 -3
- package/lib/payment_front_registry.js +53 -0
- package/lib/payment_protocol_contract.js +165 -0
- package/lib/payment_verification.js +23 -3
- package/lib/pricing_optimization_contract.js +556 -0
- package/lib/release_history.js +15 -0
- package/lib/request_rate_limit.js +144 -0
- package/lib/runtime_bridge.js +10 -2
- package/lib/runtime_operations_worker.js +282 -0
- package/lib/settlement_bsv_live.js +79 -4
- package/lib/stripe_mpp_lane_contract.js +3 -0
- package/lib/stripe_mpp_payment_front.js +158 -0
- package/lib/treasury_destinations_contract.js +543 -0
- package/lib/treasury_egress_policy_contract.js +91 -0
- package/package.json +14 -21
- package/server.js +627 -88
- package/OPERATIONS_RUNBOOK.md +0 -66
- package/OPERATOR_START_HERE.md +0 -63
- package/PROGRAM_COMPLETE_RELEASE.md +0 -63
- package/PROGRAM_STATUS.md +0 -57
- package/PUBLISH_PLAN.md +0 -14
- 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
|
};
|
package/lib/payment_config.js
CHANGED
|
@@ -59,14 +59,64 @@ function loadTreasuryDestinationMap() {
|
|
|
59
59
|
process.env.XYTARA_TREASURY_DESTINATIONS_PATH,
|
|
60
60
|
{}
|
|
61
61
|
);
|
|
62
|
-
|
|
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
|
|
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
|
+
};
|