@conto_finance/sdk 0.3.1 → 0.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.
@@ -0,0 +1,95 @@
1
+ declare const CHECKOUT_CAPABILITY_MANIFEST_VERSION: "conto.checkout-capabilities.v1";
2
+ declare const CHECKOUT_VERIFICATION_REPORT_VERSION: "conto.checkout-verification.v1";
3
+ declare const CHECKOUT_METHOD_IDS: readonly ["LINK", "CARD", "SHOP_PAY", "PAYPAL"];
4
+ type CheckoutMethodId = (typeof CHECKOUT_METHOD_IDS)[number];
5
+ declare const CHECKOUT_CAPABILITY_KINDS: readonly ["GUARDED_CHECKOUT", "NAVIGATION", "INSPECTION", "CLICK", "FORM_SUBMIT", "KEYBOARD_INPUT", "SCRIPT_EVALUATION", "CREDENTIAL_ACCESS", "PROVIDER_CONTROL", "ALTERNATE_PAYMENT"];
6
+ type CheckoutCapabilityKind = (typeof CHECKOUT_CAPABILITY_KINDS)[number];
7
+ type CheckoutCapabilityExposure = 'AGENT' | 'PRIVILEGED_RUNTIME' | 'AUTHENTICATED_OPERATOR';
8
+ type CheckoutCapabilityPaymentBoundary = 'NOT_PAYMENT_CAPABLE' | 'CONTO_GUARDED' | 'UNRESTRICTED';
9
+ type CheckoutSessionBinding = 'CONTO_RUNTIME' | 'PROOF_CARRYING_HANDOFF' | 'CALLER_ASSERTED';
10
+ type CheckoutCapabilityInventoryScope = 'COMPLETE_AGENT_CAPABILITY_SET' | 'DECLARED_SUBSET';
11
+ interface CheckoutIntegrationComponent {
12
+ /** Stable lowercase identifier, such as browserbase or browser-use-cloud. */
13
+ id: string;
14
+ /** Adapter or provider version reported by the trusted integration host. */
15
+ version: string;
16
+ }
17
+ interface CheckoutCapabilityDescriptor {
18
+ /** Stable unique identifier for the concrete tool or runtime capability. */
19
+ id: string;
20
+ kind: CheckoutCapabilityKind;
21
+ exposure: CheckoutCapabilityExposure;
22
+ paymentBoundary: CheckoutCapabilityPaymentBoundary;
23
+ }
24
+ interface CheckoutCapabilityManifest {
25
+ schemaVersion: typeof CHECKOUT_CAPABILITY_MANIFEST_VERSION;
26
+ agentHost: CheckoutIntegrationComponent;
27
+ browserProvider: CheckoutIntegrationComponent;
28
+ adapter: CheckoutIntegrationComponent;
29
+ checkoutMethods: CheckoutMethodId[];
30
+ sessionBinding: CheckoutSessionBinding;
31
+ /** Must cover every capability available to the model, not only Conto integration tools. */
32
+ inventoryScope: CheckoutCapabilityInventoryScope;
33
+ capabilities: CheckoutCapabilityDescriptor[];
34
+ }
35
+ declare const CHECKOUT_CONFORMANCE_PROBE_IDS: readonly ["DENIAL_NO_MUTATION", "APPROVAL_SINGLE_USE", "AMOUNT_TAMPER_FAILS_CLOSED", "CART_TAMPER_FAILS_CLOSED", "MERCHANT_TAMPER_FAILS_CLOSED", "SESSION_TAMPER_FAILS_CLOSED", "TAB_TAMPER_FAILS_CLOSED", "TARGET_TAMPER_FAILS_CLOSED", "ALTERNATE_PAYMENT_PATHS_BLOCKED", "AMBIGUOUS_DISPATCH_NO_RETRY"];
36
+ type CheckoutConformanceProbeId = (typeof CHECKOUT_CONFORMANCE_PROBE_IDS)[number];
37
+ type CheckoutConformanceProbeOutcome = 'DENIED_NO_MUTATION' | 'ONE_DISPATCH_REPLAY_BLOCKED' | 'REJECTED_NO_MUTATION' | 'INDETERMINATE_NO_RETRY';
38
+ interface CheckoutConformanceProbeRequest {
39
+ probeId: CheckoutConformanceProbeId;
40
+ /** Fresh challenge that must be echoed by the trusted probe runner. */
41
+ challengeId: string;
42
+ manifestFingerprint: string;
43
+ }
44
+ interface CheckoutConformanceProbeObservation {
45
+ probeId: CheckoutConformanceProbeId;
46
+ challengeId: string;
47
+ outcome: CheckoutConformanceProbeOutcome;
48
+ }
49
+ type CheckoutConformanceProbeRunner = (request: CheckoutConformanceProbeRequest) => Promise<CheckoutConformanceProbeObservation> | CheckoutConformanceProbeObservation;
50
+ type CheckoutIntegrationStatus = 'ENFORCEABLE' | 'ADVISORY' | 'MISCONFIGURED' | 'UNVERIFIED';
51
+ type CheckoutVerificationFindingCode = 'MANIFEST_INVALID' | 'GUARDED_CHECKOUT_MISSING' | 'CAPABILITY_INVENTORY_INCOMPLETE' | 'SESSION_BINDING_NOT_PROVEN' | 'AGENT_PAYMENT_BYPASS' | 'CONFORMANCE_PROBES_NOT_RUN' | 'CONFORMANCE_PROBE_FAILED';
52
+ interface CheckoutVerificationFinding {
53
+ code: CheckoutVerificationFindingCode;
54
+ severity: 'BLOCKER' | 'WARNING';
55
+ message: string;
56
+ capabilityId?: string;
57
+ probeId?: CheckoutConformanceProbeId;
58
+ }
59
+ interface CheckoutConformanceProbeResult {
60
+ probeId: CheckoutConformanceProbeId;
61
+ status: 'PASSED' | 'FAILED' | 'NOT_RUN';
62
+ expectedOutcome: CheckoutConformanceProbeOutcome;
63
+ observedOutcome?: CheckoutConformanceProbeOutcome | 'INVALID_RESULT' | 'RUNNER_ERROR';
64
+ }
65
+ interface CheckoutIntegrationVerificationReport {
66
+ schemaVersion: typeof CHECKOUT_VERIFICATION_REPORT_VERSION;
67
+ status: CheckoutIntegrationStatus;
68
+ /** Conservative: false only after static isolation and every active probe pass. */
69
+ canBypass: boolean;
70
+ manifestFingerprint?: string;
71
+ verifiedAt: string;
72
+ inventory: {
73
+ totalCapabilities: number;
74
+ agentExposedCapabilities: number;
75
+ paymentSensitiveCapabilities: number;
76
+ bypassCapabilityIds: string[];
77
+ };
78
+ findings: CheckoutVerificationFinding[];
79
+ probes: CheckoutConformanceProbeResult[];
80
+ }
81
+ interface VerifyCheckoutIntegrationOptions {
82
+ /** Omit for a static report with UNVERIFIED status. */
83
+ runProbe?: CheckoutConformanceProbeRunner;
84
+ /** Test and host hook. Values must be unique, opaque identifiers. */
85
+ challengeId?: () => string;
86
+ now?: () => Date;
87
+ }
88
+ /**
89
+ * Verifies whether the configured agent path is an exclusive Conto payment boundary. Static
90
+ * inventory failures cannot be repaired by probe results. A report is ENFORCEABLE only after every
91
+ * fresh active probe passes; every other result conservatively reports canBypass=true.
92
+ */
93
+ declare function verifyCheckoutIntegration(value: CheckoutCapabilityManifest | unknown, options?: VerifyCheckoutIntegrationOptions): Promise<CheckoutIntegrationVerificationReport>;
94
+
95
+ export { CHECKOUT_CAPABILITY_KINDS, CHECKOUT_CAPABILITY_MANIFEST_VERSION, CHECKOUT_CONFORMANCE_PROBE_IDS, CHECKOUT_METHOD_IDS, CHECKOUT_VERIFICATION_REPORT_VERSION, type CheckoutCapabilityDescriptor, type CheckoutCapabilityExposure, type CheckoutCapabilityInventoryScope, type CheckoutCapabilityKind, type CheckoutCapabilityManifest, type CheckoutCapabilityPaymentBoundary, type CheckoutConformanceProbeId, type CheckoutConformanceProbeObservation, type CheckoutConformanceProbeOutcome, type CheckoutConformanceProbeRequest, type CheckoutConformanceProbeResult, type CheckoutConformanceProbeRunner, type CheckoutIntegrationComponent, type CheckoutIntegrationStatus, type CheckoutIntegrationVerificationReport, type CheckoutMethodId, type CheckoutSessionBinding, type CheckoutVerificationFinding, type CheckoutVerificationFindingCode, type VerifyCheckoutIntegrationOptions, verifyCheckoutIntegration };
@@ -0,0 +1,95 @@
1
+ declare const CHECKOUT_CAPABILITY_MANIFEST_VERSION: "conto.checkout-capabilities.v1";
2
+ declare const CHECKOUT_VERIFICATION_REPORT_VERSION: "conto.checkout-verification.v1";
3
+ declare const CHECKOUT_METHOD_IDS: readonly ["LINK", "CARD", "SHOP_PAY", "PAYPAL"];
4
+ type CheckoutMethodId = (typeof CHECKOUT_METHOD_IDS)[number];
5
+ declare const CHECKOUT_CAPABILITY_KINDS: readonly ["GUARDED_CHECKOUT", "NAVIGATION", "INSPECTION", "CLICK", "FORM_SUBMIT", "KEYBOARD_INPUT", "SCRIPT_EVALUATION", "CREDENTIAL_ACCESS", "PROVIDER_CONTROL", "ALTERNATE_PAYMENT"];
6
+ type CheckoutCapabilityKind = (typeof CHECKOUT_CAPABILITY_KINDS)[number];
7
+ type CheckoutCapabilityExposure = 'AGENT' | 'PRIVILEGED_RUNTIME' | 'AUTHENTICATED_OPERATOR';
8
+ type CheckoutCapabilityPaymentBoundary = 'NOT_PAYMENT_CAPABLE' | 'CONTO_GUARDED' | 'UNRESTRICTED';
9
+ type CheckoutSessionBinding = 'CONTO_RUNTIME' | 'PROOF_CARRYING_HANDOFF' | 'CALLER_ASSERTED';
10
+ type CheckoutCapabilityInventoryScope = 'COMPLETE_AGENT_CAPABILITY_SET' | 'DECLARED_SUBSET';
11
+ interface CheckoutIntegrationComponent {
12
+ /** Stable lowercase identifier, such as browserbase or browser-use-cloud. */
13
+ id: string;
14
+ /** Adapter or provider version reported by the trusted integration host. */
15
+ version: string;
16
+ }
17
+ interface CheckoutCapabilityDescriptor {
18
+ /** Stable unique identifier for the concrete tool or runtime capability. */
19
+ id: string;
20
+ kind: CheckoutCapabilityKind;
21
+ exposure: CheckoutCapabilityExposure;
22
+ paymentBoundary: CheckoutCapabilityPaymentBoundary;
23
+ }
24
+ interface CheckoutCapabilityManifest {
25
+ schemaVersion: typeof CHECKOUT_CAPABILITY_MANIFEST_VERSION;
26
+ agentHost: CheckoutIntegrationComponent;
27
+ browserProvider: CheckoutIntegrationComponent;
28
+ adapter: CheckoutIntegrationComponent;
29
+ checkoutMethods: CheckoutMethodId[];
30
+ sessionBinding: CheckoutSessionBinding;
31
+ /** Must cover every capability available to the model, not only Conto integration tools. */
32
+ inventoryScope: CheckoutCapabilityInventoryScope;
33
+ capabilities: CheckoutCapabilityDescriptor[];
34
+ }
35
+ declare const CHECKOUT_CONFORMANCE_PROBE_IDS: readonly ["DENIAL_NO_MUTATION", "APPROVAL_SINGLE_USE", "AMOUNT_TAMPER_FAILS_CLOSED", "CART_TAMPER_FAILS_CLOSED", "MERCHANT_TAMPER_FAILS_CLOSED", "SESSION_TAMPER_FAILS_CLOSED", "TAB_TAMPER_FAILS_CLOSED", "TARGET_TAMPER_FAILS_CLOSED", "ALTERNATE_PAYMENT_PATHS_BLOCKED", "AMBIGUOUS_DISPATCH_NO_RETRY"];
36
+ type CheckoutConformanceProbeId = (typeof CHECKOUT_CONFORMANCE_PROBE_IDS)[number];
37
+ type CheckoutConformanceProbeOutcome = 'DENIED_NO_MUTATION' | 'ONE_DISPATCH_REPLAY_BLOCKED' | 'REJECTED_NO_MUTATION' | 'INDETERMINATE_NO_RETRY';
38
+ interface CheckoutConformanceProbeRequest {
39
+ probeId: CheckoutConformanceProbeId;
40
+ /** Fresh challenge that must be echoed by the trusted probe runner. */
41
+ challengeId: string;
42
+ manifestFingerprint: string;
43
+ }
44
+ interface CheckoutConformanceProbeObservation {
45
+ probeId: CheckoutConformanceProbeId;
46
+ challengeId: string;
47
+ outcome: CheckoutConformanceProbeOutcome;
48
+ }
49
+ type CheckoutConformanceProbeRunner = (request: CheckoutConformanceProbeRequest) => Promise<CheckoutConformanceProbeObservation> | CheckoutConformanceProbeObservation;
50
+ type CheckoutIntegrationStatus = 'ENFORCEABLE' | 'ADVISORY' | 'MISCONFIGURED' | 'UNVERIFIED';
51
+ type CheckoutVerificationFindingCode = 'MANIFEST_INVALID' | 'GUARDED_CHECKOUT_MISSING' | 'CAPABILITY_INVENTORY_INCOMPLETE' | 'SESSION_BINDING_NOT_PROVEN' | 'AGENT_PAYMENT_BYPASS' | 'CONFORMANCE_PROBES_NOT_RUN' | 'CONFORMANCE_PROBE_FAILED';
52
+ interface CheckoutVerificationFinding {
53
+ code: CheckoutVerificationFindingCode;
54
+ severity: 'BLOCKER' | 'WARNING';
55
+ message: string;
56
+ capabilityId?: string;
57
+ probeId?: CheckoutConformanceProbeId;
58
+ }
59
+ interface CheckoutConformanceProbeResult {
60
+ probeId: CheckoutConformanceProbeId;
61
+ status: 'PASSED' | 'FAILED' | 'NOT_RUN';
62
+ expectedOutcome: CheckoutConformanceProbeOutcome;
63
+ observedOutcome?: CheckoutConformanceProbeOutcome | 'INVALID_RESULT' | 'RUNNER_ERROR';
64
+ }
65
+ interface CheckoutIntegrationVerificationReport {
66
+ schemaVersion: typeof CHECKOUT_VERIFICATION_REPORT_VERSION;
67
+ status: CheckoutIntegrationStatus;
68
+ /** Conservative: false only after static isolation and every active probe pass. */
69
+ canBypass: boolean;
70
+ manifestFingerprint?: string;
71
+ verifiedAt: string;
72
+ inventory: {
73
+ totalCapabilities: number;
74
+ agentExposedCapabilities: number;
75
+ paymentSensitiveCapabilities: number;
76
+ bypassCapabilityIds: string[];
77
+ };
78
+ findings: CheckoutVerificationFinding[];
79
+ probes: CheckoutConformanceProbeResult[];
80
+ }
81
+ interface VerifyCheckoutIntegrationOptions {
82
+ /** Omit for a static report with UNVERIFIED status. */
83
+ runProbe?: CheckoutConformanceProbeRunner;
84
+ /** Test and host hook. Values must be unique, opaque identifiers. */
85
+ challengeId?: () => string;
86
+ now?: () => Date;
87
+ }
88
+ /**
89
+ * Verifies whether the configured agent path is an exclusive Conto payment boundary. Static
90
+ * inventory failures cannot be repaired by probe results. A report is ENFORCEABLE only after every
91
+ * fresh active probe passes; every other result conservatively reports canBypass=true.
92
+ */
93
+ declare function verifyCheckoutIntegration(value: CheckoutCapabilityManifest | unknown, options?: VerifyCheckoutIntegrationOptions): Promise<CheckoutIntegrationVerificationReport>;
94
+
95
+ export { CHECKOUT_CAPABILITY_KINDS, CHECKOUT_CAPABILITY_MANIFEST_VERSION, CHECKOUT_CONFORMANCE_PROBE_IDS, CHECKOUT_METHOD_IDS, CHECKOUT_VERIFICATION_REPORT_VERSION, type CheckoutCapabilityDescriptor, type CheckoutCapabilityExposure, type CheckoutCapabilityInventoryScope, type CheckoutCapabilityKind, type CheckoutCapabilityManifest, type CheckoutCapabilityPaymentBoundary, type CheckoutConformanceProbeId, type CheckoutConformanceProbeObservation, type CheckoutConformanceProbeOutcome, type CheckoutConformanceProbeRequest, type CheckoutConformanceProbeResult, type CheckoutConformanceProbeRunner, type CheckoutIntegrationComponent, type CheckoutIntegrationStatus, type CheckoutIntegrationVerificationReport, type CheckoutMethodId, type CheckoutSessionBinding, type CheckoutVerificationFinding, type CheckoutVerificationFindingCode, type VerifyCheckoutIntegrationOptions, verifyCheckoutIntegration };
@@ -0,0 +1,400 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/checkout-verifier.ts
21
+ var checkout_verifier_exports = {};
22
+ __export(checkout_verifier_exports, {
23
+ CHECKOUT_CAPABILITY_KINDS: () => CHECKOUT_CAPABILITY_KINDS,
24
+ CHECKOUT_CAPABILITY_MANIFEST_VERSION: () => CHECKOUT_CAPABILITY_MANIFEST_VERSION,
25
+ CHECKOUT_CONFORMANCE_PROBE_IDS: () => CHECKOUT_CONFORMANCE_PROBE_IDS,
26
+ CHECKOUT_METHOD_IDS: () => CHECKOUT_METHOD_IDS,
27
+ CHECKOUT_VERIFICATION_REPORT_VERSION: () => CHECKOUT_VERIFICATION_REPORT_VERSION,
28
+ verifyCheckoutIntegration: () => verifyCheckoutIntegration
29
+ });
30
+ module.exports = __toCommonJS(checkout_verifier_exports);
31
+ var import_node_crypto = require("crypto");
32
+ var CHECKOUT_CAPABILITY_MANIFEST_VERSION = "conto.checkout-capabilities.v1";
33
+ var CHECKOUT_VERIFICATION_REPORT_VERSION = "conto.checkout-verification.v1";
34
+ var CHECKOUT_METHOD_IDS = ["LINK", "CARD", "SHOP_PAY", "PAYPAL"];
35
+ var CHECKOUT_CAPABILITY_KINDS = [
36
+ "GUARDED_CHECKOUT",
37
+ "NAVIGATION",
38
+ "INSPECTION",
39
+ "CLICK",
40
+ "FORM_SUBMIT",
41
+ "KEYBOARD_INPUT",
42
+ "SCRIPT_EVALUATION",
43
+ "CREDENTIAL_ACCESS",
44
+ "PROVIDER_CONTROL",
45
+ "ALTERNATE_PAYMENT"
46
+ ];
47
+ var CHECKOUT_CONFORMANCE_PROBE_IDS = [
48
+ "DENIAL_NO_MUTATION",
49
+ "APPROVAL_SINGLE_USE",
50
+ "AMOUNT_TAMPER_FAILS_CLOSED",
51
+ "CART_TAMPER_FAILS_CLOSED",
52
+ "MERCHANT_TAMPER_FAILS_CLOSED",
53
+ "SESSION_TAMPER_FAILS_CLOSED",
54
+ "TAB_TAMPER_FAILS_CLOSED",
55
+ "TARGET_TAMPER_FAILS_CLOSED",
56
+ "ALTERNATE_PAYMENT_PATHS_BLOCKED",
57
+ "AMBIGUOUS_DISPATCH_NO_RETRY"
58
+ ];
59
+ var COMPONENT_ID = /^[a-z0-9][a-z0-9._-]{0,127}$/;
60
+ var COMPONENT_VERSION = /^[A-Za-z0-9][A-Za-z0-9.+_-]{0,63}$/;
61
+ var CAPABILITY_ID = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;
62
+ var CHALLENGE_ID = /^[A-Za-z0-9][A-Za-z0-9_-]{15,127}$/;
63
+ var EXPOSURES = /* @__PURE__ */ new Set([
64
+ "AGENT",
65
+ "PRIVILEGED_RUNTIME",
66
+ "AUTHENTICATED_OPERATOR"
67
+ ]);
68
+ var PAYMENT_BOUNDARIES = /* @__PURE__ */ new Set([
69
+ "NOT_PAYMENT_CAPABLE",
70
+ "CONTO_GUARDED",
71
+ "UNRESTRICTED"
72
+ ]);
73
+ var SESSION_BINDINGS = /* @__PURE__ */ new Set([
74
+ "CONTO_RUNTIME",
75
+ "PROOF_CARRYING_HANDOFF",
76
+ "CALLER_ASSERTED"
77
+ ]);
78
+ var INVENTORY_SCOPES = /* @__PURE__ */ new Set([
79
+ "COMPLETE_AGENT_CAPABILITY_SET",
80
+ "DECLARED_SUBSET"
81
+ ]);
82
+ var METHOD_IDS = new Set(CHECKOUT_METHOD_IDS);
83
+ var CAPABILITY_KINDS = new Set(CHECKOUT_CAPABILITY_KINDS);
84
+ var PROBE_OUTCOMES = /* @__PURE__ */ new Set([
85
+ "DENIED_NO_MUTATION",
86
+ "ONE_DISPATCH_REPLAY_BLOCKED",
87
+ "REJECTED_NO_MUTATION",
88
+ "INDETERMINATE_NO_RETRY"
89
+ ]);
90
+ var PAYMENT_SENSITIVE_KINDS = /* @__PURE__ */ new Set([
91
+ "GUARDED_CHECKOUT",
92
+ "CLICK",
93
+ "FORM_SUBMIT",
94
+ "KEYBOARD_INPUT",
95
+ "SCRIPT_EVALUATION",
96
+ "CREDENTIAL_ACCESS",
97
+ "PROVIDER_CONTROL",
98
+ "ALTERNATE_PAYMENT"
99
+ ]);
100
+ var EXPECTED_PROBE_OUTCOMES = {
101
+ DENIAL_NO_MUTATION: "DENIED_NO_MUTATION",
102
+ APPROVAL_SINGLE_USE: "ONE_DISPATCH_REPLAY_BLOCKED",
103
+ AMOUNT_TAMPER_FAILS_CLOSED: "REJECTED_NO_MUTATION",
104
+ CART_TAMPER_FAILS_CLOSED: "REJECTED_NO_MUTATION",
105
+ MERCHANT_TAMPER_FAILS_CLOSED: "REJECTED_NO_MUTATION",
106
+ SESSION_TAMPER_FAILS_CLOSED: "REJECTED_NO_MUTATION",
107
+ TAB_TAMPER_FAILS_CLOSED: "REJECTED_NO_MUTATION",
108
+ TARGET_TAMPER_FAILS_CLOSED: "REJECTED_NO_MUTATION",
109
+ ALTERNATE_PAYMENT_PATHS_BLOCKED: "REJECTED_NO_MUTATION",
110
+ AMBIGUOUS_DISPATCH_NO_RETRY: "INDETERMINATE_NO_RETRY"
111
+ };
112
+ function isRecord(value) {
113
+ return !!value && typeof value === "object" && !Array.isArray(value);
114
+ }
115
+ function hasExactKeys(value, keys) {
116
+ const actual = Object.keys(value).sort();
117
+ const expected = [...keys].sort();
118
+ return actual.length === expected.length && actual.every((key, index) => key === expected[index]);
119
+ }
120
+ function component(value) {
121
+ if (!isRecord(value) || !hasExactKeys(value, ["id", "version"])) return false;
122
+ return typeof value.id === "string" && COMPONENT_ID.test(value.id) && typeof value.version === "string" && COMPONENT_VERSION.test(value.version);
123
+ }
124
+ function capability(value) {
125
+ if (!isRecord(value) || !hasExactKeys(value, ["id", "kind", "exposure", "paymentBoundary"])) {
126
+ return false;
127
+ }
128
+ return typeof value.id === "string" && CAPABILITY_ID.test(value.id) && typeof value.kind === "string" && CAPABILITY_KINDS.has(value.kind) && typeof value.exposure === "string" && EXPOSURES.has(value.exposure) && typeof value.paymentBoundary === "string" && PAYMENT_BOUNDARIES.has(value.paymentBoundary);
129
+ }
130
+ function manifest(value) {
131
+ if (!isRecord(value) || !hasExactKeys(value, [
132
+ "schemaVersion",
133
+ "agentHost",
134
+ "browserProvider",
135
+ "adapter",
136
+ "checkoutMethods",
137
+ "sessionBinding",
138
+ "inventoryScope",
139
+ "capabilities"
140
+ ]) || value.schemaVersion !== CHECKOUT_CAPABILITY_MANIFEST_VERSION || !component(value.agentHost) || !component(value.browserProvider) || !component(value.adapter) || !Array.isArray(value.checkoutMethods) || value.checkoutMethods.length === 0 || value.checkoutMethods.length > CHECKOUT_METHOD_IDS.length || !value.checkoutMethods.every(
141
+ (method) => typeof method === "string" && METHOD_IDS.has(method)
142
+ ) || new Set(value.checkoutMethods).size !== value.checkoutMethods.length || typeof value.sessionBinding !== "string" || !SESSION_BINDINGS.has(value.sessionBinding) || typeof value.inventoryScope !== "string" || !INVENTORY_SCOPES.has(value.inventoryScope) || !Array.isArray(value.capabilities) || value.capabilities.length === 0 || value.capabilities.length > 100 || !value.capabilities.every(capability)) {
143
+ return false;
144
+ }
145
+ return new Set(value.capabilities.map(({ id }) => id)).size === value.capabilities.length;
146
+ }
147
+ function fingerprint(value) {
148
+ const canonical = {
149
+ schemaVersion: value.schemaVersion,
150
+ agentHost: { id: value.agentHost.id, version: value.agentHost.version },
151
+ browserProvider: { id: value.browserProvider.id, version: value.browserProvider.version },
152
+ adapter: { id: value.adapter.id, version: value.adapter.version },
153
+ checkoutMethods: [...value.checkoutMethods].sort(),
154
+ sessionBinding: value.sessionBinding,
155
+ inventoryScope: value.inventoryScope,
156
+ capabilities: value.capabilities.map(({ id, kind, exposure, paymentBoundary }) => ({
157
+ id,
158
+ kind,
159
+ exposure,
160
+ paymentBoundary
161
+ })).sort((left, right) => left.id < right.id ? -1 : left.id > right.id ? 1 : 0)
162
+ };
163
+ return `sha256:${(0, import_node_crypto.createHash)("sha256").update(JSON.stringify(canonical)).digest("hex")}`;
164
+ }
165
+ function emptyProbeResults(status) {
166
+ return CHECKOUT_CONFORMANCE_PROBE_IDS.map((probeId) => ({
167
+ probeId,
168
+ status,
169
+ expectedOutcome: EXPECTED_PROBE_OUTCOMES[probeId]
170
+ }));
171
+ }
172
+ function report(input) {
173
+ return Object.freeze({
174
+ schemaVersion: CHECKOUT_VERIFICATION_REPORT_VERSION,
175
+ status: input.status,
176
+ canBypass: input.status !== "ENFORCEABLE",
177
+ ...input.manifestFingerprint ? { manifestFingerprint: input.manifestFingerprint } : {},
178
+ verifiedAt: input.verifiedAt,
179
+ inventory: Object.freeze({
180
+ ...input.inventory,
181
+ bypassCapabilityIds: Object.freeze([...input.inventory.bypassCapabilityIds])
182
+ }),
183
+ findings: Object.freeze(input.findings.map((finding) => Object.freeze({ ...finding }))),
184
+ probes: Object.freeze(input.probes.map((probe) => Object.freeze({ ...probe })))
185
+ });
186
+ }
187
+ function probeObservation(value, request) {
188
+ if (!isRecord(value) || !hasExactKeys(value, ["probeId", "challengeId", "outcome"])) return false;
189
+ return value.probeId === request.probeId && value.challengeId === request.challengeId && typeof value.outcome === "string" && PROBE_OUTCOMES.has(value.outcome);
190
+ }
191
+ async function verifyCheckoutIntegration(value, options = {}) {
192
+ const now = options.now ?? (() => /* @__PURE__ */ new Date());
193
+ let verifiedAtDate;
194
+ try {
195
+ verifiedAtDate = now();
196
+ } catch {
197
+ verifiedAtDate = null;
198
+ }
199
+ const validVerifiedAt = verifiedAtDate instanceof Date && Number.isFinite(verifiedAtDate.getTime());
200
+ const verifiedAt = validVerifiedAt ? verifiedAtDate.toISOString() : (/* @__PURE__ */ new Date(0)).toISOString();
201
+ const emptyInventory = {
202
+ totalCapabilities: 0,
203
+ agentExposedCapabilities: 0,
204
+ paymentSensitiveCapabilities: 0,
205
+ bypassCapabilityIds: []
206
+ };
207
+ if (!validVerifiedAt || !manifest(value)) {
208
+ return report({
209
+ status: "MISCONFIGURED",
210
+ verifiedAt,
211
+ inventory: emptyInventory,
212
+ findings: [
213
+ {
214
+ code: "MANIFEST_INVALID",
215
+ severity: "BLOCKER",
216
+ message: "The checkout capability manifest is invalid."
217
+ }
218
+ ],
219
+ probes: emptyProbeResults("NOT_RUN")
220
+ });
221
+ }
222
+ const manifestFingerprint = fingerprint(value);
223
+ const agentCapabilities = value.capabilities.filter(({ exposure }) => exposure === "AGENT");
224
+ const paymentSensitiveCapabilities = value.capabilities.filter(
225
+ ({ kind, paymentBoundary }) => paymentBoundary === "UNRESTRICTED" || PAYMENT_SENSITIVE_KINDS.has(kind)
226
+ );
227
+ const bypassCapabilities = agentCapabilities.filter(
228
+ ({ paymentBoundary }) => paymentBoundary === "UNRESTRICTED"
229
+ );
230
+ const inventory = {
231
+ totalCapabilities: value.capabilities.length,
232
+ agentExposedCapabilities: agentCapabilities.length,
233
+ paymentSensitiveCapabilities: paymentSensitiveCapabilities.length,
234
+ bypassCapabilityIds: bypassCapabilities.map(({ id }) => id).sort()
235
+ };
236
+ const findings = [];
237
+ const guardedCheckoutPresent = agentCapabilities.some(
238
+ ({ kind, paymentBoundary }) => kind === "GUARDED_CHECKOUT" && paymentBoundary === "CONTO_GUARDED"
239
+ );
240
+ if (!guardedCheckoutPresent) {
241
+ findings.push({
242
+ code: "GUARDED_CHECKOUT_MISSING",
243
+ severity: "BLOCKER",
244
+ message: "No agent-facing checkout capability is bound to the Conto guarded runtime."
245
+ });
246
+ }
247
+ if (value.inventoryScope === "DECLARED_SUBSET") {
248
+ findings.push({
249
+ code: "CAPABILITY_INVENTORY_INCOMPLETE",
250
+ severity: "BLOCKER",
251
+ message: "The manifest does not cover every capability exposed to the agent."
252
+ });
253
+ }
254
+ if (value.sessionBinding === "CALLER_ASSERTED") {
255
+ findings.push({
256
+ code: "SESSION_BINDING_NOT_PROVEN",
257
+ severity: "BLOCKER",
258
+ message: "Browser-session ownership is caller asserted rather than runtime owned or proven."
259
+ });
260
+ }
261
+ for (const bypass of bypassCapabilities) {
262
+ findings.push({
263
+ code: "AGENT_PAYMENT_BYPASS",
264
+ severity: "BLOCKER",
265
+ capabilityId: bypass.id,
266
+ message: "An agent-exposed capability can trigger payment outside the Conto guard."
267
+ });
268
+ }
269
+ if (findings.length > 0) {
270
+ const advisory = guardedCheckoutPresent && findings.every(
271
+ ({ code }) => [
272
+ "CAPABILITY_INVENTORY_INCOMPLETE",
273
+ "SESSION_BINDING_NOT_PROVEN",
274
+ "AGENT_PAYMENT_BYPASS"
275
+ ].includes(code)
276
+ );
277
+ return report({
278
+ status: advisory ? "ADVISORY" : "MISCONFIGURED",
279
+ manifestFingerprint,
280
+ verifiedAt,
281
+ inventory,
282
+ findings,
283
+ probes: emptyProbeResults("NOT_RUN")
284
+ });
285
+ }
286
+ if (!options.runProbe) {
287
+ return report({
288
+ status: "UNVERIFIED",
289
+ manifestFingerprint,
290
+ verifiedAt,
291
+ inventory,
292
+ findings: [
293
+ {
294
+ code: "CONFORMANCE_PROBES_NOT_RUN",
295
+ severity: "WARNING",
296
+ message: "Static isolation passed, but active checkout conformance probes were not run."
297
+ }
298
+ ],
299
+ probes: emptyProbeResults("NOT_RUN")
300
+ });
301
+ }
302
+ const makeChallengeId = options.challengeId ?? import_node_crypto.randomUUID;
303
+ const usedChallenges = /* @__PURE__ */ new Set();
304
+ const probes = [];
305
+ for (const probeId of CHECKOUT_CONFORMANCE_PROBE_IDS) {
306
+ const expectedOutcome = EXPECTED_PROBE_OUTCOMES[probeId];
307
+ let challengeId;
308
+ try {
309
+ challengeId = makeChallengeId();
310
+ } catch {
311
+ challengeId = null;
312
+ }
313
+ if (typeof challengeId !== "string" || !CHALLENGE_ID.test(challengeId) || usedChallenges.has(challengeId)) {
314
+ probes.push({
315
+ probeId,
316
+ status: "FAILED",
317
+ expectedOutcome,
318
+ observedOutcome: "INVALID_RESULT"
319
+ });
320
+ findings.push({
321
+ code: "CONFORMANCE_PROBE_FAILED",
322
+ severity: "BLOCKER",
323
+ probeId,
324
+ message: "The checkout conformance probe did not return a valid fresh result."
325
+ });
326
+ continue;
327
+ }
328
+ usedChallenges.add(challengeId);
329
+ const request = Object.freeze({ probeId, challengeId, manifestFingerprint });
330
+ try {
331
+ const observation = await options.runProbe(request);
332
+ if (!probeObservation(observation, request)) {
333
+ probes.push({
334
+ probeId,
335
+ status: "FAILED",
336
+ expectedOutcome,
337
+ observedOutcome: "INVALID_RESULT"
338
+ });
339
+ findings.push({
340
+ code: "CONFORMANCE_PROBE_FAILED",
341
+ severity: "BLOCKER",
342
+ probeId,
343
+ message: "The checkout conformance probe returned an invalid or failing result."
344
+ });
345
+ continue;
346
+ }
347
+ if (observation.outcome !== expectedOutcome) {
348
+ probes.push({
349
+ probeId,
350
+ status: "FAILED",
351
+ expectedOutcome,
352
+ observedOutcome: observation.outcome
353
+ });
354
+ findings.push({
355
+ code: "CONFORMANCE_PROBE_FAILED",
356
+ severity: "BLOCKER",
357
+ probeId,
358
+ message: "The checkout conformance probe observed a failing outcome."
359
+ });
360
+ continue;
361
+ }
362
+ probes.push({
363
+ probeId,
364
+ status: "PASSED",
365
+ expectedOutcome,
366
+ observedOutcome: observation.outcome
367
+ });
368
+ } catch {
369
+ probes.push({
370
+ probeId,
371
+ status: "FAILED",
372
+ expectedOutcome,
373
+ observedOutcome: "RUNNER_ERROR"
374
+ });
375
+ findings.push({
376
+ code: "CONFORMANCE_PROBE_FAILED",
377
+ severity: "BLOCKER",
378
+ probeId,
379
+ message: "The checkout conformance probe runner failed."
380
+ });
381
+ }
382
+ }
383
+ return report({
384
+ status: findings.length === 0 ? "ENFORCEABLE" : "MISCONFIGURED",
385
+ manifestFingerprint,
386
+ verifiedAt,
387
+ inventory,
388
+ findings,
389
+ probes
390
+ });
391
+ }
392
+ // Annotate the CommonJS export names for ESM import in node:
393
+ 0 && (module.exports = {
394
+ CHECKOUT_CAPABILITY_KINDS,
395
+ CHECKOUT_CAPABILITY_MANIFEST_VERSION,
396
+ CHECKOUT_CONFORMANCE_PROBE_IDS,
397
+ CHECKOUT_METHOD_IDS,
398
+ CHECKOUT_VERIFICATION_REPORT_VERSION,
399
+ verifyCheckoutIntegration
400
+ });