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,158 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const crypto = require("crypto");
|
|
4
|
+
|
|
5
|
+
function normalizeString(value) {
|
|
6
|
+
return typeof value === "string" ? value.trim() : "";
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function safeEqualHex(left, right) {
|
|
10
|
+
const a = Buffer.from(String(left || ""), "hex");
|
|
11
|
+
const b = Buffer.from(String(right || ""), "hex");
|
|
12
|
+
if (a.length === 0 || b.length === 0 || a.length !== b.length) return false;
|
|
13
|
+
return crypto.timingSafeEqual(a, b);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function decodeBase64UrlJson(value) {
|
|
17
|
+
try {
|
|
18
|
+
return JSON.parse(Buffer.from(String(value || ""), "base64url").toString("utf8"));
|
|
19
|
+
} catch (_) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function loadStripeMppFrontConfig() {
|
|
25
|
+
const sharedSecret = normalizeString(process.env.XYTARA_MPP_SHARED_SECRET);
|
|
26
|
+
return {
|
|
27
|
+
enabled: String(process.env.XYTARA_MPP_ENABLED || (sharedSecret ? "true" : "false")).trim().toLowerCase() !== "false",
|
|
28
|
+
shared_secret: sharedSecret || null,
|
|
29
|
+
provider: normalizeString(process.env.XYTARA_MPP_PROVIDER) || "stripe_tempo_compatible",
|
|
30
|
+
settlement_family: normalizeString(process.env.XYTARA_MPP_SETTLEMENT_FAMILY) || "cards_or_stablecoin_or_lightning",
|
|
31
|
+
max_age_seconds: Math.max(30, Number(process.env.XYTARA_MPP_MAX_AGE_SECONDS || 300) || 300),
|
|
32
|
+
required_headers: ["authorization"],
|
|
33
|
+
auth_scheme: "SPT",
|
|
34
|
+
token_shape: "base64url_json_with_shared_payment_token_and_hmac_signed_payload"
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function parseStripeMppAuthorization(headers) {
|
|
39
|
+
const authorization = headers && typeof headers.authorization === "string"
|
|
40
|
+
? headers.authorization.trim()
|
|
41
|
+
: "";
|
|
42
|
+
const match = authorization.match(/^SPT\s+(.+)$/i);
|
|
43
|
+
if (!match) return null;
|
|
44
|
+
const decoded = decodeBase64UrlJson(match[1]);
|
|
45
|
+
if (!decoded || typeof decoded !== "object") return null;
|
|
46
|
+
return {
|
|
47
|
+
wallet_id: decoded.wallet_id || decoded.gateway_id || decoded.customer_id || "mpp_gateway",
|
|
48
|
+
encoded: decoded.payload || null,
|
|
49
|
+
signature: decoded.signature || null,
|
|
50
|
+
token_id: decoded.token_id || decoded.spt_id || null,
|
|
51
|
+
payment_method_type: decoded.payment_method_type || null,
|
|
52
|
+
provider_reference: decoded.provider_reference || null,
|
|
53
|
+
settlement_asset: decoded.settlement_asset || null,
|
|
54
|
+
scheme: "mpp"
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function verifyStripeMppPayload(paymentPayload, quote, walletId, maxAgeSeconds) {
|
|
59
|
+
if (!paymentPayload || typeof paymentPayload !== "object") return { ok: false, reason: "mpp_payload_invalid" };
|
|
60
|
+
if (!paymentPayload.quote_id || paymentPayload.quote_id !== quote.quote_id) return { ok: false, reason: "mpp_quote_mismatch" };
|
|
61
|
+
if (paymentPayload.amount_minor !== quote.amount_minor) return { ok: false, reason: "mpp_amount_mismatch" };
|
|
62
|
+
if (paymentPayload.currency !== quote.currency) return { ok: false, reason: "mpp_currency_mismatch" };
|
|
63
|
+
if (paymentPayload.account_id && paymentPayload.account_id !== quote.account_id) return { ok: false, reason: "mpp_account_mismatch" };
|
|
64
|
+
if (walletId && paymentPayload.wallet_id && paymentPayload.wallet_id !== walletId) return { ok: false, reason: "mpp_wallet_mismatch" };
|
|
65
|
+
if (!paymentPayload.nonce || typeof paymentPayload.nonce !== "string") return { ok: false, reason: "mpp_nonce_missing" };
|
|
66
|
+
if (!paymentPayload.issued_at_iso || Number.isNaN(Date.parse(paymentPayload.issued_at_iso))) return { ok: false, reason: "mpp_issued_at_invalid" };
|
|
67
|
+
const ageSeconds = Math.max(0, Math.floor((Date.now() - Date.parse(paymentPayload.issued_at_iso)) / 1000));
|
|
68
|
+
if (ageSeconds > maxAgeSeconds) return { ok: false, reason: "mpp_token_expired" };
|
|
69
|
+
if (!normalizeString(paymentPayload.token_id || paymentPayload.spt_id)) return { ok: false, reason: "mpp_token_missing" };
|
|
70
|
+
if (!normalizeString(paymentPayload.provider_reference || paymentPayload.payment_intent_id || paymentPayload.checkout_session_id)) {
|
|
71
|
+
return { ok: false, reason: "mpp_provider_reference_missing" };
|
|
72
|
+
}
|
|
73
|
+
return { ok: true, age_seconds: ageSeconds };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function verifyStripeMppAccessToken(headers, quote) {
|
|
77
|
+
const config = loadStripeMppFrontConfig();
|
|
78
|
+
if (!config.enabled) return { ok: false, status: 503, reason: "mpp_not_enabled" };
|
|
79
|
+
if (!config.shared_secret) return { ok: false, status: 503, reason: "mpp_shared_secret_missing" };
|
|
80
|
+
const payment = parseStripeMppAuthorization(headers || {});
|
|
81
|
+
if (!payment || !payment.encoded || !payment.signature) {
|
|
82
|
+
return { ok: false, status: 402, reason: "mpp_headers_incomplete" };
|
|
83
|
+
}
|
|
84
|
+
const expectedSignature = crypto.createHmac("sha256", config.shared_secret).update(payment.encoded).digest("hex");
|
|
85
|
+
if (!safeEqualHex(expectedSignature, payment.signature)) {
|
|
86
|
+
return { ok: false, status: 403, reason: "mpp_signature_invalid" };
|
|
87
|
+
}
|
|
88
|
+
const payload = decodeBase64UrlJson(payment.encoded);
|
|
89
|
+
const validation = verifyStripeMppPayload(payload, quote, payment.wallet_id, config.max_age_seconds);
|
|
90
|
+
if (!validation.ok) return { ok: false, status: 403, reason: validation.reason };
|
|
91
|
+
return {
|
|
92
|
+
ok: true,
|
|
93
|
+
verification_mode: "mpp_gateway_signed",
|
|
94
|
+
wallet_id: payment.wallet_id,
|
|
95
|
+
payment_payload: payload,
|
|
96
|
+
age_seconds: validation.age_seconds,
|
|
97
|
+
mpp: {
|
|
98
|
+
token_id: payment.token_id || payload.token_id || payload.spt_id || null,
|
|
99
|
+
provider_reference: payment.provider_reference || payload.provider_reference || payload.payment_intent_id || payload.checkout_session_id || null,
|
|
100
|
+
payment_method_type: payment.payment_method_type || payload.payment_method_type || null,
|
|
101
|
+
settlement_asset: payment.settlement_asset || payload.settlement_asset || null,
|
|
102
|
+
provider: config.provider,
|
|
103
|
+
settlement_family: config.settlement_family
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function buildStripeMppSecuritySummary() {
|
|
109
|
+
const config = loadStripeMppFrontConfig();
|
|
110
|
+
const blockers = [];
|
|
111
|
+
if (config.enabled && !config.shared_secret) blockers.push("mpp_shared_secret_missing");
|
|
112
|
+
return {
|
|
113
|
+
ok: true,
|
|
114
|
+
category: "machine-commerce-stripe-mpp-security-summary",
|
|
115
|
+
summary_version: "xytara-stripe-mpp-security-summary-v1",
|
|
116
|
+
enabled: config.enabled,
|
|
117
|
+
shared_secret_configured: Boolean(config.shared_secret),
|
|
118
|
+
provider: config.provider,
|
|
119
|
+
settlement_family: config.settlement_family,
|
|
120
|
+
max_age_seconds: config.max_age_seconds,
|
|
121
|
+
auth_scheme: config.auth_scheme,
|
|
122
|
+
token_shape: config.token_shape,
|
|
123
|
+
ready: config.enabled && blockers.length === 0,
|
|
124
|
+
blockers,
|
|
125
|
+
linked_surfaces: {
|
|
126
|
+
stripe_mpp_lane_ref: "/v1/stripe-mpp",
|
|
127
|
+
commands_execute_ref: "/mpp/commands/execute",
|
|
128
|
+
mcp_invoke_ref: "/mpp/mcp/tools/invoke"
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function buildStripeMppChallengePayload(quote) {
|
|
134
|
+
return {
|
|
135
|
+
ok: false,
|
|
136
|
+
payment_required: {
|
|
137
|
+
scheme: "mpp",
|
|
138
|
+
quote,
|
|
139
|
+
operator_requirements: {
|
|
140
|
+
auth_scheme: "SPT",
|
|
141
|
+
token_shape: "base64url_json_with_shared_payment_token_and_hmac_signed_payload",
|
|
142
|
+
security_ref: "/v1/stripe-mpp/security",
|
|
143
|
+
proof_requirements: [
|
|
144
|
+
"token_id",
|
|
145
|
+
"provider_reference"
|
|
146
|
+
]
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
module.exports = {
|
|
153
|
+
buildStripeMppChallengePayload,
|
|
154
|
+
buildStripeMppSecuritySummary,
|
|
155
|
+
loadStripeMppFrontConfig,
|
|
156
|
+
parseStripeMppAuthorization,
|
|
157
|
+
verifyStripeMppAccessToken
|
|
158
|
+
};
|